diff --git a/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake b/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake index 3da3bd9b09..a97a7fae3d 100644 --- a/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake +++ b/ApplicationLibCode/Application/Tools/CMakeLists_files.cmake @@ -46,6 +46,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaWellLogUnitTools.h ${CMAKE_CURRENT_LIST_DIR}/RiaWellLogUnitTools.inl ${CMAKE_CURRENT_LIST_DIR}/RiaTimeTTools.h ${CMAKE_CURRENT_LIST_DIR}/RiaValidRegExpValidator.h +${CMAKE_CURRENT_LIST_DIR}/RiaEnsembleNameTools.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -88,6 +89,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaFieldHandleTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaBoundingBoxTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaTimeTTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaValidRegExpValidator.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaEnsembleNameTools.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp new file mode 100644 index 0000000000..b8b8fa1390 --- /dev/null +++ b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.cpp @@ -0,0 +1,161 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 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 "RiaEnsembleNameTools.h" + +#include "RiaFilePathTools.h" + +#include "RimCaseDisplayNameTools.h" +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaEnsembleNameTools::findSuitableEnsembleName( const QStringList& fileNames ) +{ + std::vector componentsForAllFilePaths; + + for ( const auto& filePath : fileNames ) + { + QStringList components = RiaFilePathTools::splitPathIntoComponents( filePath ); + componentsForAllFilePaths.push_back( components ); + } + + // Find list of all folders inside a folder matching realization-* + QRegularExpression realizationRe( "realization\\-\\d+" ); + + QStringList iterations; + for ( const auto& fileComponents : componentsForAllFilePaths ) + { + QString lastComponent = ""; + for ( auto it = fileComponents.rbegin(); it != fileComponents.rend(); ++it ) + { + if ( realizationRe.match( *it ).hasMatch() ) + { + iterations.push_back( lastComponent ); + } + lastComponent = *it; + } + } + + iterations.removeDuplicates(); + + if ( iterations.size() == 1u ) + { + return iterations.front(); + } + + if ( !iterations.empty() ) + { + return QString( "Multiple iterations: %1" ).arg( iterations.join( ", " ) ); + } + + QString root = RiaFilePathTools::commonRootOfFileNames( fileNames ); + + QRegularExpression trimRe( "[^a-zA-Z0-9]+$" ); + QString trimmedRoot = root.replace( trimRe, "" ); + if ( trimmedRoot.length() >= 4 ) + { + return trimmedRoot; + } + + return "Ensemble"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaEnsembleNameTools::findCommonBaseName( const QStringList& fileNames ) +{ + QStringList baseNames; + for ( const auto& f : fileNames ) + { + QFileInfo fi( f ); + baseNames.push_back( fi.baseName() ); + } + + if ( baseNames.isEmpty() ) return "Empty"; + + auto firstName = baseNames.front(); + for ( int i = 0; i < firstName.size(); i++ ) + { + auto candidate = firstName.left( firstName.size() - i ); + bool identicalNames = true; + + for ( const auto& baseName : baseNames ) + { + auto str = baseName.left( firstName.size() - i ); + if ( candidate != str ) identicalNames = false; + } + + if ( identicalNames ) + { + return candidate; + } + } + + return "Mixed Items"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaEnsembleNameTools::uniqueShortName( const QString& sourceFileName, + const QStringList& allFileNames, + const QString& ensembleCaseName ) +{ + QRegularExpression trimRe( "^[^a-zA-Z0-9]+" ); + + std::map keyFileComponentsForAllFiles = + RiaFilePathTools::keyPathComponentsForEachFilePath( allFileNames ); + + QStringList keyFileComponents = keyFileComponentsForAllFiles[sourceFileName]; + if ( keyFileComponents.empty() ) return "Unnamed"; + + if ( !ensembleCaseName.isEmpty() ) + { + for ( auto& component : keyFileComponents ) + { + component = component.replace( ensembleCaseName, "" ); + component = component.replace( trimRe, "" ); + } + } + + QStringList shortNameComponents; + QRegularExpression numberRe( "[0-9]+" ); + for ( auto keyComponent : keyFileComponents ) + { + QStringList subComponents; + QString numberGroup = numberRe.match( keyComponent ).captured(); + if ( !numberGroup.isEmpty() ) + { + keyComponent = keyComponent.replace( numberGroup, "" ); + QString stem = keyComponent.left( RimCaseDisplayNameTools::CASE_SHORT_NAME_LENGTH ); + if ( !stem.isEmpty() ) subComponents.push_back( stem ); + subComponents.push_back( numberGroup ); + } + else + { + subComponents.push_back( keyComponent.left( RimCaseDisplayNameTools::CASE_SHORT_NAME_LENGTH ) ); + } + + shortNameComponents.push_back( subComponents.join( "-" ) ); + } + return shortNameComponents.join( "," ); +} diff --git a/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h new file mode 100644 index 0000000000..93b288a517 --- /dev/null +++ b/ApplicationLibCode/Application/Tools/RiaEnsembleNameTools.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +//================================================================================================== +// +//================================================================================================== +class RiaEnsembleNameTools +{ +public: + static QString findSuitableEnsembleName( const QStringList& fileNames ); + static QString findCommonBaseName( const QStringList& fileNames ); + + static QString uniqueShortName( const QString& sourceFileName, + const QStringList& allFileNames, + const QString& ensembleCaseName = QString() ); +}; diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp index 236e1bb0f9..f5a6c83acb 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp @@ -215,59 +215,6 @@ void RiaSummaryTools::getSummaryCasesAndAddressesForCalculation( int } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RiaSummaryTools::findSuitableEnsembleName( const QStringList& summaryCaseFileNames ) -{ - std::vector componentsForAllFilePaths; - - for ( auto filePath : summaryCaseFileNames ) - { - QStringList components = RiaFilePathTools::splitPathIntoComponents( filePath ); - componentsForAllFilePaths.push_back( components ); - } - - // Find list of all folders inside a folder matching realization-* - QRegularExpression realizationRe( "realization\\-\\d+" ); - - QStringList iterations; - for ( const auto& fileComponents : componentsForAllFilePaths ) - { - QString lastComponent = ""; - for ( auto it = fileComponents.rbegin(); it != fileComponents.rend(); ++it ) - { - if ( realizationRe.match( *it ).hasMatch() ) - { - iterations.push_back( lastComponent ); - } - lastComponent = *it; - } - } - - iterations.removeDuplicates(); - - if ( iterations.size() == 1u ) - { - return iterations.front(); - } - else if ( !iterations.empty() ) - { - return QString( "Multiple iterations: %1" ).arg( iterations.join( ", " ) ); - } - - QString root = RiaFilePathTools::commonRootOfFileNames( summaryCaseFileNames ); - - QRegularExpression trimRe( "[^a-zA-Z0-9]+$" ); - QString trimmedRoot = root.replace( trimRe, "" ); - if ( trimmedRoot.length() >= 4 ) - { - return trimmedRoot; - } - - return "Ensemble"; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h index 19e9f3f65f..91072498b7 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h @@ -64,8 +64,6 @@ public: std::vector& cases, std::vector& addresses ); - static QString findSuitableEnsembleName( const QStringList& summaryCaseFileNames ); - static std::pair, std::vector> resampledValuesForPeriod( const RifEclipseSummaryAddress& address, const std::vector& timeSteps, diff --git a/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp b/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp index cd220942cf..d3ed3b4eb8 100644 --- a/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp +++ b/ApplicationLibCode/Commands/RicImportEnsembleFeature.cpp @@ -19,6 +19,7 @@ #include "RicImportEnsembleFeature.h" #include "RiaApplication.h" +#include "RiaEnsembleNameTools.h" #include "RiaFilePathTools.h" #include "RiaPreferences.h" #include "RiaSummaryTools.h" @@ -76,7 +77,7 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked ) if ( fileNames.isEmpty() ) return; - QString ensembleNameSuggestion = RiaSummaryTools::findSuitableEnsembleName( fileNames ); + QString ensembleNameSuggestion = RiaEnsembleNameTools::findSuitableEnsembleName( fileNames ); QString ensembleName = askForEnsembleName( ensembleNameSuggestion ); if ( ensembleName.isEmpty() ) return; diff --git a/ApplicationLibCode/Commands/RicImportEnsembleSurfaceFeature.cpp b/ApplicationLibCode/Commands/RicImportEnsembleSurfaceFeature.cpp index d23eba267c..b1a8d105f9 100644 --- a/ApplicationLibCode/Commands/RicImportEnsembleSurfaceFeature.cpp +++ b/ApplicationLibCode/Commands/RicImportEnsembleSurfaceFeature.cpp @@ -19,7 +19,11 @@ #include "RicImportEnsembleSurfaceFeature.h" #include "RiaApplication.h" +#include "RiaEnsembleNameTools.h" #include "RiaLogging.h" +#include "RiaSummaryTools.h" + +#include "RicRecursiveFileSearchDialog.h" #include "RimEnsembleSurface.h" #include "RimFileSurface.h" @@ -27,7 +31,7 @@ #include "RimProject.h" #include "RimSurfaceCollection.h" -#include "RicRecursiveFileSearchDialog.h" +#include "Riu3DMainWindowTools.h" #include #include @@ -61,15 +65,24 @@ void RicImportEnsembleSurfaceFeature::onActionTriggered( bool isChecked ) QStringList fileNames = runRecursiveFileSearchDialog( "Import Ensemble Surface", pathCacheName ); if ( fileNames.isEmpty() ) return; - QString ensembleName = "Ensemble Surface"; - if ( ensembleName.isEmpty() ) return; + QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( fileNames ); + QString layerName = RiaEnsembleNameTools::findCommonBaseName( fileNames ); + if ( !layerName.isEmpty() ) + { + ensembleName += QString( " : %1" ).arg( layerName ); + } + + if ( ensembleName.isEmpty() ) ensembleName = "Ensemble Surface"; std::vector surfaces; - for ( QString fileName : fileNames ) + for ( const auto& fileName : fileNames ) { RimFileSurface* fileSurface = new RimFileSurface; fileSurface->setSurfaceFilePath( fileName ); + auto shortName = RiaEnsembleNameTools::uniqueShortName( fileName, fileNames ); + fileSurface->setUserDescription( shortName ); + if ( fileSurface->onLoadData() ) { surfaces.push_back( fileSurface ); @@ -84,7 +97,11 @@ void RicImportEnsembleSurfaceFeature::onActionTriggered( bool isChecked ) ensemble->addFileSurface( surface ); RimProject::current()->activeOilField()->surfaceCollection->addEnsembleSurface( ensemble ); + + ensemble->loadDataAndUpdate(); + RimProject::current()->activeOilField()->surfaceCollection->updateConnectedEditors(); + Riu3DMainWindowTools::selectAsCurrentItem( ensemble ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp index a7b60719e9..6e184e5e4e 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp @@ -597,7 +597,6 @@ void RimEclipseView::onCreateDisplayModel() m_surfaceVizModel->removeAllParts(); if ( m_surfaceCollection ) { - m_surfaceCollection->clearGeometry(); m_surfaceCollection->appendPartsToModel( m_surfaceVizModel.p(), m_reservoirGridPartManager->scaleTransform() ); nativeOrOverrideViewer()->addStaticModelOnce( m_surfaceVizModel.p(), isUsingOverrideViewer() ); } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCase.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCase.cpp index ba1de2153b..7a544f8564 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCase.cpp @@ -33,6 +33,7 @@ #include "cvfAssert.h" +#include "RiaEnsembleNameTools.h" #include #include @@ -296,42 +297,7 @@ QString RimSummaryCase::uniqueShortNameForEnsembleCase( RimSummaryCase* summaryC } } - std::map keyFileComponentsForAllFiles = - RiaFilePathTools::keyPathComponentsForEachFilePath( summaryFilePaths ); - - QStringList keyFileComponents = keyFileComponentsForAllFiles[summaryCase->summaryHeaderFilename()]; - if ( keyFileComponents.empty() ) return ensembleCaseName; - - if ( !ensembleCaseName.isEmpty() ) - { - for ( auto& component : keyFileComponents ) - { - component = component.replace( ensembleCaseName, "" ); - component = component.replace( trimRe, "" ); - } - } - - QStringList shortNameComponents; - QRegularExpression numberRe( "[0-9]+" ); - for ( auto keyComponent : keyFileComponents ) - { - QStringList subComponents; - QString numberGroup = numberRe.match( keyComponent ).captured(); - if ( !numberGroup.isEmpty() ) - { - keyComponent = keyComponent.replace( numberGroup, "" ); - QString stem = keyComponent.left( RimCaseDisplayNameTools::CASE_SHORT_NAME_LENGTH ); - if ( !stem.isEmpty() ) subComponents.push_back( stem ); - subComponents.push_back( numberGroup ); - } - else - { - subComponents.push_back( keyComponent.left( RimCaseDisplayNameTools::CASE_SHORT_NAME_LENGTH ) ); - } - - shortNameComponents.push_back( subComponents.join( "-" ) ); - } - return shortNameComponents.join( "," ); + return RiaEnsembleNameTools::uniqueShortName( summaryCase->summaryHeaderFilename(), summaryFilePaths, ensembleCaseName ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleStatisticsSurface.cpp b/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleStatisticsSurface.cpp index e6efab3bec..bc7026bb1c 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleStatisticsSurface.cpp +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleStatisticsSurface.cpp @@ -56,6 +56,8 @@ RimEnsembleStatisticsSurface::~RimEnsembleStatisticsSurface() void RimEnsembleStatisticsSurface::setStatisticsType( RigSurfaceStatisticsCalculator::StatisticsType statisticsType ) { m_statisticsType = statisticsType; + + setUserDescription( fullName() ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleSurfaceInView.cpp b/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleSurfaceInView.cpp index 16abd774b7..73909804aa 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleSurfaceInView.cpp +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimEnsembleSurfaceInView.cpp @@ -73,7 +73,7 @@ caf::PdmFieldHandle* RimEnsembleSurfaceInView::userDescriptionField() //-------------------------------------------------------------------------------------------------- QString RimEnsembleSurfaceInView::name() const { - if ( m_ensembleSurface ) return m_ensembleSurface->uiName(); + if ( m_ensembleSurface ) return m_ensembleSurface->name(); return ""; }