Fix issue with single realization when using resdata (#12737)

* Moves multi reader initialization
* Log error message if not able to open file
* Make keywordCount pure virtual

The base class `RifSummaryReaderInterface` is changed to be abstract and the `keywordCount` is declared as a pure virtual method, therefore the derived classes must implement the method.

This will ensure that all readers are responsible for reporting a keyword count.

* Ensures addresses are created if required

Calls `createAddressesIfRequired` on the summary reader to ensure addresses are created before accessing keyword count.
This prevents potential issues when the addresses haven't been initialized yet.
This commit is contained in:
Magne Sjaastad authored and GitHub committed 2025-08-12 12:52:26 +02:00
1 parent 06a3419d2b
commit c854166be6
27 files changed
+161 -28

No files matched your search

@@ -277,3 +277,11 @@ std::vector<time_t> RifColumnBasedUserData::createTimeSteps( const TableData& ta
return tsVector;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifColumnBasedUserData::keywordCount() const
{
return m_mapFromAddressToResultIndex.size();
}
@@ -52,6 +52,7 @@ public:
private:
void buildTimeStepsAndMappings();
static std::vector<time_t> createTimeSteps( const TableData& table );
size_t keywordCount() const override;
private:
std::unique_ptr<RifColumnBasedUserDataParser> m_parser;
@@ -146,3 +146,11 @@ void RifCsvSummaryReader::buildTimeStepsAndMappings()
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifCsvSummaryReader::keywordCount() const
{
return m_mapFromAddressToResultIndex.size();
}
@@ -48,8 +48,10 @@ public:
RiaDefines::EclipseUnitSystem unitSystem() const override;
protected:
void buildTimeStepsAndMappings();
void buildTimeStepsAndMappings();
size_t keywordCount() const override;
protected:
std::unique_ptr<RifCsvUserDataParser> m_parser;
std::map<RifEclipseSummaryAddress, size_t> m_mapFromAddressToResultIndex;
@@ -166,3 +166,11 @@ void RifCsvUserData::buildTimeStepsAndMappings()
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifCsvUserData::keywordCount() const
{
return m_mapFromAddressToResultIndex.size();
}
@@ -52,7 +52,8 @@ public:
RiaDefines::EclipseUnitSystem unitSystem() const override;
private:
void buildTimeStepsAndMappings();
void buildTimeStepsAndMappings();
size_t keywordCount() const override;
private:
std::unique_ptr<RifCsvUserDataParser> m_parser;
@@ -67,14 +67,24 @@ bool RifEclEclipseSummary::open( const QString& headerFileName, RiaThreadSafeLog
assert( m_ecl_sum == nullptr );
m_ecl_sum = RifEclipseSummaryTools::openEclSum( headerFileName, false );
if ( m_ecl_sum )
if ( !m_ecl_sum )
{
m_timeSteps.clear();
m_ecl_SmSpec = ecl_sum_get_smspec( m_ecl_sum );
m_timeSteps = RifEclipseSummaryTools::getTimeSteps( m_ecl_sum );
m_unitSystem = RifEclipseSummaryTools::readUnitSystem( m_ecl_sum );
if ( threadSafeLogger )
{
QString msg = "Not able to create resdata file reader for " + headerFileName;
threadSafeLogger->error( msg );
}
return false;
}
m_timeSteps.clear();
m_ecl_SmSpec = ecl_sum_get_smspec( m_ecl_sum );
m_timeSteps = RifEclipseSummaryTools::getTimeSteps( m_ecl_sum );
m_unitSystem = RifEclipseSummaryTools::readUnitSystem( m_ecl_sum );
createAndSetAddresses();
return true;
}
@@ -363,6 +373,19 @@ void RifEclEclipseSummary::createAndSetAddresses()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifEclEclipseSummary::keywordCount() const
{
if ( m_ecl_SmSpec )
{
return static_cast<size_t>( ecl_smspec_num_nodes( m_ecl_SmSpec ) );
}
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -57,8 +57,9 @@ public:
static std::string normalizeCompletionAddress( const std::string& address );
private:
int indexFromAddress( const RifEclipseSummaryAddress& resultAddress ) const;
void createAndSetAddresses() override;
int indexFromAddress( const RifEclipseSummaryAddress& resultAddress ) const;
void createAndSetAddresses() override;
size_t keywordCount() const override;
private:
ecl_sum_type* m_ecl_sum;
@@ -266,3 +266,11 @@ QString RifKeywordVectorUserData::valueForKey( const std::map<QString, QString>&
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifKeywordVectorUserData::keywordCount() const
{
return m_mapFromAddressToVectorIndex.size();
}
@@ -54,6 +54,7 @@ private:
static bool isTimeHeader( const std::map<QString, QString>& header );
static bool isVectorHeader( const std::map<QString, QString>& header );
static QString valueForKey( const std::map<QString, QString>& header, const QString& key );
size_t keywordCount() const override;
private:
std::unique_ptr<RifKeywordVectorParser> m_parser;
@@ -194,3 +194,15 @@ bool RifOpmHdf5Summary::openESmryFile( const QString& headerFileName, bool inclu
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifOpmHdf5Summary::keywordCount() const
{
if ( m_eSmry )
{
return m_eSmry->keywordList().size();
}
return 0;
}
@@ -62,8 +62,9 @@ public:
RiaDefines::EclipseUnitSystem unitSystem() const override;
private:
void createAndSetAddresses() override;
bool openESmryFile( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
void createAndSetAddresses() override;
bool openESmryFile( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
size_t keywordCount() const override;
private:
std::unique_ptr<Opm::EclIO::ESmry> m_eSmry;
@@ -184,6 +184,14 @@ RifEclipseSummaryAddress RifReaderObservedData::address( const QString&
id );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifReaderObservedData::keywordCount() const
{
return m_allResultAddresses.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -54,6 +54,7 @@ public:
private:
RifEclipseSummaryAddress
address( const QString& vectorName, const QString& identifierName, RifEclipseSummaryAddressDefines::SummaryCategory summaryCategory );
size_t keywordCount() const override;
private:
std::unique_ptr<RifCsvUserDataParser> m_asciiParser;
@@ -69,14 +69,6 @@ void RifSummaryReaderInterface::createAddressesIfRequired()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifSummaryReaderInterface::keywordCount() const
{
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -60,13 +60,11 @@ public:
// Returns the number of result addresses. If no addresses are present, keywordCount() is returned.
size_t dataObjectCount() const;
protected:
// The keywordCount is considered a internal method, not to be used by clients. Add a friend class to allow access
friend class RifSummaryReaderAggregator;
friend class RifMultipleSummaryReaders;
friend class RifReaderEclipseSummary;
virtual size_t keywordCount() const;
// The keywordCount is considered a internal method, not to be used by clients. Having it as a protected method will not work well, as
// this class is also used as a contained object in addition to deriving from this interface.
virtual size_t keywordCount() const = 0;
protected:
void increaseSerialNumber();
std::set<RifEclipseSummaryAddress> m_allResultAddresses; // Result and error addresses
@@ -114,6 +114,14 @@ RimSummaryCalculation* RifCalculatedSummaryCurveReader::findCalculationByName( c
return dynamic_cast<RimSummaryCalculation*>( m_calculationCollection->findCalculationById( resultAddress.id() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RifCalculatedSummaryCurveReader::keywordCount() const
{
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -43,6 +43,7 @@ public:
private:
RimSummaryCalculation* findCalculationByName( const RifEclipseSummaryAddress& resultAddress ) const;
size_t keywordCount() const override;
private:
RimSummaryCalculationCollection* m_calculationCollection;
@@ -368,6 +368,14 @@ QString RimDeltaSummaryCase::caseName() const
return m_displayName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimDeltaSummaryCase::keywordCount() const
{
return m_allResultAddresses.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -88,6 +88,7 @@ public:
protected:
QString caseName() const override;
size_t keywordCount() const override;
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
@@ -318,3 +318,18 @@ void RimEnsembleCrossPlotStatisticsCase::clearData()
m_meanData.clear();
m_firstSummaryCase = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimEnsembleCrossPlotStatisticsCase::keywordCount() const
{
if ( m_firstSummaryCase && m_firstSummaryCase->summaryReader() )
{
m_firstSummaryCase->summaryReader()->createAddressesIfRequired();
return m_firstSummaryCase->summaryReader()->keywordCount();
}
return 0;
}
@@ -55,7 +55,8 @@ public:
std::string unitName( const RifEclipseSummaryAddress& resultAddress ) const override;
private:
void clearData();
void clearData();
size_t keywordCount() const override;
private:
std::vector<double> m_p10Data;
@@ -240,6 +240,21 @@ void RimEnsembleStatisticsCase::clearData()
m_firstSummaryCase = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimEnsembleStatisticsCase::keywordCount() const
{
if ( m_firstSummaryCase && m_firstSummaryCase->summaryReader() )
{
m_firstSummaryCase->summaryReader()->createAddressesIfRequired();
return m_firstSummaryCase->summaryReader()->keywordCount();
}
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -54,7 +54,8 @@ public:
static RiaDefines::DateTimePeriod findBestResamplingPeriod( time_t minTimeStep, time_t maxTimeStep );
private:
void clearData();
void clearData();
size_t keywordCount() const override;
private:
std::vector<time_t> m_timeSteps;
@@ -100,7 +100,7 @@ void RimFileSummaryCase::createSummaryReaderInterfaceThreadSafe( RifEnsembleImpo
//
// https://github.com/OPM/ResInsight/issues/11342
m_multiSummaryReader = std::make_unique<RifMultipleSummaryReaders>();
auto multiReader = std::make_unique<RifMultipleSummaryReaders>();
m_fileSummaryReaderId = -1;
m_additionalSummaryReaderId = -1;
@@ -112,6 +112,7 @@ void RimFileSummaryCase::createSummaryReaderInterfaceThreadSafe( RifEnsembleImpo
m_fileSummaryReaderId = reader->serialNumber();
m_multiSummaryReader = std::move( multiReader );
m_multiSummaryReader->addReader( std::move( reader ) );
openAndAttachAdditionalReader();
@@ -179,3 +179,11 @@ void RimSummaryCaseSumo::createAndSetAddresses()
m_allResultAddresses = addresses;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimSummaryCaseSumo::keywordCount() const
{
return m_allResultAddresses.size();
}
@@ -57,6 +57,7 @@ public:
protected:
QString caseName() const override;
void createAndSetAddresses() override;
size_t keywordCount() const override;
private:
caf::PdmPointer<RimSummaryEnsembleSumo> m_ensemble;