mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
@@ -56,6 +56,7 @@
|
||||
#include "RiaImageCompareReporter.h"
|
||||
#include "RiaImageFileCompare.h"
|
||||
#include "cafProgressInfo.h"
|
||||
#include "RigGridManager.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
@@ -234,7 +235,10 @@ bool RiaApplication::loadProject(const QString& projectFileName)
|
||||
|
||||
m_project->fileName = projectFileName;
|
||||
m_project->readFile();
|
||||
m_project->fileName = projectFileName; // Make sure we overwrite the old filename read from the project file
|
||||
|
||||
// Propagate possible new location of project
|
||||
|
||||
m_project->setProjectFileNameAndUpdateDependencies(projectFileName);
|
||||
|
||||
// On error, delete everything, and bail out.
|
||||
|
||||
@@ -301,7 +305,7 @@ bool RiaApplication::loadProject(const QString& projectFileName)
|
||||
RimCase* ri = casesToLoad[cIdx];
|
||||
CVF_ASSERT(ri);
|
||||
|
||||
caseProgress.setProgressDescription(ri->caseName());
|
||||
caseProgress.setProgressDescription(ri->caseUserDescription());
|
||||
|
||||
caf::ProgressInfo viewProgress(ri->reservoirViews().size() , "Creating Views");
|
||||
|
||||
@@ -491,25 +495,17 @@ bool RiaApplication::openEclipseCaseFromFile(const QString& fileName)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaApplication::openEclipseCase(const QString& caseName, const QString& caseFileName)
|
||||
{
|
||||
QFileInfo gridFileName(caseFileName);
|
||||
QString casePath = gridFileName.absolutePath();
|
||||
|
||||
RimResultCase* rimResultReservoir = new RimResultCase();
|
||||
rimResultReservoir->caseName = caseName;
|
||||
rimResultReservoir->caseFileName = caseFileName;
|
||||
rimResultReservoir->caseDirectory = casePath;
|
||||
rimResultReservoir->setCaseInfo(caseName, caseFileName);
|
||||
|
||||
m_project->reservoirs.push_back(rimResultReservoir);
|
||||
|
||||
RimReservoirView* riv = rimResultReservoir->createAndAddReservoirView();
|
||||
|
||||
if (m_preferences->autocomputeSOIL)
|
||||
{
|
||||
// Select SOIL as default result variable
|
||||
riv->cellResult()->resultType = RimDefines::DYNAMIC_NATIVE;
|
||||
riv->cellResult()->resultVariable = "SOIL";
|
||||
riv->animationMode = true;
|
||||
}
|
||||
// Select SOIL as default result variable
|
||||
riv->cellResult()->resultType = RimDefines::DYNAMIC_NATIVE;
|
||||
riv->cellResult()->resultVariable = "SOIL";
|
||||
riv->animationMode = true;
|
||||
|
||||
riv->loadDataAndUpdate();
|
||||
|
||||
@@ -530,7 +526,7 @@ bool RiaApplication::openEclipseCase(const QString& caseName, const QString& cas
|
||||
bool RiaApplication::openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames)
|
||||
{
|
||||
RimInputCase* rimInputReservoir = new RimInputCase();
|
||||
rimInputReservoir->caseName = caseName;
|
||||
rimInputReservoir->caseUserDescription = caseName;
|
||||
rimInputReservoir->openDataFileSet(caseFileNames);
|
||||
|
||||
m_project->reservoirs.push_back(rimInputReservoir);
|
||||
@@ -1206,7 +1202,7 @@ void RiaApplication::saveSnapshotForAllViews(const QString& snapshotFolderName)
|
||||
// Process all events to avoid a black image when grabbing frame buffer
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
QString fileName = ri->caseName() + "-" + riv->name();
|
||||
QString fileName = ri->caseUserDescription() + "-" + riv->name();
|
||||
|
||||
QString absoluteFileName = caf::Utils::constructFullFileName(snapshotPath, fileName, ".png");
|
||||
saveSnapshotAs(absoluteFileName);
|
||||
@@ -1356,59 +1352,67 @@ bool RiaApplication::addEclipseCases(const QStringList& fileNames)
|
||||
{
|
||||
if (fileNames.size() == 0) return true;
|
||||
|
||||
|
||||
// First file is read completely including grid.
|
||||
// The main grid from the first case is reused directly in for the other cases.
|
||||
// When reading active cell info, only the total cell count is tested for consistency
|
||||
RigCaseData* mainEclipseCase = NULL;
|
||||
RimResultCase* mainResultCase = NULL;
|
||||
std::vector< std::vector<int> > mainCaseGridDimensions;
|
||||
|
||||
{
|
||||
QString firstFileName = fileNames[0];
|
||||
QFileInfo gridFileName(firstFileName);
|
||||
|
||||
QString caseName = gridFileName.completeBaseName();
|
||||
QString casePath = gridFileName.absolutePath();
|
||||
|
||||
RimResultCase* rimResultReservoir = new RimResultCase();
|
||||
rimResultReservoir->caseName = caseName;
|
||||
rimResultReservoir->caseFileName = firstFileName;
|
||||
rimResultReservoir->caseDirectory = casePath;
|
||||
|
||||
m_project->reservoirs.push_back(rimResultReservoir);
|
||||
|
||||
rimResultReservoir->setCaseInfo(caseName, firstFileName);
|
||||
if (!rimResultReservoir->openEclipseGridFile())
|
||||
{
|
||||
delete rimResultReservoir;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
rimResultReservoir->readGridDimensions(mainCaseGridDimensions);
|
||||
|
||||
m_project->reservoirs.push_back(rimResultReservoir);
|
||||
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
||||
|
||||
mainEclipseCase = rimResultReservoir->reservoirData();
|
||||
mainResultCase = rimResultReservoir;
|
||||
}
|
||||
|
||||
caf::ProgressInfo info(fileNames.size(), "Reading Active Cell data");
|
||||
|
||||
for (int i = 1; i < fileNames.size(); i++)
|
||||
{
|
||||
QString fileName = fileNames[i];
|
||||
QFileInfo gridFileName(fileName);
|
||||
QString caseFileName = fileNames[i];
|
||||
QFileInfo gridFileName(caseFileName);
|
||||
|
||||
QString caseName = gridFileName.completeBaseName();
|
||||
QString casePath = gridFileName.absolutePath();
|
||||
|
||||
RimResultCase* rimResultReservoir = new RimResultCase();
|
||||
rimResultReservoir->caseName = caseName;
|
||||
rimResultReservoir->caseFileName = fileName;
|
||||
rimResultReservoir->caseDirectory = casePath;
|
||||
rimResultReservoir->setCaseInfo(caseName, caseFileName);
|
||||
|
||||
m_project->reservoirs.push_back(rimResultReservoir);
|
||||
std::vector< std::vector<int> > caseGridDimensions;
|
||||
rimResultReservoir->readGridDimensions(caseGridDimensions);
|
||||
|
||||
if (!rimResultReservoir->openAndReadActiveCellData(mainEclipseCase))
|
||||
bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions);
|
||||
if (identicalGrid)
|
||||
{
|
||||
return false;
|
||||
if (rimResultReservoir->openAndReadActiveCellData(mainResultCase->reservoirData()))
|
||||
{
|
||||
m_project->reservoirs.push_back(rimResultReservoir);
|
||||
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete rimResultReservoir;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete rimResultReservoir;
|
||||
}
|
||||
|
||||
m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir);
|
||||
|
||||
info.setProgress(i);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const
|
||||
void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&navigationPolicy);
|
||||
|
||||
|
||||
@@ -51,5 +51,5 @@ public: // Pdm Fields
|
||||
protected:
|
||||
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute);
|
||||
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const;
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ;
|
||||
};
|
||||
|
||||
@@ -148,6 +148,10 @@ set( QRC_FILES
|
||||
# Runs RCC on specified files
|
||||
qt4_add_resources( QRC_FILES_CPP ${QRC_FILES} )
|
||||
|
||||
# Adding resource (RC) files for Windows
|
||||
if ( MSVC )
|
||||
set( WIN_RESOURCE Resources/ResInsight.rc )
|
||||
endif()
|
||||
|
||||
#############################################################################
|
||||
# creating PCH's for MSVC and GCC on Linux
|
||||
@@ -208,6 +212,7 @@ add_executable(ResInsight
|
||||
${MOC_FILES_CPP}
|
||||
${FORM_FILES_CPP}
|
||||
${QRC_FILES_CPP}
|
||||
${WIN_RESOURCE}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <util.h>
|
||||
#include <int_vector.h>
|
||||
#include <ecl_intehead.h>
|
||||
#include <ecl_file.h>
|
||||
#include <ecl_kw.h>
|
||||
#include <ecl_kw_magic.h>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
#include "util.h"
|
||||
#include "ecl_file.h"
|
||||
#include "ecl_intehead.h"
|
||||
#include "ecl_kw_magic.h"
|
||||
#include "ecl_grid.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
@@ -198,7 +198,7 @@ bool RifEclipseOutputFileTools::keywordData(ecl_file_type* ecl_file, const QStri
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifEclipseOutputFileTools::fileNameByType(const QStringList& fileSet, ecl_file_enum fileType)
|
||||
QString RifEclipseOutputFileTools::firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < fileSet.count(); i++)
|
||||
@@ -216,9 +216,9 @@ QString RifEclipseOutputFileTools::fileNameByType(const QStringList& fileSet, ec
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get all files of file of given type in given list of filenames, as filename or NULL if not found
|
||||
/// Get all files of the given type from the provided list of filenames
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifEclipseOutputFileTools::fileNamesByType(const QStringList& fileSet, ecl_file_enum fileType)
|
||||
QStringList RifEclipseOutputFileTools::filterFileNamesOfType(const QStringList& fileSet, ecl_file_enum fileType)
|
||||
{
|
||||
QStringList fileNames;
|
||||
|
||||
@@ -240,14 +240,14 @@ QStringList RifEclipseOutputFileTools::fileNamesByType(const QStringList& fileSe
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get set of Eclipse files based on an input file and its path
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifEclipseOutputFileTools::fileSet(const QString& fileName, QStringList* fileSet)
|
||||
bool RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(const QString& fullPathFileName, QStringList* baseNameFiles)
|
||||
{
|
||||
CVF_ASSERT(fileSet);
|
||||
fileSet->clear();
|
||||
CVF_ASSERT(baseNameFiles);
|
||||
baseNameFiles->clear();
|
||||
|
||||
QString filePath = QFileInfo(fileName).absoluteFilePath();
|
||||
QString filePath = QFileInfo(fullPathFileName).absoluteFilePath();
|
||||
filePath = QFileInfo(filePath).path();
|
||||
QString fileNameBase = QFileInfo(fileName).baseName();
|
||||
QString fileNameBase = QFileInfo(fullPathFileName).baseName();
|
||||
|
||||
stringlist_type* eclipseFiles = stringlist_alloc_new();
|
||||
ecl_util_select_filelist(filePath.toAscii().data(), fileNameBase.toAscii().data(), ECL_OTHER_FILE, false, eclipseFiles);
|
||||
@@ -255,12 +255,12 @@ bool RifEclipseOutputFileTools::fileSet(const QString& fileName, QStringList* fi
|
||||
int i;
|
||||
for (i = 0; i < stringlist_get_size(eclipseFiles); i++)
|
||||
{
|
||||
fileSet->append(stringlist_safe_iget(eclipseFiles, i));
|
||||
baseNameFiles->append(stringlist_safe_iget(eclipseFiles, i));
|
||||
}
|
||||
|
||||
stringlist_free(eclipseFiles);
|
||||
|
||||
return fileSet->count() > 0;
|
||||
return baseNameFiles->count() > 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,3 +302,20 @@ void RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(ecl_file_type* ecl
|
||||
info.setProgress(i);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseOutputFileTools::readGridDimensions(const QString& gridFileName, std::vector< std::vector<int> >& gridDimensions)
|
||||
{
|
||||
int gridDims[3];
|
||||
|
||||
bool ret = ecl_grid_file_dims(gridFileName.toAscii().data(), NULL, gridDims);
|
||||
if (ret)
|
||||
{
|
||||
gridDimensions.resize(1);
|
||||
gridDimensions[0].push_back(gridDims[0]);
|
||||
gridDimensions[0].push_back(gridDims[1]);
|
||||
gridDimensions[0].push_back(gridDims[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,10 @@ public:
|
||||
// static void timeStepsText(ecl_file_type* ecl_file, QStringList* timeSteps);
|
||||
static void timeSteps(ecl_file_type* ecl_file, std::vector<QDateTime>* timeSteps, bool* detectedFractionOfDay = NULL);
|
||||
|
||||
static bool fileSet(const QString& fileName, QStringList* fileSet);
|
||||
static bool findSiblingFilesWithSameBaseName(const QString& fileName, QStringList* fileSet);
|
||||
|
||||
static QString fileNameByType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
static QStringList fileNamesByType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
static QString firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
static QStringList filterFileNamesOfType(const QStringList& fileSet, ecl_file_enum fileType);
|
||||
|
||||
static void readGridDimensions(const QString& gridFileName, std::vector< std::vector<int> >& gridDimensions);
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
virtual ~RifEclipseRestartDataAccess();
|
||||
|
||||
virtual bool open() = 0;
|
||||
virtual void setFileSet(const QStringList& fileSet) = 0;
|
||||
virtual void setRestartFiles(const QStringList& fileSet) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void setTimeSteps(const std::vector<QDateTime>& timeSteps) {};
|
||||
|
||||
@@ -63,12 +63,13 @@ bool RifEclipseRestartFilesetAccess::open()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseRestartFilesetAccess::setFileSet(const QStringList& fileSet)
|
||||
void RifEclipseRestartFilesetAccess::setRestartFiles(const QStringList& fileSet)
|
||||
{
|
||||
close();
|
||||
m_ecl_files.clear();
|
||||
|
||||
m_fileNames = fileSet;
|
||||
m_fileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file.
|
||||
|
||||
for (int i = 0; i < m_fileNames.size(); i++)
|
||||
{
|
||||
@@ -99,7 +100,7 @@ void RifEclipseRestartFilesetAccess::close()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseRestartFilesetAccess::setTimeSteps(const std::vector<QDateTime>& timeSteps)
|
||||
{
|
||||
CVF_ASSERT(m_fileNames.size() == timeSteps.size());
|
||||
CVF_ASSERT((size_t)m_fileNames.size() == timeSteps.size());
|
||||
m_timeSteps = timeSteps;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
virtual ~RifEclipseRestartFilesetAccess();
|
||||
|
||||
bool open();
|
||||
void setFileSet(const QStringList& fileSet);
|
||||
void setRestartFiles(const QStringList& fileSet);
|
||||
void close();
|
||||
|
||||
void setTimeSteps(const std::vector<QDateTime>& timeSteps);
|
||||
|
||||
@@ -156,7 +156,7 @@ void RifEclipseUnifiedRestartFileAccess::readWellData(well_info_type* well_info)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifEclipseUnifiedRestartFileAccess::setFileSet(const QStringList& fileSet)
|
||||
void RifEclipseUnifiedRestartFileAccess::setRestartFiles(const QStringList& fileSet)
|
||||
{
|
||||
m_filename = fileSet[0];
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
RifEclipseUnifiedRestartFileAccess();
|
||||
virtual ~RifEclipseUnifiedRestartFileAccess();
|
||||
|
||||
void setFileSet(const QStringList& fileSet);
|
||||
void setRestartFiles(const QStringList& fileSet);
|
||||
bool open();
|
||||
void close();
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellIn
|
||||
RifReaderEclipseOutput::RifReaderEclipseOutput()
|
||||
{
|
||||
m_fileName.clear();
|
||||
m_fileSet.clear();
|
||||
m_filesWithSameBaseName.clear();
|
||||
|
||||
m_timeSteps.clear();
|
||||
|
||||
@@ -349,13 +349,13 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC
|
||||
|
||||
// Get set of files
|
||||
QStringList fileSet;
|
||||
if (!RifEclipseOutputFileTools::fileSet(fileName, &fileSet)) return false;
|
||||
if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &fileSet)) return false;
|
||||
|
||||
progInfo.incrementProgress();
|
||||
|
||||
progInfo.setNextProgressIncrement(20);
|
||||
// Keep the set of files of interest
|
||||
m_fileSet = fileSet;
|
||||
m_filesWithSameBaseName = fileSet;
|
||||
|
||||
// Read geometry
|
||||
ecl_grid_type * mainEclGrid = ecl_grid_alloc( fileName.toAscii().data() );
|
||||
@@ -408,10 +408,10 @@ bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName,
|
||||
|
||||
// Get set of files
|
||||
QStringList fileSet;
|
||||
if (!RifEclipseOutputFileTools::fileSet(fileName, &fileSet)) return false;
|
||||
if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &fileSet)) return false;
|
||||
|
||||
// Keep the set of files of interest
|
||||
m_fileSet = fileSet;
|
||||
m_filesWithSameBaseName = fileSet;
|
||||
m_eclipseCase = eclipseCase;
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName,
|
||||
//if (!buildMetaData()) return false;
|
||||
// readWellCells();
|
||||
|
||||
m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet);
|
||||
m_dynamicResultsAccess = createDynamicResultsAccess();
|
||||
|
||||
m_dynamicResultsAccess->setTimeSteps(mainCaseTimeSteps);
|
||||
|
||||
@@ -442,7 +442,7 @@ bool RifReaderEclipseOutput::readActiveCellInfo()
|
||||
CVF_ASSERT(m_eclipseCase);
|
||||
CVF_ASSERT(m_eclipseCase->mainGrid());
|
||||
|
||||
QString egridFileName = RifEclipseOutputFileTools::fileNameByType(m_fileSet, ECL_EGRID_FILE);
|
||||
QString egridFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_EGRID_FILE);
|
||||
if (egridFileName.size() > 0)
|
||||
{
|
||||
ecl_file_type* ecl_file = ecl_file_open(egridFileName.toAscii().data());
|
||||
@@ -526,14 +526,14 @@ bool RifReaderEclipseOutput::readActiveCellInfo()
|
||||
bool RifReaderEclipseOutput::buildMetaData()
|
||||
{
|
||||
CVF_ASSERT(m_eclipseCase);
|
||||
CVF_ASSERT(m_fileSet.size() > 0);
|
||||
CVF_ASSERT(m_filesWithSameBaseName.size() > 0);
|
||||
|
||||
caf::ProgressInfo progInfo(m_fileSet.size() + 3,"");
|
||||
caf::ProgressInfo progInfo(m_filesWithSameBaseName.size() + 3,"");
|
||||
|
||||
progInfo.setNextProgressIncrement(m_fileSet.size());
|
||||
progInfo.setNextProgressIncrement(m_filesWithSameBaseName.size());
|
||||
|
||||
// Create access object for dynamic results
|
||||
m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet);
|
||||
m_dynamicResultsAccess = createDynamicResultsAccess();
|
||||
if (m_dynamicResultsAccess.isNull())
|
||||
{
|
||||
return false;
|
||||
@@ -641,25 +641,25 @@ bool RifReaderEclipseOutput::buildMetaData()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Create results access object (.UNRST or .X0001 ... .XNNNN)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseRestartDataAccess* RifReaderEclipseOutput::createDynamicResultsAccess(const QStringList& fileSet)
|
||||
RifEclipseRestartDataAccess* RifReaderEclipseOutput::createDynamicResultsAccess()
|
||||
{
|
||||
RifEclipseRestartDataAccess* resultsAccess = NULL;
|
||||
|
||||
// Look for unified restart file
|
||||
QString unrstFileName = RifEclipseOutputFileTools::fileNameByType(fileSet, ECL_UNIFIED_RESTART_FILE);
|
||||
QString unrstFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE);
|
||||
if (unrstFileName.size() > 0)
|
||||
{
|
||||
resultsAccess = new RifEclipseUnifiedRestartFileAccess();
|
||||
resultsAccess->setFileSet(QStringList(unrstFileName));
|
||||
resultsAccess->setRestartFiles(QStringList(unrstFileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look for set of restart files (one file per time step)
|
||||
QStringList restartFiles = RifEclipseOutputFileTools::fileNamesByType(fileSet, ECL_RESTART_FILE);
|
||||
QStringList restartFiles = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE);
|
||||
if (restartFiles.size() > 0)
|
||||
{
|
||||
resultsAccess = new RifEclipseRestartFilesetAccess();
|
||||
resultsAccess->setFileSet(restartFiles);
|
||||
resultsAccess->setRestartFiles(restartFiles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -703,7 +703,7 @@ bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelR
|
||||
{
|
||||
if (m_dynamicResultsAccess.isNull())
|
||||
{
|
||||
m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet);
|
||||
m_dynamicResultsAccess = createDynamicResultsAccess();
|
||||
}
|
||||
|
||||
if (m_dynamicResultsAccess.isNull())
|
||||
@@ -1023,7 +1023,7 @@ bool RifReaderEclipseOutput::openInitFile()
|
||||
return true;
|
||||
}
|
||||
|
||||
QString initFileName = RifEclipseOutputFileTools::fileNameByType(m_fileSet, ECL_INIT_FILE);
|
||||
QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE);
|
||||
if (initFileName.size() > 0)
|
||||
{
|
||||
m_ecl_init_file = ecl_file_open(initFileName.toAscii().data());
|
||||
|
||||
@@ -62,18 +62,18 @@ private:
|
||||
|
||||
void extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector<double>* values, const std::vector<double>& fileValues);
|
||||
|
||||
static RifEclipseRestartDataAccess* createDynamicResultsAccess(const QStringList& fileSet);
|
||||
RifEclipseRestartDataAccess* createDynamicResultsAccess();
|
||||
|
||||
QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector<size_t>& keywordDataItemCounts, const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* fractureActiveCellInfo, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const;
|
||||
|
||||
virtual std::vector<QDateTime> timeSteps();
|
||||
private:
|
||||
QString m_fileName; // Name of file used to start accessing Eclipse output files
|
||||
QStringList m_fileSet; // Set of files in filename's path with same base name as filename
|
||||
QStringList m_filesWithSameBaseName; // Set of files in filename's path with same base name as filename
|
||||
|
||||
RigCaseData* m_eclipseCase;
|
||||
RigCaseData* m_eclipseCase;
|
||||
|
||||
std::vector<QDateTime> m_timeSteps;
|
||||
std::vector<QDateTime> m_timeSteps;
|
||||
|
||||
ecl_file_type* m_ecl_init_file; // File access to static results
|
||||
cvf::ref<RifEclipseRestartDataAccess> m_dynamicResultsAccess; // File access to dynamic results
|
||||
|
||||
@@ -33,6 +33,8 @@ RivReservoirPipesPartMgr::RivReservoirPipesPartMgr(RimReservoirView* reservoirVi
|
||||
m_reservoirView = reservoirView;
|
||||
|
||||
m_scaleTransform = new cvf::Transform();
|
||||
|
||||
m_font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::LARGE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -46,42 +48,25 @@ RivReservoirPipesPartMgr::~RivReservoirPipesPartMgr()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex)
|
||||
void RivReservoirPipesPartMgr::clearGeometryCache()
|
||||
{
|
||||
if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::FORCE_ALL_OFF) return;
|
||||
|
||||
if (m_reservoirView->wellCollection()->wells.size() != m_wellPipesPartMgrs.size())
|
||||
{
|
||||
m_wellPipesPartMgrs.clear();
|
||||
m_wellHeadPartMgrs.clear();
|
||||
|
||||
for (size_t i = 0; i < m_reservoirView->wellCollection()->wells.size(); ++i)
|
||||
{
|
||||
RivWellPipesPartMgr * wppmgr = new RivWellPipesPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]);
|
||||
m_wellPipesPartMgrs.push_back(wppmgr);
|
||||
wppmgr->setScaleTransform(m_scaleTransform.p());
|
||||
|
||||
RivWellHeadPartMgr* wellHeadMgr = new RivWellHeadPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]);
|
||||
m_wellHeadPartMgrs.push_back(wellHeadMgr);
|
||||
wellHeadMgr->setScaleTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex);
|
||||
m_wellHeadPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex);
|
||||
}
|
||||
m_wellPipesPartMgrs.clear();
|
||||
m_wellHeadPartMgrs.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::updatePipeResultColor(size_t frameIndex)
|
||||
void RivReservoirPipesPartMgr::scheduleGeometryRegen()
|
||||
{
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->updatePipeResultColor( frameIndex);
|
||||
m_wellPipesPartMgrs[wIdx]->scheduleGeometryRegen();
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellHeadPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
//m_wellHeadPartMgrs[wIdx]->scheduleGeometryRegen(scaleTransform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,15 +88,44 @@ void RivReservoirPipesPartMgr::setScaleTransform(cvf::Transform * scaleTransform
|
||||
}
|
||||
}
|
||||
|
||||
void RivReservoirPipesPartMgr::scheduleGeometryRegen()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex)
|
||||
{
|
||||
if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::FORCE_ALL_OFF) return;
|
||||
|
||||
if (m_reservoirView->wellCollection()->wells.size() != m_wellPipesPartMgrs.size())
|
||||
{
|
||||
clearGeometryCache();
|
||||
|
||||
for (size_t i = 0; i < m_reservoirView->wellCollection()->wells.size(); ++i)
|
||||
{
|
||||
RivWellPipesPartMgr * wppmgr = new RivWellPipesPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]);
|
||||
m_wellPipesPartMgrs.push_back(wppmgr);
|
||||
wppmgr->setScaleTransform(m_scaleTransform.p());
|
||||
|
||||
RivWellHeadPartMgr* wellHeadMgr = new RivWellHeadPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i], m_font.p());
|
||||
m_wellHeadPartMgrs.push_back(wellHeadMgr);
|
||||
wellHeadMgr->setScaleTransform(m_scaleTransform.p());
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex);
|
||||
m_wellHeadPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivReservoirPipesPartMgr::updatePipeResultColor(size_t frameIndex)
|
||||
{
|
||||
for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
m_wellPipesPartMgrs[wIdx]->scheduleGeometryRegen();
|
||||
}
|
||||
|
||||
for (size_t wIdx = 0; wIdx != m_wellHeadPartMgrs.size(); ++ wIdx)
|
||||
{
|
||||
//m_wellHeadPartMgrs[wIdx]->scheduleGeometryRegen(scaleTransform);
|
||||
m_wellPipesPartMgrs[wIdx]->updatePipeResultColor( frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,15 +33,18 @@ public:
|
||||
RivReservoirPipesPartMgr(RimReservoirView* reservoirView);
|
||||
~RivReservoirPipesPartMgr();
|
||||
|
||||
void setScaleTransform(cvf::Transform * scaleTransform);
|
||||
void clearGeometryCache();
|
||||
void scheduleGeometryRegen();
|
||||
|
||||
void setScaleTransform(cvf::Transform * scaleTransform);
|
||||
|
||||
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex);
|
||||
void updatePipeResultColor(size_t frameIndex);
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimReservoirView> m_reservoirView;
|
||||
cvf::ref<cvf::Transform> m_scaleTransform;
|
||||
cvf::ref<cvf::Font> m_font;
|
||||
|
||||
cvf::Collection< RivWellPipesPartMgr > m_wellPipesPartMgrs;
|
||||
cvf::Collection< RivWellHeadPartMgr > m_wellHeadPartMgrs;
|
||||
|
||||
@@ -46,12 +46,12 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RivWellHeadPartMgr::RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well)
|
||||
RivWellHeadPartMgr::RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well, cvf::Font* font)
|
||||
{
|
||||
m_rimReservoirView = reservoirView;
|
||||
m_rimWell = well;
|
||||
|
||||
m_font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::LARGE);
|
||||
m_font = font;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -232,6 +232,8 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
|
||||
|
||||
if (m_rimReservoirView->wellCollection()->showWellLabel() && well->showWellLabel())
|
||||
{
|
||||
CVF_ASSERT(m_font.p());
|
||||
|
||||
cvf::ref<cvf::DrawableText> drawableText = new cvf::DrawableText;
|
||||
drawableText->setFont(m_font.p());
|
||||
drawableText->setCheckPosVisible(false);
|
||||
|
||||
@@ -38,7 +38,7 @@ class RimReservoirView;
|
||||
class RivWellHeadPartMgr : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well);
|
||||
RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well, cvf::Font* font);
|
||||
~RivWellHeadPartMgr();
|
||||
|
||||
void setScaleTransform(cvf::Transform * scaleTransform) { m_scaleTransform = scaleTransform;}
|
||||
|
||||
@@ -89,7 +89,7 @@ void Rim3dOverlayInfoConfig::update3DInfo()
|
||||
|
||||
if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && m_reservoirView->eclipseCase()->reservoirData()->mainGrid())
|
||||
{
|
||||
caseName = m_reservoirView->eclipseCase()->caseName();
|
||||
caseName = m_reservoirView->eclipseCase()->caseUserDescription();
|
||||
totCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cells().size());
|
||||
size_t mxActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount();
|
||||
size_t frActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount();
|
||||
|
||||
@@ -43,7 +43,7 @@ CAF_PDM_SOURCE_INIT(RimCase, "RimReservoir");
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCase::RimCase()
|
||||
{
|
||||
CAF_PDM_InitField(&caseName, "CaseName", QString(), "Case name", "", "" ,"");
|
||||
CAF_PDM_InitField(&caseUserDescription, "CaseUserDescription", QString(), "Case name", "", "" ,"");
|
||||
CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_matrixModelResults, "MatrixModelResults", "", "", "", "");
|
||||
@@ -51,6 +51,11 @@ RimCase::RimCase()
|
||||
CAF_PDM_InitFieldNoDefault(&m_fractureModelResults, "FractureModelResults", "", "", "", "");
|
||||
m_fractureModelResults.setUiHidden(true);
|
||||
|
||||
// Obsolete field
|
||||
CAF_PDM_InitField(&caseName, "CaseName", QString(), "Obsolete", "", "" ,"");
|
||||
caseName.setIOWritable(false);
|
||||
caseName.setUiHidden(true);
|
||||
|
||||
m_matrixModelResults = new RimReservoirCellResultsStorage;
|
||||
m_fractureModelResults = new RimReservoirCellResultsStorage;
|
||||
|
||||
@@ -103,6 +108,11 @@ void RimCase::initAfterRead()
|
||||
|
||||
riv->setEclipseCase(this);
|
||||
}
|
||||
|
||||
if (caseUserDescription().isEmpty() && !caseName().isEmpty())
|
||||
{
|
||||
caseUserDescription = caseName;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -110,17 +120,6 @@ void RimCase::initAfterRead()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimReservoirView* RimCase::createAndAddReservoirView()
|
||||
{
|
||||
// If parent is collection, and number of views is zero, make sure rig is set to NULL to initiate normal case loading
|
||||
if (parentCaseCollection() != NULL && reservoirViews().size() == 0)
|
||||
{
|
||||
if (this->reservoirData())
|
||||
{
|
||||
CVF_ASSERT(this->reservoirData()->refCount() == 1);
|
||||
}
|
||||
|
||||
this->setReservoirData( NULL );
|
||||
}
|
||||
|
||||
RimReservoirView* riv = new RimReservoirView();
|
||||
riv->setEclipseCase(this);
|
||||
|
||||
@@ -293,6 +292,23 @@ RimCaseCollection* RimCase::parentCaseCollection()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimIdenticalGridCaseGroup* RimCase::parentGridCaseGroup()
|
||||
{
|
||||
RimCaseCollection* caseColl = parentCaseCollection();
|
||||
if (caseColl)
|
||||
{
|
||||
return caseColl->parentCaseGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -328,3 +344,136 @@ RimReservoirCellResultsStorage* RimCase::results(RifReaderInterface::PorosityMod
|
||||
return m_fractureModelResults();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Relocate the supplied file name, based on the search path as follows:
|
||||
/// fileName, newProjectPath/fileNameWoPath, relocatedPath/fileNameWoPath
|
||||
/// If the file is not found in any of the positions, the fileName is returned unchanged
|
||||
///
|
||||
/// The relocatedPath is found in this way:
|
||||
/// use the start of newProjectPath
|
||||
/// plus the end of the path to m_gridFileName
|
||||
/// such that the common start of oldProjectPath and m_gridFileName is removed from m_gridFileName
|
||||
/// and replaced with the start of newProjectPath up to where newProjectPath starts to be equal to oldProjectPath
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCase::relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath,
|
||||
bool* foundFile, std::vector<QString>* searchedPaths)
|
||||
{
|
||||
if (foundFile) *foundFile = true;
|
||||
|
||||
if (searchedPaths) searchedPaths->push_back(fileName);
|
||||
if (QFile::exists(fileName))
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
// First check in the new project file directory
|
||||
{
|
||||
QString fileNameWithoutPath = QFileInfo(fileName).fileName();
|
||||
QString candidate = QDir::fromNativeSeparators(newProjectPath + QDir::separator() + fileNameWithoutPath);
|
||||
if (searchedPaths) searchedPaths->push_back(candidate);
|
||||
|
||||
if (QFile::exists(candidate))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
// Then find the possible move of a directory structure where projects and files referenced are moved in "paralell"
|
||||
|
||||
QFileInfo gridFileInfo(QDir::fromNativeSeparators(fileName));
|
||||
QString gridFilePath = gridFileInfo.path();
|
||||
QString gridFileNameWoPath = gridFileInfo.fileName();
|
||||
QStringList gridPathElements = gridFilePath.split("/", QString::KeepEmptyParts);
|
||||
|
||||
QString oldProjPath = QDir::fromNativeSeparators(oldProjectPath);
|
||||
QStringList oldProjPathElements = oldProjPath.split("/", QString::KeepEmptyParts);
|
||||
|
||||
QString newProjPath = QDir::fromNativeSeparators(newProjectPath);
|
||||
QStringList newProjPathElements = newProjPath.split("/", QString::KeepEmptyParts);
|
||||
|
||||
// Find the possible equal start of the old project path, and the referenced file
|
||||
|
||||
bool pathStartsAreEqual = false;
|
||||
bool pathEndsDiffer = false;
|
||||
int firstDiffIdx = 0;
|
||||
for ( firstDiffIdx = 0; firstDiffIdx < gridPathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx)
|
||||
{
|
||||
if (gridPathElements[firstDiffIdx] == oldProjPathElements[firstDiffIdx])
|
||||
{
|
||||
pathStartsAreEqual = pathStartsAreEqual || !gridPathElements[firstDiffIdx].isEmpty();
|
||||
}
|
||||
else
|
||||
{
|
||||
pathEndsDiffer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pathEndsDiffer && firstDiffIdx < gridPathElements.size() || firstDiffIdx < oldProjPathElements.size())
|
||||
{
|
||||
pathEndsDiffer = true;
|
||||
}
|
||||
|
||||
// If the path starts are equal, try to substitute it in the referenced file, with the corresponding new project path start
|
||||
|
||||
if (pathStartsAreEqual)
|
||||
{
|
||||
if (pathEndsDiffer)
|
||||
{
|
||||
QString oldGridFilePathEnd;
|
||||
for (int i = firstDiffIdx; i < gridPathElements.size(); ++i)
|
||||
{
|
||||
oldGridFilePathEnd += gridPathElements[i];
|
||||
oldGridFilePathEnd += "/";
|
||||
}
|
||||
|
||||
// Find the new Project File Start Path
|
||||
|
||||
QStringList oldProjectFilePathEndElements;
|
||||
for (int i = firstDiffIdx; i < oldProjPathElements.size(); ++i)
|
||||
{
|
||||
oldProjectFilePathEndElements.push_back(oldProjPathElements[i]);
|
||||
}
|
||||
|
||||
int ppIdx = oldProjectFilePathEndElements.size() -1;
|
||||
int lastDiffIdx = newProjPathElements.size() -1;
|
||||
|
||||
for (; lastDiffIdx >= 0 && ppIdx >= 0; --lastDiffIdx, --ppIdx)
|
||||
{
|
||||
if (oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastDiffIdx])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QString newProjecetFileStartPath;
|
||||
for (int i = 0; i <= lastDiffIdx; ++i)
|
||||
{
|
||||
newProjecetFileStartPath += newProjPathElements[i];
|
||||
newProjecetFileStartPath += "/";
|
||||
}
|
||||
|
||||
QString relocationPath = newProjecetFileStartPath + oldGridFilePathEnd;
|
||||
|
||||
QString relocatedFileName = relocationPath + gridFileNameWoPath;
|
||||
|
||||
if (searchedPaths) searchedPaths->push_back(relocatedFileName);
|
||||
|
||||
if (QFile::exists(relocatedFileName))
|
||||
{
|
||||
return relocatedFileName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The Grid file was located in the same dir as the Project file. This is supposed to be handled above.
|
||||
// So we did not find it
|
||||
}
|
||||
}
|
||||
|
||||
// return the unchanged filename, if we could not find a valid relocation file
|
||||
if (foundFile) *foundFile = false;
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class RigCaseData;
|
||||
class RigGridBase;
|
||||
class RimReservoirView;
|
||||
class RimCaseCollection;
|
||||
class RimIdenticalGridCaseGroup;
|
||||
//class RimReservoirCellResultsCacher;
|
||||
|
||||
//==================================================================================================
|
||||
@@ -45,15 +46,16 @@ public:
|
||||
RimCase();
|
||||
virtual ~RimCase();
|
||||
|
||||
|
||||
// Fields:
|
||||
caf::PdmField<QString> caseName;
|
||||
caf::PdmField<QString> caseUserDescription;
|
||||
caf::PdmField<bool> releaseResultMemory;
|
||||
caf::PdmPointersField<RimReservoirView*> reservoirViews;
|
||||
|
||||
virtual bool openEclipseGridFile() { return false;}; // Should be pure virtual but PDM does not allow that.
|
||||
|
||||
RigCaseData* reservoirData();
|
||||
const RigCaseData* reservoirData() const;
|
||||
RigCaseData* reservoirData();
|
||||
const RigCaseData* reservoirData() const;
|
||||
|
||||
RimReservoirCellResultsStorage* results(RifReaderInterface::PorosityModelResultType porosityModel);
|
||||
|
||||
@@ -63,12 +65,17 @@ public:
|
||||
void removeResult(const QString& resultName);
|
||||
|
||||
virtual QString locationOnDisc() const { return QString(); }
|
||||
virtual QString gridFileName() const { return QString(); }
|
||||
|
||||
virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) { };
|
||||
|
||||
RimCaseCollection* parentCaseCollection();
|
||||
RimIdenticalGridCaseGroup* parentGridCaseGroup();
|
||||
|
||||
|
||||
// Overridden methods from PdmObject
|
||||
public:
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName; }
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() { return &caseUserDescription; }
|
||||
protected:
|
||||
virtual void initAfterRead();
|
||||
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
|
||||
@@ -77,13 +84,17 @@ protected:
|
||||
protected:
|
||||
void computeCachedData();
|
||||
void setReservoirData(RigCaseData* eclipseCase);
|
||||
|
||||
static QString relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath,
|
||||
bool* foundFile, std::vector<QString>* searchedPaths);
|
||||
|
||||
private:
|
||||
cvf::ref<RigCaseData> m_rigEclipseCase;
|
||||
cvf::ref<RigCaseData> m_rigEclipseCase;
|
||||
|
||||
private:
|
||||
caf::PdmField<RimReservoirCellResultsStorage*> m_matrixModelResults;
|
||||
caf::PdmField<RimReservoirCellResultsStorage*> m_fractureModelResults;
|
||||
|
||||
// Obsolete fields
|
||||
protected:
|
||||
caf::PdmField<QString> caseName;
|
||||
};
|
||||
|
||||
@@ -59,3 +59,19 @@ RimIdenticalGridCaseGroup* RimCaseCollection::parentCaseGroup()
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCase* RimCaseCollection::findByDescription(const QString& caseDescription) const
|
||||
{
|
||||
for (size_t i = 0; i < reservoirs.size(); i++)
|
||||
{
|
||||
if (caseDescription == reservoirs[i]->caseUserDescription())
|
||||
{
|
||||
return reservoirs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,10 @@ class RimCaseCollection : public caf::PdmObject
|
||||
public:
|
||||
RimCaseCollection();
|
||||
virtual ~RimCaseCollection();
|
||||
|
||||
caf::PdmPointersField<RimCase*> reservoirs;
|
||||
|
||||
RimIdenticalGridCaseGroup* parentCaseGroup();
|
||||
RimIdenticalGridCaseGroup* parentCaseGroup();
|
||||
RimCase* findByDescription(const QString& caseDescription) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ void RimCellPropertyFilter::setDefaultValues()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCellPropertyFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const
|
||||
void RimCellPropertyFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
// Fields declared in RimCellFilter
|
||||
uiOrdering.add(&name);
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly );
|
||||
|
||||
protected:
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const;
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ;
|
||||
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute);
|
||||
|
||||
private:
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "RimResultCase.h"
|
||||
#include "cafProgressInfo.h"
|
||||
#include "RigActiveCellInfo.h"
|
||||
#include "RigGridManager.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimIdenticalGridCaseGroup, "RimIdenticalGridCaseGroup");
|
||||
@@ -78,22 +79,17 @@ void RimIdenticalGridCaseGroup::addCase(RimCase* reservoir)
|
||||
|
||||
if (!reservoir) return;
|
||||
|
||||
RigMainGrid* incomingMainGrid = reservoir->reservoirData()->mainGrid();
|
||||
|
||||
if (!m_mainGrid)
|
||||
{
|
||||
m_mainGrid = incomingMainGrid;
|
||||
m_mainGrid = reservoir->reservoirData()->mainGrid();
|
||||
}
|
||||
|
||||
CVF_ASSERT(m_mainGrid == incomingMainGrid);
|
||||
|
||||
caseCollection()->reservoirs().push_back(reservoir);
|
||||
|
||||
if (statisticsCaseCollection->reservoirs().size() == 0)
|
||||
else
|
||||
{
|
||||
createAndAppendStatisticsCase();
|
||||
reservoir->reservoirData()->setMainGrid(m_mainGrid);
|
||||
}
|
||||
|
||||
caseCollection()->reservoirs().push_back(reservoir);
|
||||
|
||||
clearActiveCellUnions();
|
||||
clearStatisticsResults();
|
||||
updateMainGridAndActiveCellsForStatisticsCases();
|
||||
@@ -104,6 +100,11 @@ void RimIdenticalGridCaseGroup::addCase(RimCase* reservoir)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimIdenticalGridCaseGroup::removeCase(RimCase* reservoir)
|
||||
{
|
||||
if (caseCollection()->reservoirs().count(reservoir) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
caseCollection()->reservoirs().removeChildObject(reservoir);
|
||||
|
||||
if (caseCollection()->reservoirs().size() == 0)
|
||||
@@ -151,7 +152,11 @@ void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo()
|
||||
RimCase* mainCase = caseCollection()->reservoirs[0];
|
||||
mainCase->openEclipseGridFile();
|
||||
RigCaseData* mainEclipseCase = mainCase->reservoirData();
|
||||
CVF_ASSERT(mainEclipseCase);
|
||||
if (!mainEclipseCase)
|
||||
{
|
||||
// Error message
|
||||
return;
|
||||
}
|
||||
|
||||
// Read active cell info from all source cases
|
||||
|
||||
@@ -163,7 +168,8 @@ void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo()
|
||||
|
||||
if (!rimReservoir->openAndReadActiveCellData(mainEclipseCase))
|
||||
{
|
||||
CVF_ASSERT(false);
|
||||
// Error message
|
||||
continue;
|
||||
}
|
||||
|
||||
info.incrementProgress();
|
||||
@@ -299,7 +305,7 @@ RimStatisticsCase* RimIdenticalGridCaseGroup::createAndAppendStatisticsCase()
|
||||
{
|
||||
RimStatisticsCase* newStatisticsCase = new RimStatisticsCase;
|
||||
|
||||
newStatisticsCase->caseName = QString("Statistics ") + QString::number(statisticsCaseCollection()->reservoirs.size()+1);
|
||||
newStatisticsCase->caseUserDescription = QString("Statistics ") + QString::number(statisticsCaseCollection()->reservoirs.size()+1);
|
||||
statisticsCaseCollection()->reservoirs.push_back(newStatisticsCase);
|
||||
|
||||
newStatisticsCase->openEclipseGridFile();
|
||||
@@ -367,7 +373,7 @@ bool RimIdenticalGridCaseGroup::contains(RimCase* reservoir) const
|
||||
for (size_t i = 0; i < caseCollection()->reservoirs().size(); i++)
|
||||
{
|
||||
RimCase* rimReservoir = caseCollection()->reservoirs()[i];
|
||||
if (reservoir->caseName == reservoir->caseName)
|
||||
if (reservoir->gridFileName() == rimReservoir->gridFileName())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -376,6 +382,9 @@ bool RimIdenticalGridCaseGroup::contains(RimCase* reservoir) const
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigActiveCellInfo* RimIdenticalGridCaseGroup::unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType)
|
||||
{
|
||||
if (porosityType == RifReaderInterface::MATRIX_RESULTS)
|
||||
@@ -405,3 +414,41 @@ bool RimIdenticalGridCaseGroup::isStatisticsCaseCollection(RimCaseCollection* ri
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCase* RimIdenticalGridCaseGroup::mainCase()
|
||||
{
|
||||
if(caseCollection()->reservoirs().size())
|
||||
{
|
||||
return caseCollection()->reservoirs()[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimIdenticalGridCaseGroup::canCaseBeAdded(RimCase* reservoir) const
|
||||
{
|
||||
CVF_ASSERT(reservoir && reservoir->reservoirData() && reservoir->reservoirData()->mainGrid());
|
||||
|
||||
if (!m_mainGrid)
|
||||
{
|
||||
// Empty case group, reservoir can be added
|
||||
return true;
|
||||
}
|
||||
|
||||
RigMainGrid* incomingMainGrid = reservoir->reservoirData()->mainGrid();
|
||||
|
||||
if (RigGridManager::isEqual(m_mainGrid, incomingMainGrid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -43,37 +43,40 @@ public:
|
||||
RimIdenticalGridCaseGroup();
|
||||
virtual ~RimIdenticalGridCaseGroup();
|
||||
|
||||
caf::PdmField<QString> name;
|
||||
caf::PdmField<QString> name;
|
||||
caf::PdmField<RimCaseCollection*> caseCollection;
|
||||
caf::PdmField<RimCaseCollection*> statisticsCaseCollection;
|
||||
|
||||
void addCase(RimCase* reservoir);
|
||||
void removeCase(RimCase* reservoir);
|
||||
bool contains(RimCase* reservoir) const;
|
||||
void addCase(RimCase* reservoir);
|
||||
void removeCase(RimCase* reservoir);
|
||||
|
||||
RimStatisticsCase* createAndAppendStatisticsCase();
|
||||
bool contains(RimCase* reservoir) const;
|
||||
bool canCaseBeAdded(RimCase* reservoir) const;
|
||||
|
||||
caf::PdmField<RimCaseCollection*> caseCollection;
|
||||
caf::PdmField<RimCaseCollection*> statisticsCaseCollection;
|
||||
RimStatisticsCase* createAndAppendStatisticsCase();
|
||||
|
||||
void loadMainCaseAndActiveCellInfo();
|
||||
|
||||
RigMainGrid* mainGrid();
|
||||
RigActiveCellInfo* unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType);
|
||||
RimCase* mainCase();
|
||||
void loadMainCaseAndActiveCellInfo();
|
||||
|
||||
void computeUnionOfActiveCells();
|
||||
RigMainGrid* mainGrid();
|
||||
|
||||
static bool isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection);
|
||||
RigActiveCellInfo* unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType);
|
||||
void computeUnionOfActiveCells();
|
||||
|
||||
static bool isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection);
|
||||
|
||||
protected:
|
||||
virtual caf::PdmFieldHandle* userDescriptionField();
|
||||
virtual caf::PdmFieldHandle* userDescriptionField();
|
||||
|
||||
private:
|
||||
void updateMainGridAndActiveCellsForStatisticsCases();
|
||||
void clearStatisticsResults();
|
||||
void clearActiveCellUnions();
|
||||
void updateMainGridAndActiveCellsForStatisticsCases();
|
||||
void clearStatisticsResults();
|
||||
void clearActiveCellUnions();
|
||||
|
||||
private:
|
||||
RigMainGrid* m_mainGrid;
|
||||
RigMainGrid* m_mainGrid;
|
||||
|
||||
cvf::ref<RigActiveCellInfo> m_unionOfMatrixActiveCells;
|
||||
cvf::ref<RigActiveCellInfo> m_unionOfFractureActiveCells;
|
||||
cvf::ref<RigActiveCellInfo> m_unionOfMatrixActiveCells;
|
||||
cvf::ref<RigActiveCellInfo> m_unionOfFractureActiveCells;
|
||||
};
|
||||
|
||||
@@ -47,8 +47,9 @@ RimInputCase::RimInputCase()
|
||||
{
|
||||
CAF_PDM_InitObject("RimInputCase", ":/EclipseInput48x48.png", "", "");
|
||||
CAF_PDM_InitField(&m_gridFileName, "GridFileName", QString(), "Case grid filename", "", "" ,"");
|
||||
m_gridFileName.setUiReadOnly(true);
|
||||
CAF_PDM_InitFieldNoDefault(&m_additionalFileNames, "AdditionalFileNames", "Additional files", "", "" ,"");
|
||||
|
||||
m_additionalFileNames.setUiReadOnly(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_inputPropertyCollection, "InputPropertyCollection", "", "", "", "");
|
||||
m_inputPropertyCollection = new RimInputPropertyCollection;
|
||||
@@ -69,9 +70,9 @@ RimInputCase::~RimInputCase()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimInputCase::openDataFileSet(const QStringList& filenames)
|
||||
{
|
||||
if (caseName().contains("Input Mock Debug Model"))
|
||||
if (filenames.contains("Input Mock Debug Model"))
|
||||
{
|
||||
cvf::ref<RifReaderInterface> readerInterface = this->createMockModel(this->caseName());
|
||||
cvf::ref<RifReaderInterface> readerInterface = this->createMockModel(filenames[0]);
|
||||
results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p());
|
||||
results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p());
|
||||
|
||||
@@ -161,9 +162,9 @@ bool RimInputCase::openEclipseGridFile()
|
||||
{
|
||||
cvf::ref<RifReaderInterface> readerInterface;
|
||||
|
||||
if (caseName().contains("Input Mock Debug Model"))
|
||||
if (m_gridFileName().contains("Input Mock Debug Model"))
|
||||
{
|
||||
readerInterface = this->createMockModel(this->caseName());
|
||||
readerInterface = this->createMockModel(this->m_gridFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -375,6 +376,8 @@ cvf::ref<RifReaderInterface> RimInputCase::createMockModel(QString modelName)
|
||||
|
||||
if (modelName == "Input Mock Debug Model Simple")
|
||||
{
|
||||
m_gridFileName = modelName;
|
||||
|
||||
// Create the mock file interface and and RigSerervoir and set them up.
|
||||
mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20));
|
||||
mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6));
|
||||
@@ -419,3 +422,19 @@ QString RimInputCase::locationOnDisc() const
|
||||
QFileInfo fi(m_gridFileName);
|
||||
return fi.absolutePath();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimInputCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath)
|
||||
{
|
||||
bool foundFile = false;
|
||||
std::vector<QString> searchedPaths;
|
||||
|
||||
m_gridFileName = relocateFile(m_gridFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths);
|
||||
|
||||
for (size_t i = 0; i < m_additionalFileNames().size(); i++)
|
||||
{
|
||||
m_additionalFileNames.v()[i] = relocateFile(m_additionalFileNames()[i], newProjectPath, oldProjectPath, &foundFile, &searchedPaths);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,29 +45,34 @@ public:
|
||||
virtual ~RimInputCase();
|
||||
|
||||
// Fields
|
||||
caf::PdmField<std::vector<QString> > m_additionalFileNames;
|
||||
caf::PdmField<QString> m_gridFileName;
|
||||
|
||||
caf::PdmField<RimInputPropertyCollection*> m_inputPropertyCollection;
|
||||
|
||||
// File open methods
|
||||
void openDataFileSet(const QStringList& filenames);
|
||||
void loadAndSyncronizeInputProperties();
|
||||
void openDataFileSet(const QStringList& filenames);
|
||||
void loadAndSyncronizeInputProperties();
|
||||
|
||||
void removeProperty(RimInputProperty* inputProperty);
|
||||
void removeProperty(RimInputProperty* inputProperty);
|
||||
|
||||
// RimCase overrides
|
||||
virtual bool openEclipseGridFile(); // Find grid file among file set. Read, Find read and validate property date. Syncronize child property sets.
|
||||
|
||||
// PdmObject overrides
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
virtual QString locationOnDisc() const;
|
||||
// Overrides from RimCase
|
||||
virtual QString locationOnDisc() const;
|
||||
virtual QString gridFileName() const { return m_gridFileName();}
|
||||
|
||||
virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath);
|
||||
|
||||
private:
|
||||
void addFiles(const QStringList& newFileNames);
|
||||
void removeFiles(const QStringList& obsoleteFileNames);
|
||||
void addFiles(const QStringList& newFileNames);
|
||||
void removeFiles(const QStringList& obsoleteFileNames);
|
||||
|
||||
cvf::ref<RifReaderInterface> createMockModel(QString modelName);
|
||||
|
||||
// Fields
|
||||
caf::PdmField<std::vector<QString> > m_additionalFileNames;
|
||||
caf::PdmField<QString> m_gridFileName;
|
||||
|
||||
};
|
||||
|
||||
@@ -231,3 +231,40 @@ void RimProject::insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, Rim
|
||||
caseGroup->addCase(rimReservoir);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimProject::setProjectFileNameAndUpdateDependencies(const QString& fileName)
|
||||
{
|
||||
// Extract the filename of the project file when it was saved
|
||||
QString oldProjectFileName = this->fileName;
|
||||
// Replace with the new actual filename
|
||||
this->fileName = fileName;
|
||||
|
||||
// Loop over all reservoirs and update file path
|
||||
|
||||
QFileInfo fileInfo(fileName);
|
||||
QString newProjectPath = fileInfo.path();
|
||||
|
||||
QFileInfo fileInfoOld(oldProjectFileName);
|
||||
QString oldProjectPath = fileInfoOld.path();
|
||||
|
||||
|
||||
for (size_t i = 0; i < reservoirs.size(); i++)
|
||||
{
|
||||
reservoirs[i]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath);
|
||||
}
|
||||
|
||||
// Case groups : Loop over all reservoirs in and update file path
|
||||
|
||||
for (size_t i = 0; i < caseGroups.size(); i++)
|
||||
{
|
||||
RimIdenticalGridCaseGroup* cg = caseGroups()[i];
|
||||
|
||||
for (size_t j = 0; j < cg->caseCollection()->reservoirs().size(); j++)
|
||||
{
|
||||
cg->caseCollection()->reservoirs()[j]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,11 @@ class RimProject : public caf::PdmDocument
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::PdmPointersField<RimCase*> reservoirs;
|
||||
caf::PdmPointersField<RimCase*> reservoirs;
|
||||
caf::PdmPointersField<RimIdenticalGridCaseGroup*> caseGroups;
|
||||
caf::PdmField<RimScriptCollection*> scriptCollection;
|
||||
|
||||
void setUserScriptPath(const QString& path);
|
||||
//void updateProjectScriptPath();
|
||||
|
||||
QString projectFileVersionString() const;
|
||||
|
||||
@@ -52,6 +51,8 @@ public:
|
||||
|
||||
void moveEclipseCaseIntoCaseGroup(RimCase* rimReservoir);
|
||||
void removeCaseFromAllGroups(RimCase* rimReservoir);
|
||||
|
||||
void setProjectFileNameAndUpdateDependencies(const QString& fileName);
|
||||
|
||||
private:
|
||||
RigMainGrid* registerCaseInGridCollection(RigCaseData* rigEclipseCase);
|
||||
@@ -63,6 +64,5 @@ protected:
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_projectFileVersionString;
|
||||
|
||||
cvf::ref<RigGridManager> m_gridCollection;
|
||||
cvf::ref<RigGridManager> m_gridCollection;
|
||||
};
|
||||
|
||||
@@ -217,17 +217,34 @@ RifReaderInterface* RimReservoirCellResultsStorage::readerInterface()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex)
|
||||
{
|
||||
if (!m_cellResults) return cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
// Special handling for SOIL
|
||||
if (type == RimDefines::DYNAMIC_NATIVE && resultName.toUpper() == "SOIL")
|
||||
{
|
||||
loadOrComputeSOILForTimeStep(timeStepIndex);
|
||||
size_t soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName);
|
||||
|
||||
// If SOIL is not found, try to compute and return computed scalar index
|
||||
// Will return cvf::UNDEFINED_SIZE_T if no SGAS/SWAT is found
|
||||
if (soilScalarResultIndex == cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
computeSOILForTimeStep(timeStepIndex);
|
||||
|
||||
soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName);
|
||||
return soilScalarResultIndex;
|
||||
}
|
||||
|
||||
// If we have found SOIL and SOIL must be calculated, calculate and return
|
||||
if (soilScalarResultIndex != cvf::UNDEFINED_SIZE_T && m_cellResults->mustBeCalculated(soilScalarResultIndex))
|
||||
{
|
||||
computeSOILForTimeStep(timeStepIndex);
|
||||
|
||||
return soilScalarResultIndex;
|
||||
}
|
||||
}
|
||||
|
||||
size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName);
|
||||
|
||||
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T;
|
||||
size_t scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName);
|
||||
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
if (type == RimDefines::GENERATED)
|
||||
{
|
||||
@@ -280,11 +297,10 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefi
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName)
|
||||
{
|
||||
size_t resultGridIndex = cvf::UNDEFINED_SIZE_T;
|
||||
if (!m_cellResults) return cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
resultGridIndex = m_cellResults->findScalarResultIndex(type, resultName);
|
||||
|
||||
if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T;
|
||||
size_t resultGridIndex = m_cellResults->findScalarResultIndex(type, resultName);
|
||||
if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
// If we have any results on any timestep, assume we have loaded results already
|
||||
|
||||
@@ -343,14 +359,21 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::Result
|
||||
return resultGridIndex;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoirCellResultsStorage::loadOrComputeSOIL()
|
||||
{
|
||||
size_t scalarIndexSOIL = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL");
|
||||
if (scalarIndexSOIL != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t timeStepIdx = 0; timeStepIdx < m_cellResults->maxTimeStepCount(); timeStepIdx++)
|
||||
{
|
||||
loadOrComputeSOILForTimeStep(timeStepIdx);
|
||||
computeSOILForTimeStep(timeStepIdx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,7 +381,7 @@ void RimReservoirCellResultsStorage::loadOrComputeSOIL()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoirCellResultsStorage::loadOrComputeSOILForTimeStep(size_t timeStepIndex)
|
||||
void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex)
|
||||
{
|
||||
size_t scalarIndexSWAT = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SWAT", timeStepIndex);
|
||||
size_t scalarIndexSGAS = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SGAS", timeStepIndex);
|
||||
@@ -369,6 +392,8 @@ void RimReservoirCellResultsStorage::loadOrComputeSOILForTimeStep(size_t timeSte
|
||||
return;
|
||||
}
|
||||
|
||||
CVF_ASSERT(m_cellResults);
|
||||
|
||||
size_t soilResultValueCount = 0;
|
||||
size_t soilTimeStepCount = 0;
|
||||
|
||||
@@ -410,6 +435,9 @@ void RimReservoirCellResultsStorage::loadOrComputeSOILForTimeStep(size_t timeSte
|
||||
soilResultGridIndex = m_cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL", false);
|
||||
CVF_ASSERT(soilResultGridIndex != cvf::UNDEFINED_SIZE_T);
|
||||
|
||||
// Set this result to be calculated
|
||||
m_cellResults->setMustBeCalculated(soilResultGridIndex);
|
||||
|
||||
m_cellResults->cellScalarResults(soilResultGridIndex).resize(soilTimeStepCount);
|
||||
|
||||
for (size_t timeStepIdx = 0; timeStepIdx < soilTimeStepCount; timeStepIdx++)
|
||||
@@ -444,6 +472,8 @@ void RimReservoirCellResultsStorage::loadOrComputeSOILForTimeStep(size_t timeSte
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoirCellResultsStorage::computeDepthRelatedResults()
|
||||
{
|
||||
if (!m_cellResults) return;
|
||||
|
||||
size_t depthResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DEPTH");
|
||||
size_t dxResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DX");
|
||||
size_t dyResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DY");
|
||||
@@ -549,6 +579,8 @@ void RimReservoirCellResultsStorage::computeDepthRelatedResults()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& resultName)
|
||||
{
|
||||
if (!m_cellResults) return cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T;
|
||||
|
||||
scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName);
|
||||
|
||||
@@ -59,7 +59,7 @@ protected:
|
||||
virtual void setupBeforeSave();
|
||||
|
||||
private:
|
||||
void loadOrComputeSOILForTimeStep(size_t timeStepIndex);
|
||||
void computeSOILForTimeStep(size_t timeStepIndex);
|
||||
|
||||
QString getValidCacheFileName();
|
||||
QString getCacheDirectoryPath();
|
||||
|
||||
@@ -255,7 +255,7 @@ void RimReservoirView::updateViewerWidgetWindowTitle()
|
||||
QString windowTitle;
|
||||
if (m_reservoir.notNull())
|
||||
{
|
||||
windowTitle = QString("%1 - %2").arg(m_reservoir->caseName()).arg(name);
|
||||
windowTitle = QString("%1 - %2").arg(m_reservoir->caseUserDescription()).arg(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -702,7 +702,9 @@ void RimReservoirView::loadDataAndUpdate()
|
||||
{
|
||||
if (!m_reservoir->openEclipseGridFile())
|
||||
{
|
||||
QMessageBox::warning(RiuMainWindow::instance(), "Error when opening project file", "Could not open the Eclipse Grid file (EGRID/GRID): \n"+ m_reservoir->caseName());
|
||||
QMessageBox::warning(RiuMainWindow::instance(),
|
||||
"Error when opening project file",
|
||||
"Could not open the Eclipse Grid file: \n"+ m_reservoir->gridFileName());
|
||||
m_reservoir = NULL;
|
||||
return;
|
||||
}
|
||||
@@ -1282,3 +1284,24 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimReservoirView::updateDisplayModelForWellResults()
|
||||
{
|
||||
m_geometry->clearGeometryCache();
|
||||
m_pipesPartManager->clearGeometryCache();
|
||||
|
||||
syncronizeWellsWithResults();
|
||||
|
||||
createDisplayModel();
|
||||
updateDisplayModelVisibility();
|
||||
|
||||
overlayInfoConfig()->update3DInfo();
|
||||
|
||||
if (animationMode && m_viewer)
|
||||
{
|
||||
m_viewer->slotSetCurrentFrame(m_currentTimeStep);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,11 +117,11 @@ public:
|
||||
caf::PdmField<bool> animationMode;
|
||||
|
||||
// Access internal objects
|
||||
RimReservoirCellResultsStorage* currentGridCellResults();
|
||||
RimReservoirCellResultsStorage* currentGridCellResults();
|
||||
RigActiveCellInfo* currentActiveCellInfo();
|
||||
|
||||
void setEclipseCase(RimCase* reservoir);
|
||||
RimCase* eclipseCase();
|
||||
RimCase* eclipseCase();
|
||||
|
||||
// Animation
|
||||
int currentTimeStep() { return m_currentTimeStep;}
|
||||
@@ -148,6 +148,8 @@ public:
|
||||
void createDisplayModelAndRedraw();
|
||||
void scheduleGeometryRegen(unsigned short geometryType);
|
||||
void schedulePipeGeometryRegen();
|
||||
void updateDisplayModelForWellResults();
|
||||
|
||||
|
||||
// Display model generation
|
||||
private:
|
||||
@@ -178,9 +180,7 @@ private:
|
||||
|
||||
private:
|
||||
caf::PdmField<int> m_currentTimeStep;
|
||||
QPointer<RiuViewer> m_viewer;
|
||||
caf::PdmPointer<RimCase> m_reservoir;
|
||||
|
||||
|
||||
QPointer<RiuViewer> m_viewer;
|
||||
caf::PdmPointer<RimCase> m_reservoir;
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "RifReaderEclipseInput.h"
|
||||
#include "cafProgressInfo.h"
|
||||
#include "RimProject.h"
|
||||
#include "RifEclipseOutputFileTools.h"
|
||||
#include "RiaApplication.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase");
|
||||
@@ -38,9 +40,16 @@ RimResultCase::RimResultCase()
|
||||
CAF_PDM_InitObject("Eclipse Case", ":/AppLogo48x48.png", "", "");
|
||||
|
||||
CAF_PDM_InitField(&caseFileName, "CaseFileName", QString(), "Case file name", "", "" ,"");
|
||||
CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,"");
|
||||
}
|
||||
caseFileName.setUiReadOnly(true);
|
||||
|
||||
// Obsolete, unused field
|
||||
CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,"");
|
||||
caseDirectory.setIOWritable(false);
|
||||
caseDirectory.setUiHidden(true);
|
||||
|
||||
m_activeCellInfoIsReadFromFile = false;
|
||||
m_gridAndWellDataIsReadFromFile = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -51,27 +60,26 @@ bool RimResultCase::openEclipseGridFile()
|
||||
|
||||
progInfo.setProgressDescription("Open Grid File");
|
||||
progInfo.setNextProgressIncrement(48);
|
||||
// Early exit if reservoir data is created
|
||||
if (this->reservoirData()) return true;
|
||||
|
||||
// Early exit if data is already read
|
||||
if (m_gridAndWellDataIsReadFromFile) return true;
|
||||
|
||||
cvf::ref<RifReaderInterface> readerInterface;
|
||||
|
||||
if (caseName().contains("Result Mock Debug Model"))
|
||||
if (caseFileName().contains("Result Mock Debug Model"))
|
||||
{
|
||||
readerInterface = this->createMockModel(this->caseName());
|
||||
|
||||
readerInterface = this->createMockModel(this->caseFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
QString fname = createAbsoluteFilenameFromCase(caseName);
|
||||
if (fname.isEmpty())
|
||||
if (!QFile::exists(caseFileName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cvf::ref<RigCaseData> eclipseCase = new RigCaseData;
|
||||
readerInterface = new RifReaderEclipseOutput;
|
||||
if (!readerInterface->open(fname, eclipseCase.p()))
|
||||
if (!readerInterface->open(caseFileName(), eclipseCase.p()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -90,6 +98,9 @@ bool RimResultCase::openEclipseGridFile()
|
||||
progInfo.setProgressDescription("Computing Case Cache");
|
||||
computeCachedData();
|
||||
|
||||
m_gridAndWellDataIsReadFromFile = true;
|
||||
m_activeCellInfoIsReadFromFile = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -98,16 +109,17 @@ bool RimResultCase::openEclipseGridFile()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimResultCase::openAndReadActiveCellData(RigCaseData* mainEclipseCase)
|
||||
{
|
||||
cvf::ref<RifReaderInterface> readerInterface;
|
||||
// Early exit if data is already read
|
||||
if (m_activeCellInfoIsReadFromFile) return true;
|
||||
|
||||
if (caseName().contains("Result Mock Debug Model"))
|
||||
cvf::ref<RifReaderInterface> readerInterface;
|
||||
if (caseFileName().contains("Result Mock Debug Model"))
|
||||
{
|
||||
readerInterface = this->createMockModel(this->caseName());
|
||||
readerInterface = this->createMockModel(this->caseFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
QString fname = createAbsoluteFilenameFromCase(caseName);
|
||||
if (fname.isEmpty())
|
||||
if (!QFile::exists(caseFileName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -127,7 +139,7 @@ bool RimResultCase::openAndReadActiveCellData(RigCaseData* mainEclipseCase)
|
||||
std::vector<QDateTime> timeStepDates = mainEclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->timeStepDates(scalarIndexWithMaxTimeStepCount);
|
||||
|
||||
cvf::ref<RifReaderEclipseOutput> readerEclipseOutput = new RifReaderEclipseOutput;
|
||||
if (!readerEclipseOutput->openAndReadActiveCellData(fname, timeStepDates, eclipseCase.p()))
|
||||
if (!readerEclipseOutput->openAndReadActiveCellData(caseFileName(), timeStepDates, eclipseCase.p()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -147,11 +159,11 @@ bool RimResultCase::openAndReadActiveCellData(RigCaseData* mainEclipseCase)
|
||||
|
||||
reservoirData()->computeActiveCellBoundingBoxes();
|
||||
|
||||
m_activeCellInfoIsReadFromFile = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -229,7 +241,6 @@ cvf::ref<RifReaderInterface> RimResultCase::createMockModel(QString modelName)
|
||||
return mockFileInterface.p();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -243,46 +254,54 @@ RimResultCase::~RimResultCase()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimResultCase::locationOnDisc() const
|
||||
{
|
||||
return caseDirectory;
|
||||
QFileInfo fi(caseFileName());
|
||||
return fi.absolutePath();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimResultCase::createAbsoluteFilenameFromCase(const QString& caseName)
|
||||
void RimResultCase::readGridDimensions(std::vector< std::vector<int> >& gridDimensions)
|
||||
{
|
||||
QString candidate;
|
||||
|
||||
candidate = QDir::fromNativeSeparators(caseDirectory.v() + QDir::separator() + caseName + ".EGRID");
|
||||
if (QFile::exists(candidate)) return candidate;
|
||||
|
||||
candidate = QDir::fromNativeSeparators(caseDirectory.v() + QDir::separator() + caseName + ".GRID");
|
||||
if (QFile::exists(candidate)) return candidate;
|
||||
|
||||
std::vector<caf::PdmObject*> parentObjects;
|
||||
this->parentObjects(parentObjects);
|
||||
|
||||
QString projectPath;
|
||||
for (size_t i = 0; i < parentObjects.size(); i++)
|
||||
{
|
||||
caf::PdmObject* obj = parentObjects[i];
|
||||
RimProject* proj = dynamic_cast<RimProject*>(obj);
|
||||
if (proj)
|
||||
{
|
||||
QFileInfo fi(proj->fileName);
|
||||
projectPath = fi.path();
|
||||
}
|
||||
}
|
||||
|
||||
if (!projectPath.isEmpty())
|
||||
{
|
||||
candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + caseName + ".EGRID");
|
||||
if (QFile::exists(candidate)) return candidate;
|
||||
|
||||
candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + caseName + ".GRID");
|
||||
if (QFile::exists(candidate)) return candidate;
|
||||
}
|
||||
|
||||
return QString();
|
||||
RifEclipseOutputFileTools::readGridDimensions(caseFileName(), gridDimensions);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath)
|
||||
{
|
||||
bool foundFile = false;
|
||||
std::vector<QString> searchedPaths;
|
||||
|
||||
// Update filename and folder paths when opening project from a different file location
|
||||
caseFileName = relocateFile(caseFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultCase::setCaseInfo(const QString& userDescription, const QString& caseFileName)
|
||||
{
|
||||
this->caseUserDescription = userDescription;
|
||||
this->caseFileName = caseFileName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimResultCase::initAfterRead()
|
||||
{
|
||||
RimCase::initAfterRead();
|
||||
|
||||
// Convert from old (9.0.2) way of storing the case file
|
||||
if (caseFileName().isEmpty())
|
||||
{
|
||||
if (!this->caseName().isEmpty() && !caseDirectory().isEmpty())
|
||||
{
|
||||
caseFileName = QDir::fromNativeSeparators(caseDirectory()) + "/" + caseName() + ".EGRID";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,21 +40,28 @@ public:
|
||||
RimResultCase();
|
||||
virtual ~RimResultCase();
|
||||
|
||||
|
||||
// Fields:
|
||||
caf::PdmField<QString> caseFileName;
|
||||
caf::PdmField<QString> caseDirectory;
|
||||
void setCaseInfo(const QString& userDescription, const QString& caseFileName);
|
||||
|
||||
virtual bool openEclipseGridFile();
|
||||
bool openAndReadActiveCellData(RigCaseData* mainEclipseCase);
|
||||
void readGridDimensions(std::vector< std::vector<int> >& gridDimensions);
|
||||
|
||||
//virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName;}
|
||||
|
||||
virtual QString locationOnDisc() const;
|
||||
// Overrides from RimCase
|
||||
virtual QString locationOnDisc() const;
|
||||
virtual QString gridFileName() const { return caseFileName();}
|
||||
virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath);
|
||||
|
||||
private:
|
||||
cvf::ref<RifReaderInterface> createMockModel(QString modelName);
|
||||
|
||||
QString createAbsoluteFilenameFromCase(const QString& caseName);
|
||||
virtual void initAfterRead();
|
||||
|
||||
// Fields:
|
||||
caf::PdmField<QString> caseFileName;
|
||||
|
||||
// Obsolete field
|
||||
caf::PdmField<QString> caseDirectory;
|
||||
|
||||
bool m_gridAndWellDataIsReadFromFile;
|
||||
bool m_activeCellInfoIsReadFromFile;
|
||||
};
|
||||
|
||||
@@ -183,10 +183,21 @@ bool RimResultDefinition::hasResult() const
|
||||
bool RimResultDefinition::hasDynamicResult() const
|
||||
{
|
||||
const RigCaseCellResultsData* gridCellResults = m_reservoirView->currentGridCellResults()->cellResults();
|
||||
if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) > 1 )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (hasResult())
|
||||
{
|
||||
if (resultType() == RimDefines::DYNAMIC_NATIVE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gridCellResults->timeStepCount(m_gridScalarResultIndex) > 1 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -26,6 +26,21 @@
|
||||
#include "RigCaseCellResultsData.h"
|
||||
#include "RimStatisticsCaseEvaluator.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "cafPdmUiTextEditor.h"
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
#include "RiuMainWindow.h"
|
||||
#include "RimUiTreeModelPdm.h"
|
||||
|
||||
namespace caf {
|
||||
template<>
|
||||
void caf::AppEnum<RimStatisticsCase::PercentileCalcType>::setUp()
|
||||
{
|
||||
addItem(RimStatisticsCase::NEAREST_OBSERVATION, "NearestObservationPercentile", "Nearest Observation");
|
||||
addItem(RimStatisticsCase::HISTOGRAM_ESTIMATED, "HistogramEstimatedPercentile", "Histogram based estimate");
|
||||
setDefault(RimStatisticsCase::NEAREST_OBSERVATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimStatisticsCase, "RimStatisticalCalculation");
|
||||
@@ -37,8 +52,55 @@ RimStatisticsCase::RimStatisticsCase()
|
||||
: RimCase()
|
||||
{
|
||||
CAF_PDM_InitObject("Case Group Statistics", ":/Histogram16x16.png", "", "");
|
||||
CAF_PDM_InitField(&m_resultName, "ResultName", QString("PRESSURE"), "ResultName", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_calculateEditCommand, "m_editingAllowed", "", "", "", "");
|
||||
m_calculateEditCommand.setIOWritable(false);
|
||||
m_calculateEditCommand.setIOReadable(false);
|
||||
m_calculateEditCommand.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
|
||||
m_calculateEditCommand.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
m_calculateEditCommand = false;
|
||||
|
||||
CAF_PDM_InitField(&m_selectionSummary, "SelectionSummary", QString(""), "Summary of calculation setup", "", "", "");
|
||||
m_selectionSummary.setIOWritable(false);
|
||||
m_selectionSummary.setIOReadable(false);
|
||||
m_selectionSummary.setUiReadOnly(true);
|
||||
m_selectionSummary.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
|
||||
m_selectionSummary.setUiLabelPosition(caf::PdmUiItemInfo::TOP);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_resultType, "ResultType", "Result Type", "", "", "");
|
||||
m_resultType.setIOWritable(false);
|
||||
CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModel", "Porosity Model", "", "", "");
|
||||
m_porosityModel.setIOWritable(false);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedDynamicProperties, "DynamicPropertiesToCalculate", "Dyn Prop", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedStaticProperties, "StaticPropertiesToCalculate", "Stat Prop", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedGeneratedProperties, "GeneratedPropertiesToCalculate", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedInputProperties, "InputPropertiesToCalculate", "", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedFractureDynamicProperties, "FractureDynamicPropertiesToCalculate", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedFractureStaticProperties, "FractureStaticPropertiesToCalculate", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedFractureGeneratedProperties, "FractureGeneratedPropertiesToCalculate", "", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_selectedFractureInputProperties, "FractureInputPropertiesToCalculate", "", "", "", "");
|
||||
|
||||
m_selectedDynamicProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_selectedStaticProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_selectedGeneratedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_selectedInputProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
m_selectedFractureDynamicProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_selectedFractureStaticProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_selectedFractureGeneratedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_selectedFractureInputProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
|
||||
CAF_PDM_InitField(&m_calculatePercentiles, "CalculatePercentiles", true, "Calculate Percentiles", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_percentileCalculationType, "PercentileCalculationType", "Method", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_lowPercentile, "LowPercentile", 10.0, "Low", "", "", "");
|
||||
CAF_PDM_InitField(&m_midPercentile, "MidPercentile", 50.0, "Mid", "", "", "");
|
||||
CAF_PDM_InitField(&m_highPercentile, "HighPercentile", 90.0, "High", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_wellDataSourceCase, "WellDataSourceCase", RimDefines::undefinedResultName(), "Well Data Source Case", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -84,17 +146,11 @@ bool RimStatisticsCase::openEclipseGridFile()
|
||||
|
||||
this->setReservoirData( eclipseCase.p() );
|
||||
|
||||
this->populateWithDefaultsIfNeeded();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -140,6 +196,12 @@ void RimStatisticsCase::computeStatistics()
|
||||
|
||||
RimStatisticsConfig statisticsConfig;
|
||||
|
||||
statisticsConfig.m_calculatePercentiles = m_calculatePercentiles();
|
||||
statisticsConfig.m_pMaxPos = m_highPercentile();
|
||||
statisticsConfig.m_pMidPos = m_midPercentile();
|
||||
statisticsConfig.m_pMinPos = m_lowPercentile();
|
||||
statisticsConfig.m_pValMethod = m_percentileCalculationType();
|
||||
|
||||
std::vector<size_t> timeStepIndices;
|
||||
for (size_t i = 0; i < timeStepCount; i++)
|
||||
{
|
||||
@@ -148,31 +210,53 @@ void RimStatisticsCase::computeStatistics()
|
||||
|
||||
RigCaseData* resultCase = reservoirData();
|
||||
|
||||
QList<QPair<RimDefines::ResultCatType, QString> > resultSpecification;
|
||||
QList<RimStatisticsCaseEvaluator::ResSpec > resultSpecification;
|
||||
|
||||
//resultSpecification.append(qMakePair(RimDefines::DYNAMIC_NATIVE, QString("PRESSURE")));
|
||||
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedDynamicProperties().size(); ++pIdx)
|
||||
{
|
||||
QStringList resultNames = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->resultNames(RimDefines::DYNAMIC_NATIVE);
|
||||
foreach(QString resultName, resultNames)
|
||||
{
|
||||
resultSpecification.append(qMakePair(RimDefines::DYNAMIC_NATIVE, resultName));
|
||||
}
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::DYNAMIC_NATIVE, m_selectedDynamicProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedStaticProperties().size(); ++pIdx)
|
||||
{
|
||||
QStringList resultNames = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->resultNames(RimDefines::STATIC_NATIVE);
|
||||
foreach(QString resultName, resultNames)
|
||||
{
|
||||
resultSpecification.append(qMakePair(RimDefines::STATIC_NATIVE, resultName));
|
||||
}
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::STATIC_NATIVE, m_selectedStaticProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedGeneratedProperties().size(); ++pIdx)
|
||||
{
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::GENERATED, m_selectedGeneratedProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedInputProperties().size(); ++pIdx)
|
||||
{
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::INPUT_PROPERTY, m_selectedInputProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedFractureDynamicProperties().size(); ++pIdx)
|
||||
{
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::DYNAMIC_NATIVE, m_selectedFractureDynamicProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedFractureStaticProperties().size(); ++pIdx)
|
||||
{
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::STATIC_NATIVE, m_selectedFractureStaticProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedFractureGeneratedProperties().size(); ++pIdx)
|
||||
{
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::GENERATED, m_selectedFractureGeneratedProperties()[pIdx]));
|
||||
}
|
||||
|
||||
for(size_t pIdx = 0; pIdx < m_selectedFractureInputProperties().size(); ++pIdx)
|
||||
{
|
||||
resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::INPUT_PROPERTY, m_selectedFractureInputProperties()[pIdx]));
|
||||
}
|
||||
|
||||
|
||||
RimStatisticsCaseEvaluator stat(sourceCases, timeStepIndices, statisticsConfig, resultCase);
|
||||
stat.evaluateForResults(resultSpecification);
|
||||
|
||||
// Todo: Is this really the time and place to do the following ? JJS
|
||||
|
||||
for (size_t i = 0; i < reservoirViews().size(); i++)
|
||||
{
|
||||
RimReservoirView* reservoirView = reservoirViews()[i];
|
||||
@@ -182,6 +266,8 @@ void RimStatisticsCase::computeStatistics()
|
||||
reservoirView->createDisplayModelAndRedraw();
|
||||
}
|
||||
|
||||
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -218,3 +304,373 @@ RimIdenticalGridCaseGroup* RimStatisticsCase::caseGroup()
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
|
||||
updateSelectionSummaryLabel();
|
||||
updateSelectionListVisibilities();
|
||||
updatePercentileUiVisibility();
|
||||
|
||||
uiOrdering.add(&caseUserDescription);
|
||||
uiOrdering.add(&m_calculateEditCommand);
|
||||
uiOrdering.add(&m_selectionSummary);
|
||||
|
||||
caf::PdmUiGroup * group = uiOrdering.addNewGroup("Properties to consider");
|
||||
group->setUiHidden(hasComputedStatistics());
|
||||
group->add(&m_resultType);
|
||||
group->add(&m_porosityModel);
|
||||
group->add(&m_selectedDynamicProperties);
|
||||
group->add(&m_selectedStaticProperties);
|
||||
group->add(&m_selectedGeneratedProperties);
|
||||
group->add(&m_selectedInputProperties);
|
||||
group->add(&m_selectedFractureDynamicProperties);
|
||||
group->add(&m_selectedFractureStaticProperties);
|
||||
group->add(&m_selectedFractureGeneratedProperties);
|
||||
group->add(&m_selectedFractureInputProperties);
|
||||
|
||||
group = uiOrdering.addNewGroup("Percentile setup");
|
||||
group->setUiHidden(hasComputedStatistics());
|
||||
group->add(&m_calculatePercentiles);
|
||||
group->add(&m_percentileCalculationType);
|
||||
group->add(&m_lowPercentile);
|
||||
group->add(&m_midPercentile);
|
||||
group->add(&m_highPercentile);
|
||||
}
|
||||
|
||||
QList<caf::PdmOptionItemInfo> toOptionList(const QStringList& varList)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> optionList;
|
||||
int i;
|
||||
for (i = 0; i < varList.size(); ++i)
|
||||
{
|
||||
optionList.push_back(caf::PdmOptionItemInfo( varList[i], varList[i]));
|
||||
}
|
||||
return optionList;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimStatisticsCase::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
if (useOptionsOnly) *useOptionsOnly = true;
|
||||
|
||||
RimIdenticalGridCaseGroup* idgcg = caseGroup();
|
||||
if (!(caseGroup() && caseGroup()->mainCase() && caseGroup()->mainCase()->reservoirData()))
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
RigCaseData* caseData = idgcg->mainCase()->reservoirData();
|
||||
|
||||
if (&m_selectedDynamicProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedStaticProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::STATIC_NATIVE);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedGeneratedProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::GENERATED);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedInputProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::INPUT_PROPERTY);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedFractureDynamicProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedFractureStaticProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::STATIC_NATIVE);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedFractureGeneratedProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::GENERATED);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
else if (&m_selectedFractureInputProperties == fieldNeedingOptions)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::INPUT_PROPERTY);
|
||||
return toOptionList(varList);
|
||||
}
|
||||
|
||||
else if (&m_wellDataSourceCase == fieldNeedingOptions)
|
||||
{
|
||||
QStringList sourceCaseNames;
|
||||
sourceCaseNames += RimDefines::undefinedResultName();
|
||||
|
||||
for (size_t i = 0; i < caseGroup()->caseCollection()->reservoirs().size(); i++)
|
||||
{
|
||||
sourceCaseNames += caseGroup()->caseCollection()->reservoirs()[i]->caseUserDescription();
|
||||
}
|
||||
|
||||
return toOptionList(sourceCaseNames);
|
||||
}
|
||||
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (&m_resultType == changedField || &m_porosityModel == changedField)
|
||||
{
|
||||
}
|
||||
|
||||
if (&m_calculateEditCommand == changedField)
|
||||
{
|
||||
if (hasComputedStatistics())
|
||||
{
|
||||
clearComputedStatistics();
|
||||
}
|
||||
else
|
||||
{
|
||||
computeStatistics();
|
||||
}
|
||||
m_calculateEditCommand = false;
|
||||
}
|
||||
|
||||
if (&m_wellDataSourceCase == changedField)
|
||||
{
|
||||
RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel();
|
||||
|
||||
// Find or load well data for given case
|
||||
RimCase* sourceResultCase = caseGroup()->caseCollection()->findByDescription(m_wellDataSourceCase);
|
||||
if (sourceResultCase)
|
||||
{
|
||||
sourceResultCase->openEclipseGridFile();
|
||||
|
||||
// Propagate well info to statistics case
|
||||
if (sourceResultCase->reservoirData())
|
||||
{
|
||||
const cvf::Collection<RigSingleWellResultsData>& sourceCaseWellResults = sourceResultCase->reservoirData()->wellResults();
|
||||
setWellResultsAndUpdateViews(sourceCaseWellResults);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cvf::Collection<RigSingleWellResultsData> sourceCaseWellResults;
|
||||
setWellResultsAndUpdateViews(sourceCaseWellResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::setWellResultsAndUpdateViews(const cvf::Collection<RigSingleWellResultsData>& sourceCaseWellResults)
|
||||
{
|
||||
RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel();
|
||||
|
||||
this->reservoirData()->setWellResults(sourceCaseWellResults);
|
||||
|
||||
// Update views
|
||||
for (size_t i = 0; i < reservoirViews().size(); i++)
|
||||
{
|
||||
RimReservoirView* reservoirView = reservoirViews()[i];
|
||||
CVF_ASSERT(reservoirView);
|
||||
|
||||
reservoirView->wellCollection()->wells.deleteAllChildObjects();
|
||||
reservoirView->updateDisplayModelForWellResults();
|
||||
|
||||
treeModel->rebuildUiSubTree(reservoirView->wellCollection());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void addPropertySetToHtmlText(QString& html, const QString& heading, const std::vector<QString>& varNames)
|
||||
{
|
||||
if (varNames.size())
|
||||
{
|
||||
html += "<p><b>" + heading + "</b></p>";
|
||||
html += "<p class=indent>";
|
||||
for (size_t pIdx = 0; pIdx < varNames.size(); ++pIdx)
|
||||
{
|
||||
html += varNames[pIdx];
|
||||
if ( (pIdx+1)%6 == 0 ) html += "<br>";
|
||||
else if (pIdx != varNames.size() -1) html += ", ";
|
||||
}
|
||||
html += "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::updateSelectionSummaryLabel()
|
||||
{
|
||||
QString html;
|
||||
|
||||
html += "<style> "
|
||||
"p{ margin-top:0px; margin-bottom:0px;} "
|
||||
"p.indent{margin-left:20px; margin-top:0px;} "
|
||||
"p.indent2{margin-left:40px; margin-top:0px;} "
|
||||
"</style>";
|
||||
|
||||
html += "<p><b>Statistical variables to compute:</b></p>";
|
||||
html += "<p class=indent>";
|
||||
html += "Min, Max, Range, Mean, Std.dev"; ;
|
||||
if (m_calculatePercentiles())
|
||||
{
|
||||
html += "<br>";
|
||||
html += "Percentiles for : "
|
||||
+ QString::number(m_lowPercentile()) + ", "
|
||||
+ QString::number(m_midPercentile()) + ", "
|
||||
+ QString::number(m_highPercentile());
|
||||
}
|
||||
html += "</p>";
|
||||
|
||||
addPropertySetToHtmlText(html, "Dynamic properties", m_selectedDynamicProperties());
|
||||
addPropertySetToHtmlText(html, "Static properties", m_selectedStaticProperties());
|
||||
addPropertySetToHtmlText(html, "Generated properties", m_selectedGeneratedProperties());
|
||||
addPropertySetToHtmlText(html, "Input properties", m_selectedInputProperties());
|
||||
|
||||
addPropertySetToHtmlText(html, "Dynamic properties, fracture model" , m_selectedFractureDynamicProperties());
|
||||
addPropertySetToHtmlText(html, "Static properties, fracture model" , m_selectedFractureStaticProperties());
|
||||
addPropertySetToHtmlText(html, "Generated properties, fracture model", m_selectedFractureGeneratedProperties());
|
||||
addPropertySetToHtmlText(html, "Input properties, fracture model" , m_selectedFractureInputProperties());
|
||||
|
||||
m_selectionSummary = html;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute)
|
||||
{
|
||||
if (&m_selectionSummary == field)
|
||||
{
|
||||
caf::PdmUiTextEditorAttribute* textEditAttrib = dynamic_cast<caf::PdmUiTextEditorAttribute*> (attribute);
|
||||
textEditAttrib->textMode = caf::PdmUiTextEditorAttribute::HTML;
|
||||
}
|
||||
|
||||
if (&m_calculateEditCommand == field)
|
||||
{
|
||||
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
|
||||
attrib->m_buttonText = hasComputedStatistics() ? "Edit (Will DELETE current results)": "Compute";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::updateSelectionListVisibilities()
|
||||
{
|
||||
bool isLocked = hasComputedStatistics();
|
||||
m_resultType.setUiHidden(isLocked);
|
||||
m_porosityModel.setUiHidden(isLocked ); // || !caseGroup()->mainCase()->reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->resultCount()
|
||||
|
||||
m_selectedDynamicProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE));
|
||||
m_selectedStaticProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::STATIC_NATIVE));
|
||||
m_selectedGeneratedProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::GENERATED));
|
||||
m_selectedInputProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY));
|
||||
|
||||
m_selectedFractureDynamicProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE));
|
||||
m_selectedFractureStaticProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::STATIC_NATIVE));
|
||||
m_selectedFractureGeneratedProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::GENERATED));
|
||||
m_selectedFractureInputProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::updatePercentileUiVisibility()
|
||||
{
|
||||
bool isLocked = hasComputedStatistics();
|
||||
m_calculatePercentiles.setUiHidden(isLocked);
|
||||
m_percentileCalculationType.setUiHidden( isLocked || !m_calculatePercentiles());
|
||||
m_lowPercentile .setUiHidden(isLocked || !m_calculatePercentiles());
|
||||
m_midPercentile .setUiHidden(isLocked || !m_calculatePercentiles());
|
||||
m_highPercentile.setUiHidden(isLocked || !m_calculatePercentiles());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimStatisticsCase::hasComputedStatistics() const
|
||||
{
|
||||
if ( reservoirData()
|
||||
&& ( reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->resultCount()
|
||||
|| reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->resultCount()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::clearComputedStatistics()
|
||||
{
|
||||
reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->clearAllResults();
|
||||
reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->clearAllResults();
|
||||
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCase::populateWithDefaultsIfNeeded()
|
||||
{
|
||||
RimIdenticalGridCaseGroup* idgcg = caseGroup();
|
||||
if (!(caseGroup() && caseGroup()->mainCase() && caseGroup()->mainCase()->reservoirData()))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
RigCaseData* caseData = idgcg->mainCase()->reservoirData();
|
||||
|
||||
if (m_selectedDynamicProperties().size() == 0)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE);
|
||||
if (varList.contains("SOIL")) m_selectedDynamicProperties.v().push_back("SOIL");
|
||||
if (varList.contains("PRESSURE")) m_selectedDynamicProperties.v().push_back("PRESSURE");
|
||||
}
|
||||
|
||||
if (m_selectedStaticProperties().size() == 0)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::STATIC_NATIVE);
|
||||
if (varList.contains("PERMX")) m_selectedStaticProperties.v().push_back("PERMX");
|
||||
if (varList.contains("PORO")) m_selectedStaticProperties.v().push_back("PORO");
|
||||
}
|
||||
|
||||
if (m_selectedFractureDynamicProperties().size() == 0)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE);
|
||||
if (varList.contains("SOIL")) m_selectedFractureDynamicProperties.v().push_back("SOIL");
|
||||
if (varList.contains("PRESSURE")) m_selectedFractureDynamicProperties.v().push_back("PRESSURE");
|
||||
}
|
||||
|
||||
if (m_selectedFractureStaticProperties().size() == 0)
|
||||
{
|
||||
QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::STATIC_NATIVE);
|
||||
if (varList.contains("PERMX")) m_selectedFractureStaticProperties.v().push_back("PERMX");
|
||||
if (varList.contains("PORO")) m_selectedFractureStaticProperties.v().push_back("PORO");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class RimIdenticalGridCaseGroup;
|
||||
class RimResultDefinition;
|
||||
class RimStatisticsCaseCollection;
|
||||
class RigMainGrid;
|
||||
class RigSingleWellResultsData;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
@@ -46,18 +47,65 @@ public:
|
||||
|
||||
void setMainGrid(RigMainGrid* mainGrid);
|
||||
|
||||
virtual bool openEclipseGridFile();
|
||||
void computeStatistics();
|
||||
bool hasComputedStatistics() const;
|
||||
void clearComputedStatistics();
|
||||
|
||||
caf::PdmField<QString> m_resultName;
|
||||
virtual bool openEclipseGridFile();
|
||||
|
||||
RimCaseCollection* parentStatisticsCaseCollection();
|
||||
|
||||
virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) const;
|
||||
void computeStatistics();
|
||||
enum PercentileCalcType
|
||||
{
|
||||
NEAREST_OBSERVATION,
|
||||
HISTOGRAM_ESTIMATED
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
RimIdenticalGridCaseGroup* caseGroup();
|
||||
|
||||
void getSourceCases(std::vector<RimCase*>& sourceCases);
|
||||
|
||||
void populateWithDefaultsIfNeeded();
|
||||
|
||||
void updateSelectionListVisibilities();
|
||||
void updateSelectionSummaryLabel();
|
||||
void updatePercentileUiVisibility();
|
||||
|
||||
void setWellResultsAndUpdateViews(const cvf::Collection<RigSingleWellResultsData>& sourceCaseWellResults);
|
||||
|
||||
// Pdm system overrides
|
||||
virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) ;
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly );
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
|
||||
|
||||
virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute );
|
||||
|
||||
// Fields
|
||||
caf::PdmField< bool > m_calculateEditCommand;
|
||||
|
||||
caf::PdmField< caf::AppEnum< RimDefines::ResultCatType > > m_resultType;
|
||||
caf::PdmField< caf::AppEnum< RimDefines::PorosityModelType > > m_porosityModel;
|
||||
|
||||
caf::PdmField<QString> m_selectionSummary;
|
||||
|
||||
caf::PdmField<std::vector<QString> > m_selectedDynamicProperties;
|
||||
caf::PdmField<std::vector<QString> > m_selectedStaticProperties;
|
||||
caf::PdmField<std::vector<QString> > m_selectedGeneratedProperties;
|
||||
caf::PdmField<std::vector<QString> > m_selectedInputProperties;
|
||||
|
||||
caf::PdmField<std::vector<QString> > m_selectedFractureDynamicProperties;
|
||||
caf::PdmField<std::vector<QString> > m_selectedFractureStaticProperties;
|
||||
caf::PdmField<std::vector<QString> > m_selectedFractureGeneratedProperties;
|
||||
caf::PdmField<std::vector<QString> > m_selectedFractureInputProperties;
|
||||
|
||||
|
||||
caf::PdmField< bool > m_calculatePercentiles;
|
||||
caf::PdmField< caf::AppEnum< PercentileCalcType > > m_percentileCalculationType;
|
||||
caf::PdmField<double > m_lowPercentile;
|
||||
caf::PdmField<double > m_midPercentile;
|
||||
caf::PdmField<double > m_highPercentile;
|
||||
|
||||
caf::PdmField<QString> m_wellDataSourceCase;
|
||||
};
|
||||
|
||||
@@ -22,88 +22,12 @@
|
||||
#include "RimReservoirView.h"
|
||||
#include "RimCase.h"
|
||||
#include "RigCaseData.h"
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
//#include "RigCaseData.h"
|
||||
#include <QDebug>
|
||||
#include "cafProgressInfo.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// An internal class to do the actual computations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RimStatisticsEvaluator
|
||||
{
|
||||
public:
|
||||
RimStatisticsEvaluator(const std::vector<double>& values)
|
||||
: m_values(values),
|
||||
m_min(HUGE_VAL),
|
||||
m_max(-HUGE_VAL),
|
||||
m_mean(HUGE_VAL),
|
||||
m_dev(HUGE_VAL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void getStatistics(double& min, double& max, double& mean, double& dev, double& range)
|
||||
{
|
||||
evaluate();
|
||||
|
||||
min = m_min;
|
||||
max = m_max;
|
||||
mean = m_mean;
|
||||
dev = m_dev;
|
||||
|
||||
range = m_max - m_min;
|
||||
}
|
||||
|
||||
private:
|
||||
void evaluate()
|
||||
{
|
||||
double sum = 0.0;
|
||||
double sumSquared = 0.0;
|
||||
|
||||
size_t validValueCount = 0;
|
||||
|
||||
for (size_t i = 0; i < m_values.size(); i++)
|
||||
{
|
||||
double val = m_values[i];
|
||||
if (val == HUGE_VAL) continue;
|
||||
|
||||
validValueCount++;
|
||||
|
||||
if (val < m_min) m_min = val;
|
||||
if (val > m_max) m_max = val;
|
||||
|
||||
sum += val;
|
||||
sumSquared += (val * val);
|
||||
}
|
||||
|
||||
if (validValueCount > 0)
|
||||
{
|
||||
m_mean = sum / validValueCount;
|
||||
|
||||
|
||||
// http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
|
||||
// Running standard deviation
|
||||
|
||||
double s0 = validValueCount;
|
||||
double s1 = sum;
|
||||
double s2 = sumSquared;
|
||||
|
||||
m_dev = cvf::Math::sqrt( (s0 * s2) - (s1 * s1) ) / s0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const std::vector<double>& m_values;
|
||||
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_mean;
|
||||
double m_dev;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -135,29 +59,28 @@ QString createResultNameMax(const QString& resultName) { return resultName + "_
|
||||
QString createResultNameMean(const QString& resultName) { return resultName + "_MEAN"; }
|
||||
QString createResultNameDev(const QString& resultName) { return resultName + "_DEV"; }
|
||||
QString createResultNameRange(const QString& resultName) { return resultName + "_RANGE"; }
|
||||
QString createResultNamePVal(const QString& resultName, double pValPos) { return resultName + "_P_" + QString::number(pValPos); }
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCaseEvaluator::buildSourceMetaData(RimDefines::ResultCatType resultType, const QString& resultName)
|
||||
void RimStatisticsCaseEvaluator::buildSourceMetaData(RifReaderInterface::PorosityModelResultType poroModel, RimDefines::ResultCatType resultType, const QString& resultName)
|
||||
{
|
||||
if (m_sourceCases.size() == 0) return;
|
||||
|
||||
std::vector<QDateTime> timeStepDates = m_sourceCases[0]->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDates(0);
|
||||
std::vector<QDateTime> timeStepDates = m_sourceCases[0]->results(poroModel)->cellResults()->timeStepDates(0);
|
||||
|
||||
for (size_t caseIdx = 1; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||
{
|
||||
RigCaseData* eclipseCase = m_sourceCases.at(caseIdx)->reservoirData();
|
||||
|
||||
RimReservoirCellResultsStorage* matrixResults = m_sourceCases[caseIdx]->results(RifReaderInterface::MATRIX_RESULTS);
|
||||
size_t scalarResultIndex = matrixResults->findOrLoadScalarResult(resultType, resultName);
|
||||
RimReservoirCellResultsStorage* cellResultsStorage = m_sourceCases[caseIdx]->results(poroModel);
|
||||
size_t scalarResultIndex = cellResultsStorage->findOrLoadScalarResult(resultType, resultName);
|
||||
if (scalarResultIndex == cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
size_t scalarResultIndex = matrixResults->cellResults()->addEmptyScalarResult(resultType, resultName, false);
|
||||
matrixResults->cellResults()->setTimeStepDates(scalarResultIndex, timeStepDates);
|
||||
size_t scalarResultIndex = cellResultsStorage->cellResults()->addEmptyScalarResult(resultType, resultName, false);
|
||||
cellResultsStorage->cellResults()->setTimeStepDates(scalarResultIndex, timeStepDates);
|
||||
|
||||
std::vector< std::vector<double> >& dataValues = matrixResults->cellResults()->cellScalarResults(scalarResultIndex);
|
||||
std::vector< std::vector<double> >& dataValues = cellResultsStorage->cellResults()->cellScalarResults(scalarResultIndex);
|
||||
dataValues.resize(timeStepDates.size());
|
||||
}
|
||||
}
|
||||
@@ -166,222 +89,234 @@ void RimStatisticsCaseEvaluator::buildSourceMetaData(RimDefines::ResultCatType r
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimStatisticsCaseEvaluator::evaluateForResults(const QList<QPair<RimDefines::ResultCatType, QString> >& resultSpecification)
|
||||
void RimStatisticsCaseEvaluator::evaluateForResults(const QList<ResSpec>& resultSpecification)
|
||||
{
|
||||
CVF_ASSERT(m_destinationCase);
|
||||
|
||||
size_t activeMatrixCellCount = m_destinationCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount();
|
||||
RigCaseCellResultsData* matrixResults = m_destinationCase->results(RifReaderInterface::MATRIX_RESULTS);
|
||||
|
||||
// First build the destination result data structures to receive the statistics
|
||||
|
||||
for (int i = 0; i < resultSpecification.size(); i++)
|
||||
{
|
||||
RimDefines::ResultCatType resultType = resultSpecification[i].first;
|
||||
QString resultName = resultSpecification[i].second;
|
||||
RifReaderInterface::PorosityModelResultType poroModel = resultSpecification[i].m_poroModel;
|
||||
RimDefines::ResultCatType resultType = resultSpecification[i].m_resType;
|
||||
QString resultName = resultSpecification[i].m_resVarName;
|
||||
|
||||
size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->globalActiveCellCount();
|
||||
RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel);
|
||||
|
||||
// Special handling if SOIL is asked for
|
||||
// Build SGAS/SWAT meta data, SOIL is automatically generated as part of RigCaseCellResultsData::findOrLoadScalarResultForTimeStep
|
||||
if (resultName.toUpper() == "SOIL")
|
||||
{
|
||||
size_t swatIndex = m_sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->findScalarResultIndex(resultType, "SWAT");
|
||||
size_t swatIndex = m_sourceCases.at(0)->results(poroModel)->cellResults()->findScalarResultIndex(resultType, "SWAT");
|
||||
if (swatIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
buildSourceMetaData(resultType, "SWAT");
|
||||
buildSourceMetaData(poroModel, resultType, "SWAT");
|
||||
}
|
||||
|
||||
size_t sgasIndex = m_sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->findScalarResultIndex(resultType, "SGAS");
|
||||
size_t sgasIndex = m_sourceCases.at(0)->results(poroModel)->cellResults()->findScalarResultIndex(resultType, "SGAS");
|
||||
if (sgasIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
buildSourceMetaData(resultType, "SGAS");
|
||||
buildSourceMetaData(poroModel, resultType, "SGAS");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Meta info is loaded from disk for first case only
|
||||
// Build metadata for all other source cases
|
||||
buildSourceMetaData(resultType, resultName);
|
||||
// Meta info is loaded from disk for first case only
|
||||
// Build metadata for all other source cases
|
||||
buildSourceMetaData(poroModel, resultType, resultName);
|
||||
}
|
||||
|
||||
QString minResultName = createResultNameMin(resultName);
|
||||
QString maxResultName = createResultNameMax(resultName);
|
||||
QString meanResultName = createResultNameMean(resultName);
|
||||
QString devResultName = createResultNameDev(resultName);
|
||||
QString rangeResultName = createResultNameRange(resultName);
|
||||
// Create new result data structures to contain the statistical values
|
||||
std::vector<QString> statisticalResultNames;
|
||||
|
||||
if (activeMatrixCellCount > 0)
|
||||
statisticalResultNames.push_back(createResultNameMin(resultName));
|
||||
statisticalResultNames.push_back(createResultNameMax(resultName));
|
||||
statisticalResultNames.push_back(createResultNameMean(resultName));
|
||||
statisticalResultNames.push_back(createResultNameDev(resultName));
|
||||
statisticalResultNames.push_back(createResultNameRange(resultName));
|
||||
|
||||
if (m_statisticsConfig.m_calculatePercentiles)
|
||||
{
|
||||
addNamedResult(matrixResults, resultType, minResultName, activeMatrixCellCount);
|
||||
addNamedResult(matrixResults, resultType, maxResultName, activeMatrixCellCount);
|
||||
addNamedResult(matrixResults, resultType, meanResultName, activeMatrixCellCount);
|
||||
addNamedResult(matrixResults, resultType, devResultName, activeMatrixCellCount);
|
||||
addNamedResult(matrixResults, resultType, rangeResultName, activeMatrixCellCount);
|
||||
statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMinPos));
|
||||
statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMidPos));
|
||||
statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMaxPos));
|
||||
}
|
||||
|
||||
if (activeCellCount > 0)
|
||||
{
|
||||
for (size_t i = 0; i < statisticalResultNames.size(); ++i)
|
||||
{
|
||||
addNamedResult(destCellResultsData, resultType, statisticalResultNames[i], activeCellCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activeMatrixCellCount > 0)
|
||||
// Start the loop that calculates the statistics
|
||||
|
||||
caf::ProgressInfo progressInfo(m_timeStepIndices.size(), "Computing Statistics");
|
||||
|
||||
for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++)
|
||||
{
|
||||
caf::ProgressInfo info(m_timeStepIndices.size(), "Computing Statistics");
|
||||
size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx];
|
||||
|
||||
for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++)
|
||||
for (size_t gridIdx = 0; gridIdx < m_destinationCase->gridCount(); gridIdx++)
|
||||
{
|
||||
size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx];
|
||||
RigGridBase* grid = m_destinationCase->grid(gridIdx);
|
||||
|
||||
size_t gridCount = 0;
|
||||
for (size_t gridIdx = 0; gridIdx < m_destinationCase->gridCount(); gridIdx++)
|
||||
for (int i = 0; i < resultSpecification.size(); i++)
|
||||
{
|
||||
RigGridBase* grid = m_destinationCase->grid(gridIdx);
|
||||
RifReaderInterface::PorosityModelResultType poroModel = resultSpecification[i].m_poroModel;
|
||||
RimDefines::ResultCatType resultType = resultSpecification[i].m_resType;
|
||||
QString resultName = resultSpecification[i].m_resVarName;
|
||||
|
||||
for (int i = 0; i < resultSpecification.size(); i++)
|
||||
size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->globalActiveCellCount();
|
||||
|
||||
if (activeCellCount == 0) continue;
|
||||
|
||||
RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel);
|
||||
|
||||
size_t dataAccessTimeStepIndex = timeStepIdx;
|
||||
|
||||
// Always evaluate statistics once, and always use time step index zero
|
||||
if (resultType == RimDefines::STATIC_NATIVE)
|
||||
{
|
||||
RimDefines::ResultCatType resultType = resultSpecification[i].first;
|
||||
QString resultName = resultSpecification[i].second;
|
||||
if (timeIndicesIdx > 0) continue;
|
||||
|
||||
size_t dataAccessTimeStepIndex = timeStepIdx;
|
||||
dataAccessTimeStepIndex = 0;
|
||||
}
|
||||
|
||||
// Always evaluate statistics once, and always use time step index zero
|
||||
if (resultType == RimDefines::STATIC_NATIVE)
|
||||
// Build data access objects for source scalar results
|
||||
|
||||
cvf::Collection<cvf::StructGridScalarDataAccess> sourceDataAccessList;
|
||||
for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||
{
|
||||
RimCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||
|
||||
size_t scalarResultIndex = eclipseCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex);
|
||||
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->reservoirData()->dataAccessObject(grid, poroModel, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
if (dataAccessObject.notNull())
|
||||
{
|
||||
if (timeIndicesIdx > 0) continue;
|
||||
|
||||
dataAccessTimeStepIndex = 0;
|
||||
sourceDataAccessList.push_back(dataAccessObject.p());
|
||||
}
|
||||
}
|
||||
|
||||
// Build data access objects for source scalar results
|
||||
cvf::Collection<cvf::StructGridScalarDataAccess> dataAccesObjectList;
|
||||
for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||
// Build data access objects for destination scalar results
|
||||
// Find the created result container, if any, and put its dataAccessObject into the enum indexed destination collection
|
||||
|
||||
cvf::Collection<cvf::StructGridScalarDataAccess> destinationDataAccessList;
|
||||
std::vector<QString> statisticalResultNames(STAT_PARAM_COUNT);
|
||||
|
||||
statisticalResultNames[MIN] = createResultNameMin(resultName);
|
||||
statisticalResultNames[MAX] = createResultNameMax(resultName);
|
||||
statisticalResultNames[RANGE] = createResultNameRange(resultName);
|
||||
statisticalResultNames[MEAN] = createResultNameMean(resultName);
|
||||
statisticalResultNames[STDEV] = createResultNameDev(resultName);
|
||||
statisticalResultNames[PMIN] = createResultNamePVal(resultName, m_statisticsConfig.m_pMinPos);
|
||||
statisticalResultNames[PMID] = createResultNamePVal(resultName, m_statisticsConfig.m_pMidPos);
|
||||
statisticalResultNames[PMAX] = createResultNamePVal(resultName, m_statisticsConfig.m_pMaxPos);
|
||||
|
||||
for (size_t stIdx = 0; stIdx < statisticalResultNames.size(); ++stIdx)
|
||||
{
|
||||
size_t scalarResultIndex = destCellResultsData->findScalarResultIndex(resultType, statisticalResultNames[stIdx]);
|
||||
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
RimCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||
|
||||
size_t scalarResultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex);
|
||||
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->reservoirData()->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
if (dataAccessObject.notNull())
|
||||
{
|
||||
dataAccesObjectList.push_back(dataAccessObject.p());
|
||||
}
|
||||
destinationDataAccessList.push_back(m_destinationCase->dataAccessObject(grid, poroModel, dataAccessTimeStepIndex, scalarResultIndex).p());
|
||||
}
|
||||
|
||||
|
||||
// Build data access objects form destination scalar results
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectMin = NULL;
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectMax = NULL;
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectMean = NULL;
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectDev = NULL;
|
||||
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectRange = NULL;
|
||||
|
||||
else
|
||||
{
|
||||
size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameMin(resultName));
|
||||
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
dataAccessObjectMin = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
}
|
||||
destinationDataAccessList.push_back(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over the cells in the grid, get the case values, and calculate the cell statistics
|
||||
|
||||
for (size_t cellIdx = 0; cellIdx < grid->cellCount(); cellIdx++)
|
||||
{
|
||||
|
||||
size_t globalGridCellIdx = grid->globalGridCellIndex(cellIdx);
|
||||
if (m_destinationCase->activeCellInfo(poroModel)->isActive(globalGridCellIdx))
|
||||
{
|
||||
size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameMax(resultName));
|
||||
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
dataAccessObjectMax = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
}
|
||||
}
|
||||
// Extract the cell values from each of the cases and assemble them into one vector
|
||||
|
||||
{
|
||||
size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameMean(resultName));
|
||||
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
dataAccessObjectMean = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
}
|
||||
}
|
||||
std::vector<double> values(sourceDataAccessList.size(), HUGE_VAL);
|
||||
|
||||
{
|
||||
size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameDev(resultName));
|
||||
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
bool foundAnyValidValues = false;
|
||||
for (size_t caseIdx = 0; caseIdx < sourceDataAccessList.size(); caseIdx++)
|
||||
{
|
||||
dataAccessObjectDev = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
}
|
||||
}
|
||||
double val = sourceDataAccessList.at(caseIdx)->cellScalar(cellIdx);
|
||||
values[caseIdx] = val;
|
||||
|
||||
{
|
||||
size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameRange(resultName));
|
||||
if (scalarResultIndex != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
dataAccessObjectRange = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex);
|
||||
}
|
||||
}
|
||||
|
||||
double min, max, mean, dev, range;
|
||||
for (size_t cellIdx = 0; cellIdx < grid->cellCount(); cellIdx++)
|
||||
{
|
||||
std::vector<double> values(dataAccesObjectList.size(), HUGE_VAL);
|
||||
|
||||
size_t globalGridCellIdx = grid->globalGridCellIndex(cellIdx);
|
||||
if (m_destinationCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->isActive(globalGridCellIdx))
|
||||
{
|
||||
bool foundAnyValidValues = false;
|
||||
for (size_t caseIdx = 0; caseIdx < dataAccesObjectList.size(); caseIdx++)
|
||||
if (val != HUGE_VAL)
|
||||
{
|
||||
double val = dataAccesObjectList.at(caseIdx)->cellScalar(cellIdx);
|
||||
values[caseIdx] = val;
|
||||
foundAnyValidValues = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (val != HUGE_VAL)
|
||||
// Do the real statistics calculations
|
||||
std::vector<double> statParams(STAT_PARAM_COUNT, HUGE_VAL);
|
||||
|
||||
if (foundAnyValidValues)
|
||||
{
|
||||
RigStatisticsMath::calculateBasicStatistics(values, &statParams[MIN], &statParams[MAX], &statParams[RANGE], &statParams[MEAN], &statParams[STDEV]);
|
||||
|
||||
// Calculate percentiles
|
||||
if (m_statisticsConfig.m_calculatePercentiles )
|
||||
{
|
||||
if (m_statisticsConfig.m_pValMethod == RimStatisticsCase::NEAREST_OBSERVATION)
|
||||
{
|
||||
foundAnyValidValues = true;
|
||||
std::vector<double> pValPoss;
|
||||
pValPoss.push_back(m_statisticsConfig.m_pMinPos);
|
||||
pValPoss.push_back(m_statisticsConfig.m_pMidPos);
|
||||
pValPoss.push_back(m_statisticsConfig.m_pMaxPos);
|
||||
std::vector<double> pVals = RigStatisticsMath::calculateNearestRankPercentiles(values, pValPoss);
|
||||
statParams[PMIN] = pVals[0];
|
||||
statParams[PMID] = pVals[1];
|
||||
statParams[PMAX] = pVals[2];
|
||||
}
|
||||
else if (m_statisticsConfig.m_pValMethod == RimStatisticsCase::HISTOGRAM_ESTIMATED)
|
||||
{
|
||||
std::vector<size_t> histogram;
|
||||
RigHistogramCalculator histCalc(statParams[MIN], statParams[MAX], 100, &histogram);
|
||||
histCalc.addData(values);
|
||||
statParams[PMIN] = histCalc.calculatePercentil(m_statisticsConfig.m_pMinPos);
|
||||
statParams[PMID] = histCalc.calculatePercentil(m_statisticsConfig.m_pMidPos);
|
||||
statParams[PMAX] = histCalc.calculatePercentil(m_statisticsConfig.m_pMaxPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
CVF_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
min = HUGE_VAL;
|
||||
max = HUGE_VAL;
|
||||
mean = HUGE_VAL;
|
||||
dev = HUGE_VAL;
|
||||
range = HUGE_VAL;
|
||||
|
||||
if (foundAnyValidValues)
|
||||
{
|
||||
RimStatisticsEvaluator stat(values);
|
||||
stat.getStatistics(min, max, mean, dev, range);
|
||||
}
|
||||
// Set the results into the results data structures
|
||||
|
||||
if (dataAccessObjectMin.notNull())
|
||||
for (size_t stIdx = 0; stIdx < statParams.size(); ++stIdx)
|
||||
{
|
||||
if (destinationDataAccessList[stIdx].notNull())
|
||||
{
|
||||
dataAccessObjectMin->setCellScalar(cellIdx, min);
|
||||
}
|
||||
|
||||
if (dataAccessObjectMax.notNull())
|
||||
{
|
||||
dataAccessObjectMax->setCellScalar(cellIdx, max);
|
||||
}
|
||||
|
||||
if (dataAccessObjectMean.notNull())
|
||||
{
|
||||
dataAccessObjectMean->setCellScalar(cellIdx, mean);
|
||||
}
|
||||
|
||||
if (dataAccessObjectDev.notNull())
|
||||
{
|
||||
dataAccessObjectDev->setCellScalar(cellIdx, dev);
|
||||
}
|
||||
|
||||
if (dataAccessObjectRange.notNull())
|
||||
{
|
||||
dataAccessObjectRange->setCellScalar(cellIdx, range);
|
||||
destinationDataAccessList[stIdx]->setCellScalar(cellIdx, statParams[stIdx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||
{
|
||||
RimCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||
|
||||
// When one time step is completed, close all result files.
|
||||
// Microsoft note: On Windows, the maximum number of files open at the same time is 512
|
||||
// http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx
|
||||
//
|
||||
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->readerInterface()->close();
|
||||
}
|
||||
|
||||
info.setProgress(timeIndicesIdx);
|
||||
}
|
||||
|
||||
// When one time step is completed, close all result files.
|
||||
// Microsoft note: On Windows, the maximum number of files open at the same time is 512
|
||||
// http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx
|
||||
|
||||
for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++)
|
||||
{
|
||||
RimCase* eclipseCase = m_sourceCases.at(caseIdx);
|
||||
eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->readerInterface()->close();
|
||||
eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS)->readerInterface()->close();
|
||||
}
|
||||
|
||||
progressInfo.setProgress(timeIndicesIdx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <QPair>
|
||||
#include "RimDefines.h"
|
||||
#include "RimStatisticsCase.h"
|
||||
|
||||
class RimCase;
|
||||
class RigCaseData;
|
||||
@@ -36,18 +37,20 @@ class RimStatisticsConfig
|
||||
{
|
||||
public:
|
||||
RimStatisticsConfig()
|
||||
: m_min(true),
|
||||
m_max(true),
|
||||
m_mean(true),
|
||||
m_stdDev(true)
|
||||
: m_calculatePercentiles(true),
|
||||
m_pMinPos(10.0),
|
||||
m_pMidPos(50.0),
|
||||
m_pMaxPos(90.0),
|
||||
m_pValMethod(RimStatisticsCase::NEAREST_OBSERVATION)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
bool m_min;
|
||||
bool m_max;
|
||||
bool m_mean;
|
||||
bool m_stdDev;
|
||||
bool m_calculatePercentiles;
|
||||
double m_pMinPos;
|
||||
double m_pMidPos;
|
||||
double m_pMaxPos;
|
||||
RimStatisticsCase::PercentileCalcType m_pValMethod;
|
||||
};
|
||||
|
||||
|
||||
@@ -59,21 +62,34 @@ public:
|
||||
const RimStatisticsConfig& statisticsConfig,
|
||||
RigCaseData* destinationCase);
|
||||
|
||||
struct ResSpec
|
||||
{
|
||||
ResSpec() : m_resType(RimDefines::DYNAMIC_NATIVE), m_poroModel(RifReaderInterface::MATRIX_RESULTS) {}
|
||||
ResSpec( RifReaderInterface::PorosityModelResultType poroModel,
|
||||
RimDefines::ResultCatType resType,
|
||||
QString resVarName) : m_poroModel(poroModel), m_resType(resType), m_resVarName(resVarName) {}
|
||||
|
||||
void evaluateForResults(const QList<QPair<RimDefines::ResultCatType, QString> >& resultSpecification);
|
||||
RifReaderInterface::PorosityModelResultType m_poroModel;
|
||||
RimDefines::ResultCatType m_resType;
|
||||
QString m_resVarName;
|
||||
};
|
||||
|
||||
void evaluateForResults(const QList<ResSpec >& resultSpecification);
|
||||
|
||||
void debugOutput(RimDefines::ResultCatType resultType, const QString& resultName, size_t timeStepIdx);
|
||||
|
||||
private:
|
||||
void addNamedResult(RigCaseCellResultsData* cellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeCellCount);
|
||||
void buildSourceMetaData(RimDefines::ResultCatType resultType, const QString& resultName);
|
||||
void buildSourceMetaData(RifReaderInterface::PorosityModelResultType poroModel, RimDefines::ResultCatType resultType, const QString& resultName);
|
||||
|
||||
enum StatisticsParamType { MIN, MAX, RANGE, MEAN, STDEV, PMIN, PMID, PMAX, STAT_PARAM_COUNT };
|
||||
|
||||
private:
|
||||
std::vector<RimCase*> m_sourceCases;
|
||||
std::vector<size_t> m_timeStepIndices;
|
||||
std::vector<size_t> m_timeStepIndices;
|
||||
|
||||
size_t m_globalCellCount;
|
||||
RimStatisticsConfig m_statisticsConfig;
|
||||
RigCaseData* m_destinationCase;
|
||||
size_t m_globalCellCount;
|
||||
RimStatisticsConfig m_statisticsConfig;
|
||||
RigCaseData* m_destinationCase;
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
#include "RimInputCase.h"
|
||||
#include "RimStatisticsCase.h"
|
||||
#include "RimResultCase.h"
|
||||
#include "RigGridManager.h"
|
||||
#include "RimCase.h"
|
||||
#include "RigCaseData.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -215,6 +218,8 @@ bool RimUiTreeModelPdm::deleteReservoirView(const QModelIndex& itemIndex)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiTreeModelPdm::deleteReservoir(RimCase* reservoir)
|
||||
{
|
||||
if (reservoir->parentCaseCollection())
|
||||
{
|
||||
RimCaseCollection* caseCollection = reservoir->parentCaseCollection();
|
||||
QModelIndex caseCollectionModelIndex = getModelIndexFromPdmObject(caseCollection);
|
||||
if (!caseCollectionModelIndex.isValid()) return;
|
||||
@@ -241,6 +246,22 @@ void RimUiTreeModelPdm::deleteReservoir(RimCase* reservoir)
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
proj->removeCaseFromAllGroups(reservoir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
QModelIndex mi = getModelIndexFromPdmObject(reservoir);
|
||||
if (mi.isValid())
|
||||
{
|
||||
caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(mi);
|
||||
CVF_ASSERT(uiItem);
|
||||
|
||||
// Remove Ui items pointing at the pdm object to delete
|
||||
removeRows_special(mi.row(), 1, mi.parent());
|
||||
}
|
||||
|
||||
proj->removeCaseFromAllGroups(reservoir);
|
||||
}
|
||||
|
||||
delete reservoir;
|
||||
|
||||
@@ -364,8 +385,13 @@ RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemInd
|
||||
if (collectionItem)
|
||||
{
|
||||
RimCase* rimReservoir = dynamic_cast<RimCase*>(collectionItem->dataObject().p());
|
||||
rimReservoir->openEclipseGridFile();
|
||||
|
||||
RimReservoirView* insertedView = rimReservoir->createAndAddReservoirView();
|
||||
|
||||
// Must be run before buildViewItems, as wells are created in this function
|
||||
insertedView->loadDataAndUpdate();
|
||||
|
||||
int viewCount = rowCount(collectionIndex);
|
||||
beginInsertRows(collectionIndex, viewCount, viewCount);
|
||||
|
||||
@@ -374,8 +400,6 @@ RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemInd
|
||||
|
||||
endInsertRows();
|
||||
|
||||
insertedView->loadDataAndUpdate();
|
||||
|
||||
return insertedView;
|
||||
}
|
||||
|
||||
@@ -533,36 +557,36 @@ RimStatisticsCase* RimUiTreeModelPdm::addStatisticalCalculation(const QModelInde
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimIdenticalGridCaseGroup* RimUiTreeModelPdm::addCaseGroup(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex)
|
||||
RimIdenticalGridCaseGroup* RimUiTreeModelPdm::addCaseGroup(QModelIndex& insertedModelIndex)
|
||||
{
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
CVF_ASSERT(proj);
|
||||
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex);
|
||||
QModelIndex scriptModelIndex = getModelIndexFromPdmObject(proj->scriptCollection());
|
||||
if (!scriptModelIndex.isValid()) return NULL;
|
||||
|
||||
if (dynamic_cast<RimIdenticalGridCaseGroup*>(currentItem->dataObject().p()) ||
|
||||
dynamic_cast<RimCase*>(currentItem->dataObject().p()))
|
||||
{
|
||||
QModelIndex rootIndex = itemIndex.parent();
|
||||
caf::PdmUiTreeItem* rootTreeItem = currentItem->parent();
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(scriptModelIndex);
|
||||
if (!currentItem) return NULL;
|
||||
|
||||
// New case group is inserted before the last item, the script item
|
||||
int position = rootTreeItem->childCount() - 1;
|
||||
QModelIndex rootIndex = scriptModelIndex.parent();
|
||||
caf::PdmUiTreeItem* rootTreeItem = currentItem->parent();
|
||||
|
||||
beginInsertRows(rootIndex, position, position);
|
||||
// New case group is inserted before the last item, the script item
|
||||
int position = rootTreeItem->childCount() - 1;
|
||||
|
||||
RimIdenticalGridCaseGroup* createdObject = new RimIdenticalGridCaseGroup;
|
||||
proj->caseGroups().push_back(createdObject);
|
||||
beginInsertRows(rootIndex, position, position);
|
||||
|
||||
caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(rootTreeItem, position, createdObject);
|
||||
endInsertRows();
|
||||
RimIdenticalGridCaseGroup* createdObject = new RimIdenticalGridCaseGroup;
|
||||
createdObject->createAndAppendStatisticsCase();
|
||||
createdObject->name = QString("Grid Case Group %1").arg(position + 1);
|
||||
proj->caseGroups().push_back(createdObject);
|
||||
|
||||
insertedModelIndex = index(position, 0, rootIndex);
|
||||
caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(rootTreeItem, position, createdObject);
|
||||
endInsertRows();
|
||||
|
||||
return createdObject;
|
||||
}
|
||||
insertedModelIndex = index(position, 0, rootIndex);
|
||||
|
||||
return NULL;
|
||||
return createdObject;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -573,51 +597,30 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
CVF_ASSERT(proj);
|
||||
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex);
|
||||
|
||||
RimIdenticalGridCaseGroup* gridCaseGroup = NULL;
|
||||
RimCaseCollection* caseCollection = NULL;
|
||||
|
||||
if (dynamic_cast<RimIdenticalGridCaseGroup*>(currentItem->dataObject().p()))
|
||||
{
|
||||
gridCaseGroup = dynamic_cast<RimIdenticalGridCaseGroup*>(currentItem->dataObject().p());
|
||||
caseCollection = gridCaseGroup->caseCollection();
|
||||
}
|
||||
else if (dynamic_cast<RimCaseCollection*>(currentItem->dataObject().p()))
|
||||
{
|
||||
caseCollection = dynamic_cast<RimCaseCollection*>(currentItem->dataObject().p());
|
||||
CVF_ASSERT(caseCollection);
|
||||
|
||||
gridCaseGroup = caseCollection->parentCaseGroup();
|
||||
}
|
||||
else if (dynamic_cast<RimCase*>(currentItem->dataObject().p()))
|
||||
{
|
||||
RimCase* rimReservoir = dynamic_cast<RimCase*>(currentItem->dataObject().p());
|
||||
CVF_ASSERT(rimReservoir);
|
||||
|
||||
caseCollection = rimReservoir->parentCaseCollection();
|
||||
if (caseCollection)
|
||||
{
|
||||
gridCaseGroup = caseCollection->parentCaseGroup();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RimIdenticalGridCaseGroup* gridCaseGroup = gridCaseGroupFromItemIndex(itemIndex);
|
||||
if (gridCaseGroup)
|
||||
{
|
||||
std::vector<caf::PdmPointer<RimResultCase> > typedObjects;
|
||||
pdmObjects.createCopyByType(&typedObjects);
|
||||
|
||||
RigCaseData* mainEclipseCase = NULL;
|
||||
if (gridCaseGroup->caseCollection()->reservoirs().size() > 0)
|
||||
if (typedObjects.size() == 0)
|
||||
{
|
||||
RimCase* mainReservoir = gridCaseGroup->caseCollection()->reservoirs()[0];;
|
||||
mainEclipseCase = mainReservoir->reservoirData();
|
||||
return;
|
||||
}
|
||||
|
||||
RimResultCase* mainResultCase = NULL;
|
||||
std::vector< std::vector<int> > mainCaseGridDimensions;
|
||||
|
||||
// Read out main grid and main grid dimensions if present in case group
|
||||
if (gridCaseGroup->mainCase())
|
||||
{
|
||||
mainResultCase = dynamic_cast<RimResultCase*>(gridCaseGroup->mainCase());
|
||||
CVF_ASSERT(mainResultCase);
|
||||
|
||||
mainResultCase->readGridDimensions(mainCaseGridDimensions);
|
||||
}
|
||||
|
||||
// Add cases to case group
|
||||
for (size_t i = 0; i < typedObjects.size(); i++)
|
||||
{
|
||||
RimResultCase* rimResultReservoir = typedObjects[i];
|
||||
@@ -627,14 +630,25 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gridCaseGroup->mainGrid() == NULL)
|
||||
if (!mainResultCase)
|
||||
{
|
||||
rimResultReservoir->openEclipseGridFile();
|
||||
mainEclipseCase = rimResultReservoir->reservoirData();
|
||||
rimResultReservoir->readGridDimensions(mainCaseGridDimensions);
|
||||
|
||||
mainResultCase = rimResultReservoir;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!rimResultReservoir->openAndReadActiveCellData(mainEclipseCase))
|
||||
std::vector< std::vector<int> > caseGridDimensions;
|
||||
rimResultReservoir->readGridDimensions(caseGridDimensions);
|
||||
|
||||
bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions);
|
||||
if (!identicalGrid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rimResultReservoir->openAndReadActiveCellData(mainResultCase->reservoirData()))
|
||||
{
|
||||
CVF_ASSERT(false);
|
||||
}
|
||||
@@ -645,7 +659,7 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG
|
||||
caf::PdmObjectGroup::initAfterReadTraversal(rimResultReservoir);
|
||||
|
||||
{
|
||||
QModelIndex rootIndex = getModelIndexFromPdmObject(caseCollection);
|
||||
QModelIndex rootIndex = getModelIndexFromPdmObject(gridCaseGroup->caseCollection());
|
||||
caf::PdmUiTreeItem* caseCollectionUiItem = getTreeItemFromIndex(rootIndex);
|
||||
|
||||
int position = rowCount(rootIndex);
|
||||
@@ -663,6 +677,24 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiTreeModelPdm::moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects)
|
||||
{
|
||||
addObjects(itemIndex, pdmObjects);
|
||||
|
||||
// Delete objects from original container
|
||||
std::vector<caf::PdmPointer<RimResultCase> > typedObjects;
|
||||
pdmObjects.objectsByType(&typedObjects);
|
||||
|
||||
for (size_t i = 0; i < typedObjects.size(); i++)
|
||||
{
|
||||
RimCase* rimReservoir = typedObjects[i];
|
||||
deleteReservoir(rimReservoir);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -741,7 +773,6 @@ Qt::ItemFlags RimUiTreeModelPdm::flags(const QModelIndex &index) const
|
||||
{
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(index);
|
||||
CVF_ASSERT(currentItem);
|
||||
CVF_ASSERT(currentItem->dataObject().p());
|
||||
|
||||
if (dynamic_cast<RimIdenticalGridCaseGroup*>(currentItem->dataObject().p()) ||
|
||||
dynamic_cast<RimCaseCollection*>(currentItem->dataObject().p()))
|
||||
@@ -777,18 +808,13 @@ bool RimUiTreeModelPdm::dropMimeData(const QMimeData *data, Qt::DropAction actio
|
||||
pog.objects().push_back(pdmObj);
|
||||
}
|
||||
|
||||
addObjects(parent, pog);
|
||||
|
||||
if (action == Qt::MoveAction)
|
||||
if (action == Qt::CopyAction)
|
||||
{
|
||||
std::vector<caf::PdmPointer<RimResultCase> > typedObjects;
|
||||
pog.objectsByType(&typedObjects);
|
||||
|
||||
for (size_t i = 0; i < typedObjects.size(); i++)
|
||||
{
|
||||
RimCase* rimReservoir = typedObjects[i];
|
||||
deleteReservoir(rimReservoir);
|
||||
}
|
||||
addObjects(parent, pog);
|
||||
}
|
||||
else if (action == Qt::MoveAction)
|
||||
{
|
||||
moveObjects(parent, pog);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -817,3 +843,38 @@ QStringList RimUiTreeModelPdm::mimeTypes() const
|
||||
return types;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Return grid case group when QModelIndex points to grid case group, case collection or case in a grid case group
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimIdenticalGridCaseGroup* RimUiTreeModelPdm::gridCaseGroupFromItemIndex(const QModelIndex& itemIndex)
|
||||
{
|
||||
caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex);
|
||||
|
||||
RimIdenticalGridCaseGroup* gridCaseGroup = NULL;
|
||||
|
||||
if (dynamic_cast<RimIdenticalGridCaseGroup*>(currentItem->dataObject().p()))
|
||||
{
|
||||
gridCaseGroup = dynamic_cast<RimIdenticalGridCaseGroup*>(currentItem->dataObject().p());
|
||||
}
|
||||
else if (dynamic_cast<RimCaseCollection*>(currentItem->dataObject().p()))
|
||||
{
|
||||
RimCaseCollection* caseCollection = dynamic_cast<RimCaseCollection*>(currentItem->dataObject().p());
|
||||
CVF_ASSERT(caseCollection);
|
||||
|
||||
gridCaseGroup = caseCollection->parentCaseGroup();
|
||||
}
|
||||
else if (dynamic_cast<RimCase*>(currentItem->dataObject().p()))
|
||||
{
|
||||
RimCase* rimReservoir = dynamic_cast<RimCase*>(currentItem->dataObject().p());
|
||||
CVF_ASSERT(rimReservoir);
|
||||
|
||||
RimCaseCollection* caseCollection = rimReservoir->parentCaseCollection();
|
||||
if (caseCollection)
|
||||
{
|
||||
gridCaseGroup = caseCollection->parentCaseGroup();
|
||||
}
|
||||
}
|
||||
|
||||
return gridCaseGroup;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,10 +111,12 @@ public:
|
||||
RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
RimReservoirView* addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
void addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames);
|
||||
void addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects);
|
||||
|
||||
RimStatisticsCase* addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
RimIdenticalGridCaseGroup* addCaseGroup(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
void addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects);
|
||||
void moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects);
|
||||
|
||||
RimStatisticsCase* addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex);
|
||||
RimIdenticalGridCaseGroup* addCaseGroup(QModelIndex& insertedModelIndex);
|
||||
|
||||
bool deleteObjectFromPdmPointersField(const QModelIndex& itemIndex);
|
||||
|
||||
@@ -126,6 +128,8 @@ public:
|
||||
virtual QMimeData* mimeData(const QModelIndexList &indexes) const;
|
||||
virtual QStringList mimeTypes() const;
|
||||
|
||||
RimIdenticalGridCaseGroup* gridCaseGroupFromItemIndex(const QModelIndex& itemIndex);
|
||||
|
||||
private slots:
|
||||
void slotRefreshScriptTree(QString path);
|
||||
|
||||
|
||||
@@ -62,6 +62,16 @@ void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
m_pasteAction->setEnabled(hasClipboardValidData());
|
||||
|
||||
if (selectionModel() && selectionModel()->selection().size() == 0)
|
||||
{
|
||||
// Clicking in blank space in tree view
|
||||
QMenu menu;
|
||||
menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup()));
|
||||
menu.exec(event->globalPos());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
@@ -796,28 +806,34 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiTreeView::slotCloseCase()
|
||||
{
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
QModelIndexList miList;
|
||||
miList << currentIndex();
|
||||
|
||||
if (userConfirmedGridCaseGroupChange(miList))
|
||||
{
|
||||
QItemSelectionModel* m = selectionModel();
|
||||
CVF_ASSERT(m);
|
||||
|
||||
caf::PdmObjectGroup group;
|
||||
|
||||
QModelIndexList mil = m->selectedRows();
|
||||
for (int i = 0; i < mil.size(); i++)
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(mil.at(i));
|
||||
group.addObject(uiItem->dataObject().p());
|
||||
}
|
||||
QItemSelectionModel* m = selectionModel();
|
||||
CVF_ASSERT(m);
|
||||
|
||||
std::vector<caf::PdmPointer<RimCase> > typedObjects;
|
||||
group.objectsByType(&typedObjects);
|
||||
caf::PdmObjectGroup group;
|
||||
|
||||
for (size_t i = 0; i < typedObjects.size(); i++)
|
||||
{
|
||||
RimCase* rimReservoir = typedObjects[i];
|
||||
myModel->deleteReservoir(rimReservoir);
|
||||
QModelIndexList mil = m->selectedRows();
|
||||
for (int i = 0; i < mil.size(); i++)
|
||||
{
|
||||
caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(mil.at(i));
|
||||
group.addObject(uiItem->dataObject().p());
|
||||
}
|
||||
|
||||
std::vector<caf::PdmPointer<RimCase> > typedObjects;
|
||||
group.objectsByType(&typedObjects);
|
||||
|
||||
for (size_t i = 0; i < typedObjects.size(); i++)
|
||||
{
|
||||
RimCase* rimReservoir = typedObjects[i];
|
||||
myModel->deleteReservoir(rimReservoir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -865,7 +881,7 @@ void RimUiTreeView::slotAddCaseGroup()
|
||||
if (myModel)
|
||||
{
|
||||
QModelIndex insertedIndex;
|
||||
myModel->addCaseGroup(currentIndex(), insertedIndex);
|
||||
myModel->addCaseGroup(insertedIndex);
|
||||
setCurrentIndex(insertedIndex);
|
||||
|
||||
setExpanded(insertedIndex, true);
|
||||
@@ -918,11 +934,16 @@ void RimUiTreeView::slotPastePdmObjects()
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (!myModel) return;
|
||||
|
||||
caf::PdmObjectGroup objectGroup;
|
||||
createPdmObjectsFromClipboard(&objectGroup);
|
||||
if (objectGroup.objects().size() == 0) return;
|
||||
QModelIndexList miList;
|
||||
miList << currentIndex();
|
||||
if (userConfirmedGridCaseGroupChange(miList))
|
||||
{
|
||||
caf::PdmObjectGroup objectGroup;
|
||||
createPdmObjectsFromClipboard(&objectGroup);
|
||||
if (objectGroup.objects().size() == 0) return;
|
||||
|
||||
myModel->addObjects(currentIndex(), objectGroup);
|
||||
myModel->addObjects(currentIndex(), objectGroup);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -999,3 +1020,126 @@ bool RimUiTreeView::hasClipboardValidData()
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimUiTreeView::dropEvent(QDropEvent* dropEvent)
|
||||
{
|
||||
QModelIndexList affectedModels;
|
||||
|
||||
if (dropEvent->dropAction() == Qt::MoveAction)
|
||||
{
|
||||
const MimeDataWithIndexes* myMimeData = qobject_cast<const MimeDataWithIndexes*>(dropEvent->mimeData());
|
||||
if (myMimeData)
|
||||
{
|
||||
affectedModels = myMimeData->indexes();
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex dropIndex = indexAt(dropEvent->pos());
|
||||
if (dropIndex.isValid())
|
||||
{
|
||||
affectedModels.push_back(dropIndex);
|
||||
}
|
||||
|
||||
if (userConfirmedGridCaseGroupChange(affectedModels))
|
||||
{
|
||||
QTreeView::dropEvent(dropEvent);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Displays a question to the user when a grid case group with statistical results is about to change
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimUiTreeView::userConfirmedGridCaseGroupChange(const QModelIndexList& itemIndexList)
|
||||
{
|
||||
if (itemIndexList.size() == 0) return true;
|
||||
|
||||
RimUiTreeModelPdm* myModel = dynamic_cast<RimUiTreeModelPdm*>(model());
|
||||
if (myModel)
|
||||
{
|
||||
caf::PdmObjectGroup pog;
|
||||
|
||||
for (int i = 0; i < itemIndexList.size(); i++)
|
||||
{
|
||||
QModelIndex itemIndex = itemIndexList.at(i);
|
||||
if (!itemIndex.isValid()) continue;
|
||||
|
||||
RimIdenticalGridCaseGroup* gridCaseGroup = myModel->gridCaseGroupFromItemIndex(itemIndex);
|
||||
if (gridCaseGroup)
|
||||
{
|
||||
if (hasAnyStatisticsResults(gridCaseGroup))
|
||||
{
|
||||
if (pog.objects().count(gridCaseGroup) == 0)
|
||||
{
|
||||
pog.addObject(gridCaseGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<caf::PdmPointer<RimIdenticalGridCaseGroup> > typedObjects;
|
||||
pog.objectsByType(&typedObjects);
|
||||
|
||||
if (typedObjects.size() > 0)
|
||||
{
|
||||
RiuMainWindow* mainWnd = RiuMainWindow::instance();
|
||||
|
||||
QMessageBox msgBox(mainWnd);
|
||||
msgBox.setIcon(QMessageBox::Question);
|
||||
|
||||
QString questionText;
|
||||
if (typedObjects.size() == 1)
|
||||
{
|
||||
questionText = QString("This operation will invalidate statistics results in grid case group\n\"%1\".\n").arg(typedObjects[0]->name());
|
||||
questionText += "Computed results in this group will be deleted if you continue.";
|
||||
}
|
||||
else
|
||||
{
|
||||
questionText = "This operation will invalidate statistics results in grid case groups\n";
|
||||
for (int i = 0; i < typedObjects.size(); i++)
|
||||
{
|
||||
questionText += QString("\"%1\"\n").arg(typedObjects[i]->name());
|
||||
}
|
||||
|
||||
questionText += "Computed results in these groups will be deleted if you continue.";
|
||||
}
|
||||
|
||||
msgBox.setText(questionText);
|
||||
msgBox.setInformativeText("Do you want to continue?");
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
int ret = msgBox.exec();
|
||||
if (ret == QMessageBox::No)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimUiTreeView::hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup)
|
||||
{
|
||||
CVF_ASSERT(gridCaseGroup);
|
||||
|
||||
for (size_t i = 0; i < gridCaseGroup->statisticsCaseCollection()->reservoirs().size(); i++)
|
||||
{
|
||||
RimStatisticsCase* rimStaticsCase = dynamic_cast<RimStatisticsCase*>(gridCaseGroup->statisticsCaseCollection()->reservoirs[i]);
|
||||
if (rimStaticsCase)
|
||||
{
|
||||
if (rimStaticsCase->hasComputedStatistics())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <QTreeView>
|
||||
|
||||
class QItemSelection;
|
||||
class RimIdenticalGridCaseGroup;
|
||||
|
||||
namespace caf {
|
||||
class PdmObjectGroup;
|
||||
@@ -89,10 +90,14 @@ signals:
|
||||
void selectedObjectChanged( caf::PdmObject* pdmObject );
|
||||
|
||||
private:
|
||||
bool userConfirmedGridCaseGroupChange(const QModelIndexList& itemIndexList);
|
||||
bool hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup);
|
||||
|
||||
void createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup);
|
||||
bool hasClipboardValidData();
|
||||
|
||||
virtual void keyPressEvent(QKeyEvent* keyEvent);
|
||||
virtual void dropEvent(QDropEvent* dropEvent);
|
||||
|
||||
private:
|
||||
QAction* m_pasteAction;
|
||||
|
||||
@@ -17,6 +17,8 @@ ${CEE_CURRENT_LIST_DIR}RigMainGrid.h
|
||||
${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.h
|
||||
${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.h
|
||||
${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.h
|
||||
${CEE_CURRENT_LIST_DIR}RigStatisticsMath.h
|
||||
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
@@ -31,6 +33,7 @@ ${CEE_CURRENT_LIST_DIR}RigMainGrid.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.cpp
|
||||
${CEE_CURRENT_LIST_DIR}RigStatisticsMath.cpp
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ include_directories(
|
||||
${ResInsight_SOURCE_DIR}/CommonCode
|
||||
|
||||
#Remove when RigStatistics is out
|
||||
${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization
|
||||
#${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization
|
||||
)
|
||||
|
||||
# Populate the filenames into variable lists
|
||||
@@ -38,6 +38,7 @@ set( UNIT_TEST_CPP_SOURCES
|
||||
main.cpp
|
||||
RigActiveCellInfo-Test.cpp
|
||||
RigReservoir-Test.cpp
|
||||
RigStatisticsMath-Test.cpp
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 "RiaStdInclude.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigStatisticsMath, BasicTest)
|
||||
{
|
||||
std::vector<double> values;
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(2788.2723335651900);
|
||||
values.push_back(-22481.0927881701000);
|
||||
values.push_back(68778.6851686236000);
|
||||
values.push_back(-76092.8157632591000);
|
||||
values.push_back(6391.97999909729003);
|
||||
values.push_back(65930.1200169780000);
|
||||
values.push_back(-27696.2320267235000);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(96161.7546348456000);
|
||||
values.push_back(73875.6716288563000);
|
||||
values.push_back(80720.4378655615000);
|
||||
values.push_back(-98649.8109937874000);
|
||||
values.push_back(99372.9362079615000);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(-57020.4389966513000);
|
||||
|
||||
double min, max, range, mean, stdev;
|
||||
RigStatisticsMath::calculateBasicStatistics(values, &min, &max, &range, &mean, &stdev);
|
||||
|
||||
EXPECT_DOUBLE_EQ(-98649.8109937874000, min );
|
||||
EXPECT_DOUBLE_EQ(99372.9362079615000 , max );
|
||||
EXPECT_DOUBLE_EQ(198022.7472017490000, range );
|
||||
EXPECT_DOUBLE_EQ(16313.8051759152000 , mean );
|
||||
EXPECT_DOUBLE_EQ(66104.391542887200 , stdev );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigStatisticsMath, RankPercentiles)
|
||||
{
|
||||
std::vector<double> values;
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(2788.2723335651900);
|
||||
values.push_back(-22481.0927881701000);
|
||||
values.push_back(68778.6851686236000);
|
||||
values.push_back(-76092.8157632591000);
|
||||
values.push_back(6391.97999909729003);
|
||||
values.push_back(65930.1200169780000);
|
||||
values.push_back(-27696.2320267235000);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(96161.7546348456000);
|
||||
values.push_back(73875.6716288563000);
|
||||
values.push_back(80720.4378655615000);
|
||||
values.push_back(-98649.8109937874000);
|
||||
values.push_back(99372.9362079615000);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(-57020.4389966513000);
|
||||
|
||||
std::vector<double> pValPos;
|
||||
pValPos.push_back(10);
|
||||
pValPos.push_back(40);
|
||||
pValPos.push_back(50);
|
||||
pValPos.push_back(90);
|
||||
std::vector<double> pVals = RigStatisticsMath::calculateNearestRankPercentiles(values, pValPos);
|
||||
|
||||
EXPECT_DOUBLE_EQ( -76092.8157632591000, pVals[0]);
|
||||
EXPECT_DOUBLE_EQ( 2788.2723335651900 , pVals[1]);
|
||||
EXPECT_DOUBLE_EQ( 6391.979999097290 , pVals[2]);
|
||||
EXPECT_DOUBLE_EQ( 96161.7546348456000 , pVals[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(RigStatisticsMath, HistogramPercentiles)
|
||||
{
|
||||
std::vector<double> values;
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(2788.2723335651900);
|
||||
values.push_back(-22481.0927881701000);
|
||||
values.push_back(68778.6851686236000);
|
||||
values.push_back(-76092.8157632591000);
|
||||
values.push_back(6391.97999909729003);
|
||||
values.push_back(65930.1200169780000);
|
||||
values.push_back(-27696.2320267235000);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(96161.7546348456000);
|
||||
values.push_back(73875.6716288563000);
|
||||
values.push_back(80720.4378655615000);
|
||||
values.push_back(-98649.8109937874000);
|
||||
values.push_back(99372.9362079615000);
|
||||
values.push_back(HUGE_VAL);
|
||||
values.push_back(-57020.4389966513000);
|
||||
|
||||
|
||||
double min, max, range, mean, stdev;
|
||||
RigStatisticsMath::calculateBasicStatistics(values, &min, &max, &range, &mean, &stdev);
|
||||
|
||||
std::vector<size_t> histogram;
|
||||
RigHistogramCalculator histCalc(min, max, 100, &histogram);
|
||||
histCalc.addData(values);
|
||||
std::vector<double> pVals;
|
||||
double p10, p50, p90;
|
||||
p10 = histCalc.calculatePercentil(0.1);
|
||||
p50 = histCalc.calculatePercentil(0.5);
|
||||
p90 = histCalc.calculatePercentil(0.9);
|
||||
|
||||
EXPECT_DOUBLE_EQ( -76273.240559989776, p10);
|
||||
EXPECT_DOUBLE_EQ( 5312.1312871307755 , p50);
|
||||
EXPECT_DOUBLE_EQ( 94818.413022321271 , p90);
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "RifReaderInterface.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <math.h>
|
||||
|
||||
@@ -180,7 +182,9 @@ const std::vector<size_t>& RigCaseCellResultsData::cellScalarValuesHistogram(siz
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90)
|
||||
{
|
||||
const std::vector<size_t>& histogr = cellScalarValuesHistogram( scalarResultIndex);
|
||||
// First make sure they are calculated
|
||||
const std::vector<size_t>& histogr = cellScalarValuesHistogram( scalarResultIndex);
|
||||
// Then return them
|
||||
p10 = m_p10p90[scalarResultIndex].first;
|
||||
p90 = m_p10p90[scalarResultIndex].second;
|
||||
}
|
||||
@@ -346,7 +350,7 @@ size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType ty
|
||||
{
|
||||
scalarResultIndex = this->resultCount();
|
||||
m_cellScalarResults.push_back(std::vector<std::vector<double> >());
|
||||
ResultInfo resInfo(type, needsToBeStored, resultName, scalarResultIndex);
|
||||
ResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex);
|
||||
m_resultInfos.push_back(resInfo);
|
||||
}
|
||||
|
||||
@@ -536,3 +540,35 @@ RifReaderInterface::PorosityModelResultType RigCaseCellResultsData::convertFromP
|
||||
return RifReaderInterface::FRACTURE_RESULTS;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigCaseCellResultsData::mustBeCalculated(size_t scalarResultIndex) const
|
||||
{
|
||||
std::vector<ResultInfo>::const_iterator it;
|
||||
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++)
|
||||
{
|
||||
if (it->m_gridScalarResultIndex == scalarResultIndex)
|
||||
{
|
||||
return it->m_mustBeCalculated;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex)
|
||||
{
|
||||
std::vector<ResultInfo>::iterator it;
|
||||
for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++)
|
||||
{
|
||||
if (it->m_gridScalarResultIndex == scalarResultIndex)
|
||||
{
|
||||
it->m_mustBeCalculated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,18 +80,23 @@ public:
|
||||
class ResultInfo
|
||||
{
|
||||
public:
|
||||
ResultInfo(RimDefines::ResultCatType resultType, bool needsToBeStored, QString resultName, size_t gridScalarResultIndex)
|
||||
: m_resultType(resultType), m_needsToBeStored(needsToBeStored), m_resultName(resultName), m_gridScalarResultIndex(gridScalarResultIndex) { }
|
||||
ResultInfo(RimDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated, QString resultName, size_t gridScalarResultIndex)
|
||||
: m_resultType(resultType), m_needsToBeStored(needsToBeStored), m_resultName(resultName), m_gridScalarResultIndex(gridScalarResultIndex), m_mustBeCalculated(mustBeCalculated) { }
|
||||
|
||||
public:
|
||||
RimDefines::ResultCatType m_resultType;
|
||||
bool m_needsToBeStored;
|
||||
bool m_mustBeCalculated;
|
||||
QString m_resultName;
|
||||
size_t m_gridScalarResultIndex;
|
||||
std::vector<QDateTime> m_timeStepDates;
|
||||
};
|
||||
|
||||
const std::vector<ResultInfo>& infoForEachResultIndex() { return m_resultInfos;}
|
||||
|
||||
bool mustBeCalculated(size_t scalarResultIndex) const;
|
||||
void setMustBeCalculated(size_t scalarResultIndex);
|
||||
|
||||
|
||||
public:
|
||||
size_t addStaticScalarResult(RimDefines::ResultCatType type,
|
||||
@@ -116,86 +121,3 @@ private:
|
||||
RigMainGrid* m_ownerMainGrid;
|
||||
|
||||
};
|
||||
|
||||
class RigHistogramCalculator
|
||||
{
|
||||
public:
|
||||
RigHistogramCalculator(double min, double max, size_t nBins, std::vector<size_t>* histogram)
|
||||
{
|
||||
CVF_ASSERT(histogram);
|
||||
CVF_ASSERT(nBins > 0);
|
||||
|
||||
if (max == min) { nBins = 1; } // Avoid dividing on 0 range
|
||||
|
||||
m_histogram = histogram;
|
||||
m_min = min;
|
||||
m_observationCount = 0;
|
||||
|
||||
// Initialize bins
|
||||
m_histogram->resize(nBins);
|
||||
for (size_t i = 0; i < m_histogram->size(); ++i) (*m_histogram)[i] = 0;
|
||||
|
||||
m_range = max - min;
|
||||
maxIndex = nBins-1;
|
||||
}
|
||||
|
||||
void addData(const std::vector<double>& data)
|
||||
{
|
||||
CVF_ASSERT(m_histogram);
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
if (data[i] == HUGE_VAL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
if (maxIndex > 0) index = (size_t)(maxIndex*(data[i] - m_min)/m_range);
|
||||
|
||||
if(index < m_histogram->size()) // Just clip to the max min range (-index will overflow to positive )
|
||||
{
|
||||
(*m_histogram)[index]++;
|
||||
m_observationCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the estimated percentile from the histogram.
|
||||
/// the percentile is the domain value at which pVal of the observations are below it.
|
||||
/// Will only consider observed values between min and max, as all other values are discarded from the histogram
|
||||
|
||||
double calculatePercentil(double pVal)
|
||||
{
|
||||
CVF_ASSERT(m_histogram);
|
||||
CVF_ASSERT(m_histogram->size());
|
||||
CVF_ASSERT( 0.0 <= pVal && pVal <= 1.0);
|
||||
|
||||
double pValObservationCount = pVal*m_observationCount;
|
||||
if (pValObservationCount == 0.0) return m_min;
|
||||
|
||||
size_t accObsCount = 0;
|
||||
double binWidth = m_range/m_histogram->size();
|
||||
for (size_t binIdx = 0; binIdx < m_histogram->size(); ++binIdx)
|
||||
{
|
||||
size_t binObsCount = (*m_histogram)[binIdx];
|
||||
|
||||
accObsCount += binObsCount;
|
||||
if (accObsCount >= pValObservationCount)
|
||||
{
|
||||
double domainValueAtEndOfBin = m_min + (binIdx+1) * binWidth;
|
||||
double unusedFractionOfLastBin = (double)(accObsCount - pValObservationCount)/binObsCount;
|
||||
return domainValueAtEndOfBin - unusedFractionOfLastBin*binWidth;
|
||||
}
|
||||
}
|
||||
CVF_ASSERT(false);
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t maxIndex;
|
||||
double m_range;
|
||||
double m_min;
|
||||
size_t m_observationCount;
|
||||
std::vector<size_t>* m_histogram;
|
||||
};
|
||||
|
||||
@@ -375,7 +375,7 @@ void RigCaseData::setActiveCellInfo(RifReaderInterface::PorosityModelResultType
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseData::computeActiveCellsGeometryBoundingBox()
|
||||
{
|
||||
if (m_activeCellInfo.notNull() || m_fractureActiveCellInfo.notNull())
|
||||
if (m_activeCellInfo.isNull() || m_fractureActiveCellInfo.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ public:
|
||||
RigGridBase* grid(size_t index);
|
||||
size_t gridCount() const;
|
||||
|
||||
RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel);
|
||||
const RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel) const;
|
||||
RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel);
|
||||
const RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel) const;
|
||||
|
||||
RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel);
|
||||
const RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const;
|
||||
@@ -80,9 +80,9 @@ private:
|
||||
cvf::ref<RigActiveCellInfo> m_activeCellInfo;
|
||||
cvf::ref<RigActiveCellInfo> m_fractureActiveCellInfo;
|
||||
|
||||
cvf::ref<RigCaseCellResultsData> m_matrixModelResults;
|
||||
cvf::ref<RigCaseCellResultsData> m_fractureModelResults;
|
||||
cvf::ref<RigCaseCellResultsData> m_matrixModelResults;
|
||||
cvf::ref<RigCaseCellResultsData> m_fractureModelResults;
|
||||
|
||||
cvf::Collection<RigSingleWellResultsData> m_wellResults; //< A WellResults object for each well in the reservoir
|
||||
cvf::Collection<RigSingleWellResultsData> m_wellResults; //< A WellResults object for each well in the reservoir
|
||||
cvf::Collection<cvf::UByteArray> m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling wether the cell is a well cell or not
|
||||
};
|
||||
|
||||
@@ -96,6 +96,29 @@ void RigGridManager::clear()
|
||||
m_caseToGrid.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGridManager::isGridDimensionsEqual(const std::vector< std::vector<int> >& mainCaseGridDimensions, const std::vector< std::vector<int> >& caseGridDimensions)
|
||||
{
|
||||
if (mainCaseGridDimensions.size() != caseGridDimensions.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < mainCaseGridDimensions.size(); j++)
|
||||
{
|
||||
if (mainCaseGridDimensions[j].size() != 3) return false;
|
||||
if (caseGridDimensions[j].size() != 3) return false;
|
||||
|
||||
if (mainCaseGridDimensions[j][0] != caseGridDimensions[j][0]) return false;
|
||||
if (mainCaseGridDimensions[j][1] != caseGridDimensions[j][1]) return false;
|
||||
if (mainCaseGridDimensions[j][2] != caseGridDimensions[j][2]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -38,10 +38,9 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
static bool isEqual(RigMainGrid* gridA, RigMainGrid* gridB);
|
||||
|
||||
static bool isGridDimensionsEqual(const std::vector< std::vector<int> >& mainCaseGridDimensions, const std::vector< std::vector<int> >& caseGridDimensions);
|
||||
private:
|
||||
class CaseToGridMap : public cvf::Object
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
//##################################################################################################
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 "RigGridScalarDataAccess.h"
|
||||
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
//##################################################################################################
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2012 Ceetron AS
|
||||
//
|
||||
// This library 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.
|
||||
//
|
||||
// This library 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.
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
192
ApplicationCode/ReservoirDataModel/RigStatisticsMath.cpp
Normal file
192
ApplicationCode/ReservoirDataModel/RigStatisticsMath.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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 "RigStatisticsMath.h"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// A function to do basic statistical calculations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RigStatisticsMath::calculateBasicStatistics(const std::vector<double>& values, double* min, double* max, double* range, double* mean, double* dev)
|
||||
{
|
||||
double m_min(HUGE_VAL);
|
||||
double m_max(-HUGE_VAL);
|
||||
double m_mean(HUGE_VAL);
|
||||
double m_dev(HUGE_VAL);
|
||||
|
||||
double sum = 0.0;
|
||||
double sumSquared = 0.0;
|
||||
|
||||
size_t validValueCount = 0;
|
||||
|
||||
for (size_t i = 0; i < values.size(); i++)
|
||||
{
|
||||
double val = values[i];
|
||||
if (val == HUGE_VAL) continue;
|
||||
|
||||
validValueCount++;
|
||||
|
||||
if (val < m_min) m_min = val;
|
||||
if (val > m_max) m_max = val;
|
||||
|
||||
sum += val;
|
||||
sumSquared += (val * val);
|
||||
}
|
||||
|
||||
if (validValueCount > 0)
|
||||
{
|
||||
m_mean = sum / validValueCount;
|
||||
|
||||
|
||||
// http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
|
||||
// Running standard deviation
|
||||
|
||||
double s0 = static_cast<double>(validValueCount);
|
||||
double s1 = sum;
|
||||
double s2 = sumSquared;
|
||||
|
||||
m_dev = sqrt( (s0 * s2) - (s1 * s1) ) / s0;
|
||||
}
|
||||
|
||||
if (min) *min = m_min;
|
||||
if (max) *max = m_max;
|
||||
if (range) *range = m_max - m_min;
|
||||
|
||||
if (mean) *mean = m_mean;
|
||||
if (dev) *dev = m_dev;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Calculate the percentiles of /a inputValues at the pValPosition percentages using the "Nearest Rank"
|
||||
/// method. This method treats HUGE_VAL as "undefined" values, and ignores these. Will return HUGE_VAL if
|
||||
/// the inputValues does not contain any valid values
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
std::vector<double> RigStatisticsMath::calculateNearestRankPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions)
|
||||
{
|
||||
std::vector<double> sortedValues;
|
||||
sortedValues.reserve(inputValues.size());
|
||||
|
||||
for (size_t i = 0; i < inputValues.size(); ++i)
|
||||
{
|
||||
if (inputValues[i] != HUGE_VAL)
|
||||
{
|
||||
sortedValues.push_back(inputValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(sortedValues.begin(), sortedValues.end());
|
||||
|
||||
std::vector<double> percentiles(pValPositions.size(), HUGE_VAL);
|
||||
if (sortedValues.size())
|
||||
{
|
||||
for (size_t i = 0; i < pValPositions.size(); ++i)
|
||||
{
|
||||
double pVal = HUGE_VAL;
|
||||
|
||||
size_t pValIndex = static_cast<size_t>(sortedValues.size() * fabs(pValPositions[i]) / 100);
|
||||
|
||||
if (pValIndex >= sortedValues.size() ) pValIndex = sortedValues.size() - 1;
|
||||
|
||||
pVal = sortedValues[pValIndex];
|
||||
percentiles[i] = pVal;
|
||||
}
|
||||
}
|
||||
|
||||
return percentiles;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigHistogramCalculator::RigHistogramCalculator(double min, double max, size_t nBins, std::vector<size_t>* histogram)
|
||||
{
|
||||
assert(histogram);
|
||||
assert(nBins > 0);
|
||||
|
||||
if (max == min) { nBins = 1; } // Avoid dividing on 0 range
|
||||
|
||||
m_histogram = histogram;
|
||||
m_min = min;
|
||||
m_observationCount = 0;
|
||||
|
||||
// Initialize bins
|
||||
m_histogram->resize(nBins);
|
||||
for (size_t i = 0; i < m_histogram->size(); ++i) (*m_histogram)[i] = 0;
|
||||
|
||||
m_range = max - min;
|
||||
maxIndex = nBins-1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigHistogramCalculator::addData(const std::vector<double>& data)
|
||||
{
|
||||
assert(m_histogram);
|
||||
for (size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
if (data[i] == HUGE_VAL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
if (maxIndex > 0) index = (size_t)(maxIndex*(data[i] - m_min)/m_range);
|
||||
|
||||
if(index < m_histogram->size()) // Just clip to the max min range (-index will overflow to positive )
|
||||
{
|
||||
(*m_histogram)[index]++;
|
||||
m_observationCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigHistogramCalculator::calculatePercentil(double pVal)
|
||||
{
|
||||
assert(m_histogram);
|
||||
assert(m_histogram->size());
|
||||
assert( 0.0 <= pVal && pVal <= 1.0);
|
||||
|
||||
double pValObservationCount = pVal*m_observationCount;
|
||||
if (pValObservationCount == 0.0) return m_min;
|
||||
|
||||
size_t accObsCount = 0;
|
||||
double binWidth = m_range/m_histogram->size();
|
||||
for (size_t binIdx = 0; binIdx < m_histogram->size(); ++binIdx)
|
||||
{
|
||||
size_t binObsCount = (*m_histogram)[binIdx];
|
||||
|
||||
accObsCount += binObsCount;
|
||||
if (accObsCount >= pValObservationCount)
|
||||
{
|
||||
double domainValueAtEndOfBin = m_min + (binIdx+1) * binWidth;
|
||||
double unusedFractionOfLastBin = (double)(accObsCount - pValObservationCount)/binObsCount;
|
||||
return domainValueAtEndOfBin - unusedFractionOfLastBin*binWidth;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
return HUGE_VAL;
|
||||
}
|
||||
54
ApplicationCode/ReservoirDataModel/RigStatisticsMath.h
Normal file
54
ApplicationCode/ReservoirDataModel/RigStatisticsMath.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
|
||||
class RigStatisticsMath
|
||||
{
|
||||
public:
|
||||
static void calculateBasicStatistics(const std::vector<double>& values, double* min, double* max, double* range, double* mean, double* dev);
|
||||
static std::vector<double> calculateNearestRankPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Class to calculate a histogram, and histogram based p-value estimates
|
||||
//==================================================================================================
|
||||
|
||||
class RigHistogramCalculator
|
||||
{
|
||||
public:
|
||||
RigHistogramCalculator(double min, double max, size_t nBins, std::vector<size_t>* histogram);
|
||||
|
||||
void addData(const std::vector<double>& data);
|
||||
|
||||
/// Calculates the estimated percentile from the histogram.
|
||||
/// the percentile is the domain value at which pVal of the observations are below it.
|
||||
/// Will only consider observed values between min and max, as all other values are discarded from the histogram
|
||||
|
||||
double calculatePercentil(double pVal);
|
||||
|
||||
private:
|
||||
size_t maxIndex;
|
||||
double m_range;
|
||||
double m_min;
|
||||
size_t m_observationCount;
|
||||
std::vector<size_t>* m_histogram;
|
||||
};
|
||||
BIN
ApplicationCode/Resources/AppLogo48x48.ico
Normal file
BIN
ApplicationCode/Resources/AppLogo48x48.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
1
ApplicationCode/Resources/ResInsight.rc
Normal file
1
ApplicationCode/Resources/ResInsight.rc
Normal file
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON "AppLogo48x48.ico"
|
||||
@@ -179,7 +179,7 @@ RimCase* RiaSocketServer::findReservoir(const QString& caseName)
|
||||
{
|
||||
for (size_t cIdx = 0; cIdx < project->reservoirs.size(); ++cIdx)
|
||||
{
|
||||
if (project->reservoirs[cIdx] && project->reservoirs[cIdx]->caseName() == caseName )
|
||||
if (project->reservoirs[cIdx] && project->reservoirs[cIdx]->caseUserDescription() == caseName )
|
||||
{
|
||||
return project->reservoirs[cIdx];
|
||||
}
|
||||
@@ -452,9 +452,9 @@ void RiaSocketServer::readPropertyDataFromOctave()
|
||||
if (cellCountFromOctave != gridActiveCellCount && cellCountFromOctave != gridTotalCellCount)
|
||||
{
|
||||
m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") +
|
||||
tr("The number of cells in the data coming from octave does not match the case") + ":\"" + m_currentReservoir->caseName() + "\"\n"
|
||||
tr("The number of cells in the data coming from octave does not match the case") + ":\"" + m_currentReservoir->caseUserDescription() + "\"\n"
|
||||
" Octave: " + QString::number(cellCountFromOctave) + "\n"
|
||||
" " + m_currentReservoir->caseName() + ": Active cell count: " + QString::number(gridActiveCellCount) + " Total cell count: " + QString::number(gridTotalCellCount)) ;
|
||||
" " + m_currentReservoir->caseUserDescription() + ": Active cell count: " + QString::number(gridActiveCellCount) + " Total cell count: " + QString::number(gridTotalCellCount)) ;
|
||||
|
||||
cellCountFromOctave = 0;
|
||||
m_invalidActiveCellCountDetected = true;
|
||||
|
||||
@@ -580,6 +580,13 @@ void RiuMainWindow::refreshAnimationActions()
|
||||
timeStepStrings.push_back(tr("Static Property"));
|
||||
}
|
||||
}
|
||||
|
||||
// Animation control is only relevant for more than one time step
|
||||
if (timeStepStrings.size() < 2)
|
||||
{
|
||||
enableAnimControls = false;
|
||||
}
|
||||
|
||||
m_animationToolBar->setFrameRate(app->activeReservoirView()->maximumFrameRate());
|
||||
}
|
||||
|
||||
@@ -1269,9 +1276,8 @@ void RiuMainWindow::hideAllDockWindows()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuMainWindow::slotOpenMultipleCases()
|
||||
{
|
||||
#if 1
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
|
||||
/*
|
||||
RiuMultiCaseImportDialog dialog;
|
||||
int action = dialog.exec();
|
||||
if (action == QDialog::Accepted)
|
||||
@@ -1279,8 +1285,9 @@ void RiuMainWindow::slotOpenMultipleCases()
|
||||
QStringList gridFileNames = dialog.eclipseCaseFileNames();
|
||||
app->addEclipseCases(gridFileNames);
|
||||
}
|
||||
*/
|
||||
|
||||
#else // Code to fast generate a test project
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
|
||||
QStringList gridFileNames;
|
||||
|
||||
@@ -1299,6 +1306,6 @@ void RiuMainWindow::slotOpenMultipleCases()
|
||||
}
|
||||
|
||||
app->addEclipseCases(gridFileNames);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -67,8 +67,13 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent)
|
||||
|
||||
QColor c;
|
||||
QPalette p = QApplication::palette();
|
||||
QColor frameAndTextColor(255, 255, 255, 255);
|
||||
p.setColor(QPalette::Window, QColor(144, 173, 208, 180));
|
||||
//QColor frameAndTextColor(255, 255, 255, 255);
|
||||
QColor frameAndTextColor(0, 0, 0, 255);
|
||||
QColor progressAndHistogramColor(0,0,90,70); // Also Progressbar dark text color
|
||||
|
||||
//p.setColor(QPalette::Window, QColor(144, 173, 208, 180));
|
||||
p.setColor(QPalette::Window, QColor(255, 255, 255, 50));
|
||||
|
||||
p.setColor(QPalette::WindowText, frameAndTextColor);
|
||||
|
||||
c = p.color(QPalette::Base );
|
||||
@@ -80,11 +85,14 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent)
|
||||
//p.setColor(QPalette::AlternateBase, c);
|
||||
|
||||
|
||||
p.setColor(QPalette::Highlight, QColor(20, 20, 130, 100));
|
||||
//p.setColor(QPalette::Highlight, QColor(20, 20, 130, 40));
|
||||
p.setColor(QPalette::Highlight, progressAndHistogramColor);
|
||||
|
||||
p.setColor(QPalette::HighlightedText, frameAndTextColor);
|
||||
//p.setColor(QPalette::HighlightedText, frameAndTextColor);
|
||||
p.setColor(QPalette::HighlightedText, QColor(255, 255, 255, 255)); //Progressbar light text color
|
||||
|
||||
p.setColor(QPalette::Dark, QColor(230, 250, 255, 100));
|
||||
//p.setColor(QPalette::Dark, QColor(230, 250, 255, 100));
|
||||
p.setColor(QPalette::Dark, progressAndHistogramColor);
|
||||
|
||||
// Info Text
|
||||
m_InfoLabel = new QLabel();
|
||||
|
||||
Reference in New Issue
Block a user