From b7420ebc70f474b8dc18691411f7ae87cc1a65e9 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 26 May 2023 11:26:22 +0200 Subject: [PATCH] Use rock type colors when "Facies" is imported --- .../Application/RiaResultNames.cpp | 8 ++ .../Application/RiaResultNames.h | 1 + .../RicFaciesPropertiesImportTools.cpp | 66 +++++----- .../Commands/RicFaciesPropertiesImportTools.h | 4 + .../FileInterface/RifRoffFileTools.cpp | 114 ++++++++++-------- .../RimColorLegendCollection.cpp | 4 +- .../RimColorLegendCollection.h | 2 +- 7 files changed, 120 insertions(+), 79 deletions(-) diff --git a/ApplicationLibCode/Application/RiaResultNames.cpp b/ApplicationLibCode/Application/RiaResultNames.cpp index 0d859bdaf6..5db1de4257 100644 --- a/ApplicationLibCode/Application/RiaResultNames.cpp +++ b/ApplicationLibCode/Application/RiaResultNames.cpp @@ -379,6 +379,14 @@ QString RiaResultNames::faultDistanceName() return "FAULTDIST"; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaResultNames::facies() +{ + return "FACIES"; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaResultNames.h b/ApplicationLibCode/Application/RiaResultNames.h index d3d0283045..a56594c201 100644 --- a/ApplicationLibCode/Application/RiaResultNames.h +++ b/ApplicationLibCode/Application/RiaResultNames.h @@ -75,6 +75,7 @@ QString indexKResultName(); RigEclipseResultAddress staticIntegerAddress( const QString& resultName ); QString faultDistanceName(); +QString facies(); QString soil(); QString sgas(); diff --git a/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.cpp b/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.cpp index e11cbbfdcb..0ffd3e35b1 100644 --- a/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.cpp +++ b/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.cpp @@ -65,39 +65,14 @@ void RicFaciesPropertiesImportTools::importFaciesPropertiesFromFile( const QStri faciesProperties->clearFaciesCodeNames(); - for ( auto it : codeNames ) + for ( const auto& it : codeNames ) { faciesProperties->setFaciesCodeName( it.first, it.second ); } if ( createColorLegend ) { - const caf::ColorTable& colorTable = RiaColorTables::contrastCategoryPaletteColors(); - RimColorLegendCollection* colorLegendCollection = RimProject::current()->colorLegendCollection; - RimColorLegend* rockTypeColorLegend = colorLegendCollection->findByName( RiaDefines::rockTypeColorLegendName() ); - - RimColorLegend* colorLegend = new RimColorLegend; - colorLegend->setColorLegendName( RiaDefines::faciesColorLegendName() ); - - for ( auto it : codeNames ) - { - RimColorLegendItem* colorLegendItem = new RimColorLegendItem; - - // Try to find a color from the rock type color legend by fuzzy matching names - cvf::Color3f color; - if ( !predefinedColorMatch( it.second, rockTypeColorLegend, color ) && !matchByName( it.second, rockTypeColorLegend, color ) ) - { - // No match use a random color - color = colorTable.cycledColor3f( it.first ); - } - - colorLegendItem->setValues( it.second, it.first, color ); - colorLegend->appendColorLegendItem( colorLegendItem ); - } - - colorLegendCollection->appendCustomColorLegend( colorLegend ); - colorLegendCollection->updateConnectedEditors(); - + auto colorLegend = RicFaciesPropertiesImportTools::createColorLegendMatchDefaultRockColors( codeNames ); faciesProperties->setColorLegend( colorLegend ); } @@ -107,6 +82,41 @@ void RicFaciesPropertiesImportTools::importFaciesPropertiesFromFile( const QStri stimPlanModelTemplate->updateConnectedEditors(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimColorLegend* RicFaciesPropertiesImportTools::createColorLegendMatchDefaultRockColors( const std::map& codeNames ) +{ + const caf::ColorTable& colorTable = RiaColorTables::contrastCategoryPaletteColors(); + RimColorLegendCollection* colorLegendCollection = RimProject::current()->colorLegendCollection; + RimColorLegend* rockTypeColorLegend = colorLegendCollection->findByName( RiaDefines::rockTypeColorLegendName() ); + + auto colorLegend = new RimColorLegend; + colorLegend->setColorLegendName( RiaDefines::faciesColorLegendName() ); + + for ( const auto& it : codeNames ) + { + auto colorLegendItem = new RimColorLegendItem; + + // Try to find a color from the rock type color legend by fuzzy matching names + cvf::Color3f color; + if ( rockTypeColorLegend && !predefinedColorMatch( it.second, rockTypeColorLegend, color ) && + !matchByName( it.second, rockTypeColorLegend, color ) ) + { + // No match use a random color + color = colorTable.cycledColor3f( it.first ); + } + + colorLegendItem->setValues( it.second, it.first, color ); + colorLegend->appendColorLegendItem( colorLegendItem ); + } + + colorLegendCollection->appendCustomColorLegend( colorLegend ); + colorLegendCollection->updateConnectedEditors(); + + return colorLegend; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -130,7 +140,7 @@ bool RicFaciesPropertiesImportTools::matchByName( const QString& name, RimColorL // Allow only small difference when determining if something matches const int maximumScoreToMatch = 1; - if ( bestScore <= maximumScoreToMatch ) + if ( bestItem && bestScore <= maximumScoreToMatch ) { color = bestItem->color(); return true; diff --git a/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.h b/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.h index c22cb80d9d..19eea5228e 100644 --- a/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.h +++ b/ApplicationLibCode/Commands/RicFaciesPropertiesImportTools.h @@ -18,6 +18,8 @@ #pragma once +#include + class RimColorLegend; class RimStimPlanModelTemplate; @@ -38,6 +40,8 @@ public: RimStimPlanModelTemplate* stimPlanModelTemplate, bool createColorLegend = false ); + static RimColorLegend* createColorLegendMatchDefaultRockColors( const std::map& codeNames ); + private: static int computeEditDistance( const QString& a, const QString& b ); static bool matchByName( const QString& name, RimColorLegend* colorLegend, cvf::Color3f& color ); diff --git a/ApplicationLibCode/FileInterface/RifRoffFileTools.cpp b/ApplicationLibCode/FileInterface/RifRoffFileTools.cpp index e204130e56..f91d94cfb5 100644 --- a/ApplicationLibCode/FileInterface/RifRoffFileTools.cpp +++ b/ApplicationLibCode/FileInterface/RifRoffFileTools.cpp @@ -21,6 +21,8 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "RicFaciesPropertiesImportTools.h" + #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" @@ -504,6 +506,29 @@ std::pair> RifRoffFileTools::createInputPropert return std::make_pair( false, keywordMapping ); } + auto codeNamesAndValuesForKeyword = []( const std::string& keyword, roff::Reader& reader ) -> std::map + { + const std::string codeNamesKeyword = keyword + roff::Parser::postFixCodeNames(); + const std::string codeValuesKeyword = keyword + roff::Parser::postFixCodeValues(); + + if ( reader.getArrayLength( codeNamesKeyword ) > 0 && + reader.getArrayLength( codeNamesKeyword ) == reader.getArrayLength( codeValuesKeyword ) ) + { + const auto fileCodeNames = reader.getStringArray( codeNamesKeyword ); + const auto fileCodeValues = reader.getIntArray( codeValuesKeyword ); + + std::map codeNamesAndValues; + for ( size_t i = 0; i < fileCodeNames.size(); i++ ) + { + codeNamesAndValues[fileCodeValues[i]] = QString::fromStdString( fileCodeNames[i] ).trimmed(); + } + + return codeNamesAndValues; + }; + + return {}; + }; + try { roff::Reader reader( stream ); @@ -521,6 +546,9 @@ std::pair> RifRoffFileTools::createInputPropert .arg( QString::fromStdString( roff::Token::kindToString( kind ) ) ) .arg( keywordLength ) ); } + + QString keywordUpperCase = QString::fromStdString( keyword ).toUpper(); + if ( eclipseCaseData->mainGrid()->cellCount() == keywordLength ) { QString newResultName = eclipseCaseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL ) @@ -538,61 +566,51 @@ std::pair> RifRoffFileTools::createInputPropert return std::make_pair( false, keywordMapping ); } - // Create color legend + const auto codeNames = codeNamesAndValuesForKeyword( keyword, reader ); + bool anyValidCategoryName = false; + for ( const auto& codeName : codeNames ) { - const std::string codeNamesKeyword = keyword + roff::Parser::postFixCodeNames(); - const std::string codeValuesKeyword = keyword + roff::Parser::postFixCodeValues(); - - auto codeNamesSize = reader.getArrayLength( codeNamesKeyword ); - auto codeValuesSize = reader.getArrayLength( codeValuesKeyword ); - - if ( codeNamesSize != 0 && codeNamesSize == codeValuesSize ) + if ( !codeName.second.isEmpty() ) { - const auto fileCodeNames = reader.getStringArray( codeNamesKeyword ); - const auto fileCodeValues = reader.getIntArray( codeValuesKeyword ); - - QStringList trimmedCodeNames; - bool anyValidName = false; - for ( const std::string& codeName : fileCodeNames ) - { - QString trimmedCodeName = QString::fromStdString( codeName ).trimmed(); - trimmedCodeNames.push_back( trimmedCodeName ); - - if ( !trimmedCodeName.isEmpty() ) - { - anyValidName = true; - } - } - - if ( anyValidName ) - { - std::vector> valuesAndNames; - - for ( int i = 0; i < static_cast( trimmedCodeNames.size() ); i++ ) - { - const auto& codeName = trimmedCodeNames[i]; - valuesAndNames.emplace_back( fileCodeValues[i], codeName ); - } - - RimColorLegendCollection* colorLegendCollection = RimProject::current()->colorLegendCollection; - - int caseId = 0; - auto rimCase = eclipseCaseData->ownerCase(); - if ( rimCase ) caseId = rimCase->caseId(); - - // Delete existing color legend, as new legend will be populated by values from file - colorLegendCollection->deleteColorLegend( caseId, newResultName ); - - auto colorLegend = colorLegendCollection->createColorLegend( newResultName, valuesAndNames ); - - colorLegendCollection->setDefaultColorLegendForResult( caseId, newResultName, colorLegend ); - colorLegendCollection->updateAllRequiredEditors(); - } + anyValidCategoryName = true; } } + if ( anyValidCategoryName ) + { + RimColorLegendCollection* colorLegendCollection = RimProject::current()->colorLegendCollection; + + int caseId = 0; + auto rimCase = eclipseCaseData->ownerCase(); + if ( rimCase ) caseId = rimCase->caseId(); + + // Delete existing color legend, as new legend will be populated by values from file + colorLegendCollection->deleteColorLegend( caseId, newResultName ); + + RimColorLegend* colorLegend = nullptr; + if ( keywordUpperCase == RiaResultNames::facies() ) + { + colorLegend = RicFaciesPropertiesImportTools::createColorLegendMatchDefaultRockColors( codeNames ); + } + else + { + colorLegend = colorLegendCollection->createColorLegend( newResultName, codeNames ); + } + + colorLegendCollection->setDefaultColorLegendForResult( caseId, newResultName, colorLegend ); + colorLegendCollection->updateAllRequiredEditors(); + } + keywordMapping[QString::fromStdString( keyword )] = newResultName; } + else if ( keywordUpperCase == RiaResultNames::facies() ) + { + // We have the definition of facies name and value, but we do not have values for cells. Create color legend and get values + // from other sources, i.e. Eclipse result files + + const auto codeNames = codeNamesAndValuesForKeyword( keyword, reader ); + RicFaciesPropertiesImportTools::createColorLegendMatchDefaultRockColors( codeNames ); + } } } catch ( std::runtime_error& err ) diff --git a/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.cpp index 4b0a646ce0..37521221d0 100644 --- a/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.cpp @@ -84,12 +84,12 @@ void RimColorLegendCollection::deleteCustomColorLegends() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimColorLegend* RimColorLegendCollection::createColorLegend( const QString& name, const std::vector>& valuesAndNames ) +RimColorLegend* RimColorLegendCollection::createColorLegend( const QString& colorLegendName, const std::map& valuesAndNames ) { auto colors = RiaColorTables::categoryPaletteColors().color3ubArray(); auto colorLegend = new RimColorLegend(); - colorLegend->setColorLegendName( name ); + colorLegend->setColorLegendName( colorLegendName ); int colorIndex = 0; for ( const auto& [value, name] : valuesAndNames ) { diff --git a/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.h b/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.h index c4db026418..960a35b292 100644 --- a/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.h +++ b/ApplicationLibCode/ProjectDataModel/RimColorLegendCollection.h @@ -47,7 +47,7 @@ public: bool isStandardColorLegend( RimColorLegend* colorLegend ); void deleteCustomColorLegends(); - RimColorLegend* createColorLegend( const QString& name, const std::vector>& valuesAndNames ); + RimColorLegend* createColorLegend( const QString& colorLegendName, const std::map& valuesAndNames ); void deleteColorLegend( int caseId, const QString& resultName ); void setDefaultColorLegendForResult( int caseId, const QString& resultName, RimColorLegend* colorLegend );