Support multiple RFT observation files

Add support for date on format yyyy-MM-dd
Support observations in multiple files
This commit is contained in:
Magne Sjaastad 2023-06-02 09:32:47 +02:00 committed by GitHub
parent fc51bf84a5
commit f091a6237f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 372 additions and 272 deletions

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -18,8 +18,6 @@
#pragma once #pragma once
#include "RifReaderFmuRft.h"
#include "RimNamedObject.h" #include "RimNamedObject.h"
#include "RifReaderPressureDepthData.h" #include "RifReaderPressureDepthData.h"

View File

@ -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)

View 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() );
}
}

View File

@ -0,0 +1,2 @@
461292.74 5931883.26 1759.9 1710.9 Therys
461292.74 5931883.26 1777.4 1728.4 Volon

View File

@ -0,0 +1,2 @@
280.85 3
286.41 3

View File

@ -0,0 +1,2 @@
280.85 3
286.41 3

View File

@ -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

View File

@ -0,0 +1,6 @@
280.85 3
286.41 3
-1 0
-1 0
-1 0
-1 0

View File

@ -0,0 +1,6 @@
-1 0
-1 0
280.85 3
286.41 3
-1 0
-1 0

View File

@ -0,0 +1,6 @@
-1 0
-1 0
-1 0
-1 0
280.85 3
286.41 3

View File

@ -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

View File

@ -0,0 +1,2 @@
280.85 3
286.41 3

View File

@ -0,0 +1,2 @@
461292.74 5931883.26 1759.9 1710.9 Therys
461292.74 5931883.26 1777.4 1728.4 Volon

View File

@ -0,0 +1,2 @@
280.85 3
286.41 3

View File

@ -0,0 +1,2 @@
461292.74 5931883.26 1759.9 1710.9 Therys
461292.74 5931883.26 1777.4 1728.4 Volon

View File

@ -0,0 +1,2 @@
R_A2 01 03 2018 1
R_A6 07 11 2018 1