Merge pull request #22 from OPM/internal

Internal
This commit is contained in:
Magne Sjaastad 2013-04-12 04:06:49 -07:00
commit e5b7bbc5af
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();

View File

@ -37,6 +37,11 @@ include (ResInsightVersion.cmake)
################################################################################
# ERT
################################################################################
# Disable install of ERT libs and headers, as Ert code is compiled and linked directly
# into ResInsight
SET(INSTALL_ERT OFF CACHE BOOL "Build ERT without installing")
add_subdirectory(ThirdParty/Ert/devel)
include_directories(

View File

@ -52,7 +52,7 @@ void getActiveCellInfo(int32NDArray& activeCellInfo, const QString &hostName, qu
activeCellCount = byteCount / sizeof(qint32);
dim_vector dv (2);
dim_vector dv (2, 1);
dv(0) = activeCellCount;
dv(1) = timestepCount;
activeCellInfo.resize(dv);

View File

@ -51,7 +51,7 @@ void getMainGridDimensions(int32NDArray& gridDimensions, const QString &hostName
socketStream >> jCount;
socketStream >> kCount;
dim_vector dv (1);
dim_vector dv (1, 1);
dv(0) = 3;
gridDimensions.resize(dv);

View File

@ -4,12 +4,14 @@ project( ERT C CXX )
set( ERT_VERSION_MAJOR 1 )
set( ERT_VERSION_MINOR 0 )
option( BUILD_ERT "Build the full ERT application - Linux only" OFF)
option( BUILD_ENS_PLOT "Build small Eclipse plotting program - no" OFF)
option( BUILD_TESTS "Should the tests be built" OFF)
option( BUILD_APPLICATONS "Should we build small utility applications" OFF)
option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF)
option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF)
option( BUILD_ERT "Build the full ERT application - Linux only" OFF)
option( BUILD_ENS_PLOT "Build small Eclipse plotting program - no" OFF)
option( BUILD_TESTS "Should the tests be built" OFF)
option( BUILD_APPLICATIONS "Should we build small utility applications" OFF)
option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF)
option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF)
option( INSTALL_ERT "Should anything be installed when issuing make install?" ON)
include( CheckFunctionExists )
ENABLE_TESTING()
@ -17,13 +19,15 @@ ENABLE_TESTING()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(ERT_LINUX TRUE )
add_definitions( -DERT_LINUX )
set( CMAKE_C_FLAGS "-g -O2 -Wall -std=gnu99" )
set( CMAKE_CXX_FLAGS "-g -O2 -Wall" )
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(ERT_WINDOWS TRUE)
add_definitions( -DERT_WINDOWS )
set( CMAKE_C_FLAGS "-O2" )
set( CMAKE_CXX_FLAGS "-O2" )
endif()
set( CMAKE_C_FLAGS "-g -O2 -Wall -std=gnu99 -fno-leading-underscore" )
set( CMAKE_CXX_FLAGS "-g -O2 -Wall" )
include(cmake/ert_check.cmake)
include(cmake/ert_find.cmake)
@ -35,16 +39,18 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
if (MSVC)
set(SHARED_LIB OFF)
else()
option( SHARED_LIB "Build shared libraries" ON)
endif()
if (SHARED_LIB)
set( LIBRARY_TYPE SHARED )
else()
set( LIBRARY_TYPE STATIC )
endif()
set( SHARED_LIB OFF )
else()
if (INSTALL_ERT)
set( LIBRARY_TYPE SHARED )
set( SHARED_LIB ON )
else()
set( LIBRARY_TYPE STATIC )
set( SHARED_LIB OFF )
endif(INSTALL_ERT)
endif(MSVC)
@ -57,9 +63,11 @@ if (ERT_LINUX)
set( NEED_LIBM TRUE )
set( LINK_STATIC FALSE )
add_definitions( -DHAVE_PROC )
set( NEED_LIBDL ON )
else()
set( NEED_LIBM FALSE )
set( LINK_STATIC TRUE )
set( NEED_LIBDL OFF )
endif()
@ -92,13 +100,6 @@ add_subdirectory( libecl_well )
#-----------------------------------------------------------------
if (BUILD_ERT)
#-----------------------------------------------------------------
try_compile( DLOPEN ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_dlopen.c )
if (DLOPEN)
set(NEED_LIBDL OFF)
else()
set(NEED_LIBDL ON)
endif()
option(USE_LSF "Include support for LSF" ON)
include_directories( ${PROJECT_SOURCE_DIR}/libconfig/include )

View File

@ -1,5 +0,0 @@
#include <dlfcn.h>
int main( int argc , char ** argv) {
dlopen( NULL , 0 );
}

35
ThirdParty/Ert/devel/cmake/cmake_pyc vendored Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python
import py_compile
import os
import os.path
import sys
# Small 'python compiler' used in the build system for ert. The
# commandline arguments should be:
#
# cmake_pyc.py src1.py src2.py src3.py /path/to/pyc/files
#
# The input source files can contain a path component like
# path/src1.py, but the path will not be recreated in the target
# domain.
def compile_file(src_file , target_file):
path = os.path.dirname( target_file )
if not os.path.exists( path ):
os.makedirs( path )
try:
py_compile.compile( src_file , cfile = target_file , doraise = True)
except Exception,error:
sys.exit(1)
target_path = sys.argv[-1]
for src_file in sys.argv[1:-1]:
compile_file( src_file , "%s/%sc" % (target_path , os.path.basename(src_file)))
sys.exit(0)

View File

@ -1,18 +1,18 @@
#cmakedefine HAVE_PTHREAD
#cmakedefine HAVE_EXECINFO
#cmakedefine HAVE_FORK
#cmakedefine HAVE_ZLIB
#cmakedefine HAVE_LSF
#cmakedefine HAVE_REALPATH
#cmakedefine HAVE_SYMLINK
#cmakedefine HAVE_READLINKAT
#cmakedefine HAVE_GETUID
#cmakedefine HAVE_LOCALTIME_R
#cmakedefine HAVE_LOCKF
#cmakedefine HAVE_SETENV
#cmakedefine HAVE_GLOB
#cmakedefine MKDIR_POSIX
#cmakedefine HAVE_FNMATCH
#cmakedefine NEED_BLAS
#cmakedefine HAVE_OPENMP
#cmakedefine HAVE_FTRUNCATE
#cmakedefine HAVE_PTHREAD 1
#cmakedefine HAVE_EXECINFO 1
#cmakedefine HAVE_FORK 1
#cmakedefine HAVE_ZLIB 1
#cmakedefine HAVE_LSF 1
#cmakedefine HAVE_REALPATH 1
#cmakedefine HAVE_SYMLINK 1
#cmakedefine HAVE_READLINKAT 1
#cmakedefine HAVE_GETUID 1
#cmakedefine HAVE_LOCALTIME_R 1
#cmakedefine HAVE_LOCKF 1
#cmakedefine HAVE_SETENV 1
#cmakedefine HAVE_GLOB 1
#cmakedefine MKDIR_POSIX 1
#cmakedefine HAVE_FNMATCH 1
#cmakedefine NEED_BLAS 1
#cmakedefine HAVE_OPENMP 1
#cmakedefine HAVE_FTRUNCATE 1

View File

@ -52,6 +52,8 @@ if (LATEX_PATH)
else()
set( WITH_LATEX OFF )
endif()
#-----------------------------------------------------------------f
find_program(PING_PATH NAMES ping)
#-----------------------------------------------------------------
find_path( EXECINFO_HEADER execinfo.h /usr/include )
if (EXECINFO_HEADER)
@ -63,6 +65,8 @@ if (GETOPT_HEADER)
add_definitions( -DHAVE_GETOPT )
endif()
#-----------------------------------------------------------------
find_path( UNISTD_HEADER unistd.h /usr/include )
if (ERT_WINDOWS)
find_library( SHLWAPI_LIBRARY NAMES Shlwapi )
endif()

View File

@ -3,15 +3,17 @@ macro(add_python_target tgt PYTHON_INSTALL_PATH ARGN)
foreach(file ${ARGN})
set(OUT ${CMAKE_CURRENT_BINARY_DIR}/${file}.pyc)
list(APPEND OUT_FILES ${OUT})
#------------------------------------------------------
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${file}.pyc
COMMAND python -m py_compile
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.py
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND mv
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.pyc ${CMAKE_CURRENT_BINARY_DIR}
OUTPUT ${OUT}
COMMAND ${PROJECT_SOURCE_DIR}/cmake/cmake_pyc
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.py ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PATH}
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${file}.pyc DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PATH})
#------------------------------------------------------
if (INSTALL_ERT)
install(FILES ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PATH}/${file}.pyc DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PATH})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file}.py DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PATH})
endif()
endforeach(file)
list(REMOVE_DUPLICATES OUT_FILES)
ADD_CUSTOM_TARGET(

View File

@ -1,3 +1,9 @@
libert.ecl (1.0-2) precise; urgency=low
* Mark -dev package as architecture independent
-- Arne Morten Kvarving <akva@SINTEFPC4169> Tue, 19 Feb 2013 10:03:04 +0100
libert.ecl (1.0-1) unstable; urgency=low
* Initial release

View File

@ -10,7 +10,7 @@ Vcs-Browser: https://github.com/Ensembles/ert
Package: libert.ecl-dev
Section: libdevel
Architecture: any
Architecture: all
Depends: libert.ecl1 (= ${binary:Version})
Description: The Ensemble based Reservoir Tool -- Development files
ERT - Ensemble based Reservoir Tool is a tool for managing en ensemble

View File

@ -1 +1,2 @@
usr/lib/*/lib*.so.*
usr/bin/*

View File

@ -13,4 +13,4 @@
dh $@
override_dh_auto_configure:
dh_auto_configure -- -DSHARED_LIB=1
dh_auto_configure -- -DSHARED_LIB=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release

View File

@ -2,23 +2,22 @@
#ifndef __RML_ENKF_COMMON_H__
#define __RML_ENKF_COMMON_H__
#include <stdbool.h>
#include <matrix.h>
#include <rng.h>
#include <ert/util/matrix.h>
#include <ert/util/rng.h>
void rml_enkf_common_initA__( matrix_type * A ,
matrix_type * S ,
matrix_type * Cd ,
matrix_type * E ,
matrix_type * D ,
double truncation,
double lamda,
matrix_type * Ud,
double * Wd,
matrix_type * VdT);
matrix_type * S ,
matrix_type * Cd ,
matrix_type * E ,
matrix_type * D ,
double truncation,
double lamda,
matrix_type * Ud,
double * Wd,
matrix_type * VdT);
#endif

View File

@ -16,12 +16,15 @@ endif()
set( CMAKE_SHARED_MODULE_PREFIX "" )
add_library( std_enkf MODULE std_enkf.c )
add_library( sqrt_enkf MODULE sqrt_enkf.c )
add_library( rml_enkf MODULE rml_enkf.c rml_enkf_common.c )
#-----------------------------------------------------------------
install(TARGETS analysis DESTINATION ${CMAKE_INSTALL_LIBDIR})
foreach(header ${header_files})
install(FILES ../include/ert/analysis/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/analysis)
endforeach()
if (INSTALL_ERT)
install(TARGETS analysis DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS rml_enkf DESTINATION ${CMAKE_INSTALL_LIBDIR})
foreach(header ${header_files})
install(FILES ../include/ert/analysis/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/analysis)
endforeach()
endif()

View File

@ -1 +1,2 @@
add_subdirectory( src )
add_subdirectory( tests )

View File

@ -18,61 +18,52 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ert/util/stringlist.h>
#include <ert/util/hash.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_content_node.h>
#define ECL_COM_KW "--"
#define ENKF_COM_KW "--"
/**
Types used for validation of config items.
*/
typedef enum {CONFIG_STRING = 0,
CONFIG_INT = 1,
CONFIG_FLOAT = 2,
CONFIG_FILE = 9, /* These file does not need to exist - but includes are handled. */
CONFIG_EXISTING_FILE = 3,
CONFIG_EXISTING_DIR = 4,
CONFIG_BOOLEAN = 5,
CONFIG_CONFIG = 6,
CONFIG_BYTESIZE = 7,
CONFIG_EXECUTABLE = 8 ,
CONFIG_INVALID = 1000 } config_item_types;
typedef struct config_struct config_type;
typedef struct config_schema_item_struct config_schema_item_type;
typedef struct config_struct config_type;
char ** config_alloc_active_list(const config_type *, int *);
void config_free(config_type *);
config_type * config_alloc( );
char ** config_alloc_active_list(const config_type * , int * );
void config_parse(config_type * , const char * , const char * , const char * , const char * , bool , bool );
bool config_parse(config_type * , const char * , const char * , const char * , const char * , config_schema_unrecognized_enum unrecognized_behaviour , bool );
bool config_has_schema_item(const config_type * config , const char * kw);
void config_clear(config_type * config);
/*****************************************************************/
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar );
bool config_item_set(const config_type * , const char * );
void config_schema_item_free__ (void * );
void config_schema_item_free( config_schema_item_type * );
config_schema_item_type * config_schema_item_alloc(const char * , bool , bool);
config_schema_item_type * config_get_schema_item(const config_type *, const char *);
bool config_item_set(const config_type * , const char * );
void config_add_alias(config_type * , const char * , const char * );
void config_install_message(config_type * , const char * , const char * );
const char * config_safe_get(const config_type * , const char *);
char * config_alloc_joined_string(const config_type * , const char * , const char * );
void config_add_define( config_type * config , const char * key , const char * value );
/*
bool config_schema_item_is_set(const config_schema_item_type * );
void config_schema_item_set_argc_minmax(config_schema_item_type * , int , int , int type_map_size , const config_item_types * );
void config_schema_item_set_common_selection_set(config_schema_item_type * , int argc , const char ** argv);
@ -80,17 +71,12 @@ typedef struct config_schema_item_struct config_schema_item_type;
void config_schema_item_set_required_children(config_schema_item_type * , stringlist_type * );
void config_schema_item_set_required_children_on_value(config_schema_item_type * , const char * , stringlist_type * );
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
*/
config_schema_item_type * config_add_schema_item(config_type * config,
const char * kw,
bool required);
config_schema_item_type * config_add_schema_item(config_type *,
const char * ,
bool ,
bool);
bool config_has_keys(const config_type *,
const char **,
int ,
bool );
const char * config_safe_iget(const config_type * config , const char *kw, int occurence , int index);
const char * config_iget(const config_type * , const char * , int occurence , int index);
@ -100,21 +86,29 @@ typedef struct config_schema_item_struct config_schema_item_type;
stringlist_type * config_alloc_complete_stringlist(const config_type* , const char * );
stringlist_type * config_alloc_stringlist(const config_type * config , const char * );
hash_type * config_alloc_hash(const config_type * , const char * );
const stringlist_type * config_get_stringlist_ref(const config_type * , const char * );
stringlist_type * config_iget_stringlist_ref(const config_type * , const char * , int );
bool config_has_set_item(const config_type * , const char * );
const stringlist_type * config_iget_stringlist_ref(const config_type * , const char * , int );
int config_get_occurences(const config_type * , const char * );
int config_get_occurence_size( const config_type * config , const char * kw , int occurence);
bool config_has_content_item( const config_type * config , const char * input_kw);
config_content_item_type * config_get_content_item( const config_type * config , const char * input_kw);
config_schema_item_type * config_add_key_value( config_type * config , const char * key , bool required , config_item_types item_type);
bool config_get_value_as_bool(const config_type * config , const char * kw);
int config_get_value_as_int(const config_type * config , const char * kw);
double config_get_value_as_double(const config_type * config , const char * kw);
const char * config_get_value_as_abspath( const config_type * config , const char * kw);
const char * config_get_value_as_relpath( const config_type * config , const char * kw);
const char * config_get_value_as_path( const config_type * config , const char * kw);
const char * config_get_value(const config_type * config , const char * kw);
void config_fprintf_item_list(const config_type * config , FILE * stream);
const char * config_get_config_file( const config_type * config , bool abs_path);
void config_fprintf_errors( const config_type * config , bool add_count , FILE * stream );
int config_get_schema_size( const config_type * config );
int config_get_content_size( const config_type * config );
const config_content_node_type * config_iget_content_node( const config_type * config , int index );
config_content_node_type * config_get_value_node( const config_type * config , const char * kw);
config_error_type * config_get_errors( const config_type * config );
#ifdef __cplusplus
}

View File

@ -0,0 +1,66 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_content_item.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
#ifndef __CONFIG_CONTENT_ITEM_H__
#define __CONFIG_CONTENT_ITEM_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/hash.h>
#include <ert/util/stringlist.h>
#include <ert/config/config_error.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_path_elm.h>
#include <ert/config/config_content_node.h>
typedef struct config_content_item_struct config_content_item_type;
int config_content_item_get_size(const config_content_item_type * item);
config_content_node_type * config_content_item_get_last_node(const config_content_item_type * item);
config_content_node_type * config_content_item_iget_node(const config_content_item_type * item , int index);
const config_content_node_type * config_content_item_get_last_node_const(const config_content_item_type * item);
const config_content_node_type * config_content_item_iget_node_const(const config_content_item_type * item , int index);
char * config_content_item_ialloc_joined_string(const config_content_item_type * item , const char * sep , int occurence);
char * config_content_item_alloc_joined_string(const config_content_item_type * item , const char * sep);
const stringlist_type * config_content_item_iget_stringlist_ref(const config_content_item_type * item, int occurence);
const stringlist_type * config_content_item_get_stringlist_ref(const config_content_item_type * item);
stringlist_type * config_content_item_alloc_complete_stringlist(const config_content_item_type * item, bool copy);
stringlist_type * config_content_item_alloc_stringlist(const config_content_item_type * item, bool copy);
hash_type * config_content_item_alloc_hash(const config_content_item_type * item , bool copy);
const char * config_content_item_iget(const config_content_item_type * item , int occurence , int index);
bool config_content_item_iget_as_bool(const config_content_item_type * item, int occurence , int index);
int config_content_item_iget_as_int(const config_content_item_type * item, int occurence , int index);
double config_content_item_iget_as_double(const config_content_item_type * item, int occurence , int index);
void config_content_item_clear( config_content_item_type * item );
void config_content_item_free( config_content_item_type * item );
void config_content_item_free__( void * arg );
config_content_item_type * config_content_item_alloc( const config_schema_item_type * schema , const config_path_elm_type * path_elm);
void config_content_item_validate(const config_content_item_type * item, config_error_type * error);
config_content_node_type * config_content_item_alloc_node( const config_content_item_type * item , const config_path_elm_type * path_elm);
const config_schema_item_type * config_content_item_get_schema( const config_content_item_type * item );
const config_path_elm_type * config_content_item_get_path_elm( const config_content_item_type * item );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,61 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_content_node.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
#ifndef __CONFIG_CONTENT_NODE_H__
#define __CONFIG_CONTENT_NODE_H__
#ifdef __cplusplus
define extern "C" {
#endif
#include <ert/util/hash.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_path_elm.h>
typedef struct config_content_node_struct config_content_node_type;
config_content_node_type * config_content_node_alloc( const config_schema_item_type * schema , const config_path_elm_type * cwd);
void config_content_node_add_value(config_content_node_type * node , const char * value);
void config_content_node_set(config_content_node_type * node , const stringlist_type * token_list);
char * config_content_node_alloc_joined_string(const config_content_node_type * node, const char * sep);
void config_content_node_free(config_content_node_type * node);
void config_content_node_free__(void * arg);
const char * config_content_node_get_full_string( config_content_node_type * node , const char * sep );
const char * config_content_node_iget(const config_content_node_type * node , int index);
bool config_content_node_iget_as_bool(const config_content_node_type * node , int index);
int config_content_node_iget_as_int(const config_content_node_type * node , int index);
double config_content_node_iget_as_double(const config_content_node_type * node , int index);
const char * config_content_node_iget_as_path(config_content_node_type * node , int index);
const char * config_content_node_iget_as_abspath( config_content_node_type * node , int index);
const char * config_content_node_iget_as_relpath( config_content_node_type * node , int index);
const stringlist_type * config_content_node_get_stringlist( const config_content_node_type * node );
const char * config_content_node_safe_iget(const config_content_node_type * node , int index);
int config_content_node_get_size( const config_content_node_type * node );
const char * config_content_node_get_kw( const config_content_node_type * node );
void config_content_node_assert_key_value( const config_content_node_type * node );
const config_path_elm_type * config_content_node_get_path_elm( const config_content_node_type * node );
void config_content_node_init_opt_hash( const config_content_node_type * node , hash_type * opt_hash , int elm_offset);
void config_content_node_fprintf( const config_content_node_type * node , FILE * stream );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,45 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_error.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
#ifndef __CONFIG_ERROR_H__
#define __CONFIG_ERROR_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
typedef struct config_error_struct config_error_type;
config_error_type * config_error_alloc();
config_error_type * config_error_alloc_copy( const config_error_type * src_error);
void config_error_free(config_error_type * error);
const char * config_error_iget(const config_error_type * error , int index);
void config_error_add( config_error_type * error , char * new_error );
void config_error_clear( config_error_type * error );
int config_error_count( const config_error_type * error );
void config_error_fprintf( const config_error_type * error , bool add_count , FILE * stream );
bool config_error_equal( const config_error_type * error1 , const config_error_type * error2);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,44 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'config_path_elm.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
#ifndef __CONFIG_PATH_ELM_H__
#define __CONFIG_PATH_ELM_H__
#ifdef __cplusplus
extern "C"
#endif
#include <ert/config/config_root_path.h>
typedef struct config_path_elm_struct config_path_elm_type;
void config_path_elm_free( config_path_elm_type * path_elm );
void config_path_elm_free__( void * arg );
config_path_elm_type * config_path_elm_alloc( const config_root_path_type * root_path , const char * path);
const char * config_path_elm_get_abspath( const config_path_elm_type * path_elm );
const char * config_path_elm_get_relpath( const config_path_elm_type * path_elm );
const config_root_path_type * config_path_elm_get_rootpath( const config_path_elm_type * path_elm );
char * config_path_elm_alloc_abspath(const config_path_elm_type * path_elm , const char * input_path);
char * config_path_elm_alloc_relpath(const config_path_elm_type * path_elm , const char * input_path);
char * config_path_elm_alloc_path(const config_path_elm_type * path_elm , const char * input_path);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,40 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'config_root_path.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
#ifndef __CONFIG_ROOT_PATH_H__
#define __CONFIG_ROOT_PATH_H__
#ifdef __cplusplus
extern "C"
#endif
typedef struct config_root_path_struct config_root_path_type;
void config_root_path_free( config_root_path_type * root_path );
config_root_path_type * config_root_path_alloc( const char * input_path );
const char * config_root_path_get_input_path( const config_root_path_type * root_path );
const char * config_root_path_get_rel_path( const config_root_path_type * root_path );
const char * config_root_path_get_abs_path( const config_root_path_type * root_path );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,123 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_schema_item.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
#ifndef __CONFIG_SCHEMA_ITEM_H__
#define __CONFIG_SCHEMA_ITEM_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/stringlist.h>
#include <ert/config/config_error.h>
#include <ert/config/config_path_elm.h>
/**
Types used for validation of config items.
*/
typedef enum {CONFIG_STRING = 1,
CONFIG_INT = 2,
CONFIG_FLOAT = 4,
CONFIG_PATH = 8,
CONFIG_EXISTING_PATH = 16,
CONFIG_BOOL = 32,
CONFIG_CONFIG = 64,
CONFIG_BYTESIZE = 128,
CONFIG_EXECUTABLE = 256 ,
CONFIG_INVALID = 512 } config_item_types;
#define CONFIG_ITEM_TYPE_ENUM_DEFS \
{.value = 1 , .name="CONFIG_STRING"}, \
{.value = 2 , .name="CONFIG_INT"}, \
{.value = 4 , .name="CONFIG_FLOAT"}, \
{.value = 8 , .name="CONFIG_PATH"}, \
{.value = 16 , .name="CONFIG_EXISTING_PATH"}, \
{.value = 32 , .name="CONFIG_BOOL"}, \
{.value = 64 , .name="CONFIG_CONFIG"}, \
{.value = 128 , .name="CONFIG_BYTESIZE"}, \
{.value = 256 , .name="CONFIG_EXECUTABLE"}, \
{.value = 512 , .name="CONFIG_INVALID"}
#define CONFIG_ITEM_TYPE_ENUM_SIZE 10
typedef enum {
CONFIG_UNRECOGNIZED_IGNORE = 0,
CONFIG_UNRECOGNIZED_WARN = 1,
CONFIG_UNRECOGNIZED_ERROR = 2
} config_schema_unrecognized_enum;
#define CONFIG_SCHEMA_UNRECOGNIZED_ENUM_DEFS \
{.value = 0 , .name="CONFIG_UNRECOGNIZED_IGNORE"}, \
{.value = 1 , .name="CONFIG_UNRECOGNIZED_WARN"}, \
{.value = 2 , .name="CONFIG_UNRECOGNIZED_ERROR"}
#define CONFIG_SCHEMA_UNRECOGNIZED_ENUM_SIZE 3
#define CONFIG_DEFAULT_ARG_MIN -1
#define CONFIG_DEFAULT_ARG_MAX -1
typedef struct config_schema_item_struct config_schema_item_type;
config_schema_item_type * config_schema_item_alloc(const char * kw , bool required);
bool config_schema_item_validate_set(const config_schema_item_type * item ,
stringlist_type * token_list ,
const char * config_file,
const config_path_elm_type * path_elm,
config_error_type * error_list);
void config_schema_item_free( config_schema_item_type * item);
void config_schema_item_free__ (void * void_item);
void config_schema_item_set_common_selection_set(config_schema_item_type * item , int argc , const char ** argv);
void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int index , int argc , const char ** argv);
void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist);
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar );
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
int argc_min ,
int argc_max);
void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask);
int config_schema_item_num_required_children(const config_schema_item_type * item);
const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index);
const char * config_schema_item_get_kw( const config_schema_item_type * item );
bool config_schema_item_required( const config_schema_item_type * item );
bool config_schema_item_expand_envvar( const config_schema_item_type * item );
void config_schema_item_get_argc( const config_schema_item_type * item , int *argc_min , int *argc_max);
bool config_schema_item_has_required_children_value( const config_schema_item_type * item );
stringlist_type * config_schema_item_get_required_children_value(const config_schema_item_type * item , const char * value);
void config_schema_item_iset_type( config_schema_item_type * item , int index , config_item_types type);
config_item_types config_schema_item_iget_type(const config_schema_item_type * item , int index );
void config_schema_item_set_default_type( config_schema_item_type * item , config_item_types type);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,12 +1,14 @@
set( source_files config.c conf.c conf_util.c conf_data.c)
set( header_files config.h conf.h conf_data.h)
set( source_files config.c config_error.c config_schema_item.c config_content_item.c config_content_node.c config_root_path.c config_path_elm.c conf.c conf_util.c conf_data.c)
set( header_files config.h config_error.h config_schema_item.h config_content_item.h config_content_node.h config_root_path.h config_path_elm.h conf.h conf_data.h)
add_library( config ${LIBRARY_TYPE} ${source_files} )
set_target_properties( config PROPERTIES VERSION 1.0 SOVERSION 1.0 )
target_link_libraries( config ert_util )
install(TARGETS config DESTINATION ${CMAKE_INSTALL_LIBDIR})
foreach(header ${header_files})
install(FILES ../include/ert/config/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/config)
endforeach()
if (INSTALL_ERT)
install(TARGETS config DESTINATION ${CMAKE_INSTALL_LIBDIR})
foreach(header ${header_files})
install(FILES ../include/ert/config/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/config)
endforeach()
endif()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,291 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_content_item.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdbool.h>
#include <ert/util/vector.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/util/stringlist.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_error.h>
#include <ert/config/config_path_elm.h>
#define CONFIG_CONTENT_ITEM_ID 8876752
struct config_content_item_struct {
UTIL_TYPE_ID_DECLARATION;
const config_schema_item_type * schema;
vector_type * nodes;
const config_path_elm_type * path_elm;
};
/*****************************************************************/
/**
This function counts the number of times a config item has been
set. Referring again to the example at the top:
config_content_item_get_occurences( "KEY1" )
will return 2.
*/
int config_content_item_get_size(const config_content_item_type * item) {
return vector_get_size( item->nodes );
}
config_content_node_type * config_content_item_get_last_node(const config_content_item_type * item) {
return vector_get_last( item->nodes );
}
config_content_node_type * config_content_item_iget_node(const config_content_item_type * item , int index) {
return vector_iget( item->nodes , index );
}
const config_content_node_type * config_content_item_get_last_node_const(const config_content_item_type * item) {
return vector_get_last( item->nodes );
}
const config_content_node_type * config_content_item_iget_node_const(const config_content_item_type * item , int index) {
return vector_iget( item->nodes , index );
}
char * config_content_item_ialloc_joined_string(const config_content_item_type * item , const char * sep , int occurence) {
const config_content_node_type * node = config_content_item_iget_node(item , occurence);
return config_content_node_alloc_joined_string(node , sep);
}
char * config_content_item_alloc_joined_string(const config_content_item_type * item , const char * sep) {
const int occurences = config_content_item_get_size( item );
char * joined_string = NULL;
for (int i =0; i < occurences ; i++) {
joined_string = util_strcat_realloc( joined_string , config_content_item_ialloc_joined_string(item , sep , i));
if (i < (occurences - 1))
joined_string = util_strcat_realloc( joined_string , sep );
}
return joined_string;
}
const stringlist_type * config_content_item_iget_stringlist_ref(const config_content_item_type * item, int occurence) {
const config_content_node_type * node = config_content_item_iget_node(item , occurence);
return config_content_node_get_stringlist( node );
}
const stringlist_type * config_content_item_get_stringlist_ref(const config_content_item_type * item) {
const config_content_node_type * node = config_content_item_get_last_node( item );
return config_content_node_get_stringlist( node );
}
/**
If copy == false - the stringlist will break down when/if the
config object is freed - your call.
*/
stringlist_type * config_content_item_alloc_complete_stringlist(const config_content_item_type * item, bool copy) {
int inode;
stringlist_type * stringlist = stringlist_alloc_new();
for (inode = 0; inode < vector_get_size( item->nodes ); inode++) {
const config_content_node_type * node = config_content_item_iget_node(item , inode);
const stringlist_type * src_list = config_content_node_get_stringlist( node );
if (copy)
stringlist_append_stringlist_copy( stringlist , src_list );
else
stringlist_append_stringlist_ref( stringlist , src_list );
}
return stringlist;
}
/**
If copy == false - the stringlist will break down when/if the
config object is freed - your call.
*/
stringlist_type * config_content_item_alloc_stringlist(const config_content_item_type * item, bool copy) {
const config_content_node_type * node = config_content_item_get_last_node( item );
stringlist_type * stringlist = stringlist_alloc_new();
const stringlist_type * src_list = config_content_node_get_stringlist( node );
if (copy)
stringlist_append_stringlist_copy( stringlist , src_list );
else
stringlist_append_stringlist_ref( stringlist , src_list );
return stringlist;
}
/**
If copy == false - the hash will break down when/if the
config object is freed - your call.
*/
hash_type * config_content_item_alloc_hash(const config_content_item_type * item , bool copy) {
hash_type * hash = hash_alloc();
if (item != NULL) {
int inode;
for (inode = 0; inode < vector_get_size( item->nodes ); inode++) {
const config_content_node_type * node = config_content_item_iget_node(item , inode);
const stringlist_type * src_list = config_content_node_get_stringlist( node );
const char * key = stringlist_iget(src_list , 0);
const char * value = stringlist_iget(src_list , 1);
if (copy) {
hash_insert_hash_owned_ref(hash ,
key ,
util_alloc_string_copy(value) ,
free);
} else
hash_insert_ref(hash , key , value );
}
}
return hash;
}
/******************************************************************/
const char * config_content_item_iget(const config_content_item_type * item , int occurence , int index) {
const config_content_node_type * node = config_content_item_iget_node(item , occurence);
const stringlist_type * src_list = config_content_node_get_stringlist( node );
return stringlist_iget( src_list , index );
}
bool config_content_item_iget_as_bool(const config_content_item_type * item, int occurence , int index) {
bool value;
config_schema_item_assure_type(item->schema , index , CONFIG_BOOL);
util_sscanf_bool( config_content_item_iget(item , occurence ,index) , &value );
return value;
}
int config_content_item_iget_as_int(const config_content_item_type * item, int occurence , int index) {
int value;
config_schema_item_assure_type(item->schema , index , CONFIG_INT);
util_sscanf_int( config_content_item_iget(item , occurence , index) , &value );
return value;
}
double config_content_item_iget_as_double(const config_content_item_type * item, int occurence , int index) {
double value;
config_schema_item_assure_type(item->schema , index , CONFIG_FLOAT);
util_sscanf_double( config_content_item_iget(item , occurence , index) , &value );
return value;
}
/**
Used to reset an item is the special string 'CLEAR_STRING'
is found as the only argument:
OPTION V1
OPTION V2 V3 V4
OPTION __RESET__
OPTION V6
In this case OPTION will get the value 'V6'. The example given
above is a bit contrived; this option is designed for situations
where several config files are parsed serially; and the user can
not/will not update the first.
*/
void config_content_item_clear( config_content_item_type * item ) {
vector_clear( item->nodes );
}
void config_content_item_free( config_content_item_type * item ) {
vector_free( item->nodes );
free(item);
}
UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID);
void config_content_item_free__( void * arg ) {
config_content_item_type * content_item = config_content_item_safe_cast( arg );
config_content_item_free( content_item );
}
config_content_item_type * config_content_item_alloc( const config_schema_item_type * schema , const config_path_elm_type * path_elm) {
config_content_item_type * content_item = util_malloc( sizeof * content_item );
UTIL_TYPE_ID_INIT( content_item , CONFIG_CONTENT_ITEM_ID );
content_item->schema = schema;
content_item->nodes = vector_alloc_new();
content_item->path_elm = path_elm;
return content_item;
}
config_content_node_type * config_content_item_alloc_node( const config_content_item_type * item , const config_path_elm_type * path_elm) {
config_content_node_type * node = config_content_node_alloc( item->schema , path_elm );
vector_append_owned_ref( item->nodes , node , config_content_node_free__);
return node;
}
const config_schema_item_type * config_content_item_get_schema( const config_content_item_type * item ) {
return item->schema;
}
const config_path_elm_type * config_content_item_get_path_elm( const config_content_item_type * item ) {
return item->path_elm;
}

View File

@ -0,0 +1,229 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_content_node.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdbool.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/util/stringlist.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_path_elm.h>
#define CONFIG_CONTENT_NODE_ID 6752887
struct config_content_node_struct {
UTIL_TYPE_ID_DECLARATION;
const config_schema_item_type * schema;
stringlist_type * stringlist; /* The values which have been set. */
const config_path_elm_type * cwd;
stringlist_type * string_storage;
};
static UTIL_SAFE_CAST_FUNCTION( config_content_node , CONFIG_CONTENT_NODE_ID )
config_content_node_type * config_content_node_alloc( const config_schema_item_type * schema , const config_path_elm_type * cwd) {
config_content_node_type * node = util_malloc(sizeof * node );
UTIL_TYPE_ID_INIT( node , CONFIG_CONTENT_NODE_ID );
node->stringlist = stringlist_alloc_new();
node->cwd = cwd;
node->schema = schema;
node->string_storage = NULL;
return node;
}
void config_content_node_add_value(config_content_node_type * node , const char * value) {
stringlist_append_copy( node->stringlist , value);
}
void config_content_node_set(config_content_node_type * node , const stringlist_type * token_list) {
int argc = stringlist_get_size( token_list ) - 1;
for (int iarg=0; iarg < argc; iarg++)
config_content_node_add_value( node , stringlist_iget( token_list , iarg + 1));
}
char * config_content_node_alloc_joined_string(const config_content_node_type * node, const char * sep) {
return stringlist_alloc_joined_string(node->stringlist , sep);
}
void config_content_node_free(config_content_node_type * node) {
stringlist_free(node->stringlist);
if (node->string_storage != NULL)
stringlist_free( node->string_storage );
free(node);
}
void config_content_node_free__(void * arg) {
config_content_node_type * node = config_content_node_safe_cast( arg );
config_content_node_free( node );
}
static void config_content_node_push_string( config_content_node_type * node , char * string) {
if (node->string_storage == NULL)
node->string_storage = stringlist_alloc_new( );
stringlist_append_owned_ref( node->string_storage , string );
}
const char * config_content_node_get_full_string( config_content_node_type * node , const char * sep ) {
char * full_string = stringlist_alloc_joined_string(node->stringlist , sep);
config_content_node_push_string( node , full_string );
return full_string;
}
const char * config_content_node_iget(const config_content_node_type * node , int index) {
return stringlist_iget( node->stringlist , index );
}
const char * config_content_node_safe_iget(const config_content_node_type * node , int index) {
if (index >= stringlist_get_size( node->stringlist ))
return NULL;
else
return stringlist_iget( node->stringlist , index );
}
bool config_content_node_iget_as_bool(const config_content_node_type * node , int index) {
bool value;
config_schema_item_assure_type(node->schema , index , CONFIG_BOOL);
util_sscanf_bool( config_content_node_iget(node , index) , &value );
return value;
}
int config_content_node_iget_as_int(const config_content_node_type * node , int index) {
int value;
config_schema_item_assure_type(node->schema , index , CONFIG_INT);
util_sscanf_int( config_content_node_iget(node , index) , &value );
return value;
}
double config_content_node_iget_as_double(const config_content_node_type * node , int index) {
double value;
config_schema_item_assure_type(node->schema , index , CONFIG_FLOAT + CONFIG_INT);
util_sscanf_double( config_content_node_iget(node , index) , &value );
return value;
}
const char * config_content_node_iget_as_path(config_content_node_type * node , int index) {
config_schema_item_assure_type(node->schema , index , CONFIG_PATH + CONFIG_EXISTING_PATH);
{
const char * config_value = config_content_node_iget(node , index);
char * path_value = config_path_elm_alloc_path( node->cwd , config_value );
config_content_node_push_string( node , path_value );
return path_value;
}
}
const char * config_content_node_iget_as_abspath( config_content_node_type * node , int index) {
config_schema_item_assure_type(node->schema , index , CONFIG_PATH + CONFIG_EXISTING_PATH);
{
const char * config_value = config_content_node_iget(node , index);
char * path_value = config_path_elm_alloc_abspath( node->cwd , config_value );
config_content_node_push_string( node , path_value );
return path_value;
}
}
const char * config_content_node_iget_as_relpath( config_content_node_type * node , int index) {
config_schema_item_assure_type(node->schema , index , CONFIG_PATH + CONFIG_EXISTING_PATH);
{
const char * config_value = config_content_node_iget(node , index);
char * path_value = config_path_elm_alloc_relpath( node->cwd , config_value );
config_content_node_push_string( node , path_value );
return path_value;
}
}
const stringlist_type * config_content_node_get_stringlist( const config_content_node_type * node ) {
return node->stringlist;
}
const char * config_content_node_get_kw( const config_content_node_type * node ) {
return config_schema_item_get_kw( node->schema );
}
int config_content_node_get_size( const config_content_node_type * node ) {
return stringlist_get_size( node->stringlist );
}
void config_content_node_assert_key_value( const config_content_node_type * node ) {
int argc_min , argc_max;
config_schema_item_get_argc( node->schema , &argc_min , &argc_max);
if (!((argc_min == 1) && (argc_min == 1)))
util_abort("%s: item:%s before calling config_get_value() functions *without* index you must set argc_min == argc_max = 1 \n",__func__ , config_schema_item_get_kw( node->schema ));
}
const config_path_elm_type * config_content_node_get_path_elm( const config_content_node_type * node ) {
return node->cwd;
}
/**
The node should contain elements of the type:
KEY1:VALUE1 KEY2:Value2 XX Key3:Val3 Ignored
Which will be inserted in the opt_hash dictionary as : {"KEY1" :
"VALUE1" , ... } Elements which do not conform to this syntax are
ignored.
*/
void config_content_node_init_opt_hash( const config_content_node_type * node , hash_type * opt_hash , int elm_offset) {
int i;
for (i = elm_offset; i < config_content_node_get_size( node ); i++)
hash_add_option( opt_hash , config_content_node_iget( node , i ));
}
void config_content_node_fprintf( const config_content_node_type * node , FILE * stream ) {
fprintf(stream , "%s: {" , config_schema_item_get_kw( node->schema ));
stringlist_fprintf( node->stringlist , ", " , stream );
fprintf(stream , "}\n");
}

View File

@ -0,0 +1,86 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdio.h>
#include <ert/util/util.h>
#include <ert/util/stringlist.h>
#include <ert/config/config_error.h>
struct config_error_struct {
stringlist_type * error_list;
};
config_error_type * config_error_alloc() {
config_error_type * error = util_malloc( sizeof * error );
error->error_list = stringlist_alloc_new();
return error;
}
config_error_type * config_error_alloc_copy( const config_error_type * src_error) {
config_error_type * config_error = config_error_alloc();
stringlist_deep_copy( config_error->error_list , src_error->error_list );
return config_error;
}
bool config_error_equal( const config_error_type * error1 , const config_error_type * error2) {
return stringlist_equal( error1->error_list , error2->error_list );
}
void config_error_free( config_error_type * error ) {
stringlist_free( error->error_list );
free( error );
}
void config_error_add( config_error_type * error , char * new_error) {
stringlist_append_owned_ref( error->error_list , new_error );
}
void config_error_clear( config_error_type * error ) {
stringlist_clear( error->error_list );
}
int config_error_count( const config_error_type * error ) {
return stringlist_get_size( error->error_list );
}
const char * config_error_iget( const config_error_type * error , int index) {
return stringlist_iget( error->error_list , index );
}
void config_error_fprintf( const config_error_type * error , bool add_count , FILE * stream ) {
int error_nr;
for (error_nr = 0; error_nr < stringlist_get_size( error->error_list ); error_nr++) {
if (add_count)
fprintf(stream , " %02d: " , error_nr);
fprintf( stream , "%s\n" , stringlist_iget( error->error_list , error_nr));
}
}

View File

@ -0,0 +1,114 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_get.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
*/
/*****************************************************************/
/* All the functions in this block will operate on the last item
which has been set with a particular key value. So assuming the
config file looks like:
KEY VALUE1
KEY VALUE2 OPTIONAL
KEY 100 VALUE3 OPTIONAL ERROR
these functions will all operate on the last line in the config file:
KEY 100 VALUE3 OPTIONAL ERROR
*/
config_content_node_type * config_get_value_node( const config_type * config , const char * kw) {
config_content_item_type * item = config_get_content_item(config , kw);
if (item != NULL) {
config_content_node_type * node = config_content_item_get_last_node( item );
config_content_node_assert_key_value( node );
return node;
} else
return NULL; // Will return NULL on unset keywords - must check NULL return value?!
}
static config_content_node_type * config_get_value_node__( const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node( config , kw );
if (node == NULL)
util_abort("Tried to get value node from unset kw:%s \n",__func__ , kw );
return node;
}
bool config_get_value_as_bool(const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_bool(node , 0);
}
int config_get_value_as_int(const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_int(node , 0);
}
double config_get_value_as_double(const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_double(node , 0);
}
const char * config_get_value_as_path( const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_path(node , 0);
}
const char * config_get_value_as_abspath( const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_abspath(node , 0);
}
const char * config_get_value_as_relpath( const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_relpath(node , 0);
}
const char * config_get_value(const config_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget(node , 0);
}
/*****************************************************************/
int config_get_content_size( const config_type * config ) {
return vector_get_size(config->content_list);
}
const config_content_node_type * config_iget_content_node( const config_type * config , int index) {
return vector_iget_const( config->content_list , index );
}
int config_get_schema_size( const config_type * config ) {
return hash_get_size( config->schema_items );
}
config_error_type * config_get_errors( const config_type * config ) {
return config->parse_errors;
}

View File

@ -0,0 +1,135 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'config_path_elm.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/config/config_root_path.h>
#include <ert/config/config_path_elm.h>
#define CONFIG_PATH_ELM_TYPE_ID 7100063
struct config_path_elm_struct {
UTIL_TYPE_ID_DECLARATION;
char * abs_path; // This will always be absolute
char * rel_path; // This will always be relative to the root path.
const config_root_path_type * root_path;
};
static UTIL_SAFE_CAST_FUNCTION( config_path_elm , CONFIG_PATH_ELM_TYPE_ID )
config_path_elm_type * config_path_elm_alloc( const config_root_path_type * root_path , const char * path) {
if (root_path != NULL) {
config_path_elm_type * path_elm = util_malloc( sizeof * path_elm );
UTIL_TYPE_ID_INIT(path_elm , CONFIG_PATH_ELM_TYPE_ID);
path_elm->root_path = root_path;
if (path == NULL) {
path_elm->rel_path = NULL;
path_elm->abs_path = util_alloc_string_copy( config_root_path_get_abs_path(root_path) );
} else {
if (util_is_abs_path( path )) {
path_elm->abs_path = util_alloc_string_copy( path );
path_elm->rel_path = util_alloc_rel_path( config_root_path_get_abs_path(root_path) , path );
} else {
path_elm->abs_path = util_alloc_filename( config_root_path_get_abs_path(root_path) , path , NULL );
path_elm->rel_path = util_alloc_string_copy( path );
}
}
return path_elm;
} else {
util_abort("%s: root_path input argument == NULL - invalid \n",__func__);
return NULL;
}
}
void config_path_elm_free( config_path_elm_type * path_elm ) {
util_safe_free( path_elm->rel_path );
util_safe_free( path_elm->abs_path );
free( path_elm );
}
void config_path_elm_free__( void * arg ) {
config_path_elm_type * path_elm = config_path_elm_safe_cast( arg );
config_path_elm_free( path_elm );
}
const config_root_path_type * config_path_elm_get_rootpath( const config_path_elm_type * path_elm ) {
return path_elm->root_path;
}
const char * config_path_elm_get_relpath( const config_path_elm_type * path_elm ) {
return path_elm->rel_path;
}
const char * config_path_elm_get_abspath( const config_path_elm_type * path_elm ) {
return path_elm->abs_path;
}
/*****************************************************************/
char * config_path_elm_alloc_path(const config_path_elm_type * path_elm , const char * path) {
if (util_is_abs_path( path ))
return util_alloc_string_copy( path );
else {
/* This will be relative or absolute depending on the relative/absolute
status of the root_path. */
const char * input_root = config_root_path_get_input_path( path_elm->root_path );
if (input_root == NULL)
return util_alloc_filename( path_elm->rel_path , path , NULL);
else
return util_alloc_joined_string( (const char *[3]) { input_root , path_elm->rel_path , path } , 3 , UTIL_PATH_SEP_STRING );
}
}
char * config_path_elm_alloc_relpath(const config_path_elm_type * path_elm , const char * input_path) {
if (util_is_abs_path( input_path ))
return util_alloc_rel_path( config_root_path_get_rel_path( path_elm->root_path ) , input_path);
else {
char * abs_path = config_path_elm_alloc_abspath( path_elm , input_path );
char * rel_path = util_alloc_rel_path( config_root_path_get_abs_path( path_elm->root_path ) , abs_path );
free( abs_path );
return rel_path;
}
}
char * config_path_elm_alloc_abspath(const config_path_elm_type * path_elm , const char * input_path) {
if (util_is_abs_path( input_path ))
return util_alloc_string_copy( input_path );
else {
char * abs_path1 = util_alloc_filename( path_elm->abs_path , input_path , NULL );
char * abs_path = util_alloc_realpath__( abs_path1 ); // The util_alloc_realpath__() will work also for nonexsting paths
free( abs_path1 );
return abs_path;
}
}

View File

@ -0,0 +1,97 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'config_root_path.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <ert/util/util.h>
#include <ert/config/config_root_path.h>
struct config_root_path_struct {
char * input_path;
char * abs_path;
char * rel_path;
};
/**
Input must be an existing directory, which will be used as the
root; or NULL in which case cwd will be used as root. The input
directory can be both realtive or absolute.
*/
config_root_path_type * config_root_path_alloc( const char * input_path ) {
if (input_path == NULL || util_is_directory( input_path )) {
config_root_path_type * root_path = util_malloc( sizeof * root_path );
{
char * cwd = util_alloc_cwd();
root_path->input_path = util_alloc_string_copy( input_path );
if (input_path == NULL) {
root_path->rel_path = NULL;
root_path->abs_path = util_alloc_string_copy( cwd );
} else {
if (util_is_abs_path( input_path )) {
root_path->abs_path = util_alloc_string_copy( input_path );
root_path->rel_path = util_alloc_rel_path( cwd , root_path->abs_path);
} else {
root_path->rel_path = util_alloc_string_copy( input_path );
{
char * abs_path = util_alloc_filename( cwd , input_path , NULL );
root_path->abs_path = util_alloc_realpath( abs_path );
free( abs_path );
}
}
}
free( cwd );
}
return root_path;
} else
return NULL;
}
void config_root_path_free( config_root_path_type * root_path ) {
util_safe_free( root_path->rel_path );
util_safe_free( root_path->abs_path );
util_safe_free( root_path->input_path );
free( root_path );
}
const char * config_root_path_get_input_path( const config_root_path_type * root_path ) {
return root_path->input_path;
}
const char * config_root_path_get_rel_path( const config_root_path_type * root_path ) {
return root_path->rel_path;
}
const char * config_root_path_get_abs_path( const config_root_path_type * root_path ) {
return root_path->abs_path;
}

View File

@ -0,0 +1,536 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/util/parser.h>
#include <ert/util/hash.h>
#include <ert/util/stringlist.h>
#include <ert/util/set.h>
#include <ert/util/subst_list.h>
#include <ert/util/vector.h>
#include <ert/config/config_error.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_path_elm.h>
typedef struct validate_struct validate_type;
/**
This is a 'support-struct' holding various pieces of information
needed during the validation process. Observe the following about
validation:
1. It is atomic, in the sense that if you try to an item like this:
KW ARG1 ARG2 ARG3
where ARG1 and ARG2 are valid, whereas there is something wrong
with ARG3, NOTHING IS SET.
2. Validation is a two-step process, the first step is run when an
item is parsed. This includes checking:
o The number of argument.
o That the arguments have the right type.
o That the values match the selection set.
The second validation step is done when the pasing is complete,
in this pass we check dependencies - i.e. required_children and
required_children_on_value.
Observe that nothing has-to be set in this struct. There are some dependencies:
1. Only _one_ of common_selection_set and indexed_selection_set
can be set.
2. If setting indexed_selection_set or type_map, you MUST set
argc_max first.
*/
struct validate_struct {
int argc_min; /* The minimum number of arguments: -1 means no lower limit. */
int argc_max; /* The maximum number of arguments: -1 means no upper limit. */
set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */
set_type ** indexed_selection_set; /* A selection set which will apply for specifi (indexed) arguments. */
int_vector_type * type_map; /* A list of types for the items. Set along with argc_minmax(); */
stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */
hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) (This one is complex). */
};
#define CONFIG_SCHEMA_ITEM_ID 6751
struct config_schema_item_struct {
UTIL_TYPE_ID_DECLARATION;
char * kw; /* The kw which identifies this item· */
bool required_set;
stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */
hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) */
validate_type * validate; /* Information need during validation. */
bool expand_envvar; /* Should environment variables like $HOME be expanded?*/
};
/*****************************************************************/
/*****************************************************************/
static void validate_set_default_type( validate_type * validate , config_item_types item_type) {
int_vector_set_default(validate->type_map , item_type);
}
static validate_type * validate_alloc() {
validate_type * validate = util_malloc(sizeof * validate );
validate->argc_min = CONFIG_DEFAULT_ARG_MIN;
validate->argc_max = CONFIG_DEFAULT_ARG_MAX;
validate->common_selection_set = NULL;
validate->indexed_selection_set = NULL;
validate->required_children = NULL;
validate->required_children_value = NULL;
validate->type_map = int_vector_alloc(0 , 0);
validate_set_default_type( validate , CONFIG_STRING );
return validate;
}
static void validate_free(validate_type * validate) {
if (validate->common_selection_set != NULL) set_free(validate->common_selection_set);
if (validate->indexed_selection_set != NULL) {
for (int i = 0; i < validate->argc_max; i++)
if (validate->indexed_selection_set[i] != NULL)
set_free(validate->indexed_selection_set[i]);
free(validate->indexed_selection_set);
}
int_vector_free( validate->type_map );
if (validate->required_children != NULL) stringlist_free(validate->required_children);
if (validate->required_children_value != NULL) hash_free(validate->required_children_value);
free(validate);
}
static void validate_iset_type( validate_type * validate , int index , config_item_types type) {
int_vector_iset( validate->type_map , index , type);
}
static config_item_types validate_iget_type( const validate_type * validate , int index) {
return int_vector_safe_iget( validate->type_map , index );
}
static void validate_set_argc_minmax(validate_type * validate , int argc_min , int argc_max) {
if (validate->argc_min != CONFIG_DEFAULT_ARG_MIN)
util_abort("%s: sorry - current implementation does not allow repeated calls to: %s \n",__func__ , __func__);
if (argc_min == CONFIG_DEFAULT_ARG_MIN)
argc_min = 0;
validate->argc_min = argc_min;
validate->argc_max = argc_max;
if ((argc_max != CONFIG_DEFAULT_ARG_MAX) && (argc_max < argc_min))
util_abort("%s invalid arg min/max values. argc_min:%d argc_max:%d \n",__func__ , argc_min , argc_max);
{
int internal_type_size = 0; /* Should end up in the range [argc_min,argc_max] */
if (argc_max > 0)
internal_type_size = argc_max;
else
internal_type_size = argc_min;
if (internal_type_size > 0) {
validate->indexed_selection_set = util_calloc( internal_type_size , sizeof * validate->indexed_selection_set );
for (int iarg=0; iarg < internal_type_size; iarg++)
validate->indexed_selection_set[iarg] = NULL;
}
}
}
static void validate_set_common_selection_set(validate_type * validate , int argc , const char ** argv) {
if (validate->common_selection_set != NULL)
set_free(validate->common_selection_set);
validate->common_selection_set = set_alloc( argc , argv );
}
static void validate_set_indexed_selection_set(validate_type * validate , int index , int argc , const char ** argv) {
if (validate->indexed_selection_set == NULL)
util_abort("%s: must call xxx_set_argc_minmax() first - aborting \n",__func__);
if (index >= validate->argc_min)
util_abort("%s: When not not setting argc_max selection set can only be applied to indices up to argc_min\n",__func__);
if (validate->indexed_selection_set[index] != NULL)
set_free(validate->indexed_selection_set[index]);
validate->indexed_selection_set[index] = set_alloc(argc , argv);
}
/*****************************************************************/
static UTIL_SAFE_CAST_FUNCTION( config_schema_item , CONFIG_SCHEMA_ITEM_ID)
void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask) {
bool OK = false;
if (int_vector_safe_iget( item->validate->type_map , index) & type_mask)
OK = true;
if (!OK)
util_abort("%s: failed - wrong installed type \n" , __func__);
}
config_schema_item_type * config_schema_item_alloc(const char * kw , bool required) {
config_schema_item_type * item = util_malloc(sizeof * item );
UTIL_TYPE_ID_INIT( item , CONFIG_SCHEMA_ITEM_ID);
item->kw = util_alloc_string_copy(kw);
item->required_set = required;
item->required_children = NULL;
item->required_children_value = NULL;
item->expand_envvar = true; /* Default is to expand $VAR expressions; can be turned off with
config_schema_item_set_envvar_expansion( item , false ); */
item->validate = validate_alloc();
return item;
}
static char * __alloc_relocated__(const config_path_elm_type * path_elm , const char * value) {
char * file;
if (util_is_abs_path(value))
file = util_alloc_string_copy( value );
else
file = util_alloc_filename(config_path_elm_get_relpath( path_elm ) , value , NULL);
return file;
}
bool config_schema_item_validate_set(const config_schema_item_type * item , stringlist_type * token_list , const char * config_file, const config_path_elm_type * path_elm , config_error_type * error_list) {
bool OK = true;
int argc = stringlist_get_size( token_list ) - 1;
if (item->validate->argc_min >= 0) {
if (argc < item->validate->argc_min) {
OK = false;
{
char * error_message;
if (config_file != NULL)
error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have at least %d arguments.",config_file , item->kw , item->validate->argc_min);
else
error_message = util_alloc_sprintf("Error:: Keyword:%s must have at least %d arguments.",item->kw , item->validate->argc_min);
config_error_add( error_list , error_message );
}
}
}
if (item->validate->argc_max >= 0) {
if (argc > item->validate->argc_max) {
OK = false;
{
char * error_message;
if (config_file != NULL)
error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have maximum %d arguments.",config_file , item->kw , item->validate->argc_max);
else
error_message = util_alloc_sprintf("Error:: Keyword:%s must have maximum %d arguments.",item->kw , item->validate->argc_max);
config_error_add( error_list , error_message );
}
}
}
/*
OK - now we have verified that the number of arguments is correct. Then
we start actually looking at the values.
*/
if (OK) {
/* Validating selection set - first common, then indexed */
if (item->validate->common_selection_set) {
for (int iarg = 0; iarg < argc; iarg++) {
if (!set_has_key(item->validate->common_selection_set , stringlist_iget( token_list , iarg + 1))) {
config_error_add( error_list , util_alloc_sprintf("%s: is not a valid value for: %s.",stringlist_iget( token_list , iarg + 1) , item->kw));
OK = false;
}
}
} else if (item->validate->indexed_selection_set != NULL) {
for (int iarg = 0; iarg < argc; iarg++) {
if ((item->validate->argc_max > 0) || (iarg < item->validate->argc_min)) { /* Without this test we might go out of range on the indexed selection set. */
if (item->validate->indexed_selection_set[iarg] != NULL) {
if (!set_has_key(item->validate->indexed_selection_set[iarg] , stringlist_iget( token_list , iarg + 1))) {
config_error_add( error_list , util_alloc_sprintf("%s: is not a valid value for item %d of \'%s\'.",stringlist_iget( token_list , iarg + 1) , iarg + 1 , item->kw));
OK = false;
}
}
}
}
}
/*
Observe that the following code might rewrite the content of
argv for arguments referring to path locations.
*/
/* Validate the TYPE of the various argumnents */
{
for (int iarg = 0; iarg < argc; iarg++) {
const char * value = stringlist_iget(token_list , iarg + 1);
switch (validate_iget_type( item->validate , iarg)) {
case(CONFIG_STRING): /* This never fails ... */
break;
case(CONFIG_INT):
if (!util_sscanf_int( value , NULL ))
config_error_add( error_list , util_alloc_sprintf("Failed to parse:%s as an integer.",value));
break;
case(CONFIG_FLOAT):
if (!util_sscanf_double( value , NULL )) {
config_error_add( error_list , util_alloc_sprintf("Failed to parse:%s as a floating point number.", value));
OK = false;
}
break;
case(CONFIG_PATH):
// As long as we do not reuqire the path to exist it is just a string.
break;
case(CONFIG_EXISTING_PATH):
{
char * path = config_path_elm_alloc_abspath( path_elm , value );
if (!util_entry_exists(path)) {
config_error_add( error_list , util_alloc_sprintf("Can not find entry %s in %s ",value , config_path_elm_get_relpath( path_elm) ));
OK = false;
}
free( path );
}
break;
case(CONFIG_EXECUTABLE):
{
/*
1. If the supplied value is an abolute path - do nothing.
2. If the supplied is _not_ an absolute path:
a. Try if the relocated exists - then use that.
b. Else - try if the util_alloc_PATH_executable() exists.
*/
if (!util_is_abs_path( value )) {
char * relocated = __alloc_relocated__(path_elm , value);
char * path_exe = util_alloc_PATH_executable( value );
if (util_file_exists(relocated)) {
if (util_is_executable(relocated))
stringlist_iset_copy( token_list , iarg , relocated);
} else if (path_exe != NULL)
stringlist_iset_copy( token_list , iarg , path_exe);
else
config_error_add( error_list , util_alloc_sprintf("Could not locate executable:%s ", value));
free(relocated);
util_safe_free(path_exe);
} else {
if (!util_is_executable( value ))
config_error_add( error_list , util_alloc_sprintf("Could not locate executable:%s ", value));
}
}
break;
case(CONFIG_BOOL):
if (!util_sscanf_bool( value , NULL )) {
config_error_add( error_list , util_alloc_sprintf("Failed to parse:%s as a boolean.", value));
OK = false;
}
break;
case(CONFIG_BYTESIZE):
if (!util_sscanf_bytesize( value , NULL)) {
config_error_add( error_list , util_alloc_sprintf("Failed to parse:\"%s\" as number of bytes." , value));
OK = false;
}
break;
default:
util_abort("%s: config_item_type:%d not recognized \n",__func__ , validate_iget_type(item->validate , iarg));
}
}
}
}
return OK;
}
void config_schema_item_free( config_schema_item_type * item) {
free(item->kw);
if (item->required_children != NULL) stringlist_free(item->required_children);
if (item->required_children_value != NULL) hash_free(item->required_children_value);
validate_free(item->validate);
free(item);
}
void config_schema_item_free__ (void * void_item) {
config_schema_item_type * item = config_schema_item_safe_cast( void_item );
config_schema_item_free( item );
}
void config_schema_item_set_required_children_on_value(config_schema_item_type * item , const char * value , stringlist_type * child_list) {
if (item->required_children_value == NULL)
item->required_children_value = hash_alloc();
hash_insert_hash_owned_ref( item->required_children_value , value , stringlist_alloc_deep_copy(child_list) , stringlist_free__);
}
/**
This function is used to set the minimum and maximum number of
arguments for an item. In addition you can pass in a pointer to an
array of config_schema_item_types values which will be used for validation
of the input. This vector must be argc_max elements long; it can be
NULL.
*/
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
int argc_min ,
int argc_max) {
validate_set_argc_minmax(item->validate , argc_min , argc_max);
}
void config_schema_item_iset_type( config_schema_item_type * item , int index , config_item_types type) {
validate_iset_type( item->validate , index , type );
}
void config_schema_item_set_default_type( config_schema_item_type * item , config_item_types type) {
validate_set_default_type( item->validate , type );
}
config_item_types config_schema_item_iget_type(const config_schema_item_type * item , int index ) {
return validate_iget_type( item->validate , index );
}
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ) {
item->expand_envvar = expand_envvar;
}
void config_schema_item_set_common_selection_set(config_schema_item_type * item , int argc , const char ** argv) {
validate_set_common_selection_set(item->validate , argc , argv);
}
void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int index , int argc , const char ** argv) {
validate_set_indexed_selection_set(item->validate , index , argc , argv);
}
void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist) {
item->required_children = stringlist_alloc_deep_copy(stringlist);
}
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key) {
if (item->required_children == NULL)
item->required_children = stringlist_alloc_new();
stringlist_append_copy( item->required_children , child_key );
}
int config_schema_item_num_required_children(const config_schema_item_type * item) {
if (item->required_children == NULL)
return 0;
else
return stringlist_get_size( item->required_children );
}
const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index) {
return stringlist_iget( item->required_children , index );
}
const char * config_schema_item_get_kw( const config_schema_item_type * item ) {
return item->kw;
}
bool config_schema_item_required( const config_schema_item_type * item ) {
return item->required_set;
}
bool config_schema_item_expand_envvar( const config_schema_item_type * item ) {
return item->expand_envvar;
}
void config_schema_item_get_argc( const config_schema_item_type * item , int *argc_min , int *argc_max) {
*argc_min = item->validate->argc_min;
*argc_max = item->validate->argc_max;
}
bool config_schema_item_has_required_children_value( const config_schema_item_type * item ) {
if (item->required_children_value == NULL)
return false;
else
return true;
}
stringlist_type * config_schema_item_get_required_children_value(const config_schema_item_type * item , const char * value) {
return hash_safe_get( item->required_children_value , value );
}
/*****************************************************************/
/* Small functions to support enum introspection. */
const char * config_schema_item_type_enum_iget( int index, int * value) {
return util_enum_iget( index , CONFIG_ITEM_TYPE_ENUM_SIZE , (const util_enum_element_type []) { CONFIG_ITEM_TYPE_ENUM_DEFS }, value);
}
const char * config_schema_item_unrecognized_enum_iget( int index, int * value) {
return util_enum_iget( index , CONFIG_SCHEMA_UNRECOGNIZED_ENUM_SIZE , (const util_enum_element_type []) { CONFIG_SCHEMA_UNRECOGNIZED_ENUM_DEFS }, value);
}

View File

@ -0,0 +1,49 @@
add_executable( config_append_test config_append_test.c )
target_link_libraries( config_append_test config )
add_executable( config_node_test config_node_test.c )
target_link_libraries( config_node_test config )
add_executable( config_typeOK config_typeOK.c )
target_link_libraries( config_typeOK config )
add_executable( config_typeFail config_typeFail.c )
target_link_libraries( config_typeFail config )
add_executable( config_path_elm config_path_elm.c )
target_link_libraries( config_path_elm config )
add_executable( config_root_path config_root_path.c )
target_link_libraries( config_root_path config )
add_executable( config_include_test config_include_test.c)
target_link_libraries( config_include_test config)
add_executable( config_content_node config_content_node.c)
target_link_libraries( config_content_node config)
add_executable( config_content_item config_content_item.c)
target_link_libraries( config_content_item config)
add_executable( config_error config_error.c)
target_link_libraries( config_error config)
add_test( config_error ${EXECUTABLE_OUTPUT_PATH}/config_error )
add_executable( config_config config_config.c)
target_link_libraries( config_config config)
add_test( config_config ${EXECUTABLE_OUTPUT_PATH}/config_config )
add_executable( config_schema_item config_schema_item.c)
target_link_libraries( config_schema_item config)
add_test( config_schema_item ${EXECUTABLE_OUTPUT_PATH}/config_schema_item )
add_test( config_typeOK ${EXECUTABLE_OUTPUT_PATH}/config_typeOK ${CMAKE_CURRENT_SOURCE_DIR}/data/type_testOK )
add_test( config_typeFail ${EXECUTABLE_OUTPUT_PATH}/config_typeFail ${CMAKE_CURRENT_SOURCE_DIR}/data/type_testFail )
add_test( config_append_test ${EXECUTABLE_OUTPUT_PATH}/config_append_test ${CMAKE_CURRENT_SOURCE_DIR}/data/append_test )
add_test( config_node_test ${EXECUTABLE_OUTPUT_PATH}/config_node_test ${CMAKE_CURRENT_SOURCE_DIR}/data/append_test )
add_test( config_path_elm ${EXECUTABLE_OUTPUT_PATH}/config_path_elm )
add_test( config_content_node ${EXECUTABLE_OUTPUT_PATH}/config_content_node )
add_test( config_content_item ${EXECUTABLE_OUTPUT_PATH}/config_content_item ${CMAKE_CURRENT_SOURCE_DIR}/data/content_item_test)
add_test( config_include_test ${EXECUTABLE_OUTPUT_PATH}/config_include_test ${CMAKE_CURRENT_SOURCE_DIR}/data include_test )
add_test( config_root_path ${EXECUTABLE_OUTPUT_PATH}/config_root_path ${CMAKE_CURRENT_SOURCE_DIR}/data )

View File

@ -0,0 +1,47 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_append_test.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/config/config.h>
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
bool OK;
config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false );
config_schema_item_set_argc_minmax( item , 1 , 1);
test_assert_true(config_parse(config , config_file , "--" , NULL , NULL , false , true ));
{
test_assert_int_equal( config_get_occurences( config , "APPEND" ) , 3);
{
const char * value = config_get_value( config , "APPEND");
test_assert_string_equal( value , "VALUE3");
}
}
test_assert_false( config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true));
exit(0);
}

View File

@ -0,0 +1,36 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'config_config.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/config/config.h>
#include <ert/config/config_schema_item.h>
int main(int argc , char ** argv) {
config_type * config = config_alloc();
config_schema_item_type * schema_item = config_add_schema_item( config , "KEYWORD" , false );
config_free( config );
exit(0);
}

View File

@ -0,0 +1,58 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'config_content_item.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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 <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/util/hash.h>
#include <ert/config/config.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_path_elm.h>
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
config_add_schema_item( config , "SET" , true );
config_add_schema_item( config , "NOTSET" , false );
test_assert_true( config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true ));
test_assert_not_NULL( config_get_content_item( config , "SET" ));
test_assert_NULL( config_get_content_item( config , "NOTSET" ) );
test_assert_NULL( config_get_content_item( config , "UNKNOWN" ) );
test_assert_true( config_has_schema_item( config , "SET" ));
test_assert_true( config_has_schema_item( config , "NOTSET" ));
test_assert_false( config_has_schema_item( config , "UNKNOWN" ));
test_assert_true( config_has_content_item( config , "SET" ));
test_assert_false( config_has_content_item( config , "NOTSET" ));
test_assert_false( config_has_content_item( config , "UNKNOWN" ));
exit(0);
}

Some files were not shown because too many files have changed in this diff Show More