//////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2019- 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 "RicSummaryPlotTemplateTools.h" #include "RiaApplication.h" #include "RiaGuiApplication.h" #include "RiaLogging.h" #include "RiaSummaryCurveAnalyzer.h" #include "RicSelectPlotTemplateUi.h" #include "RifSummaryReaderInterface.h" #include "PlotTemplates/RimPlotTemplateFileItem.h" #include "RimDialogData.h" #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" #include "RimMainPlotCollection.h" #include "RimProject.h" #include "RimSummaryCase.h" #include "RimSummaryCurve.h" #include "RimSummaryPlot.h" #include "RimSummaryPlotCollection.h" #include "RiuPlotMainWindow.h" #include "cafPdmUiPropertyViewDialog.h" #include "cafSelectionManager.h" #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimSummaryPlot* RicSummaryPlotTemplateTools::createPlotFromTemplateFile( const QString& fileName ) { QFile importFile( fileName ); if ( !importFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) { RiaLogging::error( QString( "Create Plot from Template : Could not open the file: %1" ).arg( fileName ) ); return nullptr; } QTextStream stream( &importFile ); QString objectAsText = stream.readAll(); caf::PdmObjectHandle* obj = caf::PdmXmlObjectHandle::readUnknownObjectFromXmlString( objectAsText, caf::PdmDefaultObjectFactory::instance() ); RimSummaryPlot* newSummaryPlot = dynamic_cast( obj ); if ( newSummaryPlot ) { return newSummaryPlot; } delete obj; return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicSummaryPlotTemplateTools::appendSummaryPlotToPlotCollection( RimSummaryPlot* summaryPlot, const std::vector& selectedSummaryCases, const std::vector& selectedEnsembles ) { if ( summaryPlot ) { RimSummaryPlotCollection* plotColl = RiaApplication::instance()->project()->mainPlotCollection()->summaryPlotCollection(); plotColl->summaryPlots.push_back( summaryPlot ); summaryPlot->resolveReferencesRecursively(); summaryPlot->initAfterReadRecursively(); { auto summaryCurves = summaryPlot->summaryCurves(); for ( const auto& curve : summaryCurves ) { auto fieldHandle = curve->findField( "SummaryCase" ); if ( fieldHandle ) { auto referenceString = fieldHandle->xmlCapability()->referenceString(); auto stringList = referenceString.split( " " ); if ( stringList.size() == 2 ) { QString indexAsString = stringList[1]; bool conversionOk = false; auto index = indexAsString.toUInt( &conversionOk ); if ( conversionOk && index < selectedSummaryCases.size() ) { auto summaryCaseY = selectedSummaryCases[index]; curve->setSummaryCaseY( summaryCaseY ); auto currentAddressY = curve->summaryAddressY(); if ( summaryCaseY->summaryReader() && !summaryCaseY->summaryReader()->hasAddress( currentAddressY ) ) { auto allAddresses = summaryCaseY->summaryReader()->allResultAddresses(); auto candidate = RicSummaryPlotTemplateTools::firstAddressByQuantity( currentAddressY, allAddresses ); if ( candidate.category() != RifEclipseSummaryAddress::SUMMARY_INVALID ) { curve->setSummaryAddressY( candidate ); } } } } } } } { auto summaryCurves = summaryPlot->ensembleCurveSetCollection()->curveSets(); for ( const auto& curveSet : summaryCurves ) { auto fieldHandle = curveSet->findField( "SummaryGroup" ); if ( fieldHandle ) { auto referenceString = fieldHandle->xmlCapability()->referenceString(); auto stringList = referenceString.split( " " ); if ( stringList.size() == 2 ) { QString indexAsString = stringList[1]; bool conversionOk = false; auto index = indexAsString.toUInt( &conversionOk ); if ( conversionOk && index < selectedEnsembles.size() ) { auto summaryCaseY = selectedEnsembles[index]; curveSet->setSummaryCaseCollection( summaryCaseY ); } } } } } // TODO: Create additional curves in selected case count is larger than template count plotColl->updateConnectedEditors(); summaryPlot->loadDataAndUpdate(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RicSummaryPlotTemplateTools::htmlTextFromPlotAndSelection( const RimSummaryPlot* templatePlot, const std::set& selectedSummaryAddresses, const std::vector& selectedSources ) { QString text; RiaSummaryCurveAnalyzer selectionAnalyzer; selectionAnalyzer.appendAddresses( selectedSummaryAddresses ); if ( templatePlot ) { std::set templateSources; RiaSummaryCurveAnalyzer templateAnalyzer; { std::set templateAddresses; for ( const auto& curve : templatePlot->summaryCurves() ) { auto adr = curve->summaryAddressY(); templateAddresses.insert( adr ); auto fieldHandle = curve->findField( "SummaryCase" ); if ( fieldHandle ) { auto test = fieldHandle->xmlCapability()->referenceString(); templateSources.insert( test ); } } templateAnalyzer.appendAddresses( templateAddresses ); } text += " Requirements
"; if ( !templateSources.empty() ) { QString itemText = "Source Cases"; size_t requiredCount = templateSources.size(); size_t selectedCount = selectedSources.size(); text += htmlTextFromCount( itemText, requiredCount, selectedCount ); } if ( !templateAnalyzer.wellNames().empty() ) { QString itemText = "Wells"; size_t requiredCount = templateAnalyzer.wellNames().size(); size_t selectedCount = selectionAnalyzer.wellNames().size(); text += htmlTextFromCount( itemText, requiredCount, selectedCount ); } if ( !templateAnalyzer.wellGroupNames().empty() ) { QString itemText = "Well Groups"; size_t requiredCount = templateAnalyzer.wellGroupNames().size(); size_t selectedCount = selectionAnalyzer.wellGroupNames().size(); text += htmlTextFromCount( itemText, requiredCount, selectedCount ); } if ( !templateAnalyzer.regionNumbers().empty() ) { QString itemText = "Regions"; size_t requiredCount = templateAnalyzer.regionNumbers().size(); size_t selectedCount = selectionAnalyzer.regionNumbers().size(); text += htmlTextFromCount( itemText, requiredCount, selectedCount ); } } return text; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RicSummaryPlotTemplateTools::htmlTextFromCount( const QString& itemText, size_t requiredItemCount, size_t selectionCount ) { QString text; QString colorString = "green"; if ( selectionCount < requiredItemCount ) colorString = "red"; else if ( selectionCount > requiredItemCount ) colorString = "orange"; text += QString( "" ).arg( colorString ); text += QString( "%1 : %2 selected (%3 required)\n" ).arg( itemText ).arg( selectionCount ).arg( requiredItemCount ); text += ""; text += "
"; return text; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RicSummaryPlotTemplateTools::selectPlotTemplatePath() { RiuPlotMainWindow* plotwindow = RiaGuiApplication::instance()->mainPlotWindow(); RicSelectPlotTemplateUi* ui = RiaGuiApplication::instance()->project()->dialogData()->selectPlotTemplateUi(); caf::PdmUiPropertyViewDialog propertyDialog( plotwindow, ui, "Select Plot Template", "" ); if ( propertyDialog.exec() == QDialog::Accepted && !ui->selectedPlotTemplates().empty() ) { QString fileName = ui->selectedPlotTemplates().front()->absoluteFilePath(); return fileName; } return QString(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RicSummaryPlotTemplateTools::selectedSummaryCases() { std::vector objects; caf::SelectionManager::instance()->objectsByType( &objects ); return objects; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RicSummaryPlotTemplateTools::selectedSummaryCaseCollections() { std::vector objects; caf::SelectionManager::instance()->objectsByType( &objects ); return objects; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RifEclipseSummaryAddress RicSummaryPlotTemplateTools::firstAddressByQuantity( const RifEclipseSummaryAddress& sourceAddress, const std::set& allAddresses ) { for ( const auto& a : allAddresses ) { if ( sourceAddress.quantityName() == a.quantityName() ) { return a; } } return RifEclipseSummaryAddress(); }