///////////////////////////////////////////////////////////////////////////////// // // 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 "RiaSummaryStringTools.h" #include "RiaLogging.h" #include "RiaStdStringTools.h" #include "RiaSummaryTools.h" #include "RiaTextStringTools.h" #include "RifEclipseSummaryAddress.h" #include "RifReaderEclipseSummary.h" #include "RifSummaryReaderInterface.h" #include "RimMainPlotCollection.h" #include "RimSummaryCase.h" #include "RimSummaryCaseCollection.h" #include "RimSummaryCaseMainCollection.h" #include "SummaryPlotCommands/RicSummaryPlotFeatureImpl.h" #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiaSummaryStringTools::splitAddressFiltersInGridAndSummary( RimSummaryCase* summaryCase, const QStringList& addressFilters, QStringList* summaryAddressFilters, QStringList* gridResultAddressFilters ) { if ( summaryCase ) { const std::set& addrs = summaryCase->summaryReader()->allResultAddresses(); QRegularExpression gridAddressPattern( "^[A-Z]+:[0-9]+,[0-9]+,[0-9]+$" ); for ( int filterIdx = 0; filterIdx < addressFilters.size(); ++filterIdx ) { const QString& address = addressFilters[filterIdx]; if ( hasFilterAnyMatch( address, addrs ) ) { summaryAddressFilters->push_back( address ); } else { if ( gridAddressPattern.match( address ).hasMatch() ) { gridResultAddressFilters->push_back( address ); } else { RiaLogging::warning( "No summary or restart vectors matched \"" + address + "\"" ); } } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::pair RiaSummaryStringTools::splitIntoAddressAndDataSourceFilters( const QString& filter ) { auto words = RiaSummaryStringTools::splitIntoWords( filter ); auto [summaryCases, ensembles] = RiaSummaryStringTools::allDataSourcesInProject(); auto dataSourceNames = RiaSummaryStringTools::dataSourceNames( summaryCases, ensembles ); QStringList addressFilters; QStringList dataSourceFilters; RiaSummaryStringTools::splitUsingDataSourceNames( words, dataSourceNames, addressFilters, dataSourceFilters ); // If no filter on data source is specified, use wildcard to match all if ( dataSourceFilters.empty() ) dataSourceFilters.push_back( "*" ); return { addressFilters, dataSourceFilters }; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RiaSummaryStringTools::hasFilterAnyMatch( const QString& curveFilter, const std::set& summaryAddresses ) { for ( const auto& addr : summaryAddresses ) { if ( addr.isUiTextMatchingFilterText( curveFilter ) ) return true; } return false; } //-------------------------------------------------------------------------------------------------- /// Sort filters into curve and data source filters //-------------------------------------------------------------------------------------------------- void RiaSummaryStringTools::splitUsingDataSourceNames( const QStringList& filters, const QStringList& dataSourceNames, QStringList& addressFilters, QStringList& dataSourceFilters ) { for ( const auto& s : filters ) { // Strip off realization filter from ensemble search string QString pureDataSourceCandidate = s.left( s.indexOf( ':' ) ); bool foundDataSource = false; QRegExp searcher( pureDataSourceCandidate, Qt::CaseInsensitive, QRegExp::WildcardUnix ); for ( const auto& ds : dataSourceNames ) { if ( !foundDataSource && searcher.exactMatch( ds ) ) { dataSourceFilters.push_back( s ); foundDataSource = true; } } if ( !foundDataSource ) { addressFilters.push_back( s ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::pair, std::vector> RiaSummaryStringTools::allDataSourcesInProject() { auto sumCaseMainColl = RiaSummaryTools::summaryCaseMainCollection(); if ( !sumCaseMainColl ) return { {}, {} }; auto summaryCases = sumCaseMainColl->topLevelSummaryCases(); auto ensembles = sumCaseMainColl->summaryCaseCollections(); return { summaryCases, ensembles }; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::pair, std::vector> RiaSummaryStringTools::dataSourcesMatchingFilters( const QStringList& dataSourceFilters ) { std::vector matchingSummaryCases; std::vector matchingEnsembles; auto [allSummaryCases, allEnsembles] = allDataSourcesInProject(); for ( const auto& dsFilter : dataSourceFilters ) { QString searchString = dsFilter.left( dsFilter.indexOf( ':' ) ); QRegExp searcher( searchString, Qt::CaseInsensitive, QRegExp::WildcardUnix ); for ( const auto& ensemble : allEnsembles ) { auto ensembleName = ensemble->name(); if ( searcher.exactMatch( ensembleName ) ) { if ( searchString == dsFilter ) { // Match on ensemble name without realization filter matchingEnsembles.push_back( ensemble ); } else { // Match on subset of realisations in ensemble QString realizationSearchString = dsFilter.right( dsFilter.size() - dsFilter.indexOf( ':' ) - 1 ); QRegExp realizationSearcher( realizationSearchString, Qt::CaseInsensitive, QRegExp::WildcardUnix ); for ( const auto& summaryCase : ensemble->allSummaryCases() ) { auto realizationName = summaryCase->displayCaseName(); if ( realizationSearcher.exactMatch( realizationName ) ) { matchingSummaryCases.push_back( summaryCase ); } } } } } for ( const auto& summaryCase : allSummaryCases ) { auto summaryCaseName = summaryCase->displayCaseName(); if ( searcher.exactMatch( summaryCaseName ) ) { matchingSummaryCases.push_back( summaryCase ); } } } return { matchingSummaryCases, matchingEnsembles }; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QStringList RiaSummaryStringTools::splitIntoWords( const QString& text ) { return RiaTextStringTools::splitSkipEmptyParts( text, QRegExp( "\\s+" ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QStringList RiaSummaryStringTools::dataSourceNames( const std::vector& summaryCases, const std::vector& ensembles ) { QStringList names; for ( const auto& summaryCase : summaryCases ) { names.push_back( summaryCase->displayCaseName() ); } for ( const auto& ensemble : ensembles ) { names.push_back( ensemble->name() ); } return names; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::set RiaSummaryStringTools::computeFilteredAddresses( const QStringList& textFilters, const std::set& sourceAddresses, bool includeDiffCurves ) { std::set addresses; std::vector usedFilters; RicSummaryPlotFeatureImpl::insertFilteredAddressesInSet( textFilters, sourceAddresses, &addresses, &usedFilters ); if ( includeDiffCurves ) return addresses; const auto diffText = RifReaderEclipseSummary::differenceIdentifier(); std::set addressesWithoutDiffVectors; for ( const auto& adr : addresses ) { if ( RiaStdStringTools::endsWith( adr.vectorName(), diffText ) ) continue; addressesWithoutDiffVectors.insert( adr ); } return addressesWithoutDiffVectors; }