#14878: Fix stale well picks, import errors and overlapping zones

This commit is contained in:
Magne Sjaastad committed 2026-10-08 12:44:14 +02:00
1 parent 029759f548
commit bc62af3bb5
20 files changed
+217 -132

No files matched your search

@@ -18,6 +18,8 @@
#include "RifWellPathFormationReader.h" #include "RifWellPathFormationReader.h"
#include "RifCsvHtmlTableTools.h"
#include <QFile> #include <QFile>
#include <QStringList> #include <QStringList>
#include <QTextStream> #include <QTextStream>
@@ -27,14 +29,6 @@
namespace namespace
{ {
//--------------------------------------------------------------------------------------------------
/// The FMU formations.csv format is comma-separated, the "well pick" formats are semicolon-separated
//--------------------------------------------------------------------------------------------------
QChar detectDelimiter( const QString& line )
{
return line.contains( ',' ) ? ',' : ';';
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -104,7 +98,7 @@ std::expected<RifWellPathFormationReader::WellFormations, QString> RifWellPathFo
if ( stream.atEnd() ) return std::unexpected( parseFailure ); if ( stream.atEnd() ) return std::unexpected( parseFailure );
const QString rawHeaderLine = stream.readLine(); const QString rawHeaderLine = stream.readLine();
delimiter = detectDelimiter( rawHeaderLine ); delimiter = RifCsvHtmlTableTools::detectDelimiter( rawHeaderLine );
header = parseHeader( rawHeaderLine, delimiter ); header = parseHeader( rawHeaderLine, delimiter );
} }
@@ -223,14 +223,6 @@ RimEclipseResultCase* RimParameterRftCrossPlot::eclipseCase() const
return m_eclipseCase(); return m_eclipseCase();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimParameterRftCrossPlot::useDepthRange() const
{
return m_filterMode() != RimRftCrossPlotTools::DepthFilterMode::NONE;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -292,8 +284,7 @@ RiuQwtPlotWidget* RimParameterRftCrossPlot::viewer()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimRftCrossPlotTools::DepthInterval> RimParameterRftCrossPlot::depthIntervals() const std::vector<RimRftCrossPlotTools::DepthInterval> RimParameterRftCrossPlot::depthIntervals() const
{ {
return RimRftCrossPlotTools::buildDepthIntervals( useDepthRange(), return RimRftCrossPlotTools::buildDepthIntervals( m_filterMode(),
m_filterMode(),
m_depthRangeMin(), m_depthRangeMin(),
m_depthRangeMax(), m_depthRangeMax(),
m_wellFormations(), m_wellFormations(),
@@ -387,15 +378,11 @@ void RimParameterRftCrossPlot::updateAxes()
const int axisTitleSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisTitleFontSize() ); const int axisTitleSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisTitleFontSize() );
const int axisValueSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisValueFontSize() ); const int axisValueSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisValueFontSize() );
const QString pressureLabel = m_samplingMode() == SamplingMode::ALL_SAMPLES ? "Pressure" : "Mean Pressure"; const QString pressureLabel = m_samplingMode() == SamplingMode::ALL_SAMPLES ? "Pressure" : "Mean Pressure";
const QString filterDescription = RimRftCrossPlotTools::depthFilterDescription( useDepthRange(), const QString filterDescription =
m_filterMode(), RimRftCrossPlotTools::depthFilterDescription( m_filterMode(), m_depthType(), m_depthRangeMin(), m_depthRangeMax(), m_selectedZones() );
m_depthType(), const QString depthLabel = filterDescription.isEmpty() ? pressureLabel
m_depthRangeMin(), : QString( "%1 [%2]" ).arg( pressureLabel ).arg( filterDescription );
m_depthRangeMax(),
m_selectedZones() );
const QString depthLabel = filterDescription.isEmpty() ? pressureLabel
: QString( "%1 [%2]" ).arg( pressureLabel ).arg( filterDescription );
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultLeft(), depthLabel ); m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultLeft(), depthLabel );
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), true ); m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), true );
@@ -844,12 +831,8 @@ void RimParameterRftCrossPlot::updatePlotTitle()
if ( m_useAutoPlotTitle && m_ensemble() ) if ( m_useAutoPlotTitle && m_ensemble() )
{ {
const QString filterDescription = RimRftCrossPlotTools::depthFilterDescription( useDepthRange(), const QString filterDescription =
m_filterMode(), RimRftCrossPlotTools::depthFilterDescription( m_filterMode(), m_depthType(), m_depthRangeMin(), m_depthRangeMax(), m_selectedZones() );
m_depthType(),
m_depthRangeMin(),
m_depthRangeMax(),
m_selectedZones() );
if ( !filterDescription.isEmpty() ) if ( !filterDescription.isEmpty() )
{ {
m_description = m_description =
@@ -83,7 +83,6 @@ public:
QDateTime selectedTimeStep() const; QDateTime selectedTimeStep() const;
RimSummaryEnsemble* ensemble() const; RimSummaryEnsemble* ensemble() const;
RimEclipseResultCase* eclipseCase() const; RimEclipseResultCase* eclipseCase() const;
bool useDepthRange() const;
double depthRangeMin() const; double depthRangeMin() const;
double depthRangeMax() const; double depthRangeMax() const;
RiaDefines::DepthType depthType() const; RiaDefines::DepthType depthType() const;
@@ -537,7 +537,6 @@ void RimRftCorrelationReportPlot::syncTornadoInputsFromCrossPlot()
m_tornadoPlot->setTimeStep( m_parameterRftCrossPlot->selectedTimeStep() ); m_tornadoPlot->setTimeStep( m_parameterRftCrossPlot->selectedTimeStep() );
m_tornadoPlot->setSelectedParameter( m_parameterRftCrossPlot->ensembleParameter() ); m_tornadoPlot->setSelectedParameter( m_parameterRftCrossPlot->ensembleParameter() );
m_tornadoPlot->setEclipseCase( m_parameterRftCrossPlot->eclipseCase() ); m_tornadoPlot->setEclipseCase( m_parameterRftCrossPlot->eclipseCase() );
m_tornadoPlot->setUseDepthRange( m_parameterRftCrossPlot->useDepthRange() );
m_tornadoPlot->setDepthRange( m_parameterRftCrossPlot->depthRangeMin(), m_parameterRftCrossPlot->depthRangeMax() ); m_tornadoPlot->setDepthRange( m_parameterRftCrossPlot->depthRangeMin(), m_parameterRftCrossPlot->depthRangeMax() );
m_tornadoPlot->setDepthType( m_parameterRftCrossPlot->depthType() ); m_tornadoPlot->setDepthType( m_parameterRftCrossPlot->depthType() );
m_tornadoPlot->setFilterMode( m_parameterRftCrossPlot->filterMode() ); m_tornadoPlot->setFilterMode( m_parameterRftCrossPlot->filterMode() );
@@ -554,7 +553,6 @@ void RimRftCorrelationReportPlot::applyWellFormationsToSubPlots()
RimWellFormationsFile* wellFormationsFile = m_parameterRftCrossPlot->wellFormationsFile(); RimWellFormationsFile* wellFormationsFile = m_parameterRftCrossPlot->wellFormationsFile();
m_parameterRftCrossPlot->setWellFormations( wellFormationsFile );
if ( m_tornadoPlot() ) m_tornadoPlot->setWellFormations( wellFormationsFile ); if ( m_tornadoPlot() ) m_tornadoPlot->setWellFormations( wellFormationsFile );
} }
@@ -101,8 +101,7 @@ std::vector<double> RimRftCrossPlotTools::filterPressuresByDepthRange( const std
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimRftCrossPlotTools::DepthInterval> RimRftCrossPlotTools::buildDepthIntervals( bool useFilter, std::vector<RimRftCrossPlotTools::DepthInterval> RimRftCrossPlotTools::buildDepthIntervals( DepthFilterMode mode,
DepthFilterMode mode,
double depthRangeMin, double depthRangeMin,
double depthRangeMax, double depthRangeMax,
RimWellFormationsFile* wellFormationsFile, RimWellFormationsFile* wellFormationsFile,
@@ -110,15 +109,15 @@ std::vector<RimRftCrossPlotTools::DepthInterval> RimRftCrossPlotTools::buildDept
const std::vector<QString>& selectedZones, const std::vector<QString>& selectedZones,
RiaDefines::DepthType depthType ) RiaDefines::DepthType depthType )
{ {
if ( !useFilter || mode == DepthFilterMode::NONE ) return {}; if ( mode == DepthFilterMode::NONE ) return {};
if ( mode == DepthFilterMode::DEPTH_RANGE ) return { DepthInterval{ depthRangeMin, depthRangeMax } }; if ( mode == DepthFilterMode::DEPTH_RANGE ) return { DepthInterval{ depthRangeMin, depthRangeMax } };
// ZONES mode // ZONES mode
if ( !wellFormationsFile || selectedZones.empty() ) return {}; if ( !wellFormationsFile || selectedZones.empty() ) return {};
std::optional<RigWellPathFormations> formations = wellFormationsFile->formationsForWell( wellName ); const RigWellPathFormations* formations = wellFormationsFile->formationsForWell( wellName );
if ( !formations.has_value() ) return {}; if ( !formations ) return {};
std::vector<DepthInterval> intervals; std::vector<DepthInterval> intervals;
for ( size_t i = 0; i < formations->formationCount(); ++i ) for ( size_t i = 0; i < formations->formationCount(); ++i )
@@ -169,14 +168,13 @@ std::vector<double> RimRftCrossPlotTools::filterPressuresByDepthIntervals( const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RimRftCrossPlotTools::depthFilterDescription( bool useFilter, QString RimRftCrossPlotTools::depthFilterDescription( DepthFilterMode mode,
DepthFilterMode mode,
RiaDefines::DepthType depthType, RiaDefines::DepthType depthType,
double depthRangeMin, double depthRangeMin,
double depthRangeMax, double depthRangeMax,
const std::vector<QString>& selectedZones ) const std::vector<QString>& selectedZones )
{ {
if ( !useFilter || mode == DepthFilterMode::NONE ) return {}; if ( mode == DepthFilterMode::NONE ) return {};
if ( mode == DepthFilterMode::ZONES ) if ( mode == DepthFilterMode::ZONES )
{ {
@@ -83,10 +83,9 @@ std::vector<double> filterPressuresByDepthRange( const std::vector<double>& dept
double depthRangeMax ); double depthRangeMax );
// Builds the active depth filter intervals from either a depth range or a set of selected zones. // Builds the active depth filter intervals from either a depth range or a set of selected zones.
// Returns an empty vector (meaning "no filter") when useFilter is false, or when ZONES mode is // Returns an empty vector (meaning "no filter") when the mode is NONE, or when ZONES mode is
// selected but no well formations file, well name, or matching zones are available. // selected but no well formations file, well name, or matching zones are available.
std::vector<DepthInterval> buildDepthIntervals( bool useFilter, std::vector<DepthInterval> buildDepthIntervals( DepthFilterMode mode,
DepthFilterMode mode,
double depthRangeMin, double depthRangeMin,
double depthRangeMax, double depthRangeMax,
RimWellFormationsFile* wellFormationsFile, RimWellFormationsFile* wellFormationsFile,
@@ -103,8 +102,7 @@ std::vector<double> filterPressuresByDepthIntervals( const std::vector<double>&
// Short description of the active depth filter for titles/axis labels/group text, e.g. // Short description of the active depth filter for titles/axis labels/group text, e.g.
// "MD 1000 - 2000 m" or "Zones: Valysar, Therys". Empty when filtering is disabled. // "MD 1000 - 2000 m" or "Zones: Valysar, Therys". Empty when filtering is disabled.
QString depthFilterDescription( bool useFilter, QString depthFilterDescription( DepthFilterMode mode,
DepthFilterMode mode,
RiaDefines::DepthType depthType, RiaDefines::DepthType depthType,
double depthRangeMin, double depthRangeMin,
double depthRangeMax, double depthRangeMax,
@@ -61,10 +61,9 @@ RimRftTornadoPlot::RimRftTornadoPlot()
CAF_PDM_InitField( &m_wellName, "WellName", QString(), "Well Name" ); CAF_PDM_InitField( &m_wellName, "WellName", QString(), "Well Name" );
CAF_PDM_InitFieldNoDefault( &m_selectedTimeStep, "TimeStep", "Time Step" ); CAF_PDM_InitFieldNoDefault( &m_selectedTimeStep, "TimeStep", "Time Step" );
CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "EclipseCase", "Eclipse Case (MD fallback)" ); CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "EclipseCase", "Eclipse Case (MD fallback)" );
CAF_PDM_InitField( &m_useDepthRange, "UseDepthRange", false, "Filter by Depth Range" );
CAF_PDM_InitField( &m_filterMode, CAF_PDM_InitField( &m_filterMode,
"FilterMode", "FilterMode",
RimRftCrossPlotTools::DepthFilterModeEnum( RimRftCrossPlotTools::DepthFilterMode::DEPTH_RANGE ), RimRftCrossPlotTools::DepthFilterModeEnum( RimRftCrossPlotTools::DepthFilterMode::NONE ),
"Filter By" ); "Filter By" );
CAF_PDM_InitField( &m_depthRangeMin, "DepthRangeMin", 0.0, "Min Depth" ); CAF_PDM_InitField( &m_depthRangeMin, "DepthRangeMin", 0.0, "Min Depth" );
CAF_PDM_InitField( &m_depthRangeMax, "DepthRangeMax", 5000.0, "Max Depth" ); CAF_PDM_InitField( &m_depthRangeMax, "DepthRangeMax", 5000.0, "Max Depth" );
@@ -138,14 +137,6 @@ void RimRftTornadoPlot::setEclipseCase( RimEclipseResultCase* eclipseCase )
m_eclipseCase = eclipseCase; m_eclipseCase = eclipseCase;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimRftTornadoPlot::setUseDepthRange( bool useDepthRange )
{
m_useDepthRange = useDepthRange;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -397,8 +388,7 @@ void RimRftTornadoPlot::onPlotItemSelected( std::shared_ptr<RiuPlotItem> plotIte
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimRftCrossPlotTools::DepthInterval> RimRftTornadoPlot::depthIntervals() const std::vector<RimRftCrossPlotTools::DepthInterval> RimRftTornadoPlot::depthIntervals() const
{ {
return RimRftCrossPlotTools::buildDepthIntervals( m_useDepthRange(), return RimRftCrossPlotTools::buildDepthIntervals( m_filterMode(),
m_filterMode(),
m_depthRangeMin(), m_depthRangeMin(),
m_depthRangeMax(), m_depthRangeMax(),
m_wellFormations(), m_wellFormations(),
@@ -466,14 +456,10 @@ void RimRftTornadoPlot::updatePlotTitle()
if ( m_useAutoPlotTitle() && m_ensemble() ) if ( m_useAutoPlotTitle() && m_ensemble() )
{ {
const QString filterDescription = RimRftCrossPlotTools::depthFilterDescription( m_useDepthRange(), const QString filterDescription =
m_filterMode(), RimRftCrossPlotTools::depthFilterDescription( m_filterMode(), m_depthType(), m_depthRangeMin(), m_depthRangeMax(), m_selectedZones() );
m_depthType(), const QString rangeStr = filterDescription.isEmpty() ? QString() : QString( " [%1]" ).arg( filterDescription );
m_depthRangeMin(), m_description = QString( "Parameter Correlation vs RFT Pressure%1, %2" ).arg( rangeStr ).arg( m_ensemble->name() );
m_depthRangeMax(),
m_selectedZones() );
const QString rangeStr = filterDescription.isEmpty() ? QString() : QString( " [%1]" ).arg( filterDescription );
m_description = QString( "Parameter Correlation vs RFT Pressure%1, %2" ).arg( rangeStr ).arg( m_ensemble->name() );
} }
m_plotWidget->setPlotTitle( m_description() ); m_plotWidget->setPlotTitle( m_description() );
@@ -62,7 +62,6 @@ public:
void setWellName( const QString& wellName ); void setWellName( const QString& wellName );
void setTimeStep( const QDateTime& timeStep ); void setTimeStep( const QDateTime& timeStep );
void setEclipseCase( RimEclipseResultCase* eclipseCase ); void setEclipseCase( RimEclipseResultCase* eclipseCase );
void setUseDepthRange( bool useDepthRange );
void setDepthRange( double minMd, double maxMd ); void setDepthRange( double minMd, double maxMd );
void setDepthType( RiaDefines::DepthType depthType ); void setDepthType( RiaDefines::DepthType depthType );
void setFilterMode( RimRftCrossPlotTools::DepthFilterMode filterMode ); void setFilterMode( RimRftCrossPlotTools::DepthFilterMode filterMode );
@@ -107,7 +106,6 @@ private:
caf::PdmField<QString> m_wellName; caf::PdmField<QString> m_wellName;
caf::PdmField<QDateTime> m_selectedTimeStep; caf::PdmField<QDateTime> m_selectedTimeStep;
caf::PdmPtrField<RimEclipseResultCase*> m_eclipseCase; caf::PdmPtrField<RimEclipseResultCase*> m_eclipseCase;
caf::PdmField<bool> m_useDepthRange;
caf::PdmField<RimRftCrossPlotTools::DepthFilterModeEnum> m_filterMode; caf::PdmField<RimRftCrossPlotTools::DepthFilterModeEnum> m_filterMode;
caf::PdmField<double> m_depthRangeMin; caf::PdmField<double> m_depthRangeMin;
caf::PdmField<double> m_depthRangeMax; caf::PdmField<double> m_depthRangeMax;
@@ -18,7 +18,6 @@
#include "RimWellFormationsCollection.h" #include "RimWellFormationsCollection.h"
#include "RiaLogging.h"
#include "RimWellFormationsFile.h" #include "RimWellFormationsFile.h"
#include "RiuMessageDialog.h" #include "RiuMessageDialog.h"
@@ -27,6 +26,8 @@
#include <QFileInfo> #include <QFileInfo>
#include <memory>
CAF_PDM_SOURCE_INIT( RimWellFormationsCollection, "WellFormationsCollection" ); CAF_PDM_SOURCE_INIT( RimWellFormationsCollection, "WellFormationsCollection" );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -42,9 +43,10 @@ RimWellFormationsCollection::RimWellFormationsCollection()
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Returns the existing entry for filePath if present, otherwise imports and returns a new one /// Returns the existing entry for filePath if present, otherwise imports and returns a new one. A
/// file that cannot be read is not added.
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimWellFormationsFile* RimWellFormationsCollection::findOrCreate( const QString& filePath ) std::expected<RimWellFormationsFile*, QString> RimWellFormationsCollection::findOrCreate( const QString& filePath )
{ {
const QString absoluteFilePath = QFileInfo( filePath ).absoluteFilePath(); const QString absoluteFilePath = QFileInfo( filePath ).absoluteFilePath();
@@ -52,20 +54,25 @@ RimWellFormationsFile* RimWellFormationsCollection::findOrCreate( const QString&
{ {
if ( QFileInfo( file->filePath() ).absoluteFilePath() == absoluteFilePath ) if ( QFileInfo( file->filePath() ).absoluteFilePath() == absoluteFilePath )
{ {
// An earlier read may have failed, e.g. if the file was missing or malformed at the time
if ( file->wellNames().isEmpty() )
{
if ( auto result = file->reload(); !result ) return std::unexpected( result.error() );
}
return file; return file;
} }
} }
auto newFile = new RimWellFormationsFile(); auto newFile = std::make_unique<RimWellFormationsFile>();
newFile->setFilePath( filePath ); newFile->setFilePath( filePath );
if ( auto result = newFile->reload(); !result ) if ( auto result = newFile->reload(); !result )
{ {
RiaLogging::error( result.error().toStdString() ); return std::unexpected( result.error() );
} }
m_wellFormationsFiles.push_back( newFile ); m_wellFormationsFiles.push_back( newFile.get() );
return newFile; return newFile.release();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -76,7 +83,7 @@ RimWellFormationsFile* RimWellFormationsCollection::findFileForWell( const QStri
{ {
for ( RimWellFormationsFile* file : m_wellFormationsFiles ) for ( RimWellFormationsFile* file : m_wellFormationsFiles )
{ {
if ( file->formationsForWell( wellName ).has_value() ) return file; if ( file->formationsForWell( wellName ) ) return file;
} }
return nullptr; return nullptr;
@@ -92,15 +99,14 @@ std::vector<RimWellFormationsFile*> RimWellFormationsCollection::importFiles( co
for ( const QString& filePath : filePaths ) for ( const QString& filePath : filePaths )
{ {
auto newFile = new RimWellFormationsFile(); auto file = findOrCreate( filePath );
newFile->setFilePath( filePath ); if ( !file )
if ( auto result = newFile->reload(); !result )
{ {
totalErrorMessage += "\nError in: " + filePath + "\n\t" + result.error(); totalErrorMessage += "\nError in: " + filePath + "\n\t" + file.error();
continue;
} }
m_wellFormationsFiles.push_back( newFile ); importedFiles.push_back( *file );
importedFiles.push_back( newFile );
} }
if ( !totalErrorMessage.isEmpty() ) if ( !totalErrorMessage.isEmpty() )
@@ -111,6 +117,15 @@ std::vector<RimWellFormationsFile*> RimWellFormationsCollection::importFiles( co
return importedFiles; return importedFiles;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFormationsCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects )
{
RimWellFormationsFile::updateReferringObjects( referringObjects );
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -21,6 +21,10 @@
#include "cafPdmChildArrayField.h" #include "cafPdmChildArrayField.h"
#include "cafPdmObject.h" #include "cafPdmObject.h"
#include <QString>
#include <expected>
namespace caf namespace caf
{ {
class CmdFeatureMenuBuilder; class CmdFeatureMenuBuilder;
@@ -42,13 +46,14 @@ public:
const caf::PdmChildArrayField<RimWellFormationsFile*>& wellFormationsFiles() const { return m_wellFormationsFiles; } const caf::PdmChildArrayField<RimWellFormationsFile*>& wellFormationsFiles() const { return m_wellFormationsFiles; }
RimWellFormationsFile* findOrCreate( const QString& filePath ); std::expected<RimWellFormationsFile*, QString> findOrCreate( const QString& filePath );
RimWellFormationsFile* findFileForWell( const QString& wellName ) const; RimWellFormationsFile* findFileForWell( const QString& wellName ) const;
std::vector<RimWellFormationsFile*> importFiles( const QStringList& filePaths ); std::vector<RimWellFormationsFile*> importFiles( const QStringList& filePaths );
protected: protected:
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override; void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
private: private:
@@ -21,6 +21,10 @@
#include "RiaLogging.h" #include "RiaLogging.h"
#include "RifCsvHtmlTableTools.h" #include "RifCsvHtmlTableTools.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimWellPath.h"
#include "cafPdmUiFilePathEditor.h" #include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiTextEditor.h" #include "cafPdmUiTextEditor.h"
#include "cafPdmUiTreeOrdering.h" #include "cafPdmUiTreeOrdering.h"
@@ -82,12 +86,12 @@ std::expected<void, QString> RimWellFormationsFile::reload()
if ( !result ) if ( !result )
{ {
m_wellFormations.clear(); m_wellFormations.clear();
updateContentTable(); m_contentTable = "";
return std::unexpected( result.error() ); return std::unexpected( result.error() );
} }
m_wellFormations = std::move( *result ); m_wellFormations = std::move( *result );
updateContentTable(); m_contentTable = "";
return {}; return {};
} }
@@ -125,11 +129,11 @@ QStringList RimWellFormationsFile::zoneNames( const QString& wellName ) const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::optional<RigWellPathFormations> RimWellFormationsFile::formationsForWell( const QString& wellName ) const const RigWellPathFormations* RimWellFormationsFile::formationsForWell( const QString& wellName ) const
{ {
if ( auto it = m_wellFormations.find( wellName ); it != m_wellFormations.end() ) if ( auto it = m_wellFormations.find( wellName ); it != m_wellFormations.end() )
{ {
return it->second; return &it->second;
} }
// Fall back to a normalized name match, to handle differences between e.g. RFT and FMU well names // Fall back to a normalized name match, to handle differences between e.g. RFT and FMU well names
@@ -138,11 +142,11 @@ std::optional<RigWellPathFormations> RimWellFormationsFile::formationsForWell( c
{ {
if ( normalizedWellName( candidateName ) == normalizedTarget ) if ( normalizedWellName( candidateName ) == normalizedTarget )
{ {
return formations; return &formations;
} }
} }
return std::nullopt; return nullptr;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -167,9 +171,30 @@ void RimWellFormationsFile::fieldChangedByUi( const caf::PdmFieldHandle* changed
{ {
RiaLogging::error( result.error().toStdString() ); RiaLogging::error( result.error().toStdString() );
} }
updateReferringObjects( objectsWithReferringPtrFields() );
} }
} }
//--------------------------------------------------------------------------------------------------
/// Well paths cache the formations resolved from their file, so they must be refreshed when the
/// file is reloaded or deleted
//--------------------------------------------------------------------------------------------------
void RimWellFormationsFile::updateReferringObjects( const std::vector<caf::PdmObjectHandle*>& referringObjects )
{
for ( caf::PdmObjectHandle* object : referringObjects )
{
if ( auto wellPath = dynamic_cast<RimWellPath*>( object ) )
{
wellPath->refreshFormationsFromFile();
wellPath->updateConnectedEditors();
}
}
RimProject::current()->scheduleCreateDisplayModelAndRedrawAllViews();
RimMainPlotCollection::current()->updatePlotsWithFormations();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -183,6 +208,9 @@ void RimWellFormationsFile::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTree
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellFormationsFile::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) void RimWellFormationsFile::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{ {
// Built on demand, as the table is only needed when the file is shown in the property editor
if ( m_contentTable().isEmpty() ) updateContentTable();
uiOrdering.add( &m_filePath ); uiOrdering.add( &m_filePath );
uiOrdering.add( &m_contentTable ); uiOrdering.add( &m_contentTable );
uiOrdering.skipRemainingFields(); uiOrdering.skipRemainingFields();
@@ -231,7 +259,9 @@ void RimWellFormationsFile::updateUiTreeName()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellFormationsFile::updateContentTable() void RimWellFormationsFile::updateContentTable()
{ {
auto result = RifCsvHtmlTableTools::generateHtmlTableFromFile( filePath() ); const int maxRowCount = 1000;
auto result = RifCsvHtmlTableTools::generateHtmlTableFromFile( filePath(), maxRowCount );
if ( result ) if ( result )
{ {
m_contentTable = *result; m_contentTable = *result;
@@ -25,6 +25,7 @@
#include <expected> #include <expected>
#include <optional> #include <optional>
#include <vector>
//================================================================================================== //==================================================================================================
/// A single well formations/well picks file (e.g. an FMU formations.csv or a well pick export), /// A single well formations/well picks file (e.g. an FMU formations.csv or a well pick export),
@@ -44,11 +45,12 @@ public:
std::expected<void, QString> reload(); std::expected<void, QString> reload();
QStringList wellNames() const; QStringList wellNames() const;
QStringList zoneNames( const QString& wellName ) const; QStringList zoneNames( const QString& wellName ) const;
std::optional<RigWellPathFormations> formationsForWell( const QString& wellName ) const; const RigWellPathFormations* formationsForWell( const QString& wellName ) const;
static QString normalizedWellName( const QString& wellName ); static QString normalizedWellName( const QString& wellName );
static void updateReferringObjects( const std::vector<caf::PdmObjectHandle*>& referringObjects );
protected: protected:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
@@ -195,13 +195,11 @@ void RimWellLogFormationSettings::setWellNameInFormationsFile( const QString& we
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::optional<RigWellPathFormations> RimWellLogFormationSettings::resolveWellPickFormations() const const RigWellPathFormations* RimWellLogFormationSettings::resolveWellPickFormations() const
{ {
if ( m_formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICK_FILTER && m_formationWellPathForSourceWellPath() ) if ( m_formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICK_FILTER && m_formationWellPathForSourceWellPath() )
{ {
const RigWellPathFormations* formations = m_formationWellPathForSourceWellPath->formationsGeometry(); return m_formationWellPathForSourceWellPath->formationsGeometry();
if ( formations ) return *formations;
return std::nullopt;
} }
if ( m_formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICKS_NO_TRAJECTORY && m_wellFormationsFile() && if ( m_formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICKS_NO_TRAJECTORY && m_wellFormationsFile() &&
@@ -210,7 +208,7 @@ std::optional<RigWellPathFormations> RimWellLogFormationSettings::resolveWellPic
return m_wellFormationsFile->formationsForWell( m_wellNameInFormationsFile() ); return m_wellFormationsFile->formationsForWell( m_wellNameInFormationsFile() );
} }
return std::nullopt; return nullptr;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -333,7 +331,7 @@ void RimWellLogFormationSettings::uiOrdering( const QString& uiConfigName, caf::
// WELL_PICKS_NO_TRAJECTORY source, so this source only ever shows the well path picker. // WELL_PICKS_NO_TRAJECTORY source, so this source only ever shows the well path picker.
uiOrdering.add( &m_formationWellPathForSourceWellPath ); uiOrdering.add( &m_formationWellPathForSourceWellPath );
if ( resolveWellPickFormations().has_value() ) if ( resolveWellPickFormations() )
{ {
uiOrdering.add( &m_formationLevel ); uiOrdering.add( &m_formationLevel );
uiOrdering.add( &m_showFormationFluids ); uiOrdering.add( &m_showFormationFluids );
@@ -346,7 +344,7 @@ void RimWellLogFormationSettings::uiOrdering( const QString& uiConfigName, caf::
uiOrdering.add( &m_wellFormationsFile ); uiOrdering.add( &m_wellFormationsFile );
if ( m_wellFormationsFile() ) uiOrdering.add( &m_wellNameInFormationsFile ); if ( m_wellFormationsFile() ) uiOrdering.add( &m_wellNameInFormationsFile );
if ( resolveWellPickFormations().has_value() ) if ( resolveWellPickFormations() )
{ {
uiOrdering.add( &m_formationLevel ); uiOrdering.add( &m_formationLevel );
uiOrdering.add( &m_showFormationFluids ); uiOrdering.add( &m_showFormationFluids );
@@ -78,7 +78,7 @@ public:
// Resolves the formations to show for the WELL_PICK_FILTER source: the selected well path's // Resolves the formations to show for the WELL_PICK_FILTER source: the selected well path's
// own formations if present, otherwise the well looked up directly in wellFormationsFile(). // own formations if present, otherwise the well looked up directly in wellFormationsFile().
std::optional<RigWellPathFormations> resolveWellPickFormations() const; const RigWellPathFormations* resolveWellPickFormations() const;
// Simulation well // Simulation well
QString simWellName() const; QString simWellName() const;
@@ -2607,7 +2607,7 @@ void RimWellLogTrack::updateFormationNamesOnPlot()
m_formationSettings->formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICKS_NO_TRAJECTORY ) m_formationSettings->formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICKS_NO_TRAJECTORY )
{ {
auto formations = m_formationSettings->resolveWellPickFormations(); auto formations = m_formationSettings->resolveWellPickFormations();
if ( !formations.has_value() ) return; if ( !formations ) return;
if ( plot->depthType() != RiaDefines::DepthType::MEASURED_DEPTH && plot->depthType() != RiaDefines::DepthType::TRUE_VERTICAL_DEPTH && if ( plot->depthType() != RiaDefines::DepthType::MEASURED_DEPTH && plot->depthType() != RiaDefines::DepthType::TRUE_VERTICAL_DEPTH &&
plot->depthType() != RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB ) plot->depthType() != RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
@@ -22,6 +22,7 @@
#include "RiaColorTables.h" #include "RiaColorTables.h"
#include "RiaFieldHandleTools.h" #include "RiaFieldHandleTools.h"
#include "RiaLogging.h"
#include "RiaSimWellBranchTools.h" #include "RiaSimWellBranchTools.h"
#include "RiaWellNameComparer.h" #include "RiaWellNameComparer.h"
@@ -489,6 +490,7 @@ void RimWellPath::fieldChangedByUi( const caf::PdmFieldHandle* changedField, con
{ {
refreshFormationsFromFile(); refreshFormationsFromFile();
proj->scheduleCreateDisplayModelAndRedrawAllViews(); proj->scheduleCreateDisplayModelAndRedrawAllViews();
RimMainPlotCollection::current()->updatePlotsWithFormations();
} }
else else
{ {
@@ -584,8 +586,14 @@ void RimWellPath::initAfterRead()
{ {
if ( !oilField->wellFormationsCollection() ) oilField->wellFormationsCollection = new RimWellFormationsCollection(); if ( !oilField->wellFormationsCollection() ) oilField->wellFormationsCollection = new RimWellFormationsCollection();
auto* file = oilField->wellFormationsCollection->findOrCreate( m_wellPathFormationFilePath_OBSOLETE().path() ); if ( auto file = oilField->wellFormationsCollection->findOrCreate( m_wellPathFormationFilePath_OBSOLETE().path() ) )
setWellFormationsFile( file, m_formationKeyInFile() ); {
setWellFormationsFile( *file, m_formationKeyInFile() );
}
else
{
RiaLogging::error( file.error().toStdString() );
}
} }
} }
} }
@@ -1058,10 +1066,18 @@ bool RimWellPath::refreshFormationsFromFile()
{ {
if ( !m_wellFormationsFile() ) if ( !m_wellFormationsFile() )
{ {
m_wellPathFormations.reset();
return false; return false;
} }
m_wellPathFormations = m_wellFormationsFile()->formationsForWell( m_formationKeyInFile() ); if ( auto formations = m_wellFormationsFile()->formationsForWell( m_formationKeyInFile() ) )
{
m_wellPathFormations = *formations;
}
else
{
m_wellPathFormations.reset();
}
return m_wellPathFormations.has_value(); return m_wellPathFormations.has_value();
} }
@@ -536,11 +536,19 @@ void RimWellPathCollection::addWellPathFormations( const QStringList& filePaths
// The collection is deletable from the project tree // The collection is deletable from the project tree
if ( !oilField->wellFormationsCollection() ) oilField->wellFormationsCollection = new RimWellFormationsCollection(); if ( !oilField->wellFormationsCollection() ) oilField->wellFormationsCollection = new RimWellFormationsCollection();
bool fileReadSuccess = false; bool fileReadSuccess = false;
QString errorMessage;
for ( const QString& filePath : filePaths ) for ( const QString& filePath : filePaths )
{ {
RimWellFormationsFile* wellFormationsFile = oilField->wellFormationsCollection->findOrCreate( filePath ); auto file = oilField->wellFormationsCollection->findOrCreate( filePath );
if ( !file )
{
errorMessage += "\nError in: " + filePath + "\n\t" + file.error();
continue;
}
RimWellFormationsFile* wellFormationsFile = *file;
for ( const QString& wellName : wellFormationsFile->wellNames() ) for ( const QString& wellName : wellFormationsFile->wellNames() )
{ {
@@ -575,6 +583,11 @@ void RimWellPathCollection::addWellPathFormations( const QStringList& filePaths
RiuMessageDialog::showError( Riu3DMainWindowTools::mainWindowWidget(), "Well Picks Import", outputMessage ); RiuMessageDialog::showError( Riu3DMainWindowTools::mainWindowWidget(), "Well Picks Import", outputMessage );
} }
if ( !errorMessage.isEmpty() )
{
RiuMessageDialog::showError( Riu3DMainWindowTools::mainWindowWidget(), "Well Picks Import", errorMessage );
}
sortWellsByName(); sortWellsByName();
updateAllRequiredEditors(); updateAllRequiredEditors();
} }
@@ -281,16 +281,22 @@ std::pair<std::vector<QString>, std::vector<double>>
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Returns one (name, top, base) range per formation whose level does not exceed the given level, /// Returns one (name, top, base) range per formation whose level does not exceed the given level,
/// for use as shaded zone regions. Unlike depthAndFormationNamesUpToLevel(), this does not merge /// for use as shaded zone regions. Each zone is clipped against the more detailed zones inside it, so
/// hierarchical levels at coincident depths, so a parent/child formation pair can overlap in the /// parent and child zones are not drawn on top of each other.
/// result when both satisfy the level filter (e.g. requesting LEVEL1 also includes any GROUP-level
/// parent zone covering the same depth range).
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<std::tuple<QString, double, double>> RigWellPathFormations::depthRangesUpToLevel( FormationLevel level, std::vector<std::tuple<QString, double, double>> RigWellPathFormations::depthRangesUpToLevel( FormationLevel level,
RiaDefines::DepthType depthType ) const RiaDefines::DepthType depthType ) const
{ {
std::vector<std::tuple<QString, double, double>> result; struct Zone
if ( level == FormationLevel::NONE ) return result; {
QString name;
double top;
double base;
FormationLevel level;
};
std::vector<Zone> zones;
if ( level == FormationLevel::NONE ) return {};
for ( const auto& [formation, formationLevel] : m_formations ) for ( const auto& [formation, formationLevel] : m_formations )
{ {
@@ -300,7 +306,49 @@ std::vector<std::tuple<QString, double, double>> RigWellPathFormations::depthRan
auto base = pickDepth( formation, PickPosition::BASE, depthType ); auto base = pickDepth( formation, PickPosition::BASE, depthType );
if ( !top || !base ) continue; if ( !top || !base ) continue;
result.emplace_back( formation.formationName, *top, *base ); zones.push_back( { formation.formationName, *top, *base, formationLevel } );
}
// UNKNOWN has no place in the hierarchy, so it neither hides nor is hidden by other zones
auto isMoreDetailed = []( FormationLevel candidate, FormationLevel reference )
{ return candidate <= FormationLevel::LEVEL10 && reference <= FormationLevel::LEVEL10 && candidate > reference; };
const double minThickness = 0.1;
std::vector<std::tuple<QString, double, double>> result;
for ( const auto& zone : zones )
{
const double lower = std::min( zone.top, zone.base );
const double upper = std::max( zone.top, zone.base );
std::vector<std::pair<double, double>> covered;
for ( const auto& other : zones )
{
if ( !isMoreDetailed( other.level, zone.level ) ) continue;
covered.emplace_back( std::min( other.top, other.base ), std::max( other.top, other.base ) );
}
std::sort( covered.begin(), covered.end() );
// Keep the parts of the zone not covered by a more detailed zone, in the zone's own direction
auto addPart = [&]( double from, double to )
{
if ( to - from <= minThickness ) return;
if ( zone.top <= zone.base )
result.emplace_back( zone.name, from, to );
else
result.emplace_back( zone.name, to, from );
};
double current = lower;
for ( const auto& [coveredLower, coveredUpper] : covered )
{
if ( coveredLower >= upper ) break;
if ( coveredUpper <= current ) continue;
addPart( current, std::min( coveredLower, upper ) );
current = std::max( current, coveredUpper );
}
addPart( current, upper );
} }
return result; return result;
} }
@@ -147,10 +147,19 @@ TEST( RigWellPathFormations, DepthRangesUpToLevelReturnsZoneIntervals )
} }
{ {
auto ranges = formations.depthRangesUpToLevel( FormationLevel::LEVEL1, DepthType::MEASURED_DEPTH ); auto ranges = formations.depthRangesUpToLevel( FormationLevel::LEVEL1, DepthType::MEASURED_DEPTH );
ASSERT_EQ( 2u, ranges.size() );
EXPECT_EQ( QString( "Garn 1" ), std::get<0>( ranges[0] ) );
EXPECT_EQ( QString( "Garn 2" ), std::get<0>( ranges[1] ) );
}
{
// Garn 2 is only partly covered by Garn 2.1, so the remainder is kept
auto ranges = formations.depthRangesUpToLevel( FormationLevel::ALL, DepthType::MEASURED_DEPTH );
ASSERT_EQ( 3u, ranges.size() ); ASSERT_EQ( 3u, ranges.size() );
EXPECT_EQ( QString( "GARN" ), std::get<0>( ranges[0] ) ); EXPECT_EQ( QString( "Garn 1" ), std::get<0>( ranges[0] ) );
EXPECT_EQ( QString( "Garn 1" ), std::get<0>( ranges[1] ) ); EXPECT_EQ( QString( "Garn 2" ), std::get<0>( ranges[1] ) );
EXPECT_EQ( QString( "Garn 2" ), std::get<0>( ranges[2] ) ); EXPECT_DOUBLE_EQ( 175.0, std::get<1>( ranges[1] ) );
EXPECT_DOUBLE_EQ( 200.0, std::get<2>( ranges[1] ) );
EXPECT_EQ( QString( "Garn 2.1" ), std::get<0>( ranges[2] ) );
} }
{ {
auto ranges = formations.depthRangesUpToLevel( FormationLevel::NONE, DepthType::MEASURED_DEPTH ); auto ranges = formations.depthRangesUpToLevel( FormationLevel::NONE, DepthType::MEASURED_DEPTH );
@@ -105,12 +105,11 @@ TEST( RimRftCrossPlotToolsTest, DepthTypeAbbreviation )
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Disabled filtering returns no intervals regardless of mode. /// Disabled filtering returns no intervals.
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_DisabledReturnsEmpty ) TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_DisabledReturnsEmpty )
{ {
auto intervals = RimRftCrossPlotTools::buildDepthIntervals( false, auto intervals = RimRftCrossPlotTools::buildDepthIntervals( RimRftCrossPlotTools::DepthFilterMode::NONE,
RimRftCrossPlotTools::DepthFilterMode::DEPTH_RANGE,
1000.0, 1000.0,
2000.0, 2000.0,
nullptr, nullptr,
@@ -125,8 +124,7 @@ TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_DisabledReturnsEmpty )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_DepthRangeProducesSingleInterval ) TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_DepthRangeProducesSingleInterval )
{ {
auto intervals = RimRftCrossPlotTools::buildDepthIntervals( true, auto intervals = RimRftCrossPlotTools::buildDepthIntervals( RimRftCrossPlotTools::DepthFilterMode::DEPTH_RANGE,
RimRftCrossPlotTools::DepthFilterMode::DEPTH_RANGE,
1000.0, 1000.0,
2000.0, 2000.0,
nullptr, nullptr,
@@ -143,8 +141,7 @@ TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_DepthRangeProducesSingleInte
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_ZonesWithoutFileReturnsEmpty ) TEST( RimRftCrossPlotToolsTest, BuildDepthIntervals_ZonesWithoutFileReturnsEmpty )
{ {
auto intervals = RimRftCrossPlotTools::buildDepthIntervals( true, auto intervals = RimRftCrossPlotTools::buildDepthIntervals( RimRftCrossPlotTools::DepthFilterMode::ZONES,
RimRftCrossPlotTools::DepthFilterMode::ZONES,
1000.0, 1000.0,
2000.0, 2000.0,
nullptr, nullptr,
@@ -187,8 +184,7 @@ TEST( RimRftCrossPlotToolsTest, FilterPressuresByDepthIntervals_FiltersByMultipl
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
TEST( RimRftCrossPlotToolsTest, DepthFilterDescription_DisabledReturnsEmpty ) TEST( RimRftCrossPlotToolsTest, DepthFilterDescription_DisabledReturnsEmpty )
{ {
QString description = RimRftCrossPlotTools::depthFilterDescription( false, QString description = RimRftCrossPlotTools::depthFilterDescription( RimRftCrossPlotTools::DepthFilterMode::NONE,
RimRftCrossPlotTools::DepthFilterMode::DEPTH_RANGE,
RiaDefines::DepthType::MEASURED_DEPTH, RiaDefines::DepthType::MEASURED_DEPTH,
1000.0, 1000.0,
2000.0, 2000.0,
@@ -201,8 +197,7 @@ TEST( RimRftCrossPlotToolsTest, DepthFilterDescription_DisabledReturnsEmpty )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
TEST( RimRftCrossPlotToolsTest, DepthFilterDescription_ZonesListsSelectedZoneNames ) TEST( RimRftCrossPlotToolsTest, DepthFilterDescription_ZonesListsSelectedZoneNames )
{ {
QString description = RimRftCrossPlotTools::depthFilterDescription( true, QString description = RimRftCrossPlotTools::depthFilterDescription( RimRftCrossPlotTools::DepthFilterMode::ZONES,
RimRftCrossPlotTools::DepthFilterMode::ZONES,
RiaDefines::DepthType::MEASURED_DEPTH, RiaDefines::DepthType::MEASURED_DEPTH,
1000.0, 1000.0,
2000.0, 2000.0,