From 95f97198a2528cf5c78b6f79b913718b7fc0a64d Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Wed, 12 Apr 2023 12:08:51 +0200 Subject: [PATCH] #9773 Generate better ensembles for StimPlan summaries. --- .../Tools/RiaEnsembleNameTools.cpp | 100 ++++++++++++++++++ .../Application/Tools/RiaEnsembleNameTools.h | 6 +- .../Commands/RicImportEnsembleFeature.cpp | 27 +++-- .../Commands/RicImportEnsembleFeature.h | 3 +- .../Commands/RicRecursiveFileSearchDialog.cpp | 22 +++- .../UnitTests/CMakeLists_files.cmake | 1 + .../UnitTests/RiaEnsembleNameTools-Test.cpp | 34 ++++++ 7 files changed, 180 insertions(+), 13 deletions(-) create mode 100644 ApplicationLibCode/UnitTests/RiaEnsembleNameTools-Test.cpp diff --git a/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp index 27b9cd7256..30ab089c48 100644 --- a/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp @@ -133,6 +133,106 @@ std::vector RiaEnsembleNameTools::groupFilesByEnsemble( const QStri return groupedByIteration; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map RiaEnsembleNameTools::groupFilesByStimPlanEnsemble( const QStringList& fileNames ) +{ + std::vector componentsForAllFilePaths; + for ( const auto& filePath : fileNames ) + { + QStringList components = RiaFilePathTools::splitPathIntoComponents( filePath ); + componentsForAllFilePaths.push_back( components ); + } + + auto mapping = findUniqueStimPlanEnsembleNames( fileNames, componentsForAllFilePaths ); + + std::set iterations; + for ( const auto& [name, iterFileNamePair] : mapping ) + { + iterations.insert( iterFileNamePair.first ); + } + + std::map groupedByIteration; + + for ( const QString& groupIteration : iterations ) + { + QStringList fileNamesFromIteration; + + for ( const auto& [name, iterFileNamePair] : mapping ) + { + QString iteration = iterFileNamePair.first; + QString fileName = iterFileNamePair.second; + + if ( groupIteration == iteration ) + { + fileNamesFromIteration << fileName; + } + } + groupedByIteration[groupIteration] = fileNamesFromIteration; + } + + return groupedByIteration; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> + RiaEnsembleNameTools::findUniqueStimPlanEnsembleNames( const QStringList& fileNames, const std::vector& fileNameComponents ) +{ + CAF_ASSERT( fileNames.size() == static_cast( fileNameComponents.size() ) ); + + struct StimPlanComponents + { + QString realization; + QString iteration; + QString well; + QString fracture; + QString job; + QString fileName; + }; + + std::vector comps; + + int i = 0; + for ( const auto& fileComponents : fileNameComponents ) + { + int numComponents = fileComponents.size(); + + if ( numComponents >= 7 ) + { + StimPlanComponents c; + c.fileName = fileNames[i]; + c.fracture = fileComponents[numComponents - 2]; + c.iteration = fileComponents[numComponents - 6]; + c.realization = fileComponents[numComponents - 7]; + + QString wellJobComponent = fileComponents[numComponents - 3]; + QStringList parts = wellJobComponent.split( "_" ); + + if ( parts.size() == 4 ) + { + c.well = parts[0]; + c.job = parts[3]; + } + + comps.push_back( c ); + } + i++; + } + + std::map> mapping; + for ( const StimPlanComponents& c : comps ) + { + QString key = QString( "%1, %2, %3, %4, %5" ).arg( c.iteration, c.realization, c.well, c.fracture, c.job ); + QString iteration = QString( "%1, %2, %3, %4" ).arg( c.iteration, c.well, c.fracture, c.job ); + mapping[key] = std::make_pair( iteration, c.fileName ); + } + + return mapping; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h index f7edc8a465..eaf5aea25c 100644 --- a/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h +++ b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h @@ -49,7 +49,11 @@ class RiaEnsembleNameTools const std::map& keyFileComponentsForAllFiles, const QString& ensembleCaseName ); - static std::vector groupFilesByEnsemble( const QStringList& fileNames, EnsembleGroupingMode groupingMode ); + static std::vector groupFilesByEnsemble( const QStringList& fileNames, EnsembleGroupingMode groupingMode ); + static std::map groupFilesByStimPlanEnsemble( const QStringList& fileNames ); + + static std::map> + findUniqueStimPlanEnsembleNames( const QStringList& fileNames, const std::vector& fileNameComponents ); static QString uniqueShortNameForEnsembleCase( RimSummaryCase* summaryCase ); static QString uniqueShortNameForSummaryCase( RimSummaryCase* summaryCase ); diff --git a/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp b/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp index ed38c4346f..25014a7f39 100644 --- a/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp +++ b/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp @@ -22,6 +22,7 @@ #include "RiaEnsembleNameTools.h" #include "RiaFilePathTools.h" #include "RiaPreferences.h" +#include "RiaSummaryDefines.h" #include "RiaSummaryTools.h" #include "RiaTextStringTools.h" @@ -84,11 +85,23 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked ) } else { - std::vector groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( fileNames, ensembleGroupingMode ); - for ( const QStringList& groupedFileNames : groupedByEnsemble ) + if ( fileType == RiaDefines::FileType::STIMPLAN_SUMMARY ) { - bool useEnsembleNameDialog = false; - importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType ); + std::map groupedByEnsemble = RiaEnsembleNameTools::groupFilesByStimPlanEnsemble( fileNames ); + for ( const auto& [ensembleName, groupedFileNames] : groupedByEnsemble ) + { + bool useEnsembleNameDialog = false; + importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType, ensembleName ); + } + } + else + { + std::vector groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( fileNames, ensembleGroupingMode ); + for ( const QStringList& groupedFileNames : groupedByEnsemble ) + { + bool useEnsembleNameDialog = false; + importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType ); + } } } } @@ -99,9 +112,11 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked ) void RicImportEnsembleFeature::importSingleEnsemble( const QStringList& fileNames, bool useEnsembleNameDialog, RiaEnsembleNameTools::EnsembleGroupingMode groupingMode, - RiaDefines::FileType fileType ) + RiaDefines::FileType fileType, + const QString& defaultEnsembleName ) { - QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, groupingMode ); + QString ensembleName = !defaultEnsembleName.isEmpty() ? defaultEnsembleName + : RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, groupingMode ); if ( useEnsembleNameDialog ) ensembleName = askForEnsembleName( ensembleName ); diff --git a/ApplicationLibCode/Commands/RicImportEnsembleFeature.h b/ApplicationLibCode/Commands/RicImportEnsembleFeature.h index 52fbce3297..beaed73e43 100644 --- a/ApplicationLibCode/Commands/RicImportEnsembleFeature.h +++ b/ApplicationLibCode/Commands/RicImportEnsembleFeature.h @@ -43,5 +43,6 @@ class RicImportEnsembleFeature : public caf::CmdFeature static void importSingleEnsemble( const QStringList& fileNames, bool useEnsembleNameDialog, RiaEnsembleNameTools::EnsembleGroupingMode groupingMode, - RiaDefines::FileType fileType ); + RiaDefines::FileType fileType, + const QString& defaultEnsembleName = QString() ); }; diff --git a/ApplicationLibCode/Commands/RicRecursiveFileSearchDialog.cpp b/ApplicationLibCode/Commands/RicRecursiveFileSearchDialog.cpp index 0ce882ae87..0a3fe84236 100644 --- a/ApplicationLibCode/Commands/RicRecursiveFileSearchDialog.cpp +++ b/ApplicationLibCode/Commands/RicRecursiveFileSearchDialog.cpp @@ -433,12 +433,24 @@ void RicRecursiveFileSearchDialog::updateFileListWidget() if ( ensembleGroupingMode() != RiaEnsembleNameTools::EnsembleGroupingMode::NONE ) { - std::vector groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( m_foundFiles, ensembleGroupingMode() ); - for ( const QStringList& groupedFileNames : groupedByEnsemble ) + if ( m_fileType == RicRecursiveFileSearchDialog::FileType::STIMPLAN_SUMMARY ) { - QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( groupedFileNames, ensembleGroupingMode() ); - new QListWidgetItem( QDir::toNativeSeparators( ensembleName ), m_fileListWidget ); - addToFileListWidget( groupedFileNames ); + std::map groupedByEnsemble = RiaEnsembleNameTools::groupFilesByStimPlanEnsemble( m_foundFiles ); + for ( auto [ensembleName, groupedFileNames] : groupedByEnsemble ) + { + new QListWidgetItem( QDir::toNativeSeparators( ensembleName ), m_fileListWidget ); + addToFileListWidget( groupedFileNames ); + } + } + else + { + std::vector groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( m_foundFiles, ensembleGroupingMode() ); + for ( const QStringList& groupedFileNames : groupedByEnsemble ) + { + QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( groupedFileNames, ensembleGroupingMode() ); + new QListWidgetItem( QDir::toNativeSeparators( ensembleName ), m_fileListWidget ); + addToFileListWidget( groupedFileNames ); + } } } else diff --git a/ApplicationLibCode/UnitTests/CMakeLists_files.cmake b/ApplicationLibCode/UnitTests/CMakeLists_files.cmake index c8023af2ef..1f44f2084c 100644 --- a/ApplicationLibCode/UnitTests/CMakeLists_files.cmake +++ b/ApplicationLibCode/UnitTests/CMakeLists_files.cmake @@ -89,6 +89,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSummaryReader-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader-Test.cpp + ${CMAKE_CURRENT_LIST_DIR}/RiaEnsembleNameTools-Test.cpp ) if(RESINSIGHT_ENABLE_GRPC) diff --git a/ApplicationLibCode/UnitTests/RiaEnsembleNameTools-Test.cpp b/ApplicationLibCode/UnitTests/RiaEnsembleNameTools-Test.cpp new file mode 100644 index 0000000000..c544593c9f --- /dev/null +++ b/ApplicationLibCode/UnitTests/RiaEnsembleNameTools-Test.cpp @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "gtest/gtest.h" + +#include "RiaEnsembleNameTools.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RiaEnsembleNameToolsTests, commonBaseName ) +{ + QStringList fileNames = { "/base/realization-0/iter-0/stimplan/output/B-H3_StimPlanModel_01_job-01/mainfrac/data_vs_time.csv", + "/base/realization-0/iter-0/stimplan/output/B-H3_StimPlanModel_02_job-02/mainfrac/data_vs_time.csv" }; + + ASSERT_EQ( "data_vs_time", RiaEnsembleNameTools::findCommonBaseName( fileNames ).toStdString() ); +}