Refactor ensemble import dialog

* #9773 Refactor ensemble import dialog.
* #9773 Add support for ensemble import of StimPlan/Reveal summary data.
* #9773 Add method for finding min and max time steps.
* #9773 Add option for resampling to hour intervals.
* #9773 Add option for resampling to minute intervals.
* #9773 Ensemble statistics: determine sub-sampling period dynamically.
* Use RiaWeightedMeanCalculator for curve resampling.
* Add HOUR and MINUTE to date time app enum.
* #9773 Generate better ensembles for StimPlan summaries.
* #9773 Fix parameters.txt lookup for StimPlan summaries
* Refactor: Improve interface of RicImportSummaryCasesFreature::createSummaryCasesFromFiles

Co-authored-by: Magne Sjaastad <magne.sjaastad@ceetronsolutions.com>
This commit is contained in:
Kristian Bendiksen
2023-04-20 10:16:43 +02:00
committed by GitHub
parent 67264da0a8
commit ff209ad7c2
34 changed files with 960 additions and 434 deletions

View File

@@ -46,6 +46,8 @@ template <>
void caf::AppEnum<RiaDefines::DateTimePeriod>::setUp() void caf::AppEnum<RiaDefines::DateTimePeriod>::setUp()
{ {
addItem( RiaDefines::DateTimePeriod::NONE, "NONE", "None" ); addItem( RiaDefines::DateTimePeriod::NONE, "NONE", "None" );
addItem( RiaDefines::DateTimePeriod::MINUTE, "MINUTE", "Minute" );
addItem( RiaDefines::DateTimePeriod::HOUR, "HOUR", "Hour" );
addItem( RiaDefines::DateTimePeriod::DAY, "DAY", "Day" ); addItem( RiaDefines::DateTimePeriod::DAY, "DAY", "Day" );
addItem( RiaDefines::DateTimePeriod::WEEK, "WEEK", "Week" ); addItem( RiaDefines::DateTimePeriod::WEEK, "WEEK", "Week" );
addItem( RiaDefines::DateTimePeriod::MONTH, "MONTH", "Month" ); addItem( RiaDefines::DateTimePeriod::MONTH, "MONTH", "Month" );

View File

@@ -45,6 +45,8 @@ enum class TimeFormatComponents
enum class DateTimePeriod enum class DateTimePeriod
{ {
NONE = -1, NONE = -1,
MINUTE,
HOUR,
DAY, DAY,
WEEK, WEEK,
MONTH, MONTH,

View File

@@ -22,6 +22,13 @@
namespace RiaDefines namespace RiaDefines
{ {
enum class FileType
{
SMSPEC,
REVEAL_SUMMARY,
STIMPLAN_SUMMARY
};
QString summaryField(); QString summaryField();
QString summaryAquifer(); QString summaryAquifer();
QString summaryNetwork(); QString summaryNetwork();

View File

@@ -133,6 +133,106 @@ std::vector<QStringList> RiaEnsembleNameTools::groupFilesByEnsemble( const QStri
return groupedByIteration; return groupedByIteration;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<QString, QStringList> RiaEnsembleNameTools::groupFilesByStimPlanEnsemble( const QStringList& fileNames )
{
std::vector<QStringList> componentsForAllFilePaths;
for ( const auto& filePath : fileNames )
{
QStringList components = RiaFilePathTools::splitPathIntoComponents( filePath );
componentsForAllFilePaths.push_back( components );
}
auto mapping = findUniqueStimPlanEnsembleNames( fileNames, componentsForAllFilePaths );
std::set<QString> iterations;
for ( const auto& [name, iterFileNamePair] : mapping )
{
iterations.insert( iterFileNamePair.first );
}
std::map<QString, QStringList> groupedByIteration;
for ( const QString& groupIteration : iterations )
{
QStringList fileNamesFromIteration;
for ( const auto& [name, iterFileNamePair] : mapping )
{
QString iteration = iterFileNamePair.first;
QString fileName = iterFileNamePair.second;
if ( groupIteration == iteration )
{
fileNamesFromIteration << fileName;
}
}
groupedByIteration[groupIteration] = fileNamesFromIteration;
}
return groupedByIteration;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<QString, std::pair<QString, QString>>
RiaEnsembleNameTools::findUniqueStimPlanEnsembleNames( const QStringList& fileNames, const std::vector<QStringList>& fileNameComponents )
{
CAF_ASSERT( fileNames.size() == static_cast<int>( fileNameComponents.size() ) );
struct StimPlanComponents
{
QString realization;
QString iteration;
QString well;
QString fracture;
QString job;
QString fileName;
};
std::vector<StimPlanComponents> comps;
int i = 0;
for ( const auto& fileComponents : fileNameComponents )
{
int numComponents = fileComponents.size();
if ( numComponents >= 7 )
{
StimPlanComponents c;
c.fileName = fileNames[i];
c.fracture = fileComponents[numComponents - 2];
c.iteration = fileComponents[numComponents - 6];
c.realization = fileComponents[numComponents - 7];
QString wellJobComponent = fileComponents[numComponents - 3];
QStringList parts = wellJobComponent.split( "_" );
if ( parts.size() == 4 )
{
c.well = parts[0];
c.job = parts[3];
}
comps.push_back( c );
}
i++;
}
std::map<QString, std::pair<QString, QString>> mapping;
for ( const StimPlanComponents& c : comps )
{
QString key = QString( "%1, %2, %3, %4, %5" ).arg( c.iteration, c.realization, c.well, c.fracture, c.job );
QString iteration = QString( "%1, %2, %3, %4" ).arg( c.iteration, c.well, c.fracture, c.job );
mapping[key] = std::make_pair( iteration, c.fileName );
}
return mapping;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -50,6 +50,10 @@ public:
const QString& ensembleCaseName ); const QString& ensembleCaseName );
static std::vector<QStringList> groupFilesByEnsemble( const QStringList& fileNames, EnsembleGroupingMode groupingMode ); static std::vector<QStringList> groupFilesByEnsemble( const QStringList& fileNames, EnsembleGroupingMode groupingMode );
static std::map<QString, QStringList> groupFilesByStimPlanEnsemble( const QStringList& fileNames );
static std::map<QString, std::pair<QString, QString>>
findUniqueStimPlanEnsembleNames( const QStringList& fileNames, const std::vector<QStringList>& fileNameComponents );
static QString uniqueShortNameForEnsembleCase( RimSummaryCase* summaryCase ); static QString uniqueShortNameForEnsembleCase( RimSummaryCase* summaryCase );
static QString uniqueShortNameForSummaryCase( RimSummaryCase* summaryCase ); static QString uniqueShortNameForSummaryCase( RimSummaryCase* summaryCase );

View File

@@ -21,6 +21,7 @@
#include <QDateTime> #include <QDateTime>
#include <QLocale> #include <QLocale>
#include <QString> #include <QString>
#include <QTime>
#include "cafPdmUiItem.h" #include "cafPdmUiItem.h"
@@ -32,6 +33,8 @@
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_MINUTE = DateTimeSpan( 0, 0, 0, 0, 1 );
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_HOUR = DateTimeSpan( 0, 0, 0, 1 );
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_DAY = DateTimeSpan( 0, 0, 1 ); const DateTimeSpan RiaQDateTimeTools::TIMESPAN_DAY = DateTimeSpan( 0, 0, 1 );
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_WEEK = DateTimeSpan( 0, 0, 7 ); const DateTimeSpan RiaQDateTimeTools::TIMESPAN_WEEK = DateTimeSpan( 0, 0, 7 );
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_MONTH = DateTimeSpan( 0, 1, 0 ); const DateTimeSpan RiaQDateTimeTools::TIMESPAN_MONTH = DateTimeSpan( 0, 1, 0 );
@@ -48,6 +51,22 @@ Qt::TimeSpec RiaQDateTimeTools::currentTimeSpec()
return Qt::UTC; return Qt::UTC;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
quint64 RiaQDateTimeTools::secondsInMinute()
{
return 60;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
quint64 RiaQDateTimeTools::secondsInHour()
{
return 60 * 60;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -142,7 +161,12 @@ QDateTime RiaQDateTimeTools::addYears( const QDateTime& dt, double years )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::addSpan( const QDateTime& dt, DateTimeSpan span ) QDateTime RiaQDateTimeTools::addSpan( const QDateTime& dt, DateTimeSpan span )
{ {
return createUtcDateTime( dt ).addYears( span.years() ).addMonths( span.months() ).addDays( span.days() ); return createUtcDateTime( dt )
.addYears( span.years() )
.addMonths( span.months() )
.addDays( span.days() )
.addSecs( span.hours() * RiaQDateTimeTools::secondsInHour() )
.addSecs( span.minutes() * RiaQDateTimeTools::secondsInMinute() );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -150,7 +174,12 @@ QDateTime RiaQDateTimeTools::addSpan( const QDateTime& dt, DateTimeSpan span )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::subtractSpan( const QDateTime& dt, DateTimeSpan span ) QDateTime RiaQDateTimeTools::subtractSpan( const QDateTime& dt, DateTimeSpan span )
{ {
return createUtcDateTime( dt ).addYears( -span.years() ).addMonths( -span.months() ).addDays( -span.days() ); return createUtcDateTime( dt )
.addYears( -span.years() )
.addMonths( -span.months() )
.addDays( -span.days() )
.addSecs( -span.hours() * RiaQDateTimeTools::secondsInHour() )
.addSecs( -span.minutes() * RiaQDateTimeTools::secondsInMinute() );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -250,6 +279,10 @@ const DateTimeSpan RiaQDateTimeTools::timeSpan( RiaDefines::DateTimePeriod perio
{ {
switch ( period ) switch ( period )
{ {
case RiaDefines::DateTimePeriod::MINUTE:
return TIMESPAN_MINUTE;
case RiaDefines::DateTimePeriod::HOUR:
return TIMESPAN_HOUR;
case RiaDefines::DateTimePeriod::DAY: case RiaDefines::DateTimePeriod::DAY:
return TIMESPAN_DAY; return TIMESPAN_DAY;
case RiaDefines::DateTimePeriod::WEEK: case RiaDefines::DateTimePeriod::WEEK:
@@ -278,9 +311,15 @@ QDateTime RiaQDateTimeTools::truncateTime( const QDateTime& dt, RiaDefines::Date
int m = dt.date().month(); int m = dt.date().month();
int d = dt.date().day(); int d = dt.date().day();
int dow = dt.date().dayOfWeek(); int dow = dt.date().dayOfWeek();
int h = dt.time().hour();
int minute = dt.time().minute();
switch ( period ) switch ( period )
{ {
case RiaDefines::DateTimePeriod::MINUTE:
return createUtcDateTime( QDate( y, m, d ), QTime( h, minute, 0 ) );
case RiaDefines::DateTimePeriod::HOUR:
return createUtcDateTime( QDate( y, m, d ), QTime( h, 0, 0 ) );
case RiaDefines::DateTimePeriod::DAY: case RiaDefines::DateTimePeriod::DAY:
return createUtcDateTime( QDate( y, m, d ) ); return createUtcDateTime( QDate( y, m, d ) );
case RiaDefines::DateTimePeriod::WEEK: case RiaDefines::DateTimePeriod::WEEK:

View File

@@ -99,6 +99,8 @@ public:
getTimeStepsWithinSelectedRange( const std::vector<QDateTime>& timeSteps, const QDateTime& fromTimeStep, const QDateTime& toTimeStep ); getTimeStepsWithinSelectedRange( const std::vector<QDateTime>& timeSteps, const QDateTime& fromTimeStep, const QDateTime& toTimeStep );
private: private:
static const DateTimeSpan TIMESPAN_MINUTE;
static const DateTimeSpan TIMESPAN_HOUR;
static const DateTimeSpan TIMESPAN_DAY; static const DateTimeSpan TIMESPAN_DAY;
static const DateTimeSpan TIMESPAN_WEEK; static const DateTimeSpan TIMESPAN_WEEK;
static const DateTimeSpan TIMESPAN_MONTH; static const DateTimeSpan TIMESPAN_MONTH;
@@ -109,6 +111,8 @@ private:
static quint64 secondsInDay(); static quint64 secondsInDay();
static quint64 secondsInYear(); static quint64 secondsInYear();
static quint64 secondsInHour();
static quint64 secondsInMinute();
}; };
//================================================================================================== //==================================================================================================
@@ -121,23 +125,31 @@ public:
: m_years( 0 ) : m_years( 0 )
, m_months( 0 ) , m_months( 0 )
, m_days( 0 ) , m_days( 0 )
, m_hours( 0 )
, m_minutes( 0 )
{ {
} }
DateTimeSpan( int years, int months, int days ) DateTimeSpan( int years, int months, int days, int hours = 0, int minutes = 0 )
: m_years( years ) : m_years( years )
, m_months( months ) , m_months( months )
, m_days( days ) , m_days( days )
, m_hours( hours )
, m_minutes( minutes )
{ {
} }
int years() const { return m_years; } int years() const { return m_years; }
int months() const { return m_months; } int months() const { return m_months; }
int days() const { return m_days; } int days() const { return m_days; }
int hours() const { return m_hours; }
int minutes() const { return m_minutes; }
bool isEmpty() { return m_years == 0 && m_months == 0 && m_days; } bool isEmpty() { return m_years == 0 && m_months == 0 && m_days == 0 && m_hours == 0 && m_minutes == 0; }
private: private:
int m_years; int m_years;
int m_months; int m_months;
int m_days; int m_days;
int m_hours;
int m_minutes;
}; };

View File

@@ -21,6 +21,7 @@
#include "RiaQDateTimeTools.h" #include "RiaQDateTimeTools.h"
#include "RiaTimeHistoryCurveResampler.h" #include "RiaTimeHistoryCurveResampler.h"
#include "RiaWeightedMeanCalculator.h"
#include <limits> #include <limits>
@@ -125,8 +126,6 @@ std::vector<time_t> RiaTimeHistoryCurveResampler::timeStepsFromTimeRange( RiaDef
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::computeWeightedMeanValues( RiaDefines::DateTimePeriod period ) void RiaTimeHistoryCurveResampler::computeWeightedMeanValues( RiaDefines::DateTimePeriod period )
{ {
size_t origDataSize = m_originalValues.second.size();
size_t oi = 0;
const auto& origTimeSteps = m_originalValues.second; const auto& origTimeSteps = m_originalValues.second;
const auto& origValues = m_originalValues.first; const auto& origValues = m_originalValues.first;
@@ -138,15 +137,19 @@ void RiaTimeHistoryCurveResampler::computeWeightedMeanValues( RiaDefines::DateTi
computeResampledTimeSteps( period ); computeResampledTimeSteps( period );
m_values.reserve( m_timeSteps.size() ); m_values.reserve( m_timeSteps.size() );
size_t origDataSize = origValues.size();
size_t oi = 0;
for ( size_t i = 0; i < m_timeSteps.size(); i++ ) for ( size_t i = 0; i < m_timeSteps.size(); i++ )
{ {
double wMean = 0.0;
time_t periodStart = time_t periodStart =
i > 0 ? m_timeSteps[i - 1] i > 0 ? m_timeSteps[i - 1]
: RiaQDateTimeTools::subtractPeriod( RiaQDateTimeTools::fromTime_t( m_timeSteps[0] ), period ).toSecsSinceEpoch(); : RiaQDateTimeTools::subtractPeriod( RiaQDateTimeTools::fromTime_t( m_timeSteps[0] ), period ).toSecsSinceEpoch();
time_t periodEnd = m_timeSteps[i]; time_t periodEnd = m_timeSteps[i];
time_t periodLength = periodEnd - periodStart; time_t periodLength = periodEnd - periodStart;
RiaWeightedMeanCalculator<double> calc;
while ( true ) while ( true )
{ {
time_t origTimeStep = 0; time_t origTimeStep = 0;
@@ -169,7 +172,7 @@ void RiaTimeHistoryCurveResampler::computeWeightedMeanValues( RiaDefines::DateTi
{ {
if ( origTimeStep == m_timeSteps[i] ) if ( origTimeStep == m_timeSteps[i] )
{ {
wMean += origValue; calc.addValueAndWeight( origValue, periodLength );
oi++; oi++;
break; break;
} }
@@ -179,7 +182,7 @@ void RiaTimeHistoryCurveResampler::computeWeightedMeanValues( RiaDefines::DateTi
time_t startTime = oi > 0 ? std::max( origTimeSteps[oi - 1], periodStart ) : periodStart; time_t startTime = oi > 0 ? std::max( origTimeSteps[oi - 1], periodStart ) : periodStart;
time_t endTime = std::min( origTimeStep, periodEnd ); time_t endTime = std::min( origTimeStep, periodEnd );
wMean += origValue * ( endTime - startTime ) / periodLength; calc.addValueAndWeight( origValue, endTime - startTime );
if ( origTimeStep > m_timeSteps[i] ) break; if ( origTimeStep > m_timeSteps[i] ) break;
if ( origTimeStep == m_timeSteps[i] ) if ( origTimeStep == m_timeSteps[i] )
@@ -190,7 +193,7 @@ void RiaTimeHistoryCurveResampler::computeWeightedMeanValues( RiaDefines::DateTi
oi++; oi++;
} }
m_values.push_back( wMean ); m_values.push_back( calc.weightedMean() );
} }
} }

View File

@@ -130,12 +130,15 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory( pathCacheName ); QString defaultDir = app->lastUsedDialogDirectory( pathCacheName );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
dialogTitle, dialogTitle,
defaultDir, defaultDir,
m_pathFilter, m_pathFilter,
m_fileNameFilter, m_fileNameFilter,
QStringList( ".xml" ) ); {
RicRecursiveFileSearchDialog::FileType::STIMPLAN_FRACTURE,
} );
// Remember filters // Remember filters
m_pathFilter = result.pathFilter; m_pathFilter = result.pathFilter;

View File

@@ -49,12 +49,13 @@ void RicCreateGridCaseGroupFromFilesFeature::onActionTriggered( bool isChecked )
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory( "INPUT_FILES" ); QString defaultDir = app->lastUsedDialogDirectory( "INPUT_FILES" );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
"Create Grid Case Group", "Create Grid Case Group",
defaultDir, defaultDir,
m_pathFilter, m_pathFilter,
m_fileNameFilter, m_fileNameFilter,
QStringList( ".EGRID" ) ); { RicRecursiveFileSearchDialog::FileType::EGRID } );
// Remember filters // Remember filters
m_pathFilter = result.pathFilter; m_pathFilter = result.pathFilter;

View File

@@ -52,13 +52,14 @@ void RicImportEclipseCasesFeature::onActionTriggered( bool isChecked )
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory( "BINARY_GRID" ); QString defaultDir = app->lastUsedDialogDirectory( "BINARY_GRID" );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
"Import Eclipse Cases", "Import Eclipse Cases",
defaultDir, defaultDir,
m_pathFilter, m_pathFilter,
m_fileNameFilter, m_fileNameFilter,
QStringList() << ".EGRID" { RicRecursiveFileSearchDialog::FileType::EGRID,
<< ".GRID" ); RicRecursiveFileSearchDialog::FileType::GRID } );
// Remember filters // Remember filters
m_pathFilter = result.pathFilter; m_pathFilter = result.pathFilter;

View File

@@ -55,12 +55,13 @@ void RicCreateEnsembleSurfaceFeature::openDialogAndExecuteCommand()
QString pathFilter( "*" ); QString pathFilter( "*" );
QString fileNameFilter( "*" ); QString fileNameFilter( "*" );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
"Choose Eclipse Cases", "Choose Eclipse Cases",
defaultDir, defaultDir,
pathFilter, pathFilter,
fileNameFilter, fileNameFilter,
QStringList( ".EGRID" ) ); { RicRecursiveFileSearchDialog::FileType::EGRID } );
if ( !result.ok || result.files.isEmpty() ) if ( !result.ok || result.files.isEmpty() )
{ {

View File

@@ -71,13 +71,14 @@ void RicCreateEnsembleWellLogFeature::openDialogAndExecuteCommand()
QString pathFilter( "*" ); QString pathFilter( "*" );
QString fileNameFilter( "*" ); QString fileNameFilter( "*" );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
"Choose Eclipse Cases", "Choose Eclipse Cases",
defaultDir, defaultDir,
pathFilter, pathFilter,
fileNameFilter, fileNameFilter,
{ ".GRDECL", ".EGRID" } ); { RicRecursiveFileSearchDialog::FileType::GRDECL,
RicRecursiveFileSearchDialog::FileType::EGRID } );
if ( !result.ok || result.files.isEmpty() ) if ( !result.ok || result.files.isEmpty() )
{ {
return; return;

View File

@@ -22,6 +22,7 @@
#include "RiaEnsembleNameTools.h" #include "RiaEnsembleNameTools.h"
#include "RiaFilePathTools.h" #include "RiaFilePathTools.h"
#include "RiaPreferences.h" #include "RiaPreferences.h"
#include "RiaSummaryDefines.h"
#include "RiaSummaryTools.h" #include "RiaSummaryTools.h"
#include "RiaTextStringTools.h" #include "RiaTextStringTools.h"
@@ -70,15 +71,28 @@ bool RicImportEnsembleFeature::isCommandEnabled()
void RicImportEnsembleFeature::onActionTriggered( bool isChecked ) void RicImportEnsembleFeature::onActionTriggered( bool isChecked )
{ {
QString pathCacheName = "ENSEMBLE_FILES"; QString pathCacheName = "ENSEMBLE_FILES";
auto [fileNames, ensembleGroupingMode] = auto result = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialogWithGrouping( "Import Ensemble", pathCacheName );
RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialogWithGrouping( "Import Ensemble", pathCacheName ); QStringList fileNames = result.files;
RiaEnsembleNameTools::EnsembleGroupingMode ensembleGroupingMode = result.groupingMode;
RiaDefines::FileType fileType = RicRecursiveFileSearchDialog::mapSummaryFileType( result.fileType );
if ( fileNames.isEmpty() ) return; if ( fileNames.isEmpty() ) return;
if ( ensembleGroupingMode == RiaEnsembleNameTools::EnsembleGroupingMode::NONE ) if ( ensembleGroupingMode == RiaEnsembleNameTools::EnsembleGroupingMode::NONE )
{ {
bool useEnsembleNameDialog = true; bool useEnsembleNameDialog = true;
importSingleEnsemble( fileNames, useEnsembleNameDialog, ensembleGroupingMode ); importSingleEnsemble( fileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType );
}
else
{
if ( fileType == RiaDefines::FileType::STIMPLAN_SUMMARY )
{
std::map<QString, QStringList> groupedByEnsemble = RiaEnsembleNameTools::groupFilesByStimPlanEnsemble( fileNames );
for ( const auto& [ensembleName, groupedFileNames] : groupedByEnsemble )
{
bool useEnsembleNameDialog = false;
importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType, ensembleName );
}
} }
else else
{ {
@@ -86,7 +100,8 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked )
for ( const QStringList& groupedFileNames : groupedByEnsemble ) for ( const QStringList& groupedFileNames : groupedByEnsemble )
{ {
bool useEnsembleNameDialog = false; bool useEnsembleNameDialog = false;
importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode ); importSingleEnsemble( groupedFileNames, useEnsembleNameDialog, ensembleGroupingMode, fileType );
}
} }
} }
} }
@@ -96,18 +111,21 @@ void RicImportEnsembleFeature::onActionTriggered( bool isChecked )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicImportEnsembleFeature::importSingleEnsemble( const QStringList& fileNames, void RicImportEnsembleFeature::importSingleEnsemble( const QStringList& fileNames,
bool useEnsembleNameDialog, bool useEnsembleNameDialog,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode ) RiaEnsembleNameTools::EnsembleGroupingMode groupingMode,
RiaDefines::FileType fileType,
const QString& defaultEnsembleName )
{ {
QString ensembleName = RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, groupingMode ); QString ensembleName = !defaultEnsembleName.isEmpty() ? defaultEnsembleName
: RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, groupingMode );
if ( useEnsembleNameDialog ) ensembleName = askForEnsembleName( ensembleName ); if ( useEnsembleNameDialog ) ensembleName = askForEnsembleName( ensembleName );
if ( ensembleName.isEmpty() ) return; if ( ensembleName.isEmpty() ) return;
std::vector<RimSummaryCase*> cases; RicImportSummaryCasesFeature::CreateConfig createConfig{ .fileType = fileType, .ensembleOrGroup = true, .allowDialogs = true };
RicImportSummaryCasesFeature::createSummaryCasesFromFiles( fileNames, &cases, true ); auto [isOk, cases] = RicImportSummaryCasesFeature::createSummaryCasesFromFiles( fileNames, createConfig );
if ( cases.empty() ) return; if ( !isOk || cases.empty() ) return;
RimSummaryCaseCollection* ensemble = RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, ensembleName, true ); RimSummaryCaseCollection* ensemble = RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, ensembleName, true );
@@ -124,7 +142,7 @@ void RicImportEnsembleFeature::importSingleEnsemble( const QStringList&
std::vector<RimCase*> allCases; std::vector<RimCase*> allCases;
RiaApplication::instance()->project()->allCases( allCases ); RiaApplication::instance()->project()->allCases( allCases );
if ( allCases.size() == 0 ) if ( allCases.empty() )
{ {
RiuMainWindow::closeIfOpen(); RiuMainWindow::closeIfOpen();
} }

View File

@@ -19,6 +19,7 @@
#pragma once #pragma once
#include "RiaEnsembleNameTools.h" #include "RiaEnsembleNameTools.h"
#include "RiaSummaryDefines.h"
#include "cafCmdFeature.h" #include "cafCmdFeature.h"
@@ -41,5 +42,7 @@ protected:
static QString askForEnsembleName( const QString& suggestion ); static QString askForEnsembleName( const QString& suggestion );
static void importSingleEnsemble( const QStringList& fileNames, static void importSingleEnsemble( const QStringList& fileNames,
bool useEnsembleNameDialog, bool useEnsembleNameDialog,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode ); RiaEnsembleNameTools::EnsembleGroupingMode groupingMode,
RiaDefines::FileType fileType,
const QString& defaultEnsembleName = QString() );
}; };

View File

@@ -188,13 +188,13 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory( pathCacheName ); QString defaultDir = app->lastUsedDialogDirectory( pathCacheName );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
dialogTitle, dialogTitle,
defaultDir, defaultDir,
m_pathFilter, m_pathFilter,
m_fileNameFilter, m_fileNameFilter,
QStringList() << ".TS" { RicRecursiveFileSearchDialog::FileType::SURFACE } );
<< ".ts" );
// Remember filters // Remember filters
m_pathFilter = result.pathFilter; m_pathFilter = result.pathFilter;

View File

@@ -138,13 +138,13 @@ std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode>
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory( pathCacheName ); QString defaultDir = app->lastUsedDialogDirectory( pathCacheName );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, RicRecursiveFileSearchDialogResult result =
RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr,
dialogTitle, dialogTitle,
defaultDir, defaultDir,
m_pathFilter, m_pathFilter,
m_fileNameFilter, m_fileNameFilter,
QStringList() << ".LAS" { RicRecursiveFileSearchDialog::FileType::LAS } );
<< ".las" );
// Remember filters // Remember filters
m_pathFilter = result.pathFilter; m_pathFilter = result.pathFilter;

View File

@@ -353,8 +353,8 @@ bool RicImportGeneralDataFeature::openInputEclipseCaseFromFileNames( const QStri
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RicImportGeneralDataFeature::openSummaryCaseFromFileNames( const QStringList& fileNames, bool doCreateDefaultPlot ) bool RicImportGeneralDataFeature::openSummaryCaseFromFileNames( const QStringList& fileNames, bool doCreateDefaultPlot )
{ {
std::vector<RimSummaryCase*> newCases; auto [isOk, newCases] = RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles( fileNames, doCreateDefaultPlot );
if ( RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles( fileNames, doCreateDefaultPlot, &newCases ) ) if ( isOk )
{ {
RicImportSummaryCasesFeature::addCasesToGroupIfRelevant( newCases ); RicImportSummaryCasesFeature::addCasesToGroupIfRelevant( newCases );
for ( const RimSummaryCase* newCase : newCases ) for ( const RimSummaryCase* newCase : newCases )

View File

@@ -18,6 +18,7 @@
#include "RicImportSummaryCasesFeature.h" #include "RicImportSummaryCasesFeature.h"
#include "RiaSummaryDefines.h"
#include "SummaryPlotCommands/RicNewSummaryCurveFeature.h" #include "SummaryPlotCommands/RicNewSummaryCurveFeature.h"
#include "RiaGuiApplication.h" #include "RiaGuiApplication.h"
@@ -75,10 +76,17 @@ void RicImportSummaryCasesFeature::onActionTriggered( bool isChecked )
{ {
RiaGuiApplication* app = RiaGuiApplication::instance(); RiaGuiApplication* app = RiaGuiApplication::instance();
QString pathCacheName = "INPUT_FILES"; QString pathCacheName = "INPUT_FILES";
QStringList fileNames = runRecursiveSummaryCaseFileSearchDialog( "Import Summary Cases", pathCacheName ); auto result = runRecursiveSummaryCaseFileSearchDialog( "Import Summary Cases", pathCacheName );
QStringList fileNames = result.files;
RiaDefines::FileType fileType = RicRecursiveFileSearchDialog::mapSummaryFileType( result.fileType );
std::vector<RimSummaryCase*> cases; std::vector<RimSummaryCase*> cases;
if ( !fileNames.isEmpty() ) createSummaryCasesFromFiles( fileNames, &cases );
if ( !fileNames.isEmpty() )
{
CreateConfig createConfig{ .fileType = fileType, .ensembleOrGroup = false, .allowDialogs = true };
auto [isOk, cases] = createSummaryCasesFromFiles( fileNames, createConfig );
}
addSummaryCases( cases ); addSummaryCases( cases );
if ( !cases.empty() ) if ( !cases.empty() )
@@ -121,21 +129,21 @@ void RicImportSummaryCasesFeature::setupActionLook( QAction* actionToSetup )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles( const QStringList& fileNames, std::pair<bool, std::vector<RimSummaryCase*>> RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles( const QStringList& fileNames,
bool doCreateDefaultPlot, bool doCreateDefaultPlot )
std::vector<RimSummaryCase*>* newCases )
{ {
RiaGuiApplication* app = RiaGuiApplication::instance(); RiaGuiApplication* app = RiaGuiApplication::instance();
std::vector<RimSummaryCase*> temp; CreateConfig createConfig{ .fileType = RiaDefines::FileType::SMSPEC, .ensembleOrGroup = false, .allowDialogs = true };
std::vector<RimSummaryCase*>* cases = newCases ? newCases : &temp; auto [isOk, cases] = createSummaryCasesFromFiles( fileNames, createConfig );
if ( createSummaryCasesFromFiles( fileNames, cases ) ) if ( isOk )
{ {
addSummaryCases( *cases ); addSummaryCases( cases );
if ( !cases->empty() && doCreateDefaultPlot ) if ( !cases.empty() && doCreateDefaultPlot )
{ {
RimSummaryMultiPlot* plotToSelect = nullptr; RimSummaryMultiPlot* plotToSelect = nullptr;
for ( auto sumCase : *cases ) for ( auto sumCase : cases )
{ {
plotToSelect = RicSummaryPlotBuilder::createAndAppendDefaultSummaryMultiPlot( { sumCase }, {} ); plotToSelect = RicSummaryPlotBuilder::createAndAppendDefaultSummaryMultiPlot( { sumCase }, {} );
} }
@@ -147,7 +155,7 @@ bool RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles( const QStr
} }
RiuPlotMainWindow* mainPlotWindow = app->getOrCreateAndShowMainPlotWindow(); RiuPlotMainWindow* mainPlotWindow = app->getOrCreateAndShowMainPlotWindow();
if ( mainPlotWindow && !cases->empty() ) if ( mainPlotWindow && !cases.empty() )
{ {
mainPlotWindow->updateMultiPlotToolBar(); mainPlotWindow->updateMultiPlotToolBar();
@@ -160,53 +168,64 @@ bool RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles( const QStr
RiuMainWindow::closeIfOpen(); RiuMainWindow::closeIfOpen();
} }
} }
return true; return std::make_pair( true, cases );
} }
return false; return std::make_pair( false, cases );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RicImportSummaryCasesFeature::createSummaryCasesFromFiles( const QStringList& fileNames, std::pair<bool, std::vector<RimSummaryCase*>> RicImportSummaryCasesFeature::createSummaryCasesFromFiles( const QStringList& fileNames,
std::vector<RimSummaryCase*>* newCases, CreateConfig createConfig )
bool ensembleOrGroup,
bool allowDialogs )
{ {
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
RimProject* proj = app->project(); RimProject* proj = app->project();
RimSummaryCaseMainCollection* sumCaseColl = proj->activeOilField() ? proj->activeOilField()->summaryCaseMainCollection() : nullptr; RimSummaryCaseMainCollection* sumCaseColl = proj->activeOilField() ? proj->activeOilField()->summaryCaseMainCollection() : nullptr;
if ( newCases ) newCases->clear(); std::vector<RimSummaryCase*> newCases;
if ( !sumCaseColl ) return false;
if ( !sumCaseColl ) return std::make_pair( false, newCases );
std::vector<RifSummaryCaseFileResultInfo> importFileInfos;
if ( createConfig.fileType == RiaDefines::FileType::SMSPEC )
{
RifSummaryCaseRestartSelector fileSelector; RifSummaryCaseRestartSelector fileSelector;
if ( !RiaGuiApplication::isRunning() || !allowDialogs ) if ( !RiaGuiApplication::isRunning() || !createConfig.allowDialogs )
{ {
fileSelector.showDialog( false ); fileSelector.showDialog( false );
} }
fileSelector.setEnsembleOrGroupMode( ensembleOrGroup ); fileSelector.setEnsembleOrGroupMode( createConfig.ensembleOrGroup );
fileSelector.determineFilesToImportFromSummaryFiles( fileNames ); fileSelector.determineFilesToImportFromSummaryFiles( fileNames );
std::vector<RifSummaryCaseFileResultInfo> importFileInfos = fileSelector.summaryFileInfos(); importFileInfos = fileSelector.summaryFileInfos();
if ( !importFileInfos.empty() )
{
std::vector<RimSummaryCase*> sumCases = sumCaseColl->createSummaryCasesFromFileInfos( importFileInfos, true );
if ( newCases ) newCases->insert( newCases->end(), sumCases.begin(), sumCases.end() );
}
if ( fileSelector.foundErrors() ) if ( fileSelector.foundErrors() )
{ {
QString errorMessage = fileSelector.createCombinedErrorMessage(); QString errorMessage = fileSelector.createCombinedErrorMessage();
RiaLogging::error( errorMessage ); RiaLogging::error( errorMessage );
} }
}
else
{
// No restart files for these file types: just copy to result info
for ( auto f : fileNames )
{
importFileInfos.push_back( RifSummaryCaseFileResultInfo( f, false, createConfig.fileType ) );
}
}
return true; if ( !importFileInfos.empty() )
{
std::vector<RimSummaryCase*> sumCases = sumCaseColl->createSummaryCasesFromFileInfos( importFileInfos, true );
newCases.insert( newCases.end(), sumCases.begin(), sumCases.end() );
}
return std::make_pair( true, newCases );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -258,36 +277,36 @@ void RicImportSummaryCasesFeature::addCasesToGroupIfRelevant( const std::vector<
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode> RicRecursiveFileSearchDialogResult
RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialogWithGrouping( const QString& dialogTitle, const QString& pathCacheName ) RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialogWithGrouping( const QString& dialogTitle, const QString& pathCacheName )
{ {
RiaApplication* app = RiaApplication::instance(); RiaApplication* app = RiaApplication::instance();
QString defaultDir = app->lastUsedDialogDirectory( pathCacheName ); QString defaultDir = app->lastUsedDialogDirectory( pathCacheName );
RicRecursiveFileSearchDialogResult result = RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, auto fileTypes = { RicRecursiveFileSearchDialog::FileType::SMSPEC,
dialogTitle, RicRecursiveFileSearchDialog::FileType::REVEAL_SUMMARY,
defaultDir, RicRecursiveFileSearchDialog::FileType::STIMPLAN_SUMMARY };
m_pathFilter,
m_fileNameFilter, RicRecursiveFileSearchDialogResult result =
QStringList( ".SMSPEC" ) ); RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, dialogTitle, defaultDir, m_pathFilter, m_fileNameFilter, fileTypes );
// Remember filters // Remember filters
m_pathFilter = result.pathFilter; m_pathFilter = result.pathFilter;
m_fileNameFilter = result.fileNameFilter; m_fileNameFilter = result.fileNameFilter;
if ( !result.ok ) return std::make_pair( QStringList(), RiaEnsembleNameTools::EnsembleGroupingMode::NONE ); if ( !result.ok ) return result;
// Remember the path to next time // Remember the path to next time
app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() ); app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() );
return std::make_pair( result.files, result.groupingMode ); return result;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QStringList RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName ) RicRecursiveFileSearchDialogResult RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName )
{ {
auto result = runRecursiveSummaryCaseFileSearchDialogWithGrouping( dialogTitle, pathCacheName ); return runRecursiveSummaryCaseFileSearchDialogWithGrouping( dialogTitle, pathCacheName );
return result.first;
} }

View File

@@ -19,7 +19,9 @@
#pragma once #pragma once
#include "RiaEnsembleNameTools.h" #include "RiaEnsembleNameTools.h"
#include "RiaSummaryDefines.h"
#include "RicRecursiveFileSearchDialog.h"
#include "cafCmdFeature.h" #include "cafCmdFeature.h"
#include <QString> #include <QString>
@@ -38,20 +40,26 @@ class RicImportSummaryCasesFeature : public caf::CmdFeature
public: public:
RicImportSummaryCasesFeature() {} RicImportSummaryCasesFeature() {}
static bool createAndAddSummaryCasesFromFiles( const QStringList& fileName, static std::pair<bool, std::vector<RimSummaryCase*>> createAndAddSummaryCasesFromFiles( const QStringList& fileName,
bool doCreateDefaultPlot, bool doCreateDefaultPlot );
std::vector<RimSummaryCase*>* newCases = nullptr );
static bool createSummaryCasesFromFiles( const QStringList& fileName, struct CreateConfig
std::vector<RimSummaryCase*>* newCases, {
bool ensembleOrGroup = false, RiaDefines::FileType fileType;
bool allowDialogs = true ); bool ensembleOrGroup;
bool allowDialogs;
};
static std::pair<bool, std::vector<RimSummaryCase*>> createSummaryCasesFromFiles( const QStringList& fileName, CreateConfig createConfig );
static void addSummaryCases( const std::vector<RimSummaryCase*>& cases ); static void addSummaryCases( const std::vector<RimSummaryCase*>& cases );
static void addCasesToGroupIfRelevant( const std::vector<RimSummaryCase*>& cases ); static void addCasesToGroupIfRelevant( const std::vector<RimSummaryCase*>& cases );
static QStringList runRecursiveSummaryCaseFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName ); static RicRecursiveFileSearchDialogResult runRecursiveSummaryCaseFileSearchDialog( const QString& dialogTitle,
const QString& pathCacheName );
static std::pair<QStringList, RiaEnsembleNameTools::EnsembleGroupingMode> static RicRecursiveFileSearchDialogResult runRecursiveSummaryCaseFileSearchDialogWithGrouping( const QString& dialogTitle,
runRecursiveSummaryCaseFileSearchDialogWithGrouping( const QString& dialogTitle, const QString& pathCacheName ); const QString& pathCacheName );
protected: protected:
bool isCommandEnabled() override; bool isCommandEnabled() override;

View File

@@ -21,6 +21,7 @@
#include "RiaGuiApplication.h" #include "RiaGuiApplication.h"
#include "RiaPreferences.h" #include "RiaPreferences.h"
#include "RiaSummaryDefines.h"
#include "RicCreateSummaryCaseCollectionFeature.h" #include "RicCreateSummaryCaseCollectionFeature.h"
#include "RicImportSummaryCasesFeature.h" #include "RicImportSummaryCasesFeature.h"
@@ -55,12 +56,14 @@ void RicImportSummaryGroupFeature::onActionTriggered( bool isChecked )
{ {
RiaGuiApplication* app = RiaGuiApplication::instance(); RiaGuiApplication* app = RiaGuiApplication::instance();
QString pathCacheName = "INPUT_FILES"; QString pathCacheName = "INPUT_FILES";
QStringList fileNames = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog( "Import Summary Case Group", pathCacheName ); auto result = RicImportSummaryCasesFeature::runRecursiveSummaryCaseFileSearchDialog( "Import Summary Case Group", pathCacheName );
QStringList fileNames = result.files;
if ( fileNames.isEmpty() ) return; if ( fileNames.isEmpty() ) return;
std::vector<RimSummaryCase*> cases; RiaDefines::FileType fileType = RicRecursiveFileSearchDialog::mapSummaryFileType( result.fileType );
RicImportSummaryCasesFeature::createSummaryCasesFromFiles( fileNames, &cases, true );
RicImportSummaryCasesFeature::CreateConfig createConfig{ .fileType = fileType, .ensembleOrGroup = true, .allowDialogs = true };
auto [isOk, cases] = RicImportSummaryCasesFeature::createSummaryCasesFromFiles( fileNames, createConfig );
RicImportSummaryCasesFeature::addSummaryCases( cases ); RicImportSummaryCasesFeature::addSummaryCases( cases );
RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, "", false ); RicCreateSummaryCaseCollectionFeature::groupSummaryCases( cases, "", false );

View File

@@ -25,6 +25,7 @@
#include "RiuFileDialogTools.h" #include "RiuFileDialogTools.h"
#include "RiuTools.h" #include "RiuTools.h"
#include "opm/io/eclipse/EclUtil.hpp"
#include <QAbstractItemView> #include <QAbstractItemView>
#include <QAction> #include <QAction>
@@ -58,7 +59,6 @@
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Internal functions /// Internal functions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
static QStringList trimLeftStrings( const QStringList& strings, const QString& trimText );
static void sortStringsByLength( QStringList& strings, bool ascending = true ); static void sortStringsByLength( QStringList& strings, bool ascending = true );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -69,14 +69,14 @@ RicRecursiveFileSearchDialogResult RicRecursiveFileSearchDialog::runRecursiveSea
const QString& dir, const QString& dir,
const QString& pathFilter, const QString& pathFilter,
const QString& fileNameFilter, const QString& fileNameFilter,
const QStringList& fileExtensions ) const std::vector<FileType>& fileTypes )
{ {
const QString filePathRegistryKey = QString( "RicRecursiveFileSearchDialog %1" ).arg( caption ).replace( " ", "_" ); const QString filePathRegistryKey = QString( "RicRecursiveFileSearchDialog %1" ).arg( caption ).replace( " ", "_" );
const QString fileFilterRegistryKey = QString( "RicRecursiveFileSearchDialog file filter %1" ).arg( caption ).replace( " ", "_" ); const QString fileFilterRegistryKey = QString( "RicRecursiveFileSearchDialog file filter %1" ).arg( caption ).replace( " ", "_" );
const QString useRealizationStarRegistryKey = "RecursiveFileSearchDialog_use_realization"; const QString useRealizationStarRegistryKey = "RecursiveFileSearchDialog_use_realization";
QSettings settings; QSettings settings;
RicRecursiveFileSearchDialog dialog( parent, fileExtensions ); RicRecursiveFileSearchDialog dialog( parent, fileTypes );
{ {
QSignalBlocker signalBlocker( dialog.m_pathFilterField ); QSignalBlocker signalBlocker( dialog.m_pathFilterField );
QSignalBlocker signalBlocker2( dialog.m_ensembleGroupingMode ); QSignalBlocker signalBlocker2( dialog.m_ensembleGroupingMode );
@@ -89,8 +89,11 @@ RicRecursiveFileSearchDialogResult RicRecursiveFileSearchDialog::runRecursiveSea
dialog.m_fileFilterField->addItem( fileNameFilter ); dialog.m_fileFilterField->addItem( fileNameFilter );
dialog.m_pathFilterField->addItem( QDir::toNativeSeparators( pathFilterText ) ); dialog.m_pathFilterField->addItem( QDir::toNativeSeparators( pathFilterText ) );
QString joined = fileExtensions.join( '|' ); for ( const auto& fileType : fileTypes )
dialog.m_fileExtensionsField->setText( joined ); {
QString item = QString( "%1 (%2)" ).arg( fileNameForType( fileType ) ).arg( fileExtensionForType( fileType ) );
dialog.m_fileTypeField->addItem( item, static_cast<int>( fileType ) );
}
dialog.m_fileFilterField->addItem( fileNameFilter ); dialog.m_fileFilterField->addItem( fileNameFilter );
@@ -107,7 +110,11 @@ RicRecursiveFileSearchDialogResult RicRecursiveFileSearchDialog::runRecursiveSea
dialog.m_pathFilterField->setCurrentText( QDir::toNativeSeparators( pathFilterText ) ); dialog.m_pathFilterField->setCurrentText( QDir::toNativeSeparators( pathFilterText ) );
dialog.m_pathFilterField->setEditable( true ); dialog.m_pathFilterField->setEditable( true );
dialog.m_fileExtensions = trimLeftStrings( fileExtensions, "." ); if ( !fileTypes.empty() )
{
dialog.m_fileExtensions = QStringList( fileExtensionForType( fileTypes.front() ) );
dialog.m_fileType = fileTypes.front();
}
for ( const auto& s : caf::AppEnum<RiaEnsembleNameTools::EnsembleGroupingMode>::uiTexts() ) for ( const auto& s : caf::AppEnum<RiaEnsembleNameTools::EnsembleGroupingMode>::uiTexts() )
{ {
@@ -144,15 +151,16 @@ RicRecursiveFileSearchDialogResult RicRecursiveFileSearchDialog::runRecursiveSea
dialog.rootDirWithEndSeparator(), dialog.rootDirWithEndSeparator(),
dialog.pathFilterWithoutStartSeparator(), dialog.pathFilterWithoutStartSeparator(),
dialog.fileNameFilter(), dialog.fileNameFilter(),
dialog.fileType(),
dialog.ensembleGroupingMode() ); dialog.ensembleGroupingMode() );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, const QStringList& fileExtensions ) RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, const std::vector<FileType>& fileTypes )
: QDialog( parent, RiuTools::defaultDialogFlags() ) : QDialog( parent, RiuTools::defaultDialogFlags() )
, m_incomingFileExtensions( fileExtensions ) , m_incomingFileTypes( fileTypes )
{ {
// Create widgets // Create widgets
m_browseButton = new QPushButton(); m_browseButton = new QPushButton();
@@ -164,8 +172,10 @@ RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, con
m_pathFilterField = new QComboBox(); m_pathFilterField = new QComboBox();
m_fileFilterLabel = new QLabel(); m_fileFilterLabel = new QLabel();
m_fileFilterField = new QComboBox(); m_fileFilterField = new QComboBox();
m_fileExtensionsLabel = new QLabel(); m_fileTypeLabel = new QLabel();
m_fileExtensionsField = new QLineEdit(); m_fileTypeField = new QComboBox();
m_fileExtensionLabel = new QLabel();
m_fileExtensionField = new QLineEdit();
m_effectiveFilterLabel = new QLabel(); m_effectiveFilterLabel = new QLabel();
m_effectiveFilterContentLabel = new QLabel(); m_effectiveFilterContentLabel = new QLabel();
m_ensembleGroupingMode = new QComboBox(); m_ensembleGroupingMode = new QComboBox();
@@ -183,7 +193,9 @@ RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, con
connect( m_fileFilterField, SIGNAL( currentTextChanged( const QString& ) ), this, SLOT( slotFileFilterChanged( const QString& ) ) ); connect( m_fileFilterField, SIGNAL( currentTextChanged( const QString& ) ), this, SLOT( slotFileFilterChanged( const QString& ) ) );
connect( m_fileFilterField, SIGNAL( editTextChanged( const QString& ) ), this, SLOT( slotFileFilterChanged( const QString& ) ) ); connect( m_fileFilterField, SIGNAL( editTextChanged( const QString& ) ), this, SLOT( slotFileFilterChanged( const QString& ) ) );
connect( m_fileExtensionsField, SIGNAL( editingFinished() ), this, SLOT( slotFileExtensionsChanged() ) ); connect( m_fileTypeField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( slotFileTypeChanged( int ) ) );
connect( m_fileExtensionField, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotFileExtensionChanged( const QString& ) ) );
connect( m_fileListWidget, connect( m_fileListWidget,
SIGNAL( customContextMenuRequested( const QPoint& ) ), SIGNAL( customContextMenuRequested( const QPoint& ) ),
@@ -200,7 +212,8 @@ RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, con
// Set widget properties // Set widget properties
m_pathFilterLabel->setText( "Path pattern" ); m_pathFilterLabel->setText( "Path pattern" );
m_fileFilterLabel->setText( "File pattern" ); m_fileFilterLabel->setText( "File pattern" );
m_fileExtensionsLabel->setText( "File Extensions" ); m_fileTypeLabel->setText( "File type" );
m_fileExtensionLabel->setText( "File extension" );
m_effectiveFilterLabel->setText( "Effective filter" ); m_effectiveFilterLabel->setText( "Effective filter" );
m_searchRootLabel->setText( "Root" ); m_searchRootLabel->setText( "Root" );
m_searchRootLabel->setVisible( false ); m_searchRootLabel->setVisible( false );
@@ -236,8 +249,12 @@ RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, con
inputGridLayout->addWidget( m_fileFilterField, row, 1, 1, 2 ); inputGridLayout->addWidget( m_fileFilterField, row, 1, 1, 2 );
row++; row++;
inputGridLayout->addWidget( m_fileExtensionsLabel, row, 0 ); inputGridLayout->addWidget( m_fileTypeLabel, row, 0 );
inputGridLayout->addWidget( m_fileExtensionsField, row, 1, 1, 2 ); inputGridLayout->addWidget( m_fileTypeField, row, 1, 1, 2 );
row++;
inputGridLayout->addWidget( m_fileExtensionLabel, row, 0 );
inputGridLayout->addWidget( m_fileExtensionField, row, 1, 1, 2 );
row++; row++;
{ {
@@ -291,8 +308,8 @@ RicRecursiveFileSearchDialog::RicRecursiveFileSearchDialog( QWidget* parent, con
{ {
QString text = "Define the extension using \".EGRID|.GRDECL\""; QString text = "Define the extension using \".EGRID|.GRDECL\"";
m_fileExtensionsLabel->setToolTip( text ); m_fileExtensionLabel->setToolTip( text );
m_fileExtensionsField->setToolTip( text ); m_fileExtensionField->setToolTip( text );
} }
{ {
@@ -383,6 +400,14 @@ QStringList RicRecursiveFileSearchDialog::fileExtensions() const
return exts; return exts;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicRecursiveFileSearchDialog::FileType RicRecursiveFileSearchDialog::fileType() const
{
return m_fileType;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -406,6 +431,17 @@ void RicRecursiveFileSearchDialog::updateFileListWidget()
m_fileListWidget->clear(); m_fileListWidget->clear();
if ( ensembleGroupingMode() != RiaEnsembleNameTools::EnsembleGroupingMode::NONE ) if ( ensembleGroupingMode() != RiaEnsembleNameTools::EnsembleGroupingMode::NONE )
{
if ( m_fileType == RicRecursiveFileSearchDialog::FileType::STIMPLAN_SUMMARY )
{
std::map<QString, QStringList> groupedByEnsemble = RiaEnsembleNameTools::groupFilesByStimPlanEnsemble( m_foundFiles );
for ( auto [ensembleName, groupedFileNames] : groupedByEnsemble )
{
new QListWidgetItem( QDir::toNativeSeparators( ensembleName ), m_fileListWidget );
addToFileListWidget( groupedFileNames );
}
}
else
{ {
std::vector<QStringList> groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( m_foundFiles, ensembleGroupingMode() ); std::vector<QStringList> groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( m_foundFiles, ensembleGroupingMode() );
for ( const QStringList& groupedFileNames : groupedByEnsemble ) for ( const QStringList& groupedFileNames : groupedByEnsemble )
@@ -415,6 +451,7 @@ void RicRecursiveFileSearchDialog::updateFileListWidget()
addToFileListWidget( groupedFileNames ); addToFileListWidget( groupedFileNames );
} }
} }
}
else else
{ {
addToFileListWidget( m_foundFiles ); addToFileListWidget( m_foundFiles );
@@ -720,12 +757,24 @@ void RicRecursiveFileSearchDialog::slotFileFilterChanged( const QString& text )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicRecursiveFileSearchDialog::slotFileExtensionsChanged() void RicRecursiveFileSearchDialog::slotFileTypeChanged( int index )
{ {
QStringList items = m_fileExtensionsField->text().split( '|' ); m_fileType = static_cast<FileType>( m_fileTypeField->itemData( index ).toInt() );
m_fileExtensions = trimLeftStrings( items, "." ); QString extension = fileExtensionForType( m_fileType );
m_fileExtensions = QStringList( extension );
m_fileExtensionField->setText( extension );
updateEffectiveFilter();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicRecursiveFileSearchDialog::slotFileExtensionChanged( const QString& text )
{
m_fileExtensions = QStringList( text );
updateEffectiveFilter(); updateEffectiveFilter();
} }
@@ -933,28 +982,23 @@ RiaEnsembleNameTools::EnsembleGroupingMode RicRecursiveFileSearchDialog::ensembl
return RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE; return RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE;
} }
//--------------------------------------------------------------------------------------------------
/// Internal functions
//--------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QStringList trimLeftStrings( const QStringList& strings, const QString& trimText ) QStringList RicRecursiveFileSearchDialog::fileTypeToExtensionStrings( const std::vector<RicRecursiveFileSearchDialog::FileType>& fileTypes )
{ {
QStringList trimmedStrings; QStringList extensions;
for ( const auto& string : strings ) for ( const auto& f : fileTypes )
{ {
QString trimmedString = string; extensions.append( RicRecursiveFileSearchDialog::fileExtensionForType( f ) );
if ( string.startsWith( trimText ) )
{
trimmedString = string.right( string.size() - trimText.size() );
} }
trimmedStrings.append( trimmedString ); return extensions;
}
return trimmedStrings;
} }
//--------------------------------------------------------------------------------------------------
/// Internal functions
//--------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -1042,3 +1086,84 @@ bool RicRecursiveFileSearchDialog::pathFilterMatch( const QString& pathFilter, c
QRegExp regexp( pattern, Qt::CaseInsensitive, QRegExp::Wildcard ); QRegExp regexp( pattern, Qt::CaseInsensitive, QRegExp::Wildcard );
return regexp.exactMatch( relPath ); return regexp.exactMatch( relPath );
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicRecursiveFileSearchDialog::fileExtensionForType( FileType fileType )
{
switch ( fileType )
{
case FileType::GRDECL:
return "GRDECL";
case FileType::EGRID:
return "EGRID";
case FileType::GRID:
return "GRID";
case FileType::SMSPEC:
return "SMSPEC";
case FileType::STIMPLAN_FRACTURE:
return "XML";
case FileType::LAS:
return "LAS";
case FileType::SURFACE:
return "TS";
case FileType::STIMPLAN_SUMMARY:
return "CSV";
case FileType::REVEAL_SUMMARY:
return "CSV";
default:
return "*";
}
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicRecursiveFileSearchDialog::fileNameForType( FileType fileType )
{
switch ( fileType )
{
case FileType::GRDECL:
return "Eclipse Text File";
case FileType::EGRID:
return "Eclipse Grid File";
case FileType::GRID:
return "Eclipse Grid File";
case FileType::SMSPEC:
return "Eclipse Summary File";
case FileType::STIMPLAN_FRACTURE:
return "StimPlan Fracture";
case FileType::LAS:
return "LAS File";
case FileType::SURFACE:
return "Surface File";
case FileType::STIMPLAN_SUMMARY:
return "StimPlan Summary File";
case FileType::REVEAL_SUMMARY:
return "Reveal Summary File";
default:
return "*";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::FileType RicRecursiveFileSearchDialog::mapSummaryFileType( RicRecursiveFileSearchDialog::FileType fileType )
{
switch ( fileType )
{
case RicRecursiveFileSearchDialog::FileType::SMSPEC:
return RiaDefines::FileType::SMSPEC;
case RicRecursiveFileSearchDialog::FileType::REVEAL_SUMMARY:
return RiaDefines::FileType::REVEAL_SUMMARY;
case RicRecursiveFileSearchDialog::FileType::STIMPLAN_SUMMARY:
return RiaDefines::FileType::STIMPLAN_SUMMARY;
default:
{
CAF_ASSERT( false && "Unsupported file type" );
return RiaDefines::FileType::SMSPEC;
}
}
}

View File

@@ -23,6 +23,8 @@
#include "cafPdmPointer.h" #include "cafPdmPointer.h"
#include "RiaEnsembleNameTools.h" #include "RiaEnsembleNameTools.h"
#include "RiaSummaryDefines.h"
#include <QDialog> #include <QDialog>
class QLabel; class QLabel;
@@ -44,7 +46,7 @@ class RicRecursiveFileSearchDialogResult;
class RicRecursiveFileSearchDialog : public QDialog class RicRecursiveFileSearchDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public:
enum Status enum Status
{ {
SEARCHING_FOR_DIRS, SEARCHING_FOR_DIRS,
@@ -52,22 +54,40 @@ class RicRecursiveFileSearchDialog : public QDialog
NO_FILES_FOUND NO_FILES_FOUND
}; };
public: enum class FileType
static RicRecursiveFileSearchDialogResult runRecursiveSearchDialog( QWidget* parent = nullptr, {
const QString& caption = QString(), GRDECL,
const QString& dir = QString(), EGRID,
const QString& pathFilter = QString(), GRID,
const QString& fileNameFilter = QString(), SMSPEC,
const QStringList& fileExtensions = QStringList() ); STIMPLAN_FRACTURE,
LAS,
SURFACE,
STIMPLAN_SUMMARY,
REVEAL_SUMMARY
};
static RicRecursiveFileSearchDialogResult runRecursiveSearchDialog( QWidget* parent,
const QString& caption,
const QString& dir,
const QString& pathFilter,
const QString& fileNameFilter,
const std::vector<FileType>& fileTypes );
static QString fileNameForType( FileType fileType );
static QString fileExtensionForType( FileType fileType );
static RiaDefines::FileType mapSummaryFileType( RicRecursiveFileSearchDialog::FileType fileType );
private: private:
RicRecursiveFileSearchDialog( QWidget* parent, const QStringList& fileExtensions ); RicRecursiveFileSearchDialog( QWidget* parent, const std::vector<FileType>& fileTypes );
~RicRecursiveFileSearchDialog() override; ~RicRecursiveFileSearchDialog() override;
QString cleanTextFromPathFilterField() const; QString cleanTextFromPathFilterField() const;
QString rootDirWithEndSeparator() const; QString rootDirWithEndSeparator() const;
QString pathFilterWithoutStartSeparator() const; QString pathFilterWithoutStartSeparator() const;
QString fileNameFilter() const; QString fileNameFilter() const;
FileType fileType() const;
QStringList fileExtensions() const; QStringList fileExtensions() const;
QString extensionFromFileNameFilter() const; QString extensionFromFileNameFilter() const;
@@ -93,10 +113,13 @@ private:
static void populateComboBoxHistoryFromRegistry( QComboBox* comboBox, const QString& registryKey ); static void populateComboBoxHistoryFromRegistry( QComboBox* comboBox, const QString& registryKey );
static QStringList fileTypeToExtensionStrings( const std::vector<RicRecursiveFileSearchDialog::FileType>& fileTypes );
private slots: private slots:
void slotPathFilterChanged( const QString& text ); void slotPathFilterChanged( const QString& text );
void slotFileFilterChanged( const QString& text ); void slotFileFilterChanged( const QString& text );
void slotFileExtensionsChanged(); void slotFileExtensionChanged( const QString& text );
void slotFileTypeChanged( int );
void slotBrowseButtonClicked(); void slotBrowseButtonClicked();
void slotUseRealizationStarClicked(); void slotUseRealizationStarClicked();
void slotFindOrCancelButtonClicked(); void slotFindOrCancelButtonClicked();
@@ -119,8 +142,11 @@ private:
QLabel* m_fileFilterLabel; QLabel* m_fileFilterLabel;
QComboBox* m_fileFilterField; QComboBox* m_fileFilterField;
QLabel* m_fileExtensionsLabel; QLabel* m_fileTypeLabel;
QLineEdit* m_fileExtensionsField; QComboBox* m_fileTypeField;
QLabel* m_fileExtensionLabel;
QLineEdit* m_fileExtensionField;
QLabel* m_effectiveFilterLabel; QLabel* m_effectiveFilterLabel;
QLabel* m_effectiveFilterContentLabel; QLabel* m_effectiveFilterContentLabel;
@@ -136,8 +162,9 @@ private:
QDialogButtonBox* m_buttons; QDialogButtonBox* m_buttons;
QStringList m_foundFiles; QStringList m_foundFiles;
const QStringList m_incomingFileExtensions; std::vector<FileType> m_incomingFileTypes;
QStringList m_fileExtensions; QStringList m_fileExtensions;
FileType m_fileType;
bool m_isCancelPressed; bool m_isCancelPressed;
@@ -157,12 +184,14 @@ public:
const QString& rootDir, const QString& rootDir,
const QString& pathFilter, const QString& pathFilter,
const QString& fileNameFilter, const QString& fileNameFilter,
RicRecursiveFileSearchDialog::FileType fileType,
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode ) RiaEnsembleNameTools::EnsembleGroupingMode groupingMode )
: ok( ok ) : ok( ok )
, files( files ) , files( files )
, rootDir( rootDir ) , rootDir( rootDir )
, pathFilter( pathFilter ) , pathFilter( pathFilter )
, fileNameFilter( fileNameFilter ) , fileNameFilter( fileNameFilter )
, fileType( fileType )
, groupingMode( groupingMode ) , groupingMode( groupingMode )
{ {
} }
@@ -172,6 +201,7 @@ public:
QString rootDir; QString rootDir;
QString pathFilter; QString pathFilter;
QString fileNameFilter; QString fileNameFilter;
RicRecursiveFileSearchDialog::FileType fileType;
RiaEnsembleNameTools::EnsembleGroupingMode groupingMode; RiaEnsembleNameTools::EnsembleGroupingMode groupingMode;
}; };

View File

@@ -276,22 +276,29 @@ void RicSummaryPlotFeatureImpl::createSummaryPlotsFromArgumentLine( const QStrin
} }
} }
bool isEnsembleMode = ensembleColoringStyle != EnsembleColoringType::NONE; if ( summaryFileNames.empty() )
std::vector<RimSummaryCase*> summaryCasesToUse;
if ( summaryFileNames.size() )
{ {
RicImportSummaryCasesFeature::createSummaryCasesFromFiles( summaryFileNames, &summaryCasesToUse, isEnsembleMode ); RiaLogging::error( "Needs at least one summary case to create a plot." );
RicImportSummaryCasesFeature::addSummaryCases( summaryCasesToUse ); return;
RiaApplication::instance()->setLastUsedDialogDirectory( RiaDefines::defaultDirectoryLabel(
RiaDefines::ImportFileType::ECLIPSE_SUMMARY_FILE ),
QFileInfo( summaryFileNames[0] ).absolutePath() );
} }
if ( summaryCasesToUse.size() ) bool isEnsembleMode = ensembleColoringStyle != EnsembleColoringType::NONE;
RicImportSummaryCasesFeature::CreateConfig createConfig{ .fileType = RiaDefines::FileType::SMSPEC,
.ensembleOrGroup = isEnsembleMode,
.allowDialogs = true };
auto [isOk, summaryCasesToUse] = RicImportSummaryCasesFeature::createSummaryCasesFromFiles( summaryFileNames, createConfig );
if ( !isOk || summaryCasesToUse.empty() )
{ {
RiaLogging::error( "Needs at least one summary case to create a plot." );
return;
}
RicImportSummaryCasesFeature::addSummaryCases( summaryCasesToUse );
RiaApplication::instance()->setLastUsedDialogDirectory( RiaDefines::defaultDirectoryLabel( RiaDefines::ImportFileType::ECLIPSE_SUMMARY_FILE ),
QFileInfo( summaryFileNames[0] ).absolutePath() );
// Sort in summary and grid curve addresses // Sort in summary and grid curve addresses
QStringList gridResultAddressFilters; QStringList gridResultAddressFilters;
QStringList summaryAddressFilters; QStringList summaryAddressFilters;
@@ -500,11 +507,6 @@ void RicSummaryPlotFeatureImpl::createSummaryPlotsFromArgumentLine( const QStrin
RiuMainWindow::closeIfOpen(); RiuMainWindow::closeIfOpen();
} }
}
else
{
RiaLogging::error( "Needs at least one summary case to create a plot." );
}
} }
RimSummaryPlot* RicSummaryPlotFeatureImpl::createSummaryPlotForEnsemble( const std::vector<RimSummaryCase*>& summaryCasesToUse, RimSummaryPlot* RicSummaryPlotFeatureImpl::createSummaryPlotForEnsemble( const std::vector<RimSummaryCase*>& summaryCasesToUse,

View File

@@ -247,7 +247,8 @@ void RifCaseRealizationRunspecificationReader::parse()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RifCaseRealizationParametersFileLocator::locate( const QString& modelPath ) QString RifCaseRealizationParametersFileLocator::locate( const QString& modelPath )
{ {
int MAX_LEVELS_UP = 3; // Chosen to find parameters file for StimPlan ensembles.
int MAX_LEVELS_UP = 5;
int dirLevel = 0; int dirLevel = 0;
QDir qdir( modelPath ); QDir qdir( modelPath );

View File

@@ -382,10 +382,13 @@ QString RifSummaryCaseRestartSelector::getSummaryFileFromGridFile( const QString
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RifSummaryCaseFileImportInfo::RifSummaryCaseFileImportInfo( const QString& summaryFileName, const QString& gridFileName ) RifSummaryCaseFileImportInfo::RifSummaryCaseFileImportInfo( const QString& summaryFileName,
const QString& gridFileName,
RiaDefines::FileType fileType )
: m_summaryFileName( summaryFileName ) : m_summaryFileName( summaryFileName )
, m_gridFileName( gridFileName ) , m_gridFileName( gridFileName )
, m_failOnSummaryFileImportError( false ) , m_failOnSummaryFileImportError( false )
, m_fileType( fileType )
{ {
} }
@@ -424,9 +427,18 @@ void RifSummaryCaseFileImportInfo::setFailOnSummaryFileError( bool failOnSummary
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RifSummaryCaseFileResultInfo::RifSummaryCaseFileResultInfo( const QString& summaryFileName, bool includeRestartFiles ) RiaDefines::FileType RifSummaryCaseFileImportInfo::fileType() const
{
return m_fileType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifSummaryCaseFileResultInfo::RifSummaryCaseFileResultInfo( const QString& summaryFileName, bool includeRestartFiles, RiaDefines::FileType fileType )
: m_summaryFileName( summaryFileName ) : m_summaryFileName( summaryFileName )
, m_includeRestartFiles( includeRestartFiles ) , m_includeRestartFiles( includeRestartFiles )
, m_fileType( fileType )
{ {
CVF_ASSERT( !m_summaryFileName.isEmpty() ); CVF_ASSERT( !m_summaryFileName.isEmpty() );
} }
@@ -447,6 +459,14 @@ bool RifSummaryCaseFileResultInfo::includeRestartFiles() const
return m_includeRestartFiles; return m_includeRestartFiles;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::FileType RifSummaryCaseFileResultInfo::fileType() const
{
return m_fileType;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -18,6 +18,8 @@
#pragma once #pragma once
#include "RiaSummaryDefines.h"
#include "RicSummaryCaseRestartDialog.h" #include "RicSummaryCaseRestartDialog.h"
#include <QString> #include <QString>
@@ -70,17 +72,21 @@ private:
class RifSummaryCaseFileImportInfo class RifSummaryCaseFileImportInfo
{ {
public: public:
RifSummaryCaseFileImportInfo( const QString& summaryFileName, const QString& gridFileName ); RifSummaryCaseFileImportInfo( const QString& summaryFileName,
const QString& gridFileName,
RiaDefines::FileType fileType = RiaDefines::FileType::SMSPEC );
const QString& summaryFileName() const; const QString& summaryFileName() const;
const QString& gridFileName() const; const QString& gridFileName() const;
bool failOnSummaryFileError() const; bool failOnSummaryFileError() const;
void setFailOnSummaryFileError( bool failOnSummaryFileImportError ); void setFailOnSummaryFileError( bool failOnSummaryFileImportError );
RiaDefines::FileType fileType() const;
private: private:
QString m_summaryFileName; QString m_summaryFileName;
QString m_gridFileName; QString m_gridFileName;
bool m_failOnSummaryFileImportError; bool m_failOnSummaryFileImportError;
RiaDefines::FileType m_fileType;
}; };
//================================================================================================== //==================================================================================================
@@ -89,10 +95,13 @@ private:
class RifSummaryCaseFileResultInfo class RifSummaryCaseFileResultInfo
{ {
public: public:
RifSummaryCaseFileResultInfo( const QString& summaryFileName, bool includeRestartFiles ); RifSummaryCaseFileResultInfo( const QString& summaryFileName,
bool includeRestartFiles,
RiaDefines::FileType fileType = RiaDefines::FileType::SMSPEC );
const QString& summaryFileName() const; const QString& summaryFileName() const;
bool includeRestartFiles() const; bool includeRestartFiles() const;
RiaDefines::FileType fileType() const;
bool operator<( const RifSummaryCaseFileResultInfo& other ) const; bool operator<( const RifSummaryCaseFileResultInfo& other ) const;
bool operator==( const RifSummaryCaseFileResultInfo& other ) const; bool operator==( const RifSummaryCaseFileResultInfo& other ) const;
@@ -100,4 +109,5 @@ public:
private: private:
QString m_summaryFileName; QString m_summaryFileName;
bool m_includeRestartFiles; bool m_includeRestartFiles;
RiaDefines::FileType m_fileType;
}; };

View File

@@ -21,6 +21,7 @@
#include "RifEnsembleStatisticsReader.h" #include "RifEnsembleStatisticsReader.h"
#include "RiaSummaryTools.h" #include "RiaSummaryTools.h"
#include "RiaTimeHistoryCurveResampler.h"
#include "RigStatisticsMath.h" #include "RigStatisticsMath.h"
@@ -137,7 +138,7 @@ void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*>& s
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*> sumCases, void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*>& sumCases,
const RifEclipseSummaryAddress& inputAddress, const RifEclipseSummaryAddress& inputAddress,
bool includeIncompleteCurves ) bool includeIncompleteCurves )
{ {
@@ -146,6 +147,10 @@ void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*> su
if ( !inputAddress.isValid() ) return; if ( !inputAddress.isValid() ) return;
auto [minTimeStep, maxTimeStep] = findMinMaxTimeStep( sumCases, inputAddress );
RiaDefines::DateTimePeriod period = findBestResamplingPeriod( minTimeStep, maxTimeStep );
caseAndTimeStepValues.reserve( sumCases.size() ); caseAndTimeStepValues.reserve( sumCases.size() );
for ( const auto& sumCase : sumCases ) for ( const auto& sumCase : sumCases )
{ {
@@ -160,8 +165,7 @@ void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*> su
if ( !includeIncompleteCurves && timeSteps.size() != values.size() ) continue; if ( !includeIncompleteCurves && timeSteps.size() != values.size() ) continue;
auto [resampledTimeSteps, resampledValues] = auto [resampledTimeSteps, resampledValues] = RiaSummaryTools::resampledValuesForPeriod( inputAddress, timeSteps, values, period );
RiaSummaryTools::resampledValuesForPeriod( inputAddress, timeSteps, values, RiaDefines::DateTimePeriod::DAY );
if ( allTimeSteps.empty() ) allTimeSteps = resampledTimeSteps; if ( allTimeSteps.empty() ) allTimeSteps = resampledTimeSteps;
caseAndTimeStepValues.push_back( resampledValues ); caseAndTimeStepValues.push_back( resampledValues );
@@ -220,7 +224,7 @@ void RimEnsembleStatisticsCase::clearData()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCase*> RimEnsembleStatisticsCase::validSummaryCases( const std::vector<RimSummaryCase*> allSumCases, std::vector<RimSummaryCase*> RimEnsembleStatisticsCase::validSummaryCases( const std::vector<RimSummaryCase*>& allSumCases,
const RifEclipseSummaryAddress& inputAddress, const RifEclipseSummaryAddress& inputAddress,
bool includeIncompleteCurves ) bool includeIncompleteCurves )
{ {
@@ -239,7 +243,7 @@ std::vector<RimSummaryCase*> RimEnsembleStatisticsCase::validSummaryCases( const
{ {
time_t lastTimeStep = timeSteps.back(); time_t lastTimeStep = timeSteps.back();
if ( lastTimeStep > maxTimeStep ) maxTimeStep = lastTimeStep; maxTimeStep = std::max( lastTimeStep, maxTimeStep );
times.push_back( std::make_pair( sumCase, lastTimeStep ) ); times.push_back( std::make_pair( sumCase, lastTimeStep ) );
} }
} }
@@ -259,5 +263,54 @@ std::vector<RimSummaryCase*> RimEnsembleStatisticsCase::validSummaryCases( const
validCases.push_back( sumCase ); validCases.push_back( sumCase );
} }
return validCases; return validCases;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<time_t, time_t> RimEnsembleStatisticsCase::findMinMaxTimeStep( const std::vector<RimSummaryCase*>& sumCases,
const RifEclipseSummaryAddress& inputAddress )
{
time_t minTimeStep = std::numeric_limits<time_t>::max();
time_t maxTimeStep = 0;
for ( const auto& sumCase : sumCases )
{
const auto& reader = sumCase->summaryReader();
if ( reader )
{
const std::vector<time_t>& timeSteps = reader->timeSteps( inputAddress );
if ( !timeSteps.empty() )
{
minTimeStep = std::min( timeSteps.front(), minTimeStep );
maxTimeStep = std::max( timeSteps.back(), maxTimeStep );
}
}
}
return std::make_pair( minTimeStep, maxTimeStep );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::DateTimePeriod RimEnsembleStatisticsCase::findBestResamplingPeriod( time_t minTimeStep, time_t maxTimeStep )
{
std::vector<RiaDefines::DateTimePeriod> periods = { RiaDefines::DateTimePeriod::DAY,
RiaDefines::DateTimePeriod::HOUR,
RiaDefines::DateTimePeriod::MINUTE };
for ( auto p : periods )
{
size_t numSamples = RiaTimeHistoryCurveResampler::timeStepsFromTimeRange( p, minTimeStep, maxTimeStep ).size();
// Resampled data should ideally have at least 100 samples to look good.
if ( numSamples > 100 )
{
return p;
}
}
return RiaDefines::DateTimePeriod::DAY;
}

View File

@@ -18,7 +18,9 @@
#pragma once #pragma once
#include "RiaDateTimeDefines.h"
#include "RiaDefines.h" #include "RiaDefines.h"
#include "RifEclipseSummaryAddress.h" #include "RifEclipseSummaryAddress.h"
#include "RimSummaryCase.h" #include "RimSummaryCase.h"
@@ -55,11 +57,14 @@ public:
RiaDefines::EclipseUnitSystem unitSystem() const; RiaDefines::EclipseUnitSystem unitSystem() const;
private: private:
void calculate( const std::vector<RimSummaryCase*> sumCases, const RifEclipseSummaryAddress& inputAddress, bool includeIncompleteCurves ); void calculate( const std::vector<RimSummaryCase*>& sumCases, const RifEclipseSummaryAddress& inputAddress, bool includeIncompleteCurves );
void clearData(); void clearData();
std::vector<RimSummaryCase*> validSummaryCases( const std::vector<RimSummaryCase*> allSumCases, static std::vector<RimSummaryCase*> validSummaryCases( const std::vector<RimSummaryCase*>& allSumCases,
const RifEclipseSummaryAddress& inputAddress, const RifEclipseSummaryAddress& inputAddress,
bool includeIncompleteCurves ); bool includeIncompleteCurves );
static std::pair<time_t, time_t> findMinMaxTimeStep( const std::vector<RimSummaryCase*>& sumCases,
const RifEclipseSummaryAddress& inputAddress );
static RiaDefines::DateTimePeriod findBestResamplingPeriod( time_t minTimeStep, time_t maxTimeStep );
private: private:
std::unique_ptr<RifEnsembleStatisticsReader> m_statisticsReader; std::unique_ptr<RifEnsembleStatisticsReader> m_statisticsReader;

View File

@@ -33,6 +33,7 @@
#endif #endif
#include "RimCaseDisplayNameTools.h" #include "RimCaseDisplayNameTools.h"
#include "RimCsvSummaryCase.h"
#include "RimDerivedEnsembleCaseCollection.h" #include "RimDerivedEnsembleCaseCollection.h"
#include "RimEclipseResultCase.h" #include "RimEclipseResultCase.h"
#include "RimFileSummaryCase.h" #include "RimFileSummaryCase.h"
@@ -560,9 +561,25 @@ std::vector<RimSummaryCase*>
if ( !smspecFileName.isEmpty() ) if ( !smspecFileName.isEmpty() )
{ {
auto newSumCase = new RimFileSummaryCase(); RimSummaryCase* newSumCase = nullptr;
if ( fileInfo.fileType() == RiaDefines::FileType::SMSPEC )
{
auto sumCase = new RimFileSummaryCase();
sumCase->setIncludeRestartFiles( fileInfo.includeRestartFiles() );
newSumCase = sumCase;
}
else
{
auto sumCase = new RimCsvSummaryCase();
if ( fileInfo.fileType() == RiaDefines::FileType::STIMPLAN_SUMMARY )
sumCase->setFileType( RimCsvSummaryCase::FileType::STIMPLAN );
else
sumCase->setFileType( RimCsvSummaryCase::FileType::REVEAL );
newSumCase = sumCase;
}
newSumCase->setIncludeRestartFiles( fileInfo.includeRestartFiles() );
newSumCase->setSummaryHeaderFileName( smspecFileName ); newSumCase->setSummaryHeaderFileName( smspecFileName );
newSumCase->updateOptionSensitivity(); newSumCase->updateOptionSensitivity();
project->assignCaseIdToSummaryCase( newSumCase ); project->assignCaseIdToSummaryCase( newSumCase );

View File

@@ -63,11 +63,12 @@ caf::PdmObjectHandle* RimProject_importSummaryCase::execute()
} }
QStringList summaryFileNames{ absolutePath }; QStringList summaryFileNames{ absolutePath };
std::vector<RimSummaryCase*> newCases;
bool ensembleOrGroup = false;
bool allowDialogs = false;
if ( RicImportSummaryCasesFeature::createSummaryCasesFromFiles( summaryFileNames, &newCases, ensembleOrGroup, allowDialogs ) ) RicImportSummaryCasesFeature::CreateConfig createConfig{ .fileType = RiaDefines::FileType::SMSPEC,
.ensembleOrGroup = false,
.allowDialogs = false };
auto [isOk, newCases] = RicImportSummaryCasesFeature::createSummaryCasesFromFiles( summaryFileNames, createConfig );
if ( isOk )
{ {
RicImportSummaryCasesFeature::addSummaryCases( newCases ); RicImportSummaryCasesFeature::addSummaryCases( newCases );

View File

@@ -89,6 +89,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSectionSummaryReader-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSummaryReader-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifRevealCsvSummaryReader-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifStimPlanCsvSummaryReader-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaEnsembleNameTools-Test.cpp
) )
if(RESINSIGHT_ENABLE_GRPC) if(RESINSIGHT_ENABLE_GRPC)

View File

@@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "gtest/gtest.h"
#include "RiaEnsembleNameTools.h"
#include <QStringList>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaEnsembleNameToolsTests, commonBaseName )
{
QStringList fileNames = { "/base/realization-0/iter-0/stimplan/output/B-H3_StimPlanModel_01_job-01/mainfrac/data_vs_time.csv",
"/base/realization-0/iter-0/stimplan/output/B-H3_StimPlanModel_02_job-02/mainfrac/data_vs_time.csv" };
ASSERT_EQ( "data_vs_time", RiaEnsembleNameTools::findCommonBaseName( fileNames ).toStdString() );
}

View File

@@ -25,7 +25,7 @@ TEST( RifCaseRealizationParametersReaderTest, LocatorTestSuccess )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
TEST( RifCaseRealizationParametersReaderTest, LocatorTestFailure ) TEST( RifCaseRealizationParametersReaderTest, LocatorTestFailure )
{ {
QString file = RifCaseRealizationParametersFileLocator::locate( CASE_REAL_TEST_DATA_DIRECTORY_01 + "4/3/2/1" ); QString file = RifCaseRealizationParametersFileLocator::locate( CASE_REAL_TEST_DATA_DIRECTORY_01 + "6/5/4/3/2/1" );
QString expected = ""; QString expected = "";
EXPECT_EQ( expected.toStdString(), file.toStdString() ); EXPECT_EQ( expected.toStdString(), file.toStdString() );
} }