mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Support multiple RFT observation files
Add support for date on format yyyy-MM-dd Support observations in multiple files
This commit is contained in:
parent
fc51bf84a5
commit
f091a6237f
@ -15,10 +15,12 @@
|
|||||||
// for more details.
|
// for more details.
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "RifReaderFmuRft.h"
|
#include "RifReaderFmuRft.h"
|
||||||
|
|
||||||
#include "RiaLogging.h"
|
#include "RiaLogging.h"
|
||||||
#include "RiaQDateTimeTools.h"
|
#include "RiaQDateTimeTools.h"
|
||||||
|
#include "RiaTextStringTools.h"
|
||||||
|
|
||||||
#include "cafAssert.h"
|
#include "cafAssert.h"
|
||||||
|
|
||||||
@ -29,39 +31,6 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RifReaderFmuRft::Observation::Observation()
|
|
||||||
: utmx( -std::numeric_limits<double>::infinity() )
|
|
||||||
, utmy( -std::numeric_limits<double>::infinity() )
|
|
||||||
, mdrkb( -std::numeric_limits<double>::infinity() )
|
|
||||||
, tvdmsl( -std::numeric_limits<double>::infinity() )
|
|
||||||
, pressure( -std::numeric_limits<double>::infinity() )
|
|
||||||
, pressureError( -std::numeric_limits<double>::infinity() )
|
|
||||||
, formation()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
bool RifReaderFmuRft::Observation::valid() const
|
|
||||||
{
|
|
||||||
return utmx != std::numeric_limits<double>::infinity() && utmy != std::numeric_limits<double>::infinity() &&
|
|
||||||
mdrkb != std::numeric_limits<double>::infinity() && tvdmsl != std::numeric_limits<double>::infinity() &&
|
|
||||||
pressure != std::numeric_limits<double>::infinity() && pressureError != std::numeric_limits<double>::infinity();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RifReaderFmuRft::WellObservationSet::WellObservationSet( const QDateTime& dateTime, int measurementIndex )
|
|
||||||
: dateTime( dateTime )
|
|
||||||
, measurementIndex( measurementIndex )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -91,7 +60,7 @@ QStringList RifReaderFmuRft::findSubDirectoriesWithFmuRftData( const QString& fi
|
|||||||
QDir dir( filePath );
|
QDir dir( filePath );
|
||||||
|
|
||||||
QStringList subDirs = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable, QDir::Name );
|
QStringList subDirs = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable, QDir::Name );
|
||||||
for ( QString subDir : subDirs )
|
for ( const QString& subDir : subDirs )
|
||||||
{
|
{
|
||||||
QString absDir = dir.absoluteFilePath( subDir );
|
QString absDir = dir.absoluteFilePath( subDir );
|
||||||
subDirsContainingFmuRftData.append( findSubDirectoriesWithFmuRftData( absDir ) );
|
subDirsContainingFmuRftData.append( findSubDirectoriesWithFmuRftData( absDir ) );
|
||||||
@ -122,19 +91,17 @@ bool RifReaderFmuRft::directoryContainsFmuRftData( const QString& filePath )
|
|||||||
<< "*.txt";
|
<< "*.txt";
|
||||||
QFileInfoList fileInfos = dir.entryInfoList( obsFiles, QDir::Files, QDir::Name );
|
QFileInfoList fileInfos = dir.entryInfoList( obsFiles, QDir::Files, QDir::Name );
|
||||||
|
|
||||||
std::map<QString, int> fileStemCounts;
|
bool foundObsFile = false;
|
||||||
for ( QFileInfo fileInfo : fileInfos )
|
bool foundTxtFile = false;
|
||||||
{
|
for ( const QFileInfo& fileInfo : fileInfos )
|
||||||
// TODO:
|
|
||||||
// Uses completeBaseName() to support wells with a dot in the name.
|
|
||||||
// Not sure if this is necessary or desired
|
|
||||||
fileStemCounts[fileInfo.completeBaseName()]++;
|
|
||||||
if ( fileStemCounts[fileInfo.completeBaseName()] == 2 )
|
|
||||||
{
|
{
|
||||||
|
if ( fileInfo.fileName().endsWith( "obs" ) ) foundObsFile = true;
|
||||||
|
if ( fileInfo.fileName().endsWith( "txt" ) ) foundTxtFile = true;
|
||||||
|
|
||||||
// At least one matching obs and txt file.
|
// At least one matching obs and txt file.
|
||||||
return true;
|
if ( foundObsFile && foundTxtFile ) return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,21 +120,15 @@ std::vector<QString> RifReaderFmuRft::labels( const RifEclipseRftAddress& rftAdd
|
|||||||
{
|
{
|
||||||
std::vector<QString> formationLabels;
|
std::vector<QString> formationLabels;
|
||||||
|
|
||||||
if ( m_allWellObservations.empty() )
|
for ( const auto& observation : m_observations )
|
||||||
{
|
{
|
||||||
load();
|
if ( observation.wellDate.wellName == rftAddress.wellName() )
|
||||||
}
|
|
||||||
|
|
||||||
auto it = m_allWellObservations.find( rftAddress.wellName() );
|
|
||||||
if ( it != m_allWellObservations.end() )
|
|
||||||
{
|
|
||||||
const std::vector<Observation>& observations = it->second.observations;
|
|
||||||
for ( const Observation& observation : observations )
|
|
||||||
{
|
{
|
||||||
formationLabels.push_back(
|
formationLabels.push_back(
|
||||||
QString( "%1 - Pressure: %2 +/- %3" ).arg( observation.formation ).arg( observation.pressure ).arg( observation.pressureError ) );
|
QString( "%1 - Pressure: %2 +/- %3" ).arg( observation.location.formation ).arg( observation.pressure ).arg( observation.pressureError ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formationLabels;
|
return formationLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,21 +137,20 @@ std::vector<QString> RifReaderFmuRft::labels( const RifEclipseRftAddress& rftAdd
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::set<RifEclipseRftAddress> RifReaderFmuRft::eclipseRftAddresses()
|
std::set<RifEclipseRftAddress> RifReaderFmuRft::eclipseRftAddresses()
|
||||||
{
|
{
|
||||||
if ( m_allWellObservations.empty() )
|
if ( m_observations.empty() )
|
||||||
{
|
{
|
||||||
load();
|
importData();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::pair<QString, QDateTime>> wellDateTimePairs;
|
||||||
|
for ( const auto& observation : m_observations )
|
||||||
|
{
|
||||||
|
wellDateTimePairs.insert( { observation.wellDate.wellName, observation.wellDate.dateTime } );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<RifEclipseRftAddress> allAddresses;
|
std::set<RifEclipseRftAddress> allAddresses;
|
||||||
for ( const WellObservationPair& wellObservationPair : m_allWellObservations )
|
|
||||||
{
|
|
||||||
const QString& wellName = wellObservationPair.first;
|
|
||||||
const QDateTime& dateTime = wellObservationPair.second.dateTime;
|
|
||||||
const std::vector<Observation>& observations = wellObservationPair.second.observations;
|
|
||||||
|
|
||||||
for ( const Observation& observation : observations )
|
for ( const auto& [wellName, dateTime] : wellDateTimePairs )
|
||||||
{
|
|
||||||
if ( observation.valid() )
|
|
||||||
{
|
{
|
||||||
RifEclipseRftAddress tvdAddress =
|
RifEclipseRftAddress tvdAddress =
|
||||||
RifEclipseRftAddress::createAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::TVD );
|
RifEclipseRftAddress::createAddress( wellName, dateTime, RifEclipseRftAddress::RftWellLogChannelType::TVD );
|
||||||
@ -205,8 +165,7 @@ std::set<RifEclipseRftAddress> RifReaderFmuRft::eclipseRftAddresses()
|
|||||||
allAddresses.insert( pressureAddress );
|
allAddresses.insert( pressureAddress );
|
||||||
allAddresses.insert( pressureErrorAddress );
|
allAddresses.insert( pressureErrorAddress );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return allAddresses;
|
return allAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,26 +176,22 @@ void RifReaderFmuRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
|||||||
{
|
{
|
||||||
CAF_ASSERT( values );
|
CAF_ASSERT( values );
|
||||||
|
|
||||||
if ( m_allWellObservations.empty() )
|
if ( m_observations.empty() )
|
||||||
{
|
{
|
||||||
load();
|
importData();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = m_allWellObservations.find( rftAddress.wellName() );
|
for ( const auto& observation : m_observations )
|
||||||
if ( it != m_allWellObservations.end() )
|
|
||||||
{
|
{
|
||||||
const std::vector<Observation>& observations = it->second.observations;
|
if ( observation.wellDate.wellName == rftAddress.wellName() )
|
||||||
values->clear();
|
|
||||||
values->reserve( observations.size() );
|
|
||||||
for ( const Observation& observation : observations )
|
|
||||||
{
|
{
|
||||||
switch ( rftAddress.wellLogChannel() )
|
switch ( rftAddress.wellLogChannel() )
|
||||||
{
|
{
|
||||||
case RifEclipseRftAddress::RftWellLogChannelType::TVD:
|
case RifEclipseRftAddress::RftWellLogChannelType::TVD:
|
||||||
values->push_back( observation.tvdmsl );
|
values->push_back( observation.location.tvdmsl );
|
||||||
break;
|
break;
|
||||||
case RifEclipseRftAddress::RftWellLogChannelType::MD:
|
case RifEclipseRftAddress::RftWellLogChannelType::MD:
|
||||||
values->push_back( observation.mdrkb );
|
values->push_back( observation.location.mdrkb );
|
||||||
break;
|
break;
|
||||||
case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE:
|
case RifEclipseRftAddress::RftWellLogChannelType::PRESSURE:
|
||||||
values->push_back( observation.pressure );
|
values->push_back( observation.pressure );
|
||||||
@ -245,7 +200,7 @@ void RifReaderFmuRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
|||||||
values->push_back( observation.pressureError );
|
values->push_back( observation.pressureError );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CAF_ASSERT( false && "Wrong channel type sent to Fmu RFT reader" );
|
CAF_ASSERT( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,54 +209,75 @@ void RifReaderFmuRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RifReaderFmuRft::load()
|
void RifReaderFmuRft::importData()
|
||||||
{
|
{
|
||||||
QString errorMsg;
|
|
||||||
|
|
||||||
QFileInfo fileInfo( m_filePath );
|
QFileInfo fileInfo( m_filePath );
|
||||||
if ( !( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) )
|
if ( !( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) )
|
||||||
{
|
{
|
||||||
errorMsg = QString( "Directory '%1' does not exist or isn't readable" ).arg( m_filePath );
|
auto errorMsg = QString( "Directory '%1' does not exist or isn't readable" ).arg( m_filePath );
|
||||||
RiaLogging::error( errorMsg );
|
RiaLogging::error( errorMsg );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir dir( m_filePath );
|
QDir dir( m_filePath );
|
||||||
|
|
||||||
WellObservationMap wellObservations = loadWellDates( dir, &errorMsg );
|
auto wellDates = importWellDates( dir.absoluteFilePath( RifReaderFmuRft::wellPathFileName() ) );
|
||||||
WellObservationMap validObservations;
|
if ( wellDates.empty() )
|
||||||
if ( wellObservations.empty() )
|
|
||||||
{
|
{
|
||||||
if ( errorMsg.isEmpty() )
|
RiaLogging::error( QString( "'%1' contains no valid FMU RFT data" ).arg( m_filePath ) );
|
||||||
{
|
|
||||||
errorMsg = QString( "'%1' contains no valid FMU RFT data" ).arg( m_filePath );
|
|
||||||
}
|
|
||||||
RiaLogging::error( errorMsg );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( auto it = wellObservations.begin(); it != wellObservations.end(); ++it )
|
std::map<QString, int> nameAndMeasurementCount;
|
||||||
|
|
||||||
|
// Find the number of well measurements for each well
|
||||||
|
for ( const auto& wellDate : wellDates )
|
||||||
|
{
|
||||||
|
nameAndMeasurementCount[wellDate.wellName]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( const auto& [wellName, measurementCount] : nameAndMeasurementCount )
|
||||||
{
|
{
|
||||||
const QString& wellName = it->first;
|
|
||||||
WellObservationSet& wellObservationSet = it->second;
|
|
||||||
QString txtFile = QString( "%1.txt" ).arg( wellName );
|
QString txtFile = QString( "%1.txt" ).arg( wellName );
|
||||||
QString obsFile = QString( "%1.obs" ).arg( wellName );
|
auto locations = importLocations( dir.absoluteFilePath( txtFile ) );
|
||||||
|
if ( locations.empty() ) continue;
|
||||||
|
|
||||||
if ( !readTxtFile( dir.absoluteFilePath( txtFile ), &errorMsg, &wellObservationSet ) )
|
for ( int i = 0; i < measurementCount; i++ )
|
||||||
{
|
{
|
||||||
RiaLogging::warning( errorMsg );
|
int measurementId = i + 1;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !readObsFile( dir.absoluteFilePath( obsFile ), &errorMsg, &wellObservationSet ) )
|
auto findObservationFileName = []( const QString& wellName, int measurementId, const QDir& dir ) -> QString
|
||||||
{
|
{
|
||||||
RiaLogging::warning( errorMsg );
|
QString candidate = dir.absoluteFilePath( QString( "%1_%2.obs" ).arg( wellName ).arg( measurementId ) );
|
||||||
continue;
|
if ( QFile::exists( candidate ) )
|
||||||
}
|
{
|
||||||
validObservations.insert( *it );
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_allWellObservations.swap( validObservations );
|
QString candidateOldFormat = dir.absoluteFilePath( QString( "%1.obs" ).arg( wellName ) );
|
||||||
|
if ( QFile::exists( candidateOldFormat ) )
|
||||||
|
{
|
||||||
|
return candidateOldFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
QString observationFileName = findObservationFileName( wellName, measurementId, dir );
|
||||||
|
if ( observationFileName.isEmpty() ) continue;
|
||||||
|
|
||||||
|
for ( const auto& wellDate : wellDates )
|
||||||
|
{
|
||||||
|
if ( wellDate.wellName == wellName && wellDate.measurementId == measurementId )
|
||||||
|
{
|
||||||
|
auto observations = importObservations( dir.absoluteFilePath( observationFileName ), locations, wellDate );
|
||||||
|
m_observations.insert( m_observations.end(), observations.begin(), observations.end() );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -324,17 +300,18 @@ std::set<QDateTime> RifReaderFmuRft::availableTimeSteps( const QString&
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::set<QDateTime> RifReaderFmuRft::availableTimeSteps( const QString& wellName )
|
std::set<QDateTime> RifReaderFmuRft::availableTimeSteps( const QString& wellName )
|
||||||
{
|
{
|
||||||
if ( m_allWellObservations.empty() )
|
if ( m_observations.empty() )
|
||||||
{
|
{
|
||||||
load();
|
importData();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = m_allWellObservations.find( wellName );
|
std::set<QDateTime> dateTimes;
|
||||||
if ( it != m_allWellObservations.end() )
|
for ( const auto& observation : m_observations )
|
||||||
{
|
{
|
||||||
return { it->second.dateTime };
|
if ( observation.wellDate.wellName != wellName ) continue;
|
||||||
|
dateTimes.insert( observation.wellDate.dateTime );
|
||||||
}
|
}
|
||||||
return {};
|
return dateTimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -357,12 +334,12 @@ std::set<QDateTime> RifReaderFmuRft::availableTimeSteps( const QString&
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderFmuRft::availableWellLogChannels( const QString& wellName )
|
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderFmuRft::availableWellLogChannels( const QString& wellName )
|
||||||
{
|
{
|
||||||
if ( m_allWellObservations.empty() )
|
if ( m_observations.empty() )
|
||||||
{
|
{
|
||||||
load();
|
importData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_allWellObservations.empty() )
|
if ( !m_observations.empty() )
|
||||||
{
|
{
|
||||||
return { RifEclipseRftAddress::RftWellLogChannelType::TVD,
|
return { RifEclipseRftAddress::RftWellLogChannelType::TVD,
|
||||||
RifEclipseRftAddress::RftWellLogChannelType::MD,
|
RifEclipseRftAddress::RftWellLogChannelType::MD,
|
||||||
@ -376,42 +353,40 @@ std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderFmuRft::available
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
std::set<QString> RifReaderFmuRft::wellNames()
|
std::set<QString> RifReaderFmuRft::wellNames()
|
||||||
{
|
{
|
||||||
if ( m_allWellObservations.empty() )
|
if ( m_observations.empty() )
|
||||||
{
|
{
|
||||||
load();
|
importData();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<QString> wellNames;
|
std::set<QString> names;
|
||||||
for ( auto it = m_allWellObservations.begin(); it != m_allWellObservations.end(); ++it )
|
|
||||||
|
for ( const auto& observation : m_observations )
|
||||||
{
|
{
|
||||||
wellNames.insert( it->first );
|
names.insert( observation.wellDate.wellName );
|
||||||
}
|
}
|
||||||
return wellNames;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RifReaderFmuRft::WellObservationMap RifReaderFmuRft::loadWellDates( QDir& dir, QString* errorMsg )
|
std::vector<RifReaderFmuRft::WellDate> RifReaderFmuRft::importWellDates( const QString& fileName )
|
||||||
{
|
{
|
||||||
CAF_ASSERT( errorMsg );
|
if ( !( QFile::exists( fileName ) ) )
|
||||||
|
|
||||||
WellObservationMap validObservations;
|
|
||||||
|
|
||||||
QFileInfo wellDateFileInfo( dir.absoluteFilePath( RifReaderFmuRft::wellPathFileName() ) );
|
|
||||||
if ( !( wellDateFileInfo.exists() && wellDateFileInfo.isFile() && wellDateFileInfo.isReadable() ) )
|
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "%1 cannot be found at '%s'" ).arg( RifReaderFmuRft::wellPathFileName() ).arg( m_filePath );
|
RiaLogging::error( QString( "%1 cannot be found at '%s'" ).arg( RifReaderFmuRft::wellPathFileName() ).arg( fileName ) );
|
||||||
return WellObservationMap();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
QFile wellDateFile( fileName );
|
||||||
QFile wellDateFile( wellDateFileInfo.absoluteFilePath() );
|
|
||||||
if ( !wellDateFile.open( QIODevice::Text | QIODevice::ReadOnly ) )
|
if ( !wellDateFile.open( QIODevice::Text | QIODevice::ReadOnly ) )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "Could not read '%1'" ).arg( wellDateFileInfo.absoluteFilePath() );
|
RiaLogging::error( QString( "Could not read '%1'" ).arg( fileName ) );
|
||||||
return WellObservationMap();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<RifReaderFmuRft::WellDate> wellDates;
|
||||||
|
|
||||||
QTextStream fileStream( &wellDateFile );
|
QTextStream fileStream( &wellDateFile );
|
||||||
while ( !fileStream.atEnd() )
|
while ( !fileStream.atEnd() )
|
||||||
{
|
{
|
||||||
@ -423,42 +398,64 @@ RifReaderFmuRft::WellObservationMap RifReaderFmuRft::loadWellDates( QDir& dir, Q
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream lineStream( &line );
|
|
||||||
|
|
||||||
QString wellName;
|
QString wellName;
|
||||||
int day, month, year, measurementIndex;
|
int day, month, year, measurementIndex;
|
||||||
|
|
||||||
lineStream >> wellName >> day >> month >> year >> measurementIndex;
|
auto words = RiaTextStringTools::splitSkipEmptyParts( line );
|
||||||
if ( lineStream.status() != QTextStream::Ok )
|
if ( words.size() == 5 )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "Failed to parse '%1'" ).arg( wellDateFileInfo.absoluteFilePath() );
|
wellName = words[0];
|
||||||
return WellObservationMap();
|
day = words[1].toInt();
|
||||||
|
month = words[2].toInt();
|
||||||
|
year = words[3].toInt();
|
||||||
|
measurementIndex = words[4].toInt();
|
||||||
|
}
|
||||||
|
else if ( words.size() == 3 )
|
||||||
|
{
|
||||||
|
wellName = words[0];
|
||||||
|
|
||||||
|
QStringList dateWords = words[1].split( "-" );
|
||||||
|
if ( dateWords.size() != 3 )
|
||||||
|
{
|
||||||
|
RiaLogging::error( QString( "Failed to parse '%1'" ).arg( fileName ) );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
year = dateWords[0].toInt();
|
||||||
|
month = dateWords[1].toInt();
|
||||||
|
day = dateWords[2].toInt();
|
||||||
|
|
||||||
|
measurementIndex = words[2].toInt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RiaLogging::error( QString( "Failed to parse '%1'" ).arg( fileName ) );
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime dateTime = RiaQDateTimeTools::createDateTime( QDate( year, month, day ) );
|
QDateTime dateTime = RiaQDateTimeTools::createDateTime( QDate( year, month, day ) );
|
||||||
dateTime.setTimeSpec( Qt::UTC );
|
dateTime.setTimeSpec( Qt::UTC );
|
||||||
WellObservationSet observationSet( dateTime, measurementIndex );
|
|
||||||
validObservations.insert( std::make_pair( wellName, observationSet ) );
|
wellDates.push_back( { wellName, dateTime, measurementIndex } );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return validObservations;
|
return wellDates;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifReaderFmuRft::readTxtFile( const QString& fileName, QString* errorMsg, WellObservationSet* wellObservationSet )
|
std::vector<RifReaderFmuRft::Location> RifReaderFmuRft::importLocations( const QString& fileName )
|
||||||
{
|
{
|
||||||
CAF_ASSERT( wellObservationSet );
|
|
||||||
|
|
||||||
QFile file( fileName );
|
QFile file( fileName );
|
||||||
if ( !( file.open( QIODevice::Text | QIODevice::ReadOnly ) ) )
|
if ( !file.open( QIODevice::Text | QIODevice::ReadOnly ) )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "Could not open '%1'" ).arg( fileName );
|
RiaLogging::error( QString( "Could not open '%1'" ).arg( fileName ) );
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<RifReaderFmuRft::Location> locations;
|
||||||
|
|
||||||
QTextStream stream( &file );
|
QTextStream stream( &file );
|
||||||
while ( true )
|
while ( true )
|
||||||
{
|
{
|
||||||
@ -467,8 +464,7 @@ bool RifReaderFmuRft::readTxtFile( const QString& fileName, QString* errorMsg, W
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
QTextStream lineStream( &line );
|
QTextStream lineStream( &line );
|
||||||
|
|
||||||
double utmx, utmy, mdrkb, tvdmsl;
|
double utmx, utmy, mdrkb, tvdmsl;
|
||||||
@ -478,37 +474,33 @@ bool RifReaderFmuRft::readTxtFile( const QString& fileName, QString* errorMsg, W
|
|||||||
|
|
||||||
if ( lineStream.status() != QTextStream::Ok )
|
if ( lineStream.status() != QTextStream::Ok )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "Failed to parse '%1'" ).arg( fileName );
|
RiaLogging::error( QString( "Failed to parse '%1'" ).arg( fileName ) );
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Observation observation;
|
locations.push_back( { utmx, utmy, mdrkb, tvdmsl, formationName } );
|
||||||
observation.utmx = utmx;
|
|
||||||
observation.utmy = utmy;
|
|
||||||
observation.mdrkb = mdrkb;
|
|
||||||
observation.tvdmsl = tvdmsl;
|
|
||||||
observation.formation = formationName;
|
|
||||||
wellObservationSet->observations.push_back( observation );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RifReaderFmuRft::readObsFile( const QString& fileName, QString* errorMsg, WellObservationSet* wellObservationSet )
|
std::vector<RifReaderFmuRft::Observation>
|
||||||
|
RifReaderFmuRft::importObservations( const QString& fileName, const std::vector<Location>& locations, const WellDate& wellDate )
|
||||||
{
|
{
|
||||||
QFile file( fileName );
|
QFile file( fileName );
|
||||||
if ( !( file.open( QIODevice::Text | QIODevice::ReadOnly ) ) )
|
if ( !file.open( QIODevice::Text | QIODevice::ReadOnly ) )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "Could not open '%1'" ).arg( fileName );
|
RiaLogging::error( QString( "Could not open '%1'" ).arg( fileName ) );
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t lineNumber = 0u;
|
std::vector<RifReaderFmuRft::Observation> observations;
|
||||||
|
|
||||||
QTextStream stream( &file );
|
QTextStream stream( &file );
|
||||||
|
size_t lineNumber = 0u;
|
||||||
while ( true )
|
while ( true )
|
||||||
{
|
{
|
||||||
QString line = stream.readLine().trimmed();
|
QString line = stream.readLine().trimmed();
|
||||||
@ -516,13 +508,13 @@ bool RifReaderFmuRft::readObsFile( const QString& fileName, QString* errorMsg, W
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ( lineNumber >= wellObservationSet->observations.size() )
|
|
||||||
|
if ( lineNumber >= locations.size() )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "'%1' has more lines than corresponding txt file" ).arg( fileName );
|
RiaLogging::error( QString( "'%1' has more lines than corresponding txt file" ).arg( fileName ) );
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
QTextStream lineStream( &line );
|
QTextStream lineStream( &line );
|
||||||
|
|
||||||
double pressure, pressureError;
|
double pressure, pressureError;
|
||||||
@ -531,21 +523,19 @@ bool RifReaderFmuRft::readObsFile( const QString& fileName, QString* errorMsg, W
|
|||||||
|
|
||||||
if ( lineStream.status() != QTextStream::Ok )
|
if ( lineStream.status() != QTextStream::Ok )
|
||||||
{
|
{
|
||||||
*errorMsg = QString( "Failed to parse line %1 of '%2'" ).arg( lineNumber + 1 ).arg( fileName );
|
RiaLogging::error( QString( "Failed to parse line %1 of '%2'" ).arg( lineNumber + 1 ).arg( fileName ) );
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Observation& observation = wellObservationSet->observations[lineNumber];
|
// -1.0 is used to indicate missing data
|
||||||
observation.pressure = pressure;
|
if ( pressure != -1.0 )
|
||||||
observation.pressureError = pressureError;
|
{
|
||||||
|
observations.push_back(
|
||||||
|
{ .wellDate = wellDate, .location = locations[lineNumber], .pressure = pressure, .pressureError = pressureError } );
|
||||||
}
|
}
|
||||||
|
|
||||||
lineNumber++;
|
lineNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lineNumber != wellObservationSet->observations.size() )
|
return observations;
|
||||||
{
|
|
||||||
*errorMsg = QString( "'%1' has less lines than corresponding txt file" ).arg( fileName );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "RifEclipseRftAddress.h"
|
#include "RifEclipseRftAddress.h"
|
||||||
#include "RifReaderRftInterface.h"
|
#include "RifReaderRftInterface.h"
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -35,30 +34,29 @@
|
|||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
class RifReaderFmuRft : public RifReaderRftInterface, public cvf::Object
|
class RifReaderFmuRft : public RifReaderRftInterface, public cvf::Object
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
struct Observation
|
struct WellDate
|
||||||
|
{
|
||||||
|
QString wellName;
|
||||||
|
QDateTime dateTime;
|
||||||
|
int measurementId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Location
|
||||||
{
|
{
|
||||||
double utmx;
|
double utmx;
|
||||||
double utmy;
|
double utmy;
|
||||||
double mdrkb;
|
double mdrkb;
|
||||||
double tvdmsl;
|
double tvdmsl;
|
||||||
|
|
||||||
double pressure;
|
|
||||||
double pressureError;
|
|
||||||
QString formation;
|
QString formation;
|
||||||
|
|
||||||
Observation();
|
|
||||||
|
|
||||||
bool valid() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WellObservationSet
|
struct Observation
|
||||||
{
|
{
|
||||||
QDateTime dateTime;
|
WellDate wellDate;
|
||||||
int measurementIndex;
|
Location location;
|
||||||
std::vector<Observation> observations;
|
double pressure;
|
||||||
|
double pressureError;
|
||||||
WellObservationSet( const QDateTime& dateTime, int measurementIndex );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -83,18 +81,15 @@ public:
|
|||||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels( const QString& wellName ) override;
|
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels( const QString& wellName ) override;
|
||||||
std::set<QString> wellNames() override;
|
std::set<QString> wellNames() override;
|
||||||
|
|
||||||
public:
|
void importData();
|
||||||
void load();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using WellObservationPair = std::pair<const QString, WellObservationSet>;
|
static std::vector<WellDate> importWellDates( const QString& fileName );
|
||||||
using WellObservationMap = std::map<QString, WellObservationSet>;
|
static std::vector<Location> importLocations( const QString& fileName );
|
||||||
|
static std::vector<Observation>
|
||||||
WellObservationMap loadWellDates( QDir& dir, QString* errorMsg );
|
importObservations( const QString& fileName, const std::vector<Location>& locations, const WellDate& wellDate );
|
||||||
static bool readTxtFile( const QString& txtFileName, QString* errorMsg, WellObservationSet* wellObservationSet );
|
|
||||||
static bool readObsFile( const QString& obsFileName, QString* errorMsg, WellObservationSet* wellObservationSet );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_filePath;
|
QString m_filePath;
|
||||||
WellObservationMap m_allWellObservations;
|
std::vector<Observation> m_observations;
|
||||||
};
|
};
|
||||||
|
@ -53,7 +53,7 @@ void RimObservedFmuRftData::setDirectoryPath( const QString& path )
|
|||||||
void RimObservedFmuRftData::createRftReaderInterface()
|
void RimObservedFmuRftData::createRftReaderInterface()
|
||||||
{
|
{
|
||||||
m_fmuRftReader = new RifReaderFmuRft( m_directoryPath );
|
m_fmuRftReader = new RifReaderFmuRft( m_directoryPath );
|
||||||
m_fmuRftReader->load();
|
m_fmuRftReader->importData();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "RifReaderFmuRft.h"
|
|
||||||
|
|
||||||
#include "RimNamedObject.h"
|
#include "RimNamedObject.h"
|
||||||
|
|
||||||
#include "RifReaderPressureDepthData.h"
|
#include "RifReaderPressureDepthData.h"
|
||||||
|
@ -93,6 +93,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RigDeclineCurveCalculator-Test.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RigDeclineCurveCalculator-Test.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RigWellLogCurveData-Test.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RigWellLogCurveData-Test.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCalculatedCurve-Test.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCalculatedCurve-Test.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RifReaderFmuRft-Test.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(RESINSIGHT_ENABLE_GRPC)
|
if(RESINSIGHT_ENABLE_GRPC)
|
||||||
|
71
ApplicationLibCode/UnitTests/RifReaderFmuRft-Test.cpp
Normal file
71
ApplicationLibCode/UnitTests/RifReaderFmuRft-Test.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "RiaTestDataDirectory.h"
|
||||||
|
|
||||||
|
#include "RifReaderFmuRft.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RifReaderFmuRftTest, OldFormatLoadFile )
|
||||||
|
{
|
||||||
|
QString folderName = QString( "%1/RifReaderFmuRft_old_format/" ).arg( TEST_DATA_DIR );
|
||||||
|
|
||||||
|
auto folderNames = RifReaderFmuRft::findSubDirectoriesWithFmuRftData( folderName );
|
||||||
|
EXPECT_EQ( 1, folderNames.size() );
|
||||||
|
|
||||||
|
RifReaderFmuRft reader( folderName );
|
||||||
|
reader.importData();
|
||||||
|
|
||||||
|
auto wellNames = reader.wellNames();
|
||||||
|
EXPECT_EQ( 2u, wellNames.size() );
|
||||||
|
|
||||||
|
QString wellName = "R_A6";
|
||||||
|
auto timeSteps = reader.availableTimeSteps( wellName );
|
||||||
|
EXPECT_EQ( 1u, timeSteps.size() );
|
||||||
|
EXPECT_STREQ( timeSteps.begin()->toString( "yyyy-MM-dd" ).toStdString().data(), "2018-11-07" );
|
||||||
|
|
||||||
|
auto addresses = reader.eclipseRftAddresses();
|
||||||
|
EXPECT_EQ( 1u, timeSteps.size() );
|
||||||
|
|
||||||
|
for ( const auto& adr : addresses )
|
||||||
|
{
|
||||||
|
std::vector<double> values;
|
||||||
|
reader.values( adr, &values );
|
||||||
|
EXPECT_EQ( 2u, values.size() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RifReaderFmuRftTest, LoadFile )
|
||||||
|
{
|
||||||
|
QString folderName = QString( "%1/RifReaderFmuRft/" ).arg( TEST_DATA_DIR );
|
||||||
|
|
||||||
|
auto folderNames = RifReaderFmuRft::findSubDirectoriesWithFmuRftData( folderName );
|
||||||
|
EXPECT_EQ( 1, folderNames.size() );
|
||||||
|
|
||||||
|
RifReaderFmuRft reader( folderName );
|
||||||
|
reader.importData();
|
||||||
|
|
||||||
|
QString wellName = "R_A6";
|
||||||
|
auto timeSteps = reader.availableTimeSteps( wellName );
|
||||||
|
EXPECT_EQ( 1u, timeSteps.size() );
|
||||||
|
EXPECT_STREQ( timeSteps.begin()->toString( "yyyy-MM-dd" ).toStdString().data(), "2018-11-07" );
|
||||||
|
|
||||||
|
auto addresses = reader.eclipseRftAddresses();
|
||||||
|
EXPECT_EQ( 1u, timeSteps.size() );
|
||||||
|
|
||||||
|
for ( const auto& adr : addresses )
|
||||||
|
{
|
||||||
|
std::vector<double> values;
|
||||||
|
reader.values( adr, &values );
|
||||||
|
|
||||||
|
if ( adr.wellName() == "R_A6" ) EXPECT_EQ( 6u, values.size() );
|
||||||
|
if ( adr.wellName() == "R_A2" ) EXPECT_EQ( 4u, values.size() );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
461292.74 5931883.26 1759.9 1710.9 Therys
|
||||||
|
461292.74 5931883.26 1777.4 1728.4 Volon
|
@ -0,0 +1,2 @@
|
|||||||
|
280.85 3
|
||||||
|
286.41 3
|
@ -0,0 +1,2 @@
|
|||||||
|
280.85 3
|
||||||
|
286.41 3
|
@ -0,0 +1,6 @@
|
|||||||
|
461292.74 5931883.26 1759.9 1710.9 Therys
|
||||||
|
461292.74 5931883.26 1777.4 1728.4 Volon
|
||||||
|
461294.74 5931883.26 1759.9 1710.9 Therys
|
||||||
|
461294.74 5931883.26 1777.4 1728.4 Volon
|
||||||
|
461296.74 5931883.26 1759.9 1710.9 Therys
|
||||||
|
461296.74 5931883.26 1777.4 1728.4 Volon
|
@ -0,0 +1,6 @@
|
|||||||
|
280.85 3
|
||||||
|
286.41 3
|
||||||
|
-1 0
|
||||||
|
-1 0
|
||||||
|
-1 0
|
||||||
|
-1 0
|
@ -0,0 +1,6 @@
|
|||||||
|
-1 0
|
||||||
|
-1 0
|
||||||
|
280.85 3
|
||||||
|
286.41 3
|
||||||
|
-1 0
|
||||||
|
-1 0
|
@ -0,0 +1,6 @@
|
|||||||
|
-1 0
|
||||||
|
-1 0
|
||||||
|
-1 0
|
||||||
|
-1 0
|
||||||
|
280.85 3
|
||||||
|
286.41 3
|
@ -0,0 +1,5 @@
|
|||||||
|
R_A2 2018-03-01 1
|
||||||
|
R_A2 2019-03-01 2
|
||||||
|
R_A6 2018-11-07 1
|
||||||
|
R_A6 2018-11-07 2
|
||||||
|
R_A6 2018-11-07 3
|
@ -0,0 +1,2 @@
|
|||||||
|
280.85 3
|
||||||
|
286.41 3
|
@ -0,0 +1,2 @@
|
|||||||
|
461292.74 5931883.26 1759.9 1710.9 Therys
|
||||||
|
461292.74 5931883.26 1777.4 1728.4 Volon
|
@ -0,0 +1,2 @@
|
|||||||
|
280.85 3
|
||||||
|
286.41 3
|
@ -0,0 +1,2 @@
|
|||||||
|
461292.74 5931883.26 1759.9 1710.9 Therys
|
||||||
|
461292.74 5931883.26 1777.4 1728.4 Volon
|
@ -0,0 +1,2 @@
|
|||||||
|
R_A2 01 03 2018 1
|
||||||
|
R_A6 07 11 2018 1
|
Loading…
Reference in New Issue
Block a user