#12177 Summary Ensemble: Improve automatic naming

This commit is contained in:
Magne Sjaastad
2025-02-28 16:14:55 +01:00
committed by GitHub
parent d05de77748
commit edeb0cdbe2
32 changed files with 761 additions and 201 deletions
@@ -21,6 +21,7 @@
#include "RiaFilePathTools.h"
#include "RiaTextStringTools.h"
#include "Summary/RiaSummaryDefines.h"
#include "Tools/RiaStdStringTools.h"
#include "RimCaseDisplayNameTools.h"
#include "RimProject.h"
@@ -32,21 +33,114 @@
#include <QFileInfo>
#include <QRegularExpression>
template <>
void caf::AppEnum<RiaEnsembleNameTools::EnsembleGroupingMode>::setUp()
#include <regex>
namespace internal
{
addItem( RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE, "FMU_FOLDER_MODE", "Sub Folder" );
addItem( RiaEnsembleNameTools::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE, "EVEREST_FOLDER_MODE", "Main Folder" );
addItem( RiaEnsembleNameTools::EnsembleGroupingMode::NONE, "None", "None" );
setDefault( RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
// Find the last common folder in the common prefix of paths
std::string findLastCommonFolder( const std::vector<std::string>& paths )
{
if ( paths.empty() )
{
return "";
}
auto commonPrefix = RiaStdStringTools::findCommonPrefix( paths );
if ( commonPrefix.empty() )
{
return "";
}
// Handle the case where common prefix doesn't end at a folder boundary
// Find the last slash in the common prefix
size_t lastSlashPos = commonPrefix.find_last_of( '/' );
if ( lastSlashPos == std::string::npos )
{
// No folder structure in the common prefix
return "";
}
std::string commonPath = commonPrefix.substr( 0, lastSlashPos );
std::vector<std::string> folders = RiaStdStringTools::splitString( commonPath, '/' );
return folders.empty() ? "" : folders.back();
}
} // namespace internal
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<std::pair<std::string, std::string>, std::vector<std::string>>
RiaEnsembleNameTools::groupFilePathsFmu( const std::vector<std::string>& filepaths )
{
std::map<std::pair<std::string, std::string>, std::vector<std::string>> groupedPaths;
// Example path
// "f:/Models/scratch/project_a/realization-0/iter-0/eclipse/model/PROJECT-0.SMSPEC"
//
// Regex pattern to extract case name and iteration folder
// Group 1: Case folder name (top level folder)
// Group 2: Iteration folder name
std::regex pattern( R"(.*[\\/]+([^\\/]+)[\\/]+realization-\d+[\\/]+([^\\/]+).*)", std::regex::icase );
for ( const std::string& filepath : filepaths )
{
std::smatch matches;
if ( std::regex_match( filepath, matches, pattern ) )
{
auto key = std::make_pair( matches[1].str(), matches[2].str() );
groupedPaths[key].push_back( filepath );
}
}
return groupedPaths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaEnsembleNameTools::findSuitableEnsembleName( const QStringList& fileNames, EnsembleGroupingMode folderLevel )
std::map<std::pair<std::string, std::string>, std::vector<std::string>>
RiaEnsembleNameTools::groupFilePathsEverest( const std::vector<std::string>& filepaths )
{
if ( folderLevel == EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
std::map<std::pair<std::string, std::string>, std::vector<std::string>> groupedPaths;
std::vector<std::string> normalizedPaths;
for ( const auto& filepath : filepaths )
{
normalizedPaths.push_back( RiaFilePathTools::normalizePath( filepath ) );
}
auto commonPrefix = RiaStdStringTools::findCommonPrefix( normalizedPaths );
// strip partial folder name in prefix
auto lastSlashPos = commonPrefix.find_last_of( '/' );
if ( lastSlashPos != std::string::npos )
{
commonPrefix = commonPrefix.substr( 0, lastSlashPos );
}
auto commonFolder = internal::findLastCommonFolder( normalizedPaths );
for ( const auto& filepath : normalizedPaths )
{
auto rest = filepath.substr( commonPrefix.size() );
auto parts = RiaStdStringTools::splitString( rest, '/' );
std::string firstFolder = parts.empty() ? "" : parts.front();
groupedPaths[{ commonFolder, firstFolder }].push_back( filepath );
}
return groupedPaths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaEnsembleNameTools::findSuitableEnsembleName( const QStringList& fileNames, RiaDefines::EnsembleGroupingMode folderLevel )
{
if ( folderLevel == RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
{
QString commonRoot = RiaTextStringTools::commonRoot( fileNames );
commonRoot = commonRoot.left( commonRoot.lastIndexOf( '/' ) );
@@ -92,7 +186,7 @@ QString RiaEnsembleNameTools::findSuitableEnsembleName( const QStringList& fileN
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QStringList> RiaEnsembleNameTools::groupFilesByEnsemble( const QStringList& fileNames, EnsembleGroupingMode groupingMode )
std::vector<QStringList> RiaEnsembleNameTools::groupFilesByEnsemble( const QStringList& fileNames, RiaDefines::EnsembleGroupingMode groupingMode )
{
std::vector<QStringList> componentsForAllFilePaths;
@@ -176,6 +270,79 @@ std::map<QString, QStringList> RiaEnsembleNameTools::groupFilesByCustomEnsemble(
return groupedByIteration;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<QString, QStringList> RiaEnsembleNameTools::groupFilesByEnsembleName( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode )
{
std::map<QString, QStringList> ensemblePaths;
if ( groupingMode == RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE )
{
std::vector<std::string> allPaths;
for ( const auto& fileName : fileNames )
{
allPaths.push_back( fileName.toStdString() );
}
auto groupedPaths = RiaEnsembleNameTools::groupFilePathsFmu( allPaths );
auto shouldIncludeTopLevel = []( const auto& paths ) -> bool
{
std::set<std::string> topLevelFolderNames;
for ( auto group : paths )
{
topLevelFolderNames.insert( group.first.first );
}
return topLevelFolderNames.size() > 1;
};
bool includeTopLevel = shouldIncludeTopLevel( groupedPaths );
for ( auto group : groupedPaths )
{
std::string ensembleName;
if ( includeTopLevel )
{
ensembleName += group.first.first;
ensembleName += ", ";
}
ensembleName += group.first.second;
QStringList groupPaths;
for ( const auto& path : group.second )
{
groupPaths.push_back( QString::fromStdString( path ) );
}
ensemblePaths[QString::fromStdString( ensembleName )] = groupPaths;
}
}
else if ( groupingMode == RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
{
std::vector<std::string> allPaths;
for ( const auto& fileName : fileNames )
{
allPaths.push_back( fileName.toStdString() );
}
auto groupedPaths = RiaEnsembleNameTools::groupFilePathsEverest( allPaths );
for ( auto group : groupedPaths )
{
std::string ensembleName = group.first.first + ", " + group.first.second;
QStringList groupPaths;
for ( const auto& path : group.second )
{
groupPaths.push_back( QString::fromStdString( path ) );
}
ensemblePaths[QString::fromStdString( ensembleName )] = groupPaths;
}
}
return ensemblePaths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -233,6 +400,37 @@ std::map<QString, std::pair<QString, QString>>
return mapping;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaEnsembleNameTools::updateAutoNameEnsembles( std::vector<RimSummaryEnsemble*> ensembles )
{
std::set<std::string> key1;
std::set<std::string> key2;
for ( const auto& ensemble : ensembles )
{
const auto keys = ensemble->nameKeys();
key1.insert( keys.first );
key2.insert( keys.second );
}
bool useKey1 = key1.size() > 1;
bool useKey2 = key2.size() > 1;
if ( !useKey1 && !useKey2 )
{
useKey2 = true;
}
for ( auto ensemble : ensembles )
{
ensemble->setUsePathKey1( useKey1 );
ensemble->setUsePathKey2( useKey2 );
ensemble->ensureNameIsUpdated();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -283,12 +481,12 @@ QString RiaEnsembleNameTools::uniqueShortNameForSummaryCase( RimSummaryCase* sum
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RiaEnsembleNameTools::findUniqueEnsembleNames( const QStringList& fileNames,
const std::vector<QStringList>& fileNameComponents,
EnsembleGroupingMode groupingMode )
QStringList RiaEnsembleNameTools::findUniqueEnsembleNames( const QStringList& fileNames,
const std::vector<QStringList>& fileNameComponents,
RiaDefines::EnsembleGroupingMode groupingMode )
{
QStringList iterations;
if ( groupingMode == EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
if ( groupingMode == RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
{
QString commonRoot = RiaTextStringTools::commonRoot( fileNames );
QStringList rootComponents = RiaFilePathTools::splitPathIntoComponents( commonRoot );
@@ -319,7 +517,7 @@ QStringList RiaEnsembleNameTools::findUniqueEnsembleNames( const QStringList&
iterations.push_back( ensembleName );
}
}
else if ( groupingMode == EnsembleGroupingMode::FMU_FOLDER_STRUCTURE )
else if ( groupingMode == RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE )
{
// Find list of all folders inside a folder matching realization-*
QRegularExpression realizationRe( "realization\\-\\d+" );
@@ -26,6 +26,7 @@
#include "Summary/RiaSummaryDefines.h"
class RimSummaryCase;
class RimSummaryEnsemble;
//==================================================================================================
//
@@ -33,15 +34,7 @@ class RimSummaryCase;
class RiaEnsembleNameTools
{
public:
enum class EnsembleGroupingMode
{
FMU_FOLDER_STRUCTURE,
EVEREST_FOLDER_STRUCTURE,
NONE
};
public:
static QString findSuitableEnsembleName( const QStringList& fileNames, EnsembleGroupingMode groupingMode );
static QString findSuitableEnsembleName( const QStringList& fileNames, RiaDefines::EnsembleGroupingMode groupingMode );
static QString findCommonBaseName( const QStringList& fileNames );
static QString
@@ -51,18 +44,28 @@ public:
const std::map<QString, QStringList>& keyFileComponentsForAllFiles,
const QString& ensembleCaseName );
static std::vector<QStringList> groupFilesByEnsemble( const QStringList& fileNames, EnsembleGroupingMode groupingMode );
static std::map<std::pair<std::string, std::string>, std::vector<std::string>>
groupFilePathsFmu( const std::vector<std::string>& filepaths );
static std::map<std::pair<std::string, std::string>, std::vector<std::string>>
groupFilePathsEverest( const std::vector<std::string>& filepaths );
static std::vector<QStringList> groupFilesByEnsemble( const QStringList& fileNames, RiaDefines::EnsembleGroupingMode groupingMode );
static std::map<QString, QStringList> groupFilesByEnsembleName( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode );
static std::map<QString, QStringList> groupFilesByCustomEnsemble( const QStringList& fileNames, RiaDefines::FileType fileType );
static std::map<QString, std::pair<QString, QString>> findUniqueCustomEnsembleNames( RiaDefines::FileType fileType,
const QStringList& fileNames,
const std::vector<QStringList>& fileNameComponents );
static void updateAutoNameEnsembles( std::vector<RimSummaryEnsemble*> ensembles );
static QString uniqueShortNameForEnsembleCase( RimSummaryCase* summaryCase );
static QString uniqueShortNameForSummaryCase( RimSummaryCase* summaryCase );
private:
static QStringList findUniqueEnsembleNames( const QStringList& fileNames,
const std::vector<QStringList>& fileNameComponents,
EnsembleGroupingMode groupingMode );
static QStringList findUniqueEnsembleNames( const QStringList& fileNames,
const std::vector<QStringList>& fileNameComponents,
RiaDefines::EnsembleGroupingMode groupingMode );
};
@@ -29,10 +29,13 @@
#include <memory>
#include <set>
namespace RiaFilePathTools
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QChar RiaFilePathTools::separator()
const QChar separator()
{
return '/';
}
@@ -40,7 +43,7 @@ const QChar RiaFilePathTools::separator()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::toInternalSeparator( const QString& path )
QString toInternalSeparator( const QString& path )
{
QString currNativeSep = QDir::separator();
@@ -58,7 +61,16 @@ QString RiaFilePathTools::toInternalSeparator( const QString& path )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString& RiaFilePathTools::appendSeparatorIfNo( QString& path )
std::string normalizePath( std::string path )
{
std::replace( path.begin(), path.end(), '\\', '/' );
return path;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString& appendSeparatorIfNo( QString& path )
{
if ( !path.endsWith( separator() ) )
{
@@ -70,7 +82,7 @@ QString& RiaFilePathTools::appendSeparatorIfNo( QString& path )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::relativePath( const QString& rootDir, const QString& dir )
QString relativePath( const QString& rootDir, const QString& dir )
{
if ( dir.startsWith( rootDir ) )
{
@@ -89,7 +101,7 @@ QString RiaFilePathTools::relativePath( const QString& rootDir, const QString& d
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaFilePathTools::equalPaths( const QString& path1, const QString& path2 )
bool equalPaths( const QString& path1, const QString& path2 )
{
QString p1 = path1;
QString p2 = path2;
@@ -101,7 +113,7 @@ bool RiaFilePathTools::equalPaths( const QString& path1, const QString& path2 )
//--------------------------------------------------------------------------------------------------
/// Own canonicalPath method since the QDir::canonicalPath seems to not work
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::canonicalPath( const QString& path )
QString canonicalPath( const QString& path )
{
return QDir( path ).absolutePath();
}
@@ -109,7 +121,7 @@ QString RiaFilePathTools::canonicalPath( const QString& path )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<QString, QString> RiaFilePathTools::toFolderAndFileName( const QString& absFileName )
std::pair<QString, QString> toFolderAndFileName( const QString& absFileName )
{
auto absFN = toInternalSeparator( absFileName );
int lastSep = absFN.lastIndexOf( separator() );
@@ -126,7 +138,7 @@ std::pair<QString, QString> RiaFilePathTools::toFolderAndFileName( const QString
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::removeDuplicatePathSeparators( const QString& path )
QString removeDuplicatePathSeparators( const QString& path )
{
QString correctedPath = path;
QString prefix;
@@ -154,7 +166,7 @@ QString RiaFilePathTools::removeDuplicatePathSeparators( const QString& path )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::rootSearchPathFromSearchFilter( const QString& searchFilter )
QString rootSearchPathFromSearchFilter( const QString& searchFilter )
{
QStringList pathPartList = searchFilter.split( separator() );
@@ -184,7 +196,7 @@ QString RiaFilePathTools::rootSearchPathFromSearchFilter( const QString& searchF
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::commonRootOfFileNames( const QStringList& fileList )
QString commonRootOfFileNames( const QStringList& fileList )
{
QStringList fileNameList;
for ( auto filePath : fileList )
@@ -200,7 +212,7 @@ QString RiaFilePathTools::commonRootOfFileNames( const QStringList& fileList )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RiaFilePathTools::splitPathIntoComponents( const QString& inputPath, bool splitExtensionIntoSeparateEntry )
QStringList splitPathIntoComponents( const QString& inputPath, bool splitExtensionIntoSeparateEntry )
{
auto path = QDir::cleanPath( inputPath );
@@ -325,7 +337,7 @@ void pathToNode( PathNode* node, QStringList* path )
/// Takes a list of file paths and returns a map with the key components that separate the path
/// from the others.
//--------------------------------------------------------------------------------------------------
std::map<QString, QStringList> RiaFilePathTools::keyPathComponentsForEachFilePath( const QStringList& filePaths )
std::map<QString, QStringList> keyPathComponentsForEachFilePath( const QStringList& filePaths )
{
std::map<QString, QStringList> allComponents;
@@ -360,7 +372,7 @@ std::map<QString, QStringList> RiaFilePathTools::keyPathComponentsForEachFilePat
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaFilePathTools::isFirstOlderThanSecond( const std::string& firstFileName, const std::string& secondFileName )
bool isFirstOlderThanSecond( const std::string& firstFileName, const std::string& secondFileName )
{
if ( !std::filesystem::exists( firstFileName ) || !std::filesystem::exists( secondFileName ) ) return false;
@@ -373,7 +385,7 @@ bool RiaFilePathTools::isFirstOlderThanSecond( const std::string& firstFileName,
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RiaFilePathTools::makeSuitableAsFileName( const std::string candidateName )
std::string makeSuitableAsFileName( const std::string candidateName )
{
if ( candidateName.empty() ) return "noname";
@@ -388,3 +400,5 @@ std::string RiaFilePathTools::makeSuitableAsFileName( const std::string candidat
return tmp.toStdString();
}
} // namespace RiaFilePathTools
@@ -28,27 +28,25 @@
//==================================================================================================
//
//
//
//==================================================================================================
class RiaFilePathTools
namespace RiaFilePathTools
{
public:
static const QChar separator();
static QString toInternalSeparator( const QString& path );
static QString& appendSeparatorIfNo( QString& path );
static QString relativePath( const QString& rootDir, const QString& dir );
static bool equalPaths( const QString& path1, const QString& path2 );
static QString canonicalPath( const QString& path );
static std::pair<QString, QString> toFolderAndFileName( const QString& absFileName );
static QString removeDuplicatePathSeparators( const QString& path );
static QString rootSearchPathFromSearchFilter( const QString& searchFilter );
static QString commonRootOfFileNames( const QStringList& filePaths );
static std::string makeSuitableAsFileName( const std::string candidateName );
const QChar separator();
QString toInternalSeparator( const QString& path );
QString& appendSeparatorIfNo( QString& path );
QString relativePath( const QString& rootDir, const QString& dir );
bool equalPaths( const QString& path1, const QString& path2 );
QString canonicalPath( const QString& path );
std::pair<QString, QString> toFolderAndFileName( const QString& absFileName );
QString removeDuplicatePathSeparators( const QString& path );
QString rootSearchPathFromSearchFilter( const QString& searchFilter );
QString commonRootOfFileNames( const QStringList& filePaths );
std::string makeSuitableAsFileName( const std::string candidateName );
std::string normalizePath( std::string path );
static QStringList splitPathIntoComponents( const QString& path, bool splitExtensionIntoSeparateEntry = false );
QStringList splitPathIntoComponents( const QString& path, bool splitExtensionIntoSeparateEntry = false );
static std::map<QString, QStringList> keyPathComponentsForEachFilePath( const QStringList& filePaths );
std::map<QString, QStringList> keyPathComponentsForEachFilePath( const QStringList& filePaths );
static bool isFirstOlderThanSecond( const std::string& firstFileName, const std::string& secondFileName );
};
bool isFirstOlderThanSecond( const std::string& firstFileName, const std::string& secondFileName );
}; // namespace RiaFilePathTools
@@ -465,3 +465,45 @@ std::string RiaStdStringTools::formatRangeSelection( const std::vector<int>& val
return result.str();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RiaStdStringTools::findCommonPrefix( const std::vector<std::string>& strings )
{
if ( strings.empty() )
{
return "";
}
if ( strings.size() == 1 )
{
return strings[0];
}
// Find the shortest string length as a starting point
// We only need to check up to the length of the shortest string
size_t minLength = strings[0].length();
for ( const auto& str : strings )
{
minLength = std::min( minLength, str.length() );
}
// Compare characters from left to right
for ( size_t i = 0; i < minLength; ++i )
{
char current = strings[0][i];
for ( size_t j = 1; j < strings.size(); ++j )
{
if ( strings[j][i] != current )
{
// Found a mismatch, return the prefix up to this point
return strings[0].substr( 0, i );
}
}
}
// If we got here, all characters matched up to minLength
return strings[0].substr( 0, minLength );
}
@@ -70,6 +70,8 @@ public:
// Create a string from a set of values. {1, 2, 3, 5, 6, 7, 8, 10, 11, 12} will be converted to "1, 2, 3, 5-8, 10-12"
static std::string formatRangeSelection( const std::vector<int>& values );
static std::string findCommonPrefix( const std::vector<std::string>& strings );
private:
template <class Container>
static void splitByDelimiter( const std::string& str, Container& cont, char delimiter = ' ' );
@@ -38,6 +38,15 @@ void caf::AppEnum<RiaDefines::SummaryCurveTypeMode>::setUp()
setDefault( RiaDefines::SummaryCurveTypeMode::AUTO );
}
template <>
void caf::AppEnum<RiaDefines::EnsembleGroupingMode>::setUp()
{
addItem( RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE, "FMU_FOLDER_MODE", "Sub Folder" );
addItem( RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE, "EVEREST_FOLDER_MODE", "Main Folder" );
addItem( RiaDefines::EnsembleGroupingMode::NONE, "None", "None" );
setDefault( RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
}
} // namespace caf
//--------------------------------------------------------------------------------------------------
@@ -183,3 +192,19 @@ QString RiaDefines::summaryRealizationNumber()
{
return "RI:REALIZATION_NUM";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::key1VariableName()
{
return "$KEY1";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::key2VariableName()
{
return "$KEY2";
}
@@ -29,6 +29,13 @@ enum class FileType
STIMPLAN_SUMMARY
};
enum class EnsembleGroupingMode
{
FMU_FOLDER_STRUCTURE,
EVEREST_FOLDER_STRUCTURE,
NONE
};
enum class HorizontalAxisType
{
TIME,
@@ -61,4 +68,7 @@ QString summaryCalculated();
QString summaryRealizationNumber();
QString key1VariableName();
QString key2VariableName();
}; // namespace RiaDefines
@@ -50,7 +50,7 @@ void RicImportEnsembleFractureStatisticsFeature::onActionTriggered( bool isCheck
QString pathCacheName = "INPUT_FILES";
auto [fileNames, groupByEnsemble] = runRecursiveFileSearchDialog( "Import StimPlan Fractures", pathCacheName );
if ( groupByEnsemble == RiaEnsembleNameTools::EnsembleGroupingMode::NONE )
if ( groupByEnsemble == RiaDefines::EnsembleGroupingMode::NONE )
{
importSingleEnsembleFractureStatistics( fileNames );
}
@@ -71,7 +71,7 @@ void RicImportEnsembleFractureStatisticsFeature::importSingleEnsembleFractureSta
{
auto fractureGroupStatistics = new RimEnsembleFractureStatistics;
QString ensembleNameSuggestion =
RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
fractureGroupStatistics->setName( ensembleNameSuggestion );
caf::ProgressInfo progInfo( fileNames.size() + 1, "Creating Ensemble Fracture Statistics" );
@@ -116,7 +116,7 @@ void RicImportEnsembleFractureStatisticsFeature::setupActionLook( QAction* actio
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
std::pair<QStringList, RiaDefines::EnsembleGroupingMode>
RicImportEnsembleFractureStatisticsFeature::runRecursiveFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName )
{
RiaApplication* app = RiaApplication::instance();
@@ -136,7 +136,7 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
m_pathFilter = result.pathFilter;
m_fileNameFilter = result.fileNameFilter;
if ( !result.ok ) return std::make_pair( QStringList(), RiaEnsembleNameTools::EnsembleGroupingMode::NONE );
if ( !result.ok ) return std::make_pair( QStringList(), RiaDefines::EnsembleGroupingMode::NONE );
// Remember the path to next time
app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() );
@@ -34,8 +34,8 @@ class RicImportEnsembleFractureStatisticsFeature : public caf::CmdFeature
public:
RicImportEnsembleFractureStatisticsFeature() {}
static std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
static std::pair<QStringList, RiaDefines::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
protected:
static void importSingleEnsembleFractureStatistics( const QStringList& fileNames );
@@ -60,7 +60,7 @@ void RicCreateGridCaseEnsemblesFromFilesFeature::onActionTriggered( bool isCheck
std::vector<RimEclipseCaseEnsemble*> gridEnsembles;
if ( groupByEnsemble == RiaEnsembleNameTools::EnsembleGroupingMode::NONE )
if ( groupByEnsemble == RiaDefines::EnsembleGroupingMode::NONE )
{
gridEnsembles.push_back( importSingleGridCaseEnsemble( fileNames ) );
}
@@ -111,7 +111,7 @@ RimEclipseCaseEnsemble* RicCreateGridCaseEnsemblesFromFilesFeature::importSingle
auto eclipseCaseEnsemble = new RimEclipseCaseEnsemble;
QString ensembleNameSuggestion =
RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
eclipseCaseEnsemble->setName( ensembleNameSuggestion );
caf::ProgressInfo progInfo( fileNames.size() + 1, "Creating Grid Ensembles" );
@@ -142,7 +142,7 @@ RimEclipseCaseEnsemble* RicCreateGridCaseEnsemblesFromFilesFeature::importSingle
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
std::pair<QStringList, RiaDefines::EnsembleGroupingMode>
RicCreateGridCaseEnsemblesFromFilesFeature::runRecursiveFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName )
{
RiaApplication* app = RiaApplication::instance();
@@ -160,7 +160,7 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
m_pathFilter = result.pathFilter;
m_fileNameFilter = result.fileNameFilter;
if ( !result.ok ) return std::make_pair( QStringList(), RiaEnsembleNameTools::EnsembleGroupingMode::NONE );
if ( !result.ok ) return std::make_pair( QStringList(), RiaDefines::EnsembleGroupingMode::NONE );
// Remember the path to next time
app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() );
@@ -45,9 +45,9 @@ protected:
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
RimEclipseCaseEnsemble* importSingleGridCaseEnsemble( const QStringList& fileNames );
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
RimEclipseCaseEnsemble* importSingleGridCaseEnsemble( const QStringList& fileNames );
std::pair<QStringList, RiaDefines::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
private:
QString m_pathFilter;
@@ -117,7 +117,7 @@ void RicCreateEnsembleSurfaceFeature::executeCommand( const RicCreateEnsembleSur
if ( ui.autoCreateEnsembleSurfaces() )
RicImportEnsembleSurfaceFeature::importEnsembleSurfaceFromFiles( allSurfaceFileNames,
RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
}
//--------------------------------------------------------------------------------------------------
@@ -227,7 +227,7 @@ void RicCreateEnsembleWellLogFeature::executeCommand( const RicCreateEnsembleWel
{
std::vector<RimEnsembleWellLogs*> ensembleWellLogs =
RicImportEnsembleWellLogsFeature::createEnsembleWellLogsFromFiles( allLasFileNames,
RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
for ( auto ensembleWellLog : ensembleWellLogs )
{
@@ -36,13 +36,16 @@ CAF_CMD_SOURCE_INIT( RicCreateSummaryCaseCollectionFeature, "RicCreateSummaryCas
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryEnsemble*
RicCreateSummaryCaseCollectionFeature::groupSummaryCases( std::vector<RimSummaryCase*> cases, const QString& groupName, bool isEnsemble )
RimSummaryEnsemble* RicCreateSummaryCaseCollectionFeature::groupSummaryCases( std::vector<RimSummaryCase*> cases,
const QString& groupName,
RiaDefines::EnsembleGroupingMode groupingMode,
bool isEnsemble )
{
RimSummaryCaseMainCollection* summaryCaseMainCollection = RiaSummaryTools::summaryCaseMainCollection();
if ( !cases.empty() )
{
auto newGroup = summaryCaseMainCollection->addEnsemble( cases, groupName, isEnsemble );
newGroup->setGroupingMode( groupingMode );
summaryCaseMainCollection->updateConnectedEditors();
RiuPlotMainWindowTools::showPlotMainWindow();
@@ -91,7 +94,7 @@ void RicCreateSummaryCaseCollectionFeature::onActionTriggered( bool isChecked )
duplicates.push_back( copy );
}
groupSummaryCases( duplicates, "" );
groupSummaryCases( duplicates, "", RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
}
//--------------------------------------------------------------------------------------------------
@@ -18,6 +18,8 @@
#pragma once
#include "Summary/RiaSummaryDefines.h"
#include "cafCmdFeature.h"
#include <vector>
@@ -32,7 +34,10 @@ class RicCreateSummaryCaseCollectionFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
static RimSummaryEnsemble* groupSummaryCases( std::vector<RimSummaryCase*> cases, const QString& groupName, bool isEnsemble = false );
static RimSummaryEnsemble* groupSummaryCases( std::vector<RimSummaryCase*> cases,
const QString& groupName,
RiaDefines::EnsembleGroupingMode groupingMode,
bool isEnsemble = false );
private:
bool isCommandEnabled() const override;
@@ -64,13 +64,13 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked )
{
QString pathCacheName = "ENSEMBLE_FILES";
auto result = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialogWithGrouping( "Import Ensemble", pathCacheName );
QStringList fileNames = result.files;
RiaEnsembleNameTools::EnsembleGroupingMode ensembleGroupingMode = result.groupingMode;
RiaDefines::FileType fileType = RicRecursiveFileSearchDialog::mapSummaryFileType( result.fileType );
QStringList fileNames = result.files;
RiaDefines::EnsembleGroupingMode ensembleGroupingMode = result.groupingMode;
RiaDefines::FileType fileType = RicRecursiveFileSearchDialog::mapSummaryFileType( result.fileType );
if ( fileNames.isEmpty() ) return;
if ( ensembleGroupingMode == RiaEnsembleNameTools::EnsembleGroupingMode::NONE )
if ( ensembleGroupingMode == RiaDefines::EnsembleGroupingMode::NONE )
{
bool useEnsembleNameDialog = true;
importSingleEnsemble( fileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType );
@@ -88,12 +88,14 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked )
}
else
{
std::vector<QStringList> groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( fileNames, ensembleGroupingMode );
for ( const QStringList& groupedFileNames : groupedByEnsemble )
auto grouping = RiaEnsembleNameTools::groupFilesByEnsembleName( fileNames, ensembleGroupingMode );
for ( const auto& [groupName, fileNames] : grouping )
{
bool useEnsembleNameDialog = false;
importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType );
importSingleEnsemble( fileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType, groupName );
}
RiaEnsembleNameTools::updateAutoNameEnsembles( RiaApplication::instance()->project()->summaryGroups() );
}
}
}
@@ -101,11 +103,11 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportEnsembleFeature::importSingleEnsemble( const QStringList& fileNames,
bool useEnsembleNameDialog,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode,
RiaDefines::FileType fileType,
const QString& defaultEnsembleName )
void RicImportEnsembleFeature::importSingleEnsemble( const QStringList& fileNames,
bool useEnsembleNameDialog,
RiaDefines::EnsembleGroupingMode groupingMode,
RiaDefines::FileType fileType,
const QString& defaultEnsembleName )
{
QString ensembleName = !defaultEnsembleName.isEmpty() ? defaultEnsembleName
: RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, groupingMode );
@@ -119,7 +121,7 @@ void RicImportEnsembleFeature::importSingleEnsemble( const QStringList&
if ( !isOk || cases.empty() ) return;
RimSummaryEnsemble* ensemble = RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, ensembleName, true );
RimSummaryEnsemble* ensemble = RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, ensembleName, groupingMode, true );
if ( ensemble )
{
@@ -39,9 +39,9 @@ protected:
void setupActionLook( QAction* actionToSetup ) override;
static QString askForEnsembleName( const QString& suggestion );
static void importSingleEnsemble( const QStringList& fileNames,
bool useEnsembleNameDialog,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode,
RiaDefines::FileType fileType,
const QString& defaultEnsembleName = QString() );
static void importSingleEnsemble( const QStringList& fileNames,
bool useEnsembleNameDialog,
RiaDefines::EnsembleGroupingMode groupingMode,
RiaDefines::FileType fileType,
const QString& defaultEnsembleName = QString() );
};
@@ -62,8 +62,8 @@ void RicImportEnsembleSurfaceFeature::onActionTriggered( bool isChecked )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportEnsembleSurfaceFeature::importEnsembleSurfaceFromFiles( const QStringList& fileNames,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode )
void RicImportEnsembleSurfaceFeature::importEnsembleSurfaceFromFiles( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode )
{
if ( fileNames.isEmpty() ) return;
@@ -77,8 +77,8 @@ void RicImportEnsembleSurfaceFeature::importEnsembleSurfaceFromFiles( const QStr
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicImportEnsembleSurfaceFeature::importSingleEnsembleSurfaceFromFiles( const QStringList& fileNames,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode )
void RicImportEnsembleSurfaceFeature::importSingleEnsembleSurfaceFromFiles( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode )
{
// Create a list of file names for each layer
std::map<QString, QStringList> fileNamesForEachLayer;
@@ -176,7 +176,7 @@ void RicImportEnsembleSurfaceFeature::setupActionLook( QAction* actionToSetup )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
std::pair<QStringList, RiaDefines::EnsembleGroupingMode>
RicImportEnsembleSurfaceFeature::runRecursiveFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName )
{
RiaApplication* app = RiaApplication::instance();
@@ -194,7 +194,7 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
m_pathFilter = result.pathFilter;
m_fileNameFilter = result.fileNameFilter;
if ( !result.ok ) return std::pair( QStringList(), RiaEnsembleNameTools::EnsembleGroupingMode::NONE );
if ( !result.ok ) return std::pair( QStringList(), RiaDefines::EnsembleGroupingMode::NONE );
// Remember the path to next time
app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() );
@@ -34,16 +34,16 @@ public:
RicImportEnsembleSurfaceFeature();
static void importEnsembleSurfaceFromFiles( const QStringList& fileNames, RiaEnsembleNameTools::EnsembleGroupingMode groupingMode );
static void importEnsembleSurfaceFromFiles( const QStringList& fileNames, RiaDefines::EnsembleGroupingMode groupingMode );
protected:
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
std::pair<QStringList, RiaDefines::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
static void importSingleEnsembleSurfaceFromFiles( const QStringList& fileNames, RiaEnsembleNameTools::EnsembleGroupingMode groupingMode );
static void importSingleEnsembleSurfaceFromFiles( const QStringList& fileNames, RiaDefines::EnsembleGroupingMode groupingMode );
private:
QString m_pathFilter;
@@ -61,8 +61,8 @@ void RicImportEnsembleWellLogsFeature::onActionTriggered( bool isChecked )
///
//--------------------------------------------------------------------------------------------------
std::vector<RimEnsembleWellLogs*>
RicImportEnsembleWellLogsFeature::createEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode )
RicImportEnsembleWellLogsFeature::createEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode )
{
std::vector<RimEnsembleWellLogs*> ensembleWellLogs;
@@ -79,9 +79,8 @@ std::vector<RimEnsembleWellLogs*>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleWellLogs*
RicImportEnsembleWellLogsFeature::createSingleEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode )
RimEnsembleWellLogs* RicImportEnsembleWellLogsFeature::createSingleEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode )
{
if ( fileNames.isEmpty() ) return nullptr;
@@ -124,7 +123,7 @@ void RicImportEnsembleWellLogsFeature::setupActionLook( QAction* actionToSetup )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
std::pair<QStringList, RiaDefines::EnsembleGroupingMode>
RicImportEnsembleWellLogsFeature::runRecursiveFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName )
{
RiaApplication* app = RiaApplication::instance();
@@ -142,7 +141,7 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
m_pathFilter = result.pathFilter;
m_fileNameFilter = result.fileNameFilter;
if ( !result.ok ) return std::make_pair( QStringList(), RiaEnsembleNameTools::EnsembleGroupingMode::NONE );
if ( !result.ok ) return std::make_pair( QStringList(), RiaDefines::EnsembleGroupingMode::NONE );
// Remember the path to next time
app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() );
@@ -35,18 +35,18 @@ class RicImportEnsembleWellLogsFeature : public caf::CmdFeature
RicImportEnsembleWellLogsFeature();
static std::vector<RimEnsembleWellLogs*> createEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode );
static std::vector<RimEnsembleWellLogs*> createEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode );
private:
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
std::pair<QStringList, RiaDefines::EnsembleGroupingMode> runRecursiveFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
static RimEnsembleWellLogs* createSingleEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode );
static RimEnsembleWellLogs* createSingleEnsembleWellLogsFromFiles( const QStringList& fileNames,
RiaDefines::EnsembleGroupingMode groupingMode );
private:
QString m_pathFilter;
@@ -58,7 +58,7 @@ void RicImportSummaryGroupFeature::onActionTriggered( bool isChecked )
auto [isOk, cases] = RicImportSummaryCasesFeature::createSummaryCasesFromFiles( fileNames, createConfig );
RicImportSummaryCasesFeature::addSummaryCases( cases );
RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, "", false );
RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, "", RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE, false );
RiuPlotMainWindow* mainPlotWindow = app->getOrCreateAndShowMainPlotWindow();
if ( mainPlotWindow && !cases.empty() )
@@ -240,7 +240,7 @@ RicRecursiveFileSearchDialogResult RicRecursiveFileSearchDialog::runRecursiveSea
dialog.m_fileType = fileTypes.front();
}
for ( const auto& s : caf::AppEnum<RiaEnsembleNameTools::EnsembleGroupingMode>::uiTexts() )
for ( const auto& s : caf::AppEnum<RiaDefines::EnsembleGroupingMode>::uiTexts() )
{
dialog.m_ensembleGroupingMode->addItem( s );
}
@@ -590,7 +590,7 @@ QString RicRecursiveFileSearchDialog::extensionFromFileNameFilter() const
//--------------------------------------------------------------------------------------------------
void RicRecursiveFileSearchDialog::updateFileListWidget()
{
if ( ensembleGroupingMode() != RiaEnsembleNameTools::EnsembleGroupingMode::NONE )
if ( ensembleGroupingMode() != RiaDefines::EnsembleGroupingMode::NONE )
{
m_filePathModel.clear();
@@ -606,17 +606,16 @@ void RicRecursiveFileSearchDialog::updateFileListWidget()
}
else
{
std::vector<QStringList> groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( m_foundFiles, ensembleGroupingMode() );
for ( const QStringList& groupedFileNames : groupedByEnsemble )
auto grouping = RiaEnsembleNameTools::groupFilesByEnsembleName( m_foundFiles, ensembleGroupingMode() );
for ( const auto& [groupName, fileNames] : grouping )
{
QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( groupedFileNames, ensembleGroupingMode() );
addToTreeView( ensembleName, groupedFileNames );
addToTreeView( groupName, fileNames );
}
}
QModelIndex index = m_filePathModel.index( 0, 0 );
m_fileTreeView->expand( index );
}
QModelIndex index = m_filePathModel.index( 0, 0 );
m_fileTreeView->expand( index );
}
//--------------------------------------------------------------------------------------------------
@@ -1215,13 +1214,13 @@ void RicRecursiveFileSearchDialog::slotUseRealizationStarClicked()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaEnsembleNameTools::EnsembleGroupingMode RicRecursiveFileSearchDialog::ensembleGroupingMode() const
RiaDefines::EnsembleGroupingMode RicRecursiveFileSearchDialog::ensembleGroupingMode() const
{
if ( m_ensembleGroupingMode->currentIndex() == 0 ) return RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE;
if ( m_ensembleGroupingMode->currentIndex() == 1 ) return RiaEnsembleNameTools::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE;
if ( m_ensembleGroupingMode->currentIndex() == 2 ) return RiaEnsembleNameTools::EnsembleGroupingMode::NONE;
if ( m_ensembleGroupingMode->currentIndex() == 0 ) return RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE;
if ( m_ensembleGroupingMode->currentIndex() == 1 ) return RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE;
if ( m_ensembleGroupingMode->currentIndex() == 2 ) return RiaDefines::EnsembleGroupingMode::NONE;
return RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE;
return RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE;
}
//--------------------------------------------------------------------------------------------------
@@ -93,7 +93,7 @@ private:
QStringList fileExtensions() const;
QString extensionFromFileNameFilter() const;
RiaEnsembleNameTools::EnsembleGroupingMode ensembleGroupingMode() const;
RiaDefines::EnsembleGroupingMode ensembleGroupingMode() const;
void setOkButtonEnabled( bool enabled );
void warningIfInvalidCharacters();
@@ -190,5 +190,5 @@ struct RicRecursiveFileSearchDialogResult
QString fileNameFilter;
RicRecursiveFileSearchDialog::FileType fileType;
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode;
RiaDefines::EnsembleGroupingMode groupingMode;
};
@@ -316,7 +316,10 @@ void RicSummaryPlotFeatureImpl::createSummaryPlotsFromArgumentLine( const QStrin
if ( isEnsembleMode )
{
ensemble = RicCreateSummaryCaseCollectionFeature::groupSummaryCases( summaryCasesToUse, "Ensemble", true );
ensemble = RicCreateSummaryCaseCollectionFeature::groupSummaryCases( summaryCasesToUse,
"Ensemble",
RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE,
true );
}
if ( isSinglePlot )
@@ -19,6 +19,7 @@
#include "RimSummaryCaseMainCollection.h"
#include "RiaEclipseFileNameTools.h"
#include "RiaEnsembleNameTools.h"
#include "RiaLogging.h"
#include "RiaPreferencesSummary.h"
#include "Summary/RiaSummaryTools.h"
@@ -260,6 +261,8 @@ void RimSummaryCaseMainCollection::removeCaseCollection( RimSummaryEnsemble* cas
{
m_caseCollections.removeChild( caseCollection );
RiaEnsembleNameTools::updateAutoNameEnsembles( summaryCaseCollections() );
dataSourceHasChanged.send();
}
@@ -526,6 +529,8 @@ RimSummaryEnsemble* RimSummaryCaseMainCollection::defaultAllocator()
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseMainCollection::onCaseNameChanged( const SignalEmitter* emitter )
{
RiaEnsembleNameTools::updateAutoNameEnsembles( summaryCaseCollections() );
RimSummaryMultiPlotCollection* summaryPlotColl = RiaSummaryTools::summaryMultiPlotCollection();
summaryPlotColl->updateSummaryNameHasChanged();
}
@@ -20,8 +20,11 @@
#include "RiaEnsembleNameTools.h"
#include "RiaFieldHandleTools.h"
#include "RiaFilePathTools.h"
#include "RiaLogging.h"
#include "RiaStatisticsTools.h"
#include "RiaStdStringTools.h"
#include "RiaTextStringTools.h"
#include "Summary/RiaSummaryAddressAnalyzer.h"
#include "RifSummaryReaderInterface.h"
@@ -36,6 +39,8 @@
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiTextEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include <QFileInfo>
@@ -57,6 +62,17 @@ RimSummaryEnsemble::RimSummaryEnsemble()
CAF_PDM_InitScriptableField( &m_name, "SummaryCollectionName", QString( "Group" ), "Name" );
CAF_PDM_InitScriptableField( &m_autoName, "CreateAutoName", true, "Auto Name" );
CAF_PDM_InitScriptableField( &m_useKey1, "UseKey1", false, "Use First Path Part" );
CAF_PDM_InitScriptableField( &m_useKey2, "UseKey2", false, "Use Second Path Part" );
QString defaultText = RiaDefines::key1VariableName() + "-" + RiaDefines::key2VariableName();
CAF_PDM_InitField( &m_nameTemplateString,
"NameTemplateString",
defaultText,
"Name Template",
"",
"Variables are replaced by evaluated values based on file names" );
CAF_PDM_InitFieldNoDefault( &m_groupingMode, "GroupingMode", "Grouping Mode" );
CAF_PDM_InitScriptableFieldNoDefault( &m_nameAndItemCount, "NameCount", "Name" );
m_nameAndItemCount.registerGetMethod( this, &RimSummaryEnsemble::nameAndItemCount );
@@ -76,6 +92,11 @@ RimSummaryEnsemble::RimSummaryEnsemble()
m_dataVectorFolders->uiCapability()->setUiTreeHidden( true );
m_dataVectorFolders.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_ensembleDescription, "Description", "Description" );
m_ensembleDescription.registerGetMethod( this, &RimSummaryEnsemble::ensembleDescription );
m_ensembleDescription.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
m_ensembleDescription.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
m_commonAddressCount = 0;
}
@@ -188,22 +209,65 @@ QString RimSummaryEnsemble::name() const
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsemble::ensureNameIsUpdated()
{
const auto [key1, key2] = nameKeys();
QString templateText;
if ( m_autoName )
{
QStringList fileNames;
for ( const auto& summaryCase : m_cases )
if ( m_useKey1() ) templateText += RiaDefines::key1VariableName();
if ( m_useKey2() )
{
fileNames.push_back( summaryCase->summaryHeaderFilename() );
if ( !templateText.isEmpty() ) templateText += ", ";
templateText += RiaDefines::key2VariableName();
}
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode = RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE;
QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, groupingMode );
if ( m_name == ensembleName ) return;
m_name = ensembleName;
caseNameChanged.send();
}
else
{
templateText = m_nameTemplateString();
}
std::map<QString, QString> keyValues = {
{ RiaDefines::key1VariableName(), QString::fromStdString( key1 ) },
{ RiaDefines::key2VariableName(), QString::fromStdString( key2 ) },
};
auto candidateName = RiaTextStringTools::replaceTemplateTextWithValues( templateText, keyValues );
if ( m_name == candidateName ) return;
m_name = candidateName;
caseNameChanged.send();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsemble::setUsePathKey1( bool useKey1 )
{
m_useKey1 = useKey1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsemble::setUsePathKey2( bool useKey2 )
{
m_useKey2 = useKey2;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsemble::setGroupingMode( RiaDefines::EnsembleGroupingMode groupingMode )
{
m_groupingMode = groupingMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::EnsembleGroupingMode RimSummaryEnsemble::groupingMode() const
{
return m_groupingMode();
}
//--------------------------------------------------------------------------------------------------
@@ -785,6 +849,10 @@ void RimSummaryEnsemble::fieldChangedByUi( const caf::PdmFieldHandle* changedFie
m_autoName = false;
caseNameChanged.send();
}
if ( changedField == &m_nameTemplateString )
{
ensureNameIsUpdated();
}
}
//--------------------------------------------------------------------------------------------------
@@ -802,10 +870,12 @@ void RimSummaryEnsemble::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
{
uiOrdering.add( &m_autoName );
uiOrdering.add( &m_name );
if ( m_isEnsemble() )
{
uiOrdering.add( &m_ensembleId );
}
if ( !m_autoName() ) uiOrdering.add( &m_nameTemplateString );
if ( m_isEnsemble() ) uiOrdering.add( &m_ensembleId );
uiOrdering.add( &m_ensembleDescription );
uiOrdering.skipRemainingFields( true );
}
@@ -833,6 +903,112 @@ void RimSummaryEnsemble::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrd
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsemble::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_nameTemplateString )
{
if ( auto attr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute ) )
{
attr->placeholderText = RiaDefines::key1VariableName() + "-" + RiaDefines::key2VariableName();
attr->notifyWhenTextIsEdited = true;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryEnsemble::ensembleDescription() const
{
QString txt;
if ( !m_cases.empty() )
{
txt += QString( "First summary file of %1 files :\n " ).arg( m_cases.size() );
auto firstCase = m_cases[0]->summaryHeaderFilename();
txt += firstCase;
txt += "\n";
}
const auto [key1, key2] = nameKeys();
txt += "\nDetected variables for use when creating a custom name:\n";
txt += QString( " %1: %2\n" ).arg( RiaDefines::key1VariableName() ).arg( QString::fromStdString( key1 ) );
txt += QString( " %1: %2\n" ).arg( RiaDefines::key2VariableName() ).arg( QString::fromStdString( key2 ) );
txt += "\n";
if ( m_groupingMode() == RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
{
txt += "The ensemble is grouped by the file folder structure.\n";
}
else if ( m_groupingMode() == RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE )
{
txt += "The ensemble is grouped by the FMU file folder structure.\n";
}
return txt;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<std::string, std::string> RimSummaryEnsemble::nameKeys() const
{
std::string key1 = "Undefined KEY1";
std::string key2 = "Undefined KEY2";
if ( m_groupingMode() == RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE )
{
if ( !m_cases.empty() )
{
auto fileNames = RiaEnsembleNameTools::groupFilePathsFmu( { m_cases[0]->summaryHeaderFilename().toStdString() } );
if ( !fileNames.empty() )
{
key1 = fileNames.begin()->first.first;
key2 = fileNames.begin()->first.second;
}
}
}
else if ( m_groupingMode() == RiaDefines::EnsembleGroupingMode::EVEREST_FOLDER_STRUCTURE )
{
if ( m_cases.size() > 1 )
{
auto name1 = RiaFilePathTools::toInternalSeparator( m_cases[0]->summaryHeaderFilename() ).toStdString();
auto name2 = RiaFilePathTools::toInternalSeparator( m_cases[1]->summaryHeaderFilename() ).toStdString();
auto parts1 = RiaStdStringTools::splitString( name1, '/' );
auto parts2 = RiaStdStringTools::splitString( name2, '/' );
size_t commonParts = 0;
for ( size_t i = 0; i < std::min( parts1.size(), parts2.size() ); i++ )
{
if ( parts1[i] == parts2[i] )
{
commonParts++;
}
else
{
break;
}
}
if ( commonParts == 1 )
{
key2 = parts1[commonParts - 1];
}
else if ( commonParts > 1 )
{
key1 = parts1[commonParts - 2];
key2 = parts1[commonParts - 1];
}
}
}
return { key1, key2 };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -19,6 +19,7 @@
#pragma once
#include "RiaDefines.h"
#include "Summary/RiaSummaryDefines.h"
#include "RifEclipseSummaryAddress.h"
@@ -63,6 +64,12 @@ public:
void setName( const QString& name );
QString name() const;
void ensureNameIsUpdated();
void setUsePathKey1( bool useKey1 );
void setUsePathKey2( bool useKey2 );
void setGroupingMode( RiaDefines::EnsembleGroupingMode groupingMode );
RiaDefines::EnsembleGroupingMode groupingMode() const;
std::pair<std::string, std::string> nameKeys() const;
bool isEnsemble() const;
void setAsEnsemble( bool isEnsemble );
@@ -106,33 +113,44 @@ public:
void setMinMax( const RifEclipseSummaryAddress& address, double min, double max );
std::pair<double, double> minMax( const RifEclipseSummaryAddress& address );
protected:
virtual void onLoadDataAndUpdate();
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void buildMetaData();
private:
caf::PdmFieldHandle* userDescriptionField() override;
QString nameAndItemCount() const;
void updateIcon();
void initAfterRead() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
QString nameAndItemCount() const;
void updateIcon();
void updateReferringCurveSets( bool doZoomAll );
void initAfterRead() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void onCaseNameChanged( const SignalEmitter* emitter );
void buildChildNodes();
void clearChildNodes();
QString ensembleDescription() const;
protected:
virtual void onLoadDataAndUpdate();
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void buildMetaData();
caf::PdmChildArrayField<RimSummaryCase*> m_cases;
caf::PdmField<QString> m_name;
private:
caf::PdmField<QString> m_name;
caf::PdmField<bool> m_autoName;
caf::PdmField<QString> m_nameTemplateString;
caf::PdmField<bool> m_autoName;
caf::PdmField<bool> m_useKey1;
caf::PdmField<bool> m_useKey2;
caf::PdmProxyValueField<QString> m_ensembleDescription;
caf::PdmField<caf::AppEnum<RiaDefines::EnsembleGroupingMode>> m_groupingMode;
caf::PdmProxyValueField<QString> m_nameAndItemCount;
caf::PdmField<bool> m_isEnsemble;
caf::PdmChildField<RimSummaryAddressCollection*> m_dataVectorFolders;
@@ -455,9 +455,8 @@ void RimSummaryEnsembleSumo::buildMetaData()
void RimSummaryEnsembleSumo::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_sumoDataSource );
auto group = uiOrdering.addNewGroup( "General" );
RimSummaryEnsemble::defineUiOrdering( uiConfigName, *group );
uiOrdering.add( &m_name );
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
@@ -32,3 +32,94 @@ TEST( RiaEnsembleNameToolsTests, commonBaseName )
ASSERT_EQ( "data_vs_time", RiaEnsembleNameTools::findCommonBaseName( fileNames ).toStdString() );
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, EnsembleName )
{
{
QString testPath1( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-0/iter-3/eclipse/model/DROGON-0.SMSPEC" );
QString testPath2( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-1/iter-3/eclipse/model/DROGON-1.SMSPEC" );
QStringList allPaths = { testPath1, testPath2 };
auto ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( allPaths, RiaDefines::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
EXPECT_EQ( QString( "iter-3" ), ensembleName );
}
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, RealizationName )
{
{
QString testPath0( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-0/iter-3/eclipse/model/DROGON-0.SMSPEC" );
QString testPath1( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-1/iter-3/eclipse/model/DROGON-1.SMSPEC" );
QStringList allPaths = { testPath0, testPath1 };
QString fileName = "DROGON-0.SMSPEC";
auto name = RiaEnsembleNameTools::uniqueShortName( testPath1, allPaths, fileName );
EXPECT_EQ( QString( "real-1" ), name );
}
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, EnsembleGroupingMultipleEnsembles )
{
{
std::vector<std::string> filepaths = { "f:/Models/scratch/project_a/realization-0/iter-0/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/project_a/realization-1/iter-0/eclipse/model/PROJECT-1.SMSPEC",
"f:/Models/scratch/project_a/realization-22/iter-0/eclipse/model/PROJECT-22.SMSPEC",
"f:/Models/scratch/project_b/realization-0/iter-0/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/project_b/realization-1/iter-0/eclipse/model/PROJECT-1.SMSPEC",
"f:/Models/scratch/project_b/realization-2/iter-0/eclipse/model/PROJECT-2.SMSPEC",
"f:/Models/scratch/project_c/realization-0/iter-0/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/project_c/realization-1/iter-0/eclipse/model/PROJECT-1.SMSPEC",
"f:/Models/scratch/project_c/realization-2/iter-0/eclipse/model/PROJECT-2.SMSPEC",
"f:/Models/scratch/project_c/realization-0/iter-1/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/project_c/realization-1\\iter-1/eclipse/model\\PROJECT-1.SMSPEC",
"f:/Models/scratch/project_c/realization-\\iter-1/eclipse/model\\PROJECT-2.SMSPEC" };
auto grouping = RiaEnsembleNameTools::groupFilePathsFmu( filepaths );
std::set<std::string> keys1 = { "project_a", "project_b", "project_c" };
std::set<std::string> keys2 = { "iter-0", "iter-1" };
EXPECT_EQ( 4, grouping.size() );
for ( const auto& [keys, paths] : grouping )
{
const auto& [key1, key2] = keys;
EXPECT_TRUE( keys1.find( key1 ) != keys1.end() );
EXPECT_TRUE( keys2.find( key2 ) != keys2.end() );
}
}
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, EnsembleGroupingEverest )
{
{
std::vector<std::string> filepaths = {
"f:/Models/scratch/my_case/batch_0/geo_realization_0/simulation_0/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_0/geo_realization_1/simulation_1/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_0/geo_realization_2/simulation_2/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_0/geo_realization_2/simulation_2/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_1/geo_realization_0/simulation_0/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_1/geo_realization_1/simulation_1/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_1/geo_realization_2/simulation_2/eclipse/model/PROJECT-0.SMSPEC",
"f:/Models/scratch/my_case/batch_1/geo_realization_2/simulation_2/eclipse/model/PROJECT-0.SMSPEC",
};
auto grouping = RiaEnsembleNameTools::groupFilePathsEverest( filepaths );
std::set<std::string> keys1 = { "my_case" };
std::set<std::string> keys2 = { "batch_0", "batch_1" };
for ( const auto& [keys, paths] : grouping )
{
const auto& [key1, key2] = keys;
EXPECT_TRUE( keys1.find( key1 ) != keys1.end() );
EXPECT_TRUE( keys2.find( key2 ) != keys2.end() );
}
}
}
@@ -1,6 +1,5 @@
#include "gtest/gtest.h"
#include "RiaEnsembleNameTools.h"
#include "RiaFilePathTools.h"
#include <iostream>
@@ -152,37 +151,6 @@ TEST( RiaFilePathTools, splitIntoComponets )
}
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, EnsembleName )
{
{
QString testPath1( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-0/iter-3/eclipse/model/DROGON-0.SMSPEC" );
QString testPath2( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-1/iter-3/eclipse/model/DROGON-1.SMSPEC" );
QStringList allPaths = { testPath1, testPath2 };
auto ensembleName =
RiaEnsembleNameTools::findSuitableEnsembleName( allPaths, RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE );
EXPECT_EQ( QString( "iter-3" ), ensembleName );
}
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, RealizationName )
{
{
QString testPath0( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-0/iter-3/eclipse/model/DROGON-0.SMSPEC" );
QString testPath1( "e:/models/from_equinor_sftp/drogon3d_ahm/realization-1/iter-3/eclipse/model/DROGON-1.SMSPEC" );
QStringList allPaths = { testPath0, testPath1 };
QString fileName = "DROGON-0.SMSPEC";
auto name = RiaEnsembleNameTools::uniqueShortName( testPath1, allPaths, fileName );
EXPECT_EQ( QString( "real-1" ), name );
}
}
//--------------------------------------------------------------------------------------------------
TEST( RiaFilePathTools, keyPathComponentsForEachFilePath )
{