Merge pull request #22 from OPM/internal

Internal
This commit is contained in:
Magne Sjaastad
2013-04-12 04:06:49 -07:00
471 changed files with 20435 additions and 5692 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -37,7 +37,7 @@ public:
RifEclipseUnifiedRestartFileAccess();
virtual ~RifEclipseUnifiedRestartFileAccess();
void setFileSet(const QStringList& fileSet);
void setRestartFiles(const QStringList& fileSet);
bool open();
void close();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,7 +59,7 @@ protected:
virtual void setupBeforeSave();
private:
void loadOrComputeSOILForTimeStep(size_t timeStepIndex);
void computeSOILForTimeStep(size_t timeStepIndex);
QString getValidCacheFileName();
QString getCacheDirectoryPath();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1 @@
IDI_ICON1 ICON "AppLogo48x48.ico"

View File

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

View File

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

View File

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