mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 06:38:13 -05:00
Crash signature c0fae31c2301. RifElementPropertyReader reads column metadata when the file is added and the data later, on cell pick. If the file has since been moved or deleted, readData returns no data and CAF_ASSERT( dataColumns.size() == table.data.size() ) aborts. Return an empty result when the table has no data or the column count does not match. New test ReadAllElementPropertiesFromRemovedFile. Call stack: [5] cvf::AssertHandlerConsole::handleAssert(char const*, int, char const*, char const*) at ResInsight/Fwk/VizFwk/LibCore/cvfAssert.cpp:125 [6] RifElementPropertyReader::readAllElementPropertiesInFileContainingField(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) at ResInsight/ApplicationLibCode/FileInterface/RifElementPropertyReader.cpp:120 [7] RigFemPartResultsCollection::findOrLoadScalarResult(int, RigFemResultAddress const&) at ResInsight/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp:451 [8] RigFemPartResultsCollection::assertResultsLoaded(RigFemResultAddress const&) at ResInsight/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp:1014 [9] RimGeoMechResultDefinition::hasResult() at ResInsight/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechResultDefinition.cpp:722 [10] RiuSelectionChangedHandler::addResultCurveFromSelectionItem(RiuGeoMechSelectionItem const*) const at ResInsight/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp:208 [11] RiuSelectionChangedHandler::handleItemAppended(RiuSelectionItem const*) const at ResInsight/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp:119 [12] RiuCellAndNncPickEventHandler::handle3dPickEvent(Ric3dPickEvent const&) at ResInsight/ApplicationLibCode/UserInterface/RiuCellAndNncPickEventHandler.cpp:459 [13] RiuViewerCommands::handlePickAction(int, int, QFlags<Qt::KeyboardModifier>) at ResInsight/ApplicationLibCode/UserInterface/RiuViewerCommands.cpp:718 [17] RiaGuiApplication::notify(QObject*, QEvent*) at ResInsight/ApplicationLibCode/Application/RiaGuiApplication.cpp:1828 [23] RiaGuiApplication::notify(QObject*, QEvent*) at ResInsight/ApplicationLibCode/Application/RiaGuiApplication.cpp:1828 [34] main at ResInsight/ApplicationExeCode/RiaMain.cpp:267 [35] __libc_start_main at :0
246 lines
8.6 KiB
C++
246 lines
8.6 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2018- 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 <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RifElementPropertyReader.h"
|
|
#include "RiaEclipseUnitTools.h"
|
|
#include "RiaLogging.h"
|
|
#include "RiaQStringFormatter.h"
|
|
#include "RifFileParseTools.h"
|
|
#include "RiuMessageDialog.h"
|
|
|
|
#include "cafAssert.h"
|
|
|
|
#include <cmath>
|
|
|
|
#include <QString>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifElementPropertyReader::RifElementPropertyReader( const std::vector<int>& elementIdxToId )
|
|
: m_elementIdxToId( elementIdxToId )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifElementPropertyReader::~RifElementPropertyReader()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RifElementPropertyReader::addFile( const std::string& fileName )
|
|
{
|
|
RifElementPropertyMetadata metaData = RifElementPropertyTableReader::readMetadata( QString::fromStdString( fileName ) );
|
|
for ( QString field : metaData.dataColumns )
|
|
{
|
|
m_fieldsMetaData[field.toStdString()] = metaData;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RifElementPropertyReader::removeFile( const std::string& fileName )
|
|
{
|
|
std::map<std::string, RifElementPropertyMetadata> tempMetaData;
|
|
|
|
for ( std::pair<std::string, RifElementPropertyMetadata> metaData : m_fieldsMetaData )
|
|
{
|
|
if ( metaData.second.fileName.toStdString() != fileName )
|
|
{
|
|
tempMetaData[metaData.first] = metaData.second;
|
|
}
|
|
}
|
|
|
|
m_fieldsMetaData.swap( tempMetaData );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::string> RifElementPropertyReader::scalarElementFields() const
|
|
{
|
|
std::vector<std::string> fields;
|
|
|
|
for ( const std::pair<const std::string, RifElementPropertyMetadata>& field : m_fieldsMetaData )
|
|
{
|
|
fields.push_back( field.first );
|
|
}
|
|
|
|
return fields;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
static void scaleColumnIfModulus( const std::string& fieldName, std::vector<float>& data )
|
|
{
|
|
if ( fieldName == "MODULUS" )
|
|
{
|
|
const float paToGPa = static_cast<float>( 1.0 / RiaEclipseUnitTools::gigaPascalToPascal( 1.0 ) );
|
|
for ( float& v : data )
|
|
{
|
|
v *= paToGPa;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::map<std::string, std::vector<float>> RifElementPropertyReader::readAllElementPropertiesInFileContainingField( const std::string& fieldName )
|
|
{
|
|
std::map<std::string, std::vector<float>> fieldAndData;
|
|
|
|
if ( m_fieldsMetaData.find( fieldName ) == m_fieldsMetaData.end() )
|
|
{
|
|
return fieldAndData;
|
|
}
|
|
|
|
RifElementPropertyTable table;
|
|
try
|
|
{
|
|
RifElementPropertyTableReader::readData( &m_fieldsMetaData[fieldName], &table );
|
|
}
|
|
catch ( FileParseException& exception )
|
|
{
|
|
RiaLogging::error( std::format( "Element property import failed: '{}'.", exception.message ) );
|
|
return fieldAndData;
|
|
}
|
|
|
|
// The file may have been moved or deleted after the metadata was read
|
|
if ( !table.hasData || m_fieldsMetaData[fieldName].dataColumns.size() != table.data.size() )
|
|
{
|
|
return fieldAndData;
|
|
}
|
|
|
|
for ( size_t i = 0; i < table.data.size(); i++ )
|
|
{
|
|
CAF_ASSERT( table.data[i].size() == table.elementIds.size() );
|
|
}
|
|
|
|
const std::vector<int>& elementIdsFromFile = table.elementIds;
|
|
|
|
if ( elementIdsFromFile == m_elementIdxToId )
|
|
{
|
|
for ( size_t i = 0; i < table.data.size(); i++ )
|
|
{
|
|
const std::string& currentFieldFromFile = m_fieldsMetaData[fieldName].dataColumns[i].toStdString();
|
|
std::vector<float> columnData = table.data[i];
|
|
scaleColumnIfModulus( currentFieldFromFile, columnData );
|
|
fieldAndData[currentFieldFromFile] = std::move( columnData );
|
|
}
|
|
}
|
|
else if ( elementIdsFromFile.size() > m_elementIdxToId.size() && elementIdsFromFile.size() > m_elementIdToIdx.size() )
|
|
{
|
|
RifElementPropertyReader::outputWarningAboutWrongFileData();
|
|
return fieldAndData;
|
|
}
|
|
else
|
|
{
|
|
if ( m_elementIdToIdx.empty() )
|
|
{
|
|
makeElementIdToIdxMap();
|
|
}
|
|
|
|
std::vector<int> fileIdxToElementIdx;
|
|
fileIdxToElementIdx.reserve( elementIdsFromFile.size() );
|
|
|
|
for ( int elementId : elementIdsFromFile )
|
|
{
|
|
auto it = m_elementIdToIdx.find( elementId );
|
|
if ( it == m_elementIdToIdx.end() )
|
|
{
|
|
RifElementPropertyReader::outputWarningAboutWrongFileData();
|
|
return fieldAndData;
|
|
}
|
|
|
|
fileIdxToElementIdx.push_back( it->second );
|
|
}
|
|
|
|
for ( size_t i = 0; i < table.data.size(); i++ )
|
|
{
|
|
std::string currentFieldFromFile = m_fieldsMetaData[fieldName].dataColumns[i].toStdString();
|
|
const std::vector<float>& currentColumn = table.data[i];
|
|
|
|
std::vector<float> tempResult( m_elementIdToIdx.size(), HUGE_VAL );
|
|
|
|
for ( size_t j = 0; j < currentColumn.size(); j++ )
|
|
{
|
|
tempResult[fileIdxToElementIdx[j]] = currentColumn[j];
|
|
}
|
|
|
|
scaleColumnIfModulus( currentFieldFromFile, tempResult );
|
|
fieldAndData[currentFieldFromFile].swap( tempResult );
|
|
}
|
|
}
|
|
|
|
return fieldAndData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::string> RifElementPropertyReader::fieldsInFile( const std::string& fileName ) const
|
|
{
|
|
std::vector<std::string> fields;
|
|
|
|
for ( std::pair<std::string, RifElementPropertyMetadata> metaData : m_fieldsMetaData )
|
|
{
|
|
if ( metaData.second.fileName.toStdString() == fileName )
|
|
{
|
|
for ( const QString& column : metaData.second.dataColumns )
|
|
{
|
|
fields.push_back( column.toStdString() );
|
|
}
|
|
}
|
|
}
|
|
|
|
return fields;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RifElementPropertyReader::makeElementIdToIdxMap()
|
|
{
|
|
m_elementIdToIdx.reserve( m_elementIdxToId.size() );
|
|
|
|
for ( size_t i = 0; i < m_elementIdxToId.size(); i++ )
|
|
{
|
|
m_elementIdToIdx[m_elementIdxToId[i]] = (int)i;
|
|
}
|
|
|
|
std::vector<int> tempVectorForDeletion;
|
|
m_elementIdxToId.swap( tempVectorForDeletion );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RifElementPropertyReader::outputWarningAboutWrongFileData()
|
|
{
|
|
QString warningText = QString( "The chosen result property does not fit the model" );
|
|
|
|
RiuMessageDialog::showError( nullptr, "Element Property Reader", warningText );
|
|
}
|