Minor HDF adjustments (#7577)

* #7575 Summary HDF : Do not import summary if no UNSRMY file is found
* #7575 Summary HDF : Add optional check on time stamp of h5 file
* Use std::filesystem to check file access
* Do not keep h5 file open
This commit is contained in:
Magne Sjaastad 2021-04-16 10:52:30 +02:00 committed by GitHub
parent a44378e2f5
commit 52799e8b4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 353 additions and 361 deletions

View File

@ -106,6 +106,25 @@ bool RiaEclipseFileNameTools::isSummarySpecFile( const QString& fileName )
return hasMatchingSuffix( fileName, EclipseFileType::ECLIPSE_SMSPEC );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaEclipseFileNameTools::isSummaryDataFilePresent( const QString& smspecFileName )
{
QFileInfo fi( smspecFileName );
{
QString candidateFileName = fi.absolutePath() + '/' + fi.baseName() + ".UNSMRY";
if ( QFile::exists( candidateFileName ) ) return true;
}
{
QString candidateFileName = fi.absolutePath() + '/' + fi.baseName() + ".FUNSMRY";
if ( QFile::exists( candidateFileName ) ) return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -52,6 +52,7 @@ public:
static bool isProjectFile( const QString& fileName );
static bool isGridFile( const QString& fileName );
static bool isSummarySpecFile( const QString& fileName );
static bool isSummaryDataFilePresent( const QString& smspecFileName );
private:
QString relatedFilePath( EclipseFileType fileType ) const;

View File

@ -235,51 +235,6 @@ RiaPreferences::RiaPreferences()
CAF_PDM_InitField( &loadAndShowSoil, "loadAndShowSoil", true, "Load and Show SOIL", "", "", "" );
loadAndShowSoil.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
/*
CAF_PDM_InitFieldNoDefault( &summaryRestartFilesShowImportDialog,
"summaryRestartFilesShowImportDialog",
"Show Import Dialog",
"",
"",
"" );
CAF_PDM_InitField( &summaryImportMode,
"summaryImportMode",
SummaryRestartFilesImportModeType( RiaPreferences::SummaryRestartFilesImportMode::IMPORT ),
"Default Summary Import Option",
"",
"",
"" );
CAF_PDM_InitField( &gridImportMode,
"gridImportMode",
SummaryRestartFilesImportModeType( RiaPreferences::SummaryRestartFilesImportMode::NOT_IMPORT
), "Default Grid Import Option",
"",
"",
"" );
CAF_PDM_InitField( &summaryEnsembleImportMode,
"summaryEnsembleImportMode",
SummaryRestartFilesImportModeType( RiaPreferences::SummaryRestartFilesImportMode::IMPORT ),
"Default Ensemble Summary Import Option",
"",
"",
"" );
CAF_PDM_InitField( &defaultSummaryHistoryCurveStyle,
"defaultSummaryHistoryCurveStyle",
SummaryHistoryCurveStyleModeType( RiaPreferences::SummaryHistoryCurveStyleMode::SYMBOLS ),
"Default Curve Style for History Vectors",
"",
"",
"" );
CAF_PDM_InitField( &defaultSummaryCurvesTextFilter,
"defaultSummaryCurvesTextFilter",
QString( "FOPT" ),
"Default Summary Curves",
"",
"Semicolon separated list of filters used to create curves in new summary plots",
"" );
*/
CAF_PDM_InitFieldNoDefault( &m_holoLensExportFolder, "holoLensExportFolder", "HoloLens Export Folder", "", "", "" );
m_holoLensExportFolder.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
m_holoLensExportFolder.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() );
@ -338,27 +293,6 @@ RiaPreferences::RiaPreferences()
m_searchPlotTemplateFoldersRecursively.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitFieldNoDefault( &m_defaultPlotTemplate, "defaultPlotTemplate", "Default Plot Template", "", "", "" );
// m_plotTemplateFolders.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() );
/*
CAF_PDM_InitField( &m_showSummaryTimeAsLongString,
"showSummaryTimeAsLongString",
false,
"Show resample time text as long time text (2010-11-21 23:15:00)",
"",
"",
"" );
m_showSummaryTimeAsLongString.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitField( &m_useMultipleThreadsWhenLoadingSummaryData,
"useMultipleThreadsWhenLoadingSummaryData",
false,
"Use multiple threads when loading summary data",
"",
"",
"" );
m_useMultipleThreadsWhenLoadingSummaryData.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
*/
CAF_PDM_InitFieldNoDefault( &m_pageSize, "pageSize", "Page Size", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_pageOrientation, "pageOrientation", "Page Orientation", "", "", "" );
@ -520,26 +454,6 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
m_readerSettings->uiOrdering( uiConfigName, *newCaseBehaviourGroup );
m_summaryPreferences->appendRestartFileGroup( uiOrdering );
/*
caf::PdmUiGroup* restartBehaviourGroup = uiOrdering.addNewGroup( "Origin Files" );
restartBehaviourGroup->add( &summaryRestartFilesShowImportDialog );
{
caf::PdmUiGroup* group = restartBehaviourGroup->addNewGroup( "Origin Summary Files" );
group->add( &summaryImportMode );
}
{
caf::PdmUiGroup* group = restartBehaviourGroup->addNewGroup( "Origin Grid Files" );
group->add( &gridImportMode );
}
{
caf::PdmUiGroup* group = restartBehaviourGroup->addNewGroup( "Origin Ensemble Summary Files" );
group->add( &summaryEnsembleImportMode );
}
*/
}
else if ( uiConfigName == RiaPreferences::tabNamePlotting() )
{
@ -547,12 +461,6 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
uiOrdering.add( &m_timeFormat );
summaryPreferences()->appendItemsToPlottingGroup( uiOrdering );
/*
uiOrdering.add( &defaultSummaryCurvesTextFilter );
uiOrdering.add( &defaultSummaryHistoryCurveStyle );
uiOrdering.add( &m_showSummaryTimeAsLongString );
uiOrdering.add( &m_useMultipleThreadsWhenLoadingSummaryData );
*/
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Plot Templates" );
group->add( &m_plotTemplateFolders );
@ -577,21 +485,9 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
m_pageBottomMargin.uiCapability()->setUiName( "Bottom Margin" + unitLabel );
{
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "[BETA] Optimized Summary Reader" );
group->setCollapsedByDefault( true );
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Summary Data Import" );
m_summaryPreferences()->uiOrdering( uiConfigName, *group );
// group->add( &m_summaryReader );
//
// if ( m_summaryReader == SummaryReaderMode::OPM_COMMON )
// {
// group->add( &m_createOptimizedSummaryDataFile );
// group->add( &m_useOptimizedSummaryDataFile );
// }
// else if ( m_summaryReader == SummaryReaderMode::HDF5_OPM_COMMON )
// {
// group->add( &m_createH5SummaryDataFile );
// }
}
}
@ -657,30 +553,6 @@ QList<caf::PdmOptionItemInfo> RiaPreferences::calculateValueOptions( const caf::
QList<caf::PdmOptionItemInfo> options;
*useOptionsOnly = true;
/*
if ( fieldNeedingOptions == &gridImportMode )
{
// Manual option handling in order to one only a subset of the enum values
SummaryRestartFilesImportModeType skip( RiaPreferences::SummaryRestartFilesImportMode::NOT_IMPORT );
SummaryRestartFilesImportModeType separate( RiaPreferences::SummaryRestartFilesImportMode::SEPARATE_CASES );
options.push_back(
caf::PdmOptionItemInfo( skip.uiText(), RiaPreferences::SummaryRestartFilesImportMode::NOT_IMPORT ) );
options.push_back( caf::PdmOptionItemInfo( separate.uiText(),
RiaPreferences::SummaryRestartFilesImportMode::SEPARATE_CASES ) );
}
else if ( fieldNeedingOptions == &summaryEnsembleImportMode )
{
// Manual option handling in order to one only a subset of the enum values
SummaryRestartFilesImportModeType skip( RiaPreferences::SummaryRestartFilesImportMode::NOT_IMPORT );
SummaryRestartFilesImportModeType allowImport( RiaPreferences::SummaryRestartFilesImportMode::IMPORT );
options.push_back(
caf::PdmOptionItemInfo( skip.uiText(), RiaPreferences::SummaryRestartFilesImportMode::NOT_IMPORT ) );
options.push_back(
caf::PdmOptionItemInfo( allowImport.uiText(), RiaPreferences::SummaryRestartFilesImportMode::IMPORT ) );
}
*/
if ( fieldNeedingOptions == &m_dateFormat )
{
for ( auto dateFormat : RiaQDateTimeTools::supportedDateFormats() )
@ -1022,22 +894,6 @@ void RiaPreferences::setDefaultPlotTemplatePath( const QString& templatePath )
m_defaultPlotTemplate = templatePath;
}
// -------------------------------------------------------------------------------------------------- /
// --------------------------------------------------------------------------------------------------bool
// RiaPreferences::showSummaryTimeAsLongString()
// const
// {
// return m_showSummaryTimeAsLongString;
// }
//
// -------------------------------------------------------------------------------------------------- /
// --------------------------------------------------------------------------------------------------bool
// RiaPreferences::useMultipleThreadsWhenReadingSummaryData()
// const
// {
// return m_useMultipleThreadsWhenLoadingSummaryData;
// }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -50,10 +50,10 @@ void RiaPreferencesSummary::SummaryHistoryCurveStyleModeType::setUp()
template <>
void RiaPreferencesSummary::SummaryReaderModeType::setUp()
{
addItem( RiaPreferencesSummary::SummaryReaderMode::LIBECL, "LIBECL", "Default Reader (ecl)" );
addItem( RiaPreferencesSummary::SummaryReaderMode::HDF5_OPM_COMMON, "HDF5_OPM_COMMON", "[BETA] H5 Reader (HDF5 Eclipse)" );
addItem( RiaPreferencesSummary::SummaryReaderMode::OPM_COMMON, "OPM_COMMON", "[BETA] Performance Reader (omp-common)" );
setDefault( RiaPreferencesSummary::SummaryReaderMode::LIBECL );
addItem( RiaPreferencesSummary::SummaryReaderMode::LIBECL, "LIBECL", "UNSMRY (libecl)" );
addItem( RiaPreferencesSummary::SummaryReaderMode::HDF5_OPM_COMMON, "HDF5_OPM_COMMON", "h5 (HDF5)" );
addItem( RiaPreferencesSummary::SummaryReaderMode::OPM_COMMON, "OPM_COMMON", "LODSMRY (opm-common)" );
setDefault( RiaPreferencesSummary::SummaryReaderMode::HDF5_OPM_COMMON );
}
} // namespace caf
@ -109,40 +109,49 @@ RiaPreferencesSummary::RiaPreferencesSummary()
CAF_PDM_InitField( &m_createOptimizedSummaryDataFile,
"createOptimizedSummaryDataFile",
true,
"Create Optimized Summary Data Files [BETA]",
false,
"Create LODSMRY Summary Files",
"",
"If not present, create optimized file with extension '*.LODSMRY'",
"If not present, create summary file with extension '*.LODSMRY'",
"" );
m_createOptimizedSummaryDataFile.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitField( &m_useOptimizedSummaryDataFile,
"useOptimizedSummaryDataFile",
true,
"Use Optimized Summary Data Files [BETA]",
"Use LODSMRY Summary Files",
"",
"If not present, read optimized file with extension '*.LODSMRY'",
"If present, import summary files with extension '*.LODSMRY'",
"" );
m_useOptimizedSummaryDataFile.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitField( &m_createH5SummaryDataFile,
"createH5SummaryDataFile",
false,
"Create H5 Summary Data Files [BETA]",
"Create h5 Summary Files",
"",
"If not present, create summary file with extension '*.H5'",
"If not present, create summary file with extension '*.h5'",
"" );
m_createH5SummaryDataFile.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitField( &m_checkH5FileTimeStamp,
"checkH5FileTimeStamp",
false,
"Check File Timestamp",
"",
"Compare timestamp of h5 and SMSPEC, and recreate h5 when required",
"" );
m_checkH5FileTimeStamp.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitField( &m_createH5SummaryFileThreadCount,
"createH5SummaryFileThreadCount",
4,
"H5 Summary Data Creation Thread Count [BETA]",
1,
"h5 Summary Export Thread Count",
"",
"",
"" );
CAF_PDM_InitFieldNoDefault( &m_summaryReader, "summaryReaderType", "Summary Data File Reader", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_summaryReader, "summaryReaderType", "File Format", "", "", "" );
CAF_PDM_InitField( &m_showSummaryTimeAsLongString,
"showSummaryTimeAsLongString",
@ -156,7 +165,7 @@ RiaPreferencesSummary::RiaPreferencesSummary()
CAF_PDM_InitField( &m_useMultipleThreadsWhenLoadingSummaryData,
"useMultipleThreadsWhenLoadingSummaryData",
false,
"Use multiple threads when loading summary data",
"Use Multiple Threads for Import of Summary Files",
"",
"",
"" );
@ -203,6 +212,14 @@ bool RiaPreferencesSummary::createH5SummaryDataFiles() const
return m_createH5SummaryDataFile();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferencesSummary::checkH5SummaryDataTimeStamp() const
{
return m_checkH5FileTimeStamp;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -248,6 +265,70 @@ void RiaPreferencesSummary::appendItemsToPlottingGroup( caf::PdmUiOrdering& uiOr
uiOrdering.add( &m_useMultipleThreadsWhenLoadingSummaryData );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferencesSummary::showSummaryTimeAsLongString() const
{
return m_showSummaryTimeAsLongString;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferencesSummary::useMultipleThreadsWhenLoadingSummaryData() const
{
return m_useMultipleThreadsWhenLoadingSummaryData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferencesSummary::summaryRestartFilesShowImportDialog() const
{
return m_summaryRestartFilesShowImportDialog;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferencesSummary::SummaryRestartFilesImportMode RiaPreferencesSummary::summaryImportMode() const
{
return m_summaryImportMode();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferencesSummary::SummaryRestartFilesImportMode RiaPreferencesSummary::gridImportMode() const
{
return m_gridImportMode();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferencesSummary::SummaryRestartFilesImportMode RiaPreferencesSummary::summaryEnsembleImportMode() const
{
return m_summaryEnsembleImportMode();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaPreferencesSummary::defaultSummaryCurvesTextFilter() const
{
return m_defaultSummaryCurvesTextFilter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferencesSummary::SummaryHistoryCurveStyleMode RiaPreferencesSummary::defaultSummaryHistoryCurveStyle() const
{
return m_defaultSummaryHistoryCurveStyle();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -257,7 +338,7 @@ void RiaPreferencesSummary::defineEditorAttribute( const caf::PdmFieldHandle* fi
{
if ( field == &m_createOptimizedSummaryDataFile || field == &m_showSummaryTimeAsLongString ||
field == &m_useMultipleThreadsWhenLoadingSummaryData || field == &m_summaryRestartFilesShowImportDialog ||
field == &m_useOptimizedSummaryDataFile || field == &m_createH5SummaryDataFile )
field == &m_useOptimizedSummaryDataFile || field == &m_createH5SummaryDataFile || field == &m_checkH5FileTimeStamp )
{
auto myAttr = dynamic_cast<caf::PdmUiCheckBoxEditorAttribute*>( attribute );
if ( myAttr )
@ -276,13 +357,18 @@ void RiaPreferencesSummary::defineUiOrdering( QString uiConfigName, caf::PdmUiOr
if ( m_summaryReader == SummaryReaderMode::OPM_COMMON )
{
uiOrdering.add( &m_createOptimizedSummaryDataFile );
uiOrdering.add( &m_useOptimizedSummaryDataFile );
uiOrdering.add( &m_createOptimizedSummaryDataFile );
}
else if ( m_summaryReader == SummaryReaderMode::HDF5_OPM_COMMON )
{
uiOrdering.add( &m_createH5SummaryDataFile );
uiOrdering.add( &m_createH5SummaryFileThreadCount );
uiOrdering.add( &m_checkH5FileTimeStamp );
if ( RiaApplication::instance()->enableDevelopmentFeatures() )
{
uiOrdering.add( &m_createH5SummaryFileThreadCount );
}
}
uiOrdering.skipRemainingFields();
@ -301,10 +387,10 @@ QList<caf::PdmOptionItemInfo>
{
std::vector<SummaryReaderMode> availableModes;
availableModes.push_back( SummaryReaderMode::LIBECL );
#ifdef USE_HDF5
availableModes.push_back( SummaryReaderMode::HDF5_OPM_COMMON );
#endif // USE_HDF5
availableModes.push_back( SummaryReaderMode::LIBECL );
availableModes.push_back( SummaryReaderMode::OPM_COMMON );
for ( auto enumValue : availableModes )

View File

@ -64,21 +64,22 @@ public:
bool createOptimizedSummaryDataFiles() const;
bool createH5SummaryDataFiles() const;
bool checkH5SummaryDataTimeStamp() const;
int createH5SummaryDataThreadCount() const;
void appendRestartFileGroup( caf::PdmUiOrdering& uiOrdering ) const;
void appendItemsToPlottingGroup( caf::PdmUiOrdering& uiOrdering ) const;
bool showSummaryTimeAsLongString() const { return m_showSummaryTimeAsLongString; }
bool useMultipleThreadsWhenLoadingSummaryData() const { return m_useMultipleThreadsWhenLoadingSummaryData; }
bool summaryRestartFilesShowImportDialog() const { return m_summaryRestartFilesShowImportDialog; }
bool showSummaryTimeAsLongString() const;
bool useMultipleThreadsWhenLoadingSummaryData() const;
bool summaryRestartFilesShowImportDialog() const;
SummaryRestartFilesImportMode summaryImportMode() const { return m_summaryImportMode(); }
SummaryRestartFilesImportMode gridImportMode() const { return m_gridImportMode(); }
SummaryRestartFilesImportMode summaryEnsembleImportMode() const { return m_summaryEnsembleImportMode(); }
QString defaultSummaryCurvesTextFilter() const { return m_defaultSummaryCurvesTextFilter; }
SummaryRestartFilesImportMode summaryImportMode() const;
SummaryRestartFilesImportMode gridImportMode() const;
SummaryRestartFilesImportMode summaryEnsembleImportMode() const;
QString defaultSummaryCurvesTextFilter() const;
SummaryHistoryCurveStyleMode defaultSummaryHistoryCurveStyle() const { return m_defaultSummaryHistoryCurveStyle(); }
SummaryHistoryCurveStyleMode defaultSummaryHistoryCurveStyle() const;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
@ -105,6 +106,7 @@ private:
caf::PdmField<bool> m_useOptimizedSummaryDataFile;
caf::PdmField<bool> m_createH5SummaryDataFile;
caf::PdmField<bool> m_checkH5FileTimeStamp;
caf::PdmField<int> m_createH5SummaryFileThreadCount;
caf::PdmField<SummaryReaderModeType> m_summaryReader;

View File

@ -19,6 +19,7 @@
#include "RifHdf5SummaryExporter.h"
#include "RiaLogging.h"
#include "RiaPreferencesSummary.h"
#include "RifHdf5Exporter.h"
#include "RifSummaryReaderInterface.h"
@ -50,11 +51,13 @@ bool RifHdf5SummaryExporter::ensureHdf5FileIsCreatedMultithreaded( const std::ve
size_t hdfFilesCreatedCount = 0;
#pragma omp parallel for schedule( dynamic ) num_threads( threadCount )
bool useMultipleThreads = threadCount > 1;
#pragma omp parallel for schedule( dynamic ) if ( useMultipleThreads ) num_threads( threadCount )
for ( int cIdx = 0; cIdx < static_cast<int>( smspecFileNames.size() ); ++cIdx )
{
auto smspecFileName = smspecFileNames[cIdx];
auto h5FileName = h5FileNames[cIdx];
const auto& smspecFileName = smspecFileNames[cIdx];
const auto& h5FileName = h5FileNames[cIdx];
RifHdf5SummaryExporter::ensureHdf5FileIsCreated( smspecFileName, h5FileName, hdfFilesCreatedCount );
}
@ -76,10 +79,32 @@ bool RifHdf5SummaryExporter::ensureHdf5FileIsCreated( const std::string& smspecF
const std::string& h5FileName,
size_t& hdfFilesCreatedCount )
{
if ( !QFile::exists( QString::fromStdString( smspecFileName ) ) ) return false;
if ( !std::filesystem::exists( smspecFileName ) ) return false;
// TODO: Use time stamp of file to make sure the smspec file is older than the h5 file
if ( !QFile::exists( QString::fromStdString( h5FileName ) ) )
{
// Check if we have write permission in the folder
QFileInfo info( QString::fromStdString( smspecFileName ) );
if ( !info.isWritable() ) return true;
}
bool exportIsRequired = false;
{
bool h5FileExists = std::filesystem::exists( h5FileName );
if ( !h5FileExists ) exportIsRequired = true;
RiaPreferencesSummary* prefs = RiaPreferencesSummary::current();
if ( prefs->checkH5SummaryDataTimeStamp() && h5FileExists )
{
if ( RifHdf5SummaryExporter::isFirstOlderThanSecond( h5FileName, smspecFileName ) )
{
exportIsRequired = true;
}
}
}
if ( exportIsRequired )
{
try
{
@ -91,6 +116,8 @@ bool RifHdf5SummaryExporter::ensureHdf5FileIsCreated( const std::string& smspecF
#pragma omp critical( critical_section_HDF5_export )
{
// HDF5 file access is not thread-safe, always make sure we use the HDF5 library from a single thread
RifHdf5Exporter exporter( h5FileName );
writeGeneralSection( exporter, sourceSummaryData );
@ -210,9 +237,9 @@ bool RifHdf5SummaryExporter::writeSummaryVectors( RifHdf5Exporter& exporter, Opm
for ( auto nodeIndex : nodesForKeyword.second )
{
auto summaryNode = summaryNodeList[nodeIndex];
auto smspecKeywordIndex = summaryNode.smspecKeywordIndex;
QString smspecKeywordText = QString( "%1" ).arg( smspecKeywordIndex );
const auto& summaryNode = summaryNodeList[nodeIndex];
auto smspecKeywordIndex = summaryNode.smspecKeywordIndex;
const QString& smspecKeywordText = QString( "%1" ).arg( smspecKeywordIndex );
auto dataValuesGroup = exporter.createGroup( &keywordGroup, smspecKeywordText.toStdString() );
const std::vector<float>& values = sourceSummaryData.get( summaryNode );
@ -227,3 +254,16 @@ bool RifHdf5SummaryExporter::writeSummaryVectors( RifHdf5Exporter& exporter, Opm
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifHdf5SummaryExporter::isFirstOlderThanSecond( const std::string& firstFileName, const std::string& secondFileName )
{
if ( !std::filesystem::exists( firstFileName ) || !std::filesystem::exists( secondFileName ) ) return false;
auto timeA = std::filesystem::last_write_time( firstFileName );
auto timeB = std::filesystem::last_write_time( secondFileName );
return ( timeA < timeB );
}

View File

@ -51,4 +51,6 @@ public:
private:
static bool writeGeneralSection( RifHdf5Exporter& exporter, Opm::EclIO::ESmry& sourceSummaryData );
static bool writeSummaryVectors( RifHdf5Exporter& exporter, Opm::EclIO::ESmry& sourceSummaryData );
static bool isFirstOlderThanSecond( const std::string& firstFileName, const std::string& secondFileName );
};

View File

@ -18,7 +18,6 @@
#include "RifHdf5SummaryReader.h"
#include "RiaLogging.h"
#include "RiaQDateTimeTools.h"
#include "RiaTimeTTools.h"
#include "RifHdf5Reader.h"
@ -33,17 +32,7 @@
//--------------------------------------------------------------------------------------------------
RifHdf5SummaryReader::RifHdf5SummaryReader( const QString& fileName )
{
try
{
m_hdfFile = new H5::H5File( fileName.toStdString().c_str(), H5F_ACC_RDONLY );
}
catch ( ... )
{
RiaLogging::error( "Failed to open HDF file " + fileName );
delete m_hdfFile;
m_hdfFile = nullptr;
}
m_fileName = fileName.toStdString();
}
//--------------------------------------------------------------------------------------------------
@ -51,21 +40,6 @@ RifHdf5SummaryReader::RifHdf5SummaryReader( const QString& fileName )
//--------------------------------------------------------------------------------------------------
RifHdf5SummaryReader::~RifHdf5SummaryReader()
{
if ( m_hdfFile )
{
m_hdfFile->close();
delete m_hdfFile;
m_hdfFile = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifHdf5SummaryReader::isValid() const
{
return ( m_hdfFile != nullptr );
}
//--------------------------------------------------------------------------------------------------
@ -73,11 +47,13 @@ bool RifHdf5SummaryReader::isValid() const
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5SummaryReader::vectorNames()
{
if ( m_hdfFile )
try
{
auto h5File = H5::H5File( m_fileName.c_str(), H5F_ACC_RDONLY );
std::vector<std::string> names;
auto groupNames = RifHdf5ReaderTools::getSubGroupNames( m_hdfFile, "summary_vectors" );
auto groupNames = RifHdf5ReaderTools::getSubGroupNames( &h5File, "summary_vectors" );
names.reserve( groupNames.size() );
for ( const auto& name : groupNames )
{
@ -86,6 +62,9 @@ std::vector<std::string> RifHdf5SummaryReader::vectorNames()
return names;
}
catch ( ... )
{
}
return {};
}
@ -95,36 +74,47 @@ std::vector<std::string> RifHdf5SummaryReader::vectorNames()
//--------------------------------------------------------------------------------------------------
std::vector<time_t> RifHdf5SummaryReader::timeSteps() const
{
std::vector<time_t> times;
// TODO: This function uses code taken from ESmry::dates(). There is conversion from time_t to
// chrono::system_clock::time_points, and then back to time_t again. Consider using one representation
double time_unit = 24 * 3600;
using namespace std::chrono;
using TP = time_point<system_clock>;
using DoubSec = duration<double, seconds::period>;
auto timeDeltasInDays = values( "TIME" );
std::vector<std::chrono::system_clock::time_point> timePoints;
TP startDat = std::chrono::system_clock::from_time_t( startDate() );
timePoints.reserve( timeDeltasInDays.size() );
for ( const auto& t : timeDeltasInDays )
try
{
timePoints.push_back( startDat + duration_cast<TP::duration>( DoubSec( t * time_unit ) ) );
auto h5File = H5::H5File( m_fileName.c_str(), H5F_ACC_RDONLY );
std::vector<time_t> times;
// TODO: This function uses code taken from ESmry::dates(). There is conversion from time_t to
// chrono::system_clock::time_points, and then back to time_t again. Consider using one representation
double time_unit = 24 * 3600;
using namespace std::chrono;
using TP = time_point<system_clock>;
using DoubSec = duration<double, seconds::period>;
auto timeDeltasInDays = values( "TIME" );
std::vector<std::chrono::system_clock::time_point> timePoints;
TP startDat = std::chrono::system_clock::from_time_t( startDate() );
timePoints.reserve( timeDeltasInDays.size() );
for ( const auto& t : timeDeltasInDays )
{
timePoints.push_back( startDat + duration_cast<TP::duration>( DoubSec( t * time_unit ) ) );
}
for ( const auto& d : timePoints )
{
auto timeAsTimeT = std::chrono::system_clock::to_time_t( d );
times.push_back( timeAsTimeT );
}
return times;
}
for ( const auto& d : timePoints )
catch ( ... )
{
auto timeAsTimeT = std::chrono::system_clock::to_time_t( d );
times.push_back( timeAsTimeT );
}
return times;
return {};
}
//--------------------------------------------------------------------------------------------------
@ -132,35 +122,33 @@ std::vector<time_t> RifHdf5SummaryReader::timeSteps() const
//--------------------------------------------------------------------------------------------------
std::vector<double> RifHdf5SummaryReader::values( const std::string& vectorName, int smspecKeywordIndex ) const
{
if ( m_hdfFile )
try
{
try
auto h5File = H5::H5File( m_fileName.c_str(), H5F_ACC_RDONLY );
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
std::string idText = std::to_string( smspecKeywordIndex );
std::string groupPath = "summary_vectors/" + vectorName + "/" + idText;
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
H5::Group generalGroup = h5File.openGroup( groupPath.c_str() );
H5::DataSet dataset = H5::DataSet( generalGroup.openDataSet( "values" ) );
std::string idText = std::to_string( smspecKeywordIndex );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::string groupPath = "summary_vectors/" + vectorName + "/" + idText;
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
{
H5::Group generalGroup = m_hdfFile->openGroup( groupPath.c_str() );
H5::DataSet dataset = H5::DataSet( generalGroup.openDataSet( "values" ) );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
return values;
}
}
catch ( ... )
{
return values;
}
}
catch ( ... )
{
}
return {};
}
@ -170,37 +158,36 @@ std::vector<double> RifHdf5SummaryReader::values( const std::string& vectorName,
//--------------------------------------------------------------------------------------------------
std::vector<double> RifHdf5SummaryReader::values( const std::string& vectorName ) const
{
if ( m_hdfFile )
try
{
try
auto h5File = H5::H5File( m_fileName.c_str(), H5F_ACC_RDONLY );
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
std::string groupPath = "summary_vectors/" + vectorName;
auto groupNames = RifHdf5ReaderTools::getSubGroupNames( &h5File, groupPath );
if ( !groupNames.empty() )
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
groupPath = groupPath + "/" + groupNames[0];
std::string groupPath = "summary_vectors/" + vectorName;
H5::Group generalGroup = h5File.openGroup( groupPath.c_str() );
H5::DataSet dataset = H5::DataSet( generalGroup.openDataSet( "values" ) );
auto groupNames = RifHdf5ReaderTools::getSubGroupNames( m_hdfFile, groupPath );
if ( !groupNames.empty() )
{
groupPath = groupPath + "/" + groupNames[0];
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
H5::Group generalGroup = m_hdfFile->openGroup( groupPath.c_str() );
H5::DataSet dataset = H5::DataSet( generalGroup.openDataSet( "values" ) );
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
return values;
}
}
catch ( ... )
{
return values;
}
}
catch ( ... )
{
}
return {};
}
@ -210,48 +197,44 @@ std::vector<double> RifHdf5SummaryReader::values( const std::string& vectorName
//--------------------------------------------------------------------------------------------------
time_t RifHdf5SummaryReader::startDate() const
{
if ( m_hdfFile )
try
{
try
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
auto h5File = H5::H5File( m_fileName.c_str(), H5F_ACC_RDONLY );
QString groupPath = QString( "general" );
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
H5::Group GridFunction_00002 = m_hdfFile->openGroup( groupPath.toStdString().c_str() );
H5::DataSet dataset = H5::DataSet( GridFunction_00002.openDataSet( "start_date" ) );
QString groupPath = QString( "general" );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
H5::Group GridFunction_00002 = h5File.openGroup( groupPath.toStdString().c_str() );
H5::DataSet dataset = H5::DataSet( GridFunction_00002.openDataSet( "start_date" ) );
std::vector<int> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_INT );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
int day = values[0];
int month = values[1];
int year = values[2];
int hour = values[3];
int minute = values[4];
int second = values[5];
std::vector<int> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_INT );
QDate date( year, month, day );
QTime time( hour, minute, second );
int day = values[0];
int month = values[1];
int year = values[2];
int hour = values[3];
int minute = values[4];
int second = values[5];
QDateTime dt( date, time );
QDate date( year, month, day );
QTime time( hour, minute, second );
QDateTime reportDateTime = RiaQDateTimeTools::createUtcDateTime( dt );
QDateTime dt( date, time );
time_t myTime = RiaTimeTTools::fromQDateTime( reportDateTime );
return myTime;
}
catch ( ... )
{
}
QDateTime reportDateTime = RiaQDateTimeTools::createUtcDateTime( dt );
time_t myTime = RiaTimeTTools::fromQDateTime( reportDateTime );
return myTime;
}
catch ( ... )
{
}
RiaLogging::error( "Not able to read start_date from HDF5 " );
return {};
}

View File

@ -18,8 +18,6 @@
#pragma once
#include "H5Cpp.h"
#include <string>
#include <vector>
@ -35,8 +33,6 @@ public:
explicit RifHdf5SummaryReader( const QString& fileName );
~RifHdf5SummaryReader();
bool isValid() const;
std::vector<std::string> vectorNames();
std::vector<time_t> timeSteps() const;
@ -47,5 +43,5 @@ private:
time_t startDate() const;
private:
H5::H5File* m_hdfFile;
std::string m_fileName;
};

View File

@ -171,10 +171,16 @@ bool RifReaderEclipseSummary::open( const QString& headerFileName,
QFileInfo fi( headerFileName );
QString h5FilenameCandidate = fi.absolutePath() + "/" + fi.baseName() + ".h5";
size_t dummy = 0;
size_t createdH5FileCount = 0;
RifHdf5SummaryExporter::ensureHdf5FileIsCreated( headerFileName.toStdString(),
h5FilenameCandidate.toStdString(),
dummy );
createdH5FileCount );
if ( createdH5FileCount > 0 )
{
QString txt = QString( "Created %1 from file %2" ).arg( headerFileName ).arg( h5FilenameCandidate );
if ( threadSafeLogger ) threadSafeLogger->info( txt );
}
}
auto hdfReader = std::make_unique<RifOpmHdf5Summary>();

View File

@ -18,6 +18,7 @@
#include "RimSummaryCaseMainCollection.h"
#include "RiaEclipseFileNameTools.h"
#include "RiaLogging.h"
#include "RiaPreferencesSummary.h"
#include "RiaSummaryTools.h"
@ -418,19 +419,7 @@ void RimSummaryCaseMainCollection::loadSummaryCaseData( std::vector<RimSummaryCa
if ( !fileSummaryCases.empty() )
{
int threadCount = 1;
#ifdef USE_OPENMP
if ( prefs->summaryDataReader() != RiaPreferencesSummary::SummaryReaderMode::HDF5_OPM_COMMON )
{
threadCount = prefs->createH5SummaryDataThreadCount();
}
else
{
threadCount = omp_get_max_threads();
}
#endif
loadFileSummaryCaseData( fileSummaryCases, threadCount );
loadFileSummaryCaseData( fileSummaryCases );
}
caf::ProgressInfo progInfo( otherSummaryCases.size(), "Loading Summary Cases" );
@ -454,20 +443,20 @@ void RimSummaryCaseMainCollection::loadSummaryCaseData( std::vector<RimSummaryCa
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseMainCollection::loadFileSummaryCaseData( std::vector<RimFileSummaryCase*> fileSummaryCases,
int threadCountForHdf5Export )
void RimSummaryCaseMainCollection::loadFileSummaryCaseData( std::vector<RimFileSummaryCase*> fileSummaryCases )
{
// Use openMP when reading file summary case meta data. Avoid using the virtual interface of base class
// RimSummaryCase, as it is difficult to make sure all variants of the leaf classes are thread safe.
// Only open the summary file reader in parallel loop to reduce risk of multi threading issues
RiaPreferencesSummary* prefs = RiaPreferencesSummary::current();
// If h5 mode, check all summary files and create or recreate h5 files if required
#ifdef USE_HDF5
{
if ( prefs->summaryDataReader() == RiaPreferencesSummary::SummaryReaderMode::HDF5_OPM_COMMON &&
prefs->createH5SummaryDataFiles() )
{
int threadCount = 1;
#ifdef USE_OPENMP
threadCount = prefs->createH5SummaryDataThreadCount();
#endif
std::vector<std::string> headerFileNames;
std::vector<std::string> h5FileNames;
@ -482,20 +471,22 @@ void RimSummaryCaseMainCollection::loadFileSummaryCaseData( std::vector<RimFileS
h5FileNames.push_back( h5FilenameCandidate.toStdString() );
}
RifHdf5SummaryExporter::ensureHdf5FileIsCreatedMultithreaded( headerFileNames,
h5FileNames,
threadCountForHdf5Export );
RifHdf5SummaryExporter::ensureHdf5FileIsCreatedMultithreaded( headerFileNames, h5FileNames, threadCount );
}
}
#endif
// Use openMP when reading file summary case meta data. Avoid using the virtual interface of base class
// RimSummaryCase, as it is difficult to make sure all variants of the leaf classes are thread safe.
// Only open the summary file reader in parallel loop to reduce risk of multi threading issues
caf::ProgressInfo progInfo( fileSummaryCases.size(), "Loading Summary Cases" );
RifOpmCommonEclipseSummary::resetLodCount();
RiaThreadSafeLogger threadSafeLogger;
// The HDF5 reader requires a special configuration to be thread safe. Disable threading for HDF reader creation.
// The HDF5 reader requires a special configuration to be thread safe. Disable threading for HDF reader.
bool canUseMultipleTreads = ( prefs->summaryDataReader() != RiaPreferencesSummary::SummaryReaderMode::HDF5_OPM_COMMON );
#pragma omp parallel for schedule( dynamic ) if ( canUseMultipleTreads )
@ -523,9 +514,8 @@ void RimSummaryCaseMainCollection::loadFileSummaryCaseData( std::vector<RimFileS
}
// This loop is not thread safe, use serial loop
for ( int cIdx = 0; cIdx < static_cast<int>( fileSummaryCases.size() ); ++cIdx )
for ( RimFileSummaryCase* fileSummaryCase : fileSummaryCases )
{
RimFileSummaryCase* fileSummaryCase = fileSummaryCases[cIdx];
if ( fileSummaryCase )
{
fileSummaryCase->createRftReaderInterface();
@ -631,13 +621,25 @@ std::vector<RimSummaryCase*> RimSummaryCaseMainCollection::createSummaryCasesFro
}
else
{
RimFileSummaryCase* newSumCase = new RimFileSummaryCase();
const QString& smspecFileName = fileInfo.summaryFileName();
newSumCase->setIncludeRestartFiles( fileInfo.includeRestartFiles() );
newSumCase->setSummaryHeaderFileName( fileInfo.summaryFileName() );
newSumCase->updateOptionSensitivity();
project->assignCaseIdToSummaryCase( newSumCase );
sumCases.push_back( newSumCase );
bool foundDataFile = RiaEclipseFileNameTools::isSummaryDataFilePresent( smspecFileName );
if ( foundDataFile )
{
RimFileSummaryCase* newSumCase = new RimFileSummaryCase();
newSumCase->setIncludeRestartFiles( fileInfo.includeRestartFiles() );
newSumCase->setSummaryHeaderFileName( fileInfo.summaryFileName() );
newSumCase->updateOptionSensitivity();
project->assignCaseIdToSummaryCase( newSumCase );
sumCases.push_back( newSumCase );
}
else
{
QString txt = QString( "No UNSMRY file found for %1" ).arg( smspecFileName );
RiaLogging::warning( txt );
}
}
if ( progress != nullptr ) progress->incrementProgress();

View File

@ -74,7 +74,7 @@ public:
private:
static void loadSummaryCaseData( std::vector<RimSummaryCase*> summaryCases );
static void loadFileSummaryCaseData( std::vector<RimFileSummaryCase*> fileSummaryCases, int threadCountForHdf5Export );
static void loadFileSummaryCaseData( std::vector<RimFileSummaryCase*> fileSummaryCases );
static void reassignSummaryCurves( const RimGridSummaryCase* fromGridCase, RimFileSummaryCase* toFileCase );
static RimSummaryCaseCollection* defaultAllocator();

View File

@ -105,6 +105,14 @@ std::unique_ptr<caf::PdmObjectHandle> RimProject_importSummaryCase::defaultResul
return std::unique_ptr<caf::PdmObjectHandle>( new RimFileSummaryCase );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimProject_importSummaryCase::isNullptrValidResult() const
{
return true;
}
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimProject, RimProject_summaryCase, "summaryCase" );
//--------------------------------------------------------------------------------------------------

View File

@ -39,6 +39,7 @@ public:
caf::PdmObjectHandle* execute() override;
bool resultIsPersistent() const override;
std::unique_ptr<PdmObjectHandle> defaultResult() const override;
bool isNullptrValidResult() const override;
private:
caf::PdmField<QString> m_fileName;

View File

@ -105,14 +105,4 @@ def test_summary_no_unsmry(rips_instance, initialize_test):
shutil.copy2(casePath, temp_path)
summary_case = rips_instance.project.import_summary_case(temp_path)
values = summary_case.summary_vector_values()
assert len(values.values) == 1
time_steps = summary_case.available_time_steps()
assert len(time_steps.values) == 1
addresses = summary_case.available_addresses()
assert len(addresses.values) == 1
summary_case.resample_values()
assert summary_case is None