From 07ab821646c140dd547278b0ac479a49e50dd729 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 13 Sep 2019 13:17:07 +0200 Subject: [PATCH 01/27] #4716 Summary Case : Guard access to contained summary reader --- .../RicExportFractureCompletionsImpl.cpp | 2 +- .../RicSummaryPlotFeatureImpl.cpp | 5 ++++- .../Summary/RimSummaryCaseCollection.cpp | 2 +- .../Summary/RimSummaryCurve.cpp | 21 +++++++++++-------- .../Summary/RimSummaryPlotSourceStepping.cpp | 6 +++--- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp index 269eec1081..3c329ad7fb 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp @@ -427,7 +427,7 @@ void RicExportFractureCompletionsImpl::getWellPressuresAndInitialProductionTimeS { RimSummaryCase* summaryCase = mainCollection->findSummaryCaseFromEclipseResultCase(resultCase); - if (summaryCase) + if (summaryCase && summaryCase->summaryReader()) { std::vector values; if (summaryCase->summaryReader()->values(wbhpPressureAddress, &values)) diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp index 11811f7424..89b490fa0f 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp @@ -37,7 +37,7 @@ //-------------------------------------------------------------------------------------------------- RimSummaryCurve* RicSummaryPlotFeatureImpl::addDefaultCurveToPlot(RimSummaryPlot* plot, RimSummaryCase* summaryCase) { - if (plot) + if (plot && summaryCase && summaryCase->summaryReader()) { RifEclipseSummaryAddress defaultAddressToUse; @@ -88,6 +88,9 @@ std::vector RicSummaryPlotFeatureImpl::addDefaultCurvesToPlot( { std::vector defaultCurves; + if (!plot) return defaultCurves; + if (!summaryCase || !summaryCase->summaryReader()) return defaultCurves; + QString curvesTextFilter = RiaApplication::instance()->preferences()->defaultSummaryCurvesTextFilter; QStringList curveFilters = curvesTextFilter.split(";", QString::SkipEmptyParts); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp index 95396885f6..280b34555f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp @@ -276,7 +276,7 @@ std::set RimSummaryCaseCollection::ensembleSummaryAddr } } - if (maxAddrIndex >= 0) + if (maxAddrIndex >= 0 && m_cases[maxAddrIndex]->summaryReader()) { const std::set& addrs = m_cases[maxAddrIndex]->summaryReader()->allResultAddresses(); addresses.insert(addrs.begin(), addrs.end()); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 9ae2c362b2..521de1c23e 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -515,16 +515,19 @@ void RimSummaryCurve::onLoadDataAndUpdate(bool updateParentPlot) if (plot->timeAxisProperties()->timeMode() == RimSummaryTimeAxisProperties::DATE) { auto reader = summaryCaseY()->summaryReader(); - auto errAddress = reader->errorAddress(summaryAddressY()); - if (errAddress.isValid()) + if (reader) { - std::vector errValues; - reader->values(errAddress, &errValues); - m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, errValues, isLogCurve); - } - else - { - m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve); + auto errAddress = reader->errorAddress(summaryAddressY()); + if (errAddress.isValid()) + { + std::vector errValues; + reader->values(errAddress, &errValues); + m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, errValues, isLogCurve); + } + else + { + m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve); + } } } else diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp index 402f93bbf0..46be431e15 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp @@ -581,12 +581,12 @@ std::vector RimSummaryPlotSourceStepping::summaryRea { for (auto curve : curveCollection->curves()) { - if (isYAxisStepping() && curve->summaryCaseY()) + if (isYAxisStepping() && curve->summaryCaseY() && curve->summaryCaseY()->summaryReader()) { readers.push_back(curve->summaryCaseY()->summaryReader()); } - if (isXAxisStepping() && curve->summaryCaseX()) + if (isXAxisStepping() && curve->summaryCaseX() && curve->summaryCaseX()->summaryReader()) { readers.push_back(curve->summaryCaseX()->summaryReader()); } @@ -602,7 +602,7 @@ std::vector RimSummaryPlotSourceStepping::summaryRea { for (auto curve : curveSet->curves()) { - if (isYAxisStepping() && curve->summaryCaseY()) + if (isYAxisStepping() && curve->summaryCaseY() && curve->summaryCaseY()->summaryReader()) { readers.push_back(curve->summaryCaseY()->summaryReader()); } From da47acfc1c23bb426ae0ad1fe51f73974c011810 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 10 Sep 2019 10:41:10 +0200 Subject: [PATCH 02/27] #4644 Summary Plot: Fix missing update of plot title --- ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp index 35feb92961..27344f43cb 100644 --- a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp +++ b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp @@ -282,6 +282,9 @@ void RiaSummaryCurveAnalyzer::clear() m_wellCompletions.clear(); m_wellSegmentNumbers.clear(); m_blocks.clear(); + + m_quantitiesNoMatchingHistory.clear(); + m_quantitiesWithMatchingHistory.clear(); } //-------------------------------------------------------------------------------------------------- From b38904d158201e2652a17a8466595127b369a4fb Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 11 Sep 2019 13:31:15 +0200 Subject: [PATCH 03/27] #4699 Guard use of TERNARY cell result in property filters --- .../RicEclipsePropertyFilterFeatureImpl.cpp | 8 +++- .../RimEclipseResultDefinition.cpp | 48 ++++++++++--------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp index 9c6a3b5ebd..514921eab0 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterFeatureImpl.cpp @@ -118,8 +118,12 @@ void RicEclipsePropertyFilterFeatureImpl::setDefaults(RimEclipsePropertyFilter* RimEclipseView* reservoirView = nullptr; propertyFilter->firstAncestorOrThisOfTypeAsserted(reservoirView); - propertyFilter->resultDefinition()->setEclipseCase(reservoirView->eclipseCase()); - propertyFilter->resultDefinition()->simpleCopy(reservoirView->cellResult()); + propertyFilter->resultDefinition()->setEclipseCase( reservoirView->eclipseCase() ); + + if ( !RiaDefines::isPerCellFaceResult( reservoirView->cellResult()->resultVariable() ) ) + { + propertyFilter->resultDefinition()->simpleCopy( reservoirView->cellResult() ); + } propertyFilter->resultDefinition()->loadResult(); propertyFilter->setToDefaultValues(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 94f50131a4..d1551a13cb 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -1529,39 +1529,41 @@ QList optionList.push_back(caf::PdmOptionItemInfo(s, s)); } - // Ternary Result - if (ternaryEnabled) - { - bool hasAtLeastOneTernaryComponent = false; - if (cellCenterResultNames.contains("SOIL")) - hasAtLeastOneTernaryComponent = true; - else if (cellCenterResultNames.contains("SGAS")) - hasAtLeastOneTernaryComponent = true; - else if (cellCenterResultNames.contains("SWAT")) - hasAtLeastOneTernaryComponent = true; - - if (resultCatType == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent) - { - optionList.push_front( - caf::PdmOptionItemInfo(RiaDefines::ternarySaturationResultName(), RiaDefines::ternarySaturationResultName())); - } - } - if (addPerCellFaceOptionItems) + if ( addPerCellFaceOptionItems ) { - for (const QString& s : cellFaceResultNames) + for ( const QString& s : cellFaceResultNames ) { - if (showDerivedResultsFirst) + if ( showDerivedResultsFirst ) { - optionList.push_front(caf::PdmOptionItemInfo(s, s)); + optionList.push_front( caf::PdmOptionItemInfo( s, s ) ); } else { - optionList.push_back(caf::PdmOptionItemInfo(s, s)); + optionList.push_back( caf::PdmOptionItemInfo( s, s ) ); + } + } + + // Ternary Result + if ( ternaryEnabled ) + { + bool hasAtLeastOneTernaryComponent = false; + if ( cellCenterResultNames.contains( "SOIL" ) ) + hasAtLeastOneTernaryComponent = true; + else if ( cellCenterResultNames.contains( "SGAS" ) ) + hasAtLeastOneTernaryComponent = true; + else if ( cellCenterResultNames.contains( "SWAT" ) ) + hasAtLeastOneTernaryComponent = true; + + if ( resultCatType == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent ) + { + optionList.push_front( caf::PdmOptionItemInfo( RiaDefines::ternarySaturationResultName(), + RiaDefines::ternarySaturationResultName() ) ); } } } - optionList.push_front(caf::PdmOptionItemInfo(RiaDefines::undefinedResultName(), RiaDefines::undefinedResultName())); + optionList.push_front( + caf::PdmOptionItemInfo( RiaDefines::undefinedResultName(), RiaDefines::undefinedResultName() ) ); return optionList; } From 25c692d3dbc70c15f3d2595cac5d1e6513a16cc4 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Tue, 10 Sep 2019 09:18:40 +0200 Subject: [PATCH 04/27] #4668 Make contour time and case diff work --- .../RimEclipseContourMapProjection.cpp | 7 ++++-- .../RimEclipseResultDefinition.cpp | 20 ++++++++++++++++ .../RimEclipseResultDefinition.h | 23 +++++++++++-------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp index 9ee5933e0a..4038045578 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp @@ -202,8 +202,11 @@ std::vector RimEclipseContourMapProjection::generateResults(int timeStep else if (!(cellColors->hasStaticResult() && timeStep > 0)) { m_currentResultName = cellColors->resultVariable(); - RigEclipseResultAddress resAddr(cellColors->resultType(), cellColors->resultVariable()); - if (resAddr.isValid() && resultData->hasResultEntry(resAddr)) + RigEclipseResultAddress resAddr( cellColors->resultType(), + cellColors->resultVariable(), + cellColors->timeLapseBaseTimeStep(), + cellColors->caseDiffIndex() ); + if ( resAddr.isValid() && resultData->hasResultEntry( resAddr ) ) { gridResultValues = resultData->cellScalarResults(resAddr, timeStep); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index d1551a13cb..506a3739b9 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -968,6 +968,26 @@ QString RimEclipseResultDefinition::diffResultUiShortNameHTML() const return diffResult.join("
"); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimEclipseResultDefinition::timeLapseBaseTimeStep() const +{ + return m_timeLapseBaseTimestep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimEclipseResultDefinition::caseDiffIndex() const +{ + if ( m_differenceCase ) + { + return m_differenceCase->caseId(); + } + return -1; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 2f7dc83962..0d062cce1d 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -98,16 +98,19 @@ class RimEclipseResultDefinition : public caf::PdmObject QString diffResultUiShortName() const; QString diffResultUiShortNameHTML() const; - void loadResult(); - RigEclipseResultAddress eclipseResultAddress() const; - void setFromEclipseResultAddress(const RigEclipseResultAddress& resultAddress); - bool hasStaticResult() const; - bool hasDynamicResult() const; - bool hasResult() const; - bool isTernarySaturationSelected() const; - bool isCompletionTypeSelected() const; - bool hasCategoryResult() const; - bool isFlowDiagOrInjectionFlooding() const; + int timeLapseBaseTimeStep() const; + int caseDiffIndex() const; + + void loadResult(); + RigEclipseResultAddress eclipseResultAddress() const; + void setFromEclipseResultAddress( const RigEclipseResultAddress& resultAddress ); + bool hasStaticResult() const; + bool hasDynamicResult() const; + bool hasResult() const; + bool isTernarySaturationSelected() const; + bool isCompletionTypeSelected() const; + bool hasCategoryResult() const; + bool isFlowDiagOrInjectionFlooding() const; RigCaseCellResultsData* currentGridCellResults() const; From 1cb17203273a829a2d573e0c02b7c4056efa02dd Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 13 Sep 2019 14:55:04 +0200 Subject: [PATCH 05/27] #4688 Contour plot : Changing Base Time Step has no effect --- .../RimEclipseResultDefinition.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 506a3739b9..7948395323 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -52,6 +52,8 @@ #include "RimReservoirCellResultsStorage.h" #include "RimViewLinker.h" #include "RimWellLogExtractionCurve.h" +#include "RimContourMapProjection.h" +#include "RimEclipseContourMapView.h" #include "cafPdmUiListEditor.h" #include "cafPdmUiToolButtonEditor.h" @@ -286,14 +288,28 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha loadDataAndUpdate(); } + RimEclipseContourMapView* contourMapView = nullptr; + this->firstAncestorOrThisOfType(contourMapView); + if (&m_differenceCase == changedField) { m_timeLapseBaseTimestep = RigEclipseResultAddress::noTimeLapseValue(); + + if (contourMapView) + { + contourMapView->contourMapProjection()->updatedWeightingResult(); + } + loadDataAndUpdate(); } if (&m_timeLapseBaseTimestep == changedField) { + if (contourMapView) + { + contourMapView->contourMapProjection()->updatedWeightingResult(); + } + loadDataAndUpdate(); } From 920c6e482811d96812608dea58332b0fe55cea87 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 13 Sep 2019 19:16:06 +0200 Subject: [PATCH 06/27] #4709 Summary Plot Editor : Avoid default selection of field vectors --- .../RiuSummaryCurveDefSelection.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp index be1b2935ec..1a715cccec 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp @@ -423,7 +423,7 @@ void RiuSummaryCurveDefSelection::setDefaultSelection(const std::vector 0) { - RifEclipseSummaryAddress defaultAddress = RifEclipseSummaryAddress::fieldAddress("FOPT"); + RifEclipseSummaryAddress defaultAddress; std::vector selectTheseSources = defaultSources; if (selectTheseSources.empty()) selectTheseSources.push_back(allSumCases[0]); @@ -456,11 +456,6 @@ void RiuSummaryCurveDefSelection::setSelectedCurveDefinitions(const std::vector< RimSummaryCase* summaryCase = curveDef.summaryCase(); RifEclipseSummaryAddress summaryAddress = curveDef.summaryAddress(); - if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_INVALID) - { - // If we have an invalid address, set the default address to Field - summaryAddress = RifEclipseSummaryAddress::fieldAddress(summaryAddress.quantityName()); - } // Ignore ensemble statistics curves if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; @@ -471,7 +466,15 @@ void RiuSummaryCurveDefSelection::setSelectedCurveDefinitions(const std::vector< if (std::find(selectedCategories.begin(), selectedCategories.end(), summaryAddress.category()) == selectedCategories.end()) { - m_selectedSummaryCategories.v().push_back(summaryAddress.category()); + if ( summaryAddress.category() != RifEclipseSummaryAddress::SUMMARY_INVALID ) + { + m_selectedSummaryCategories.v().push_back( summaryAddress.category() ); + } + else + { + // Use field category as fall back category to avoid an empty list of vectors + summaryAddress = RifEclipseSummaryAddress::fieldAddress( "" ); + } } // Select case if not already selected From 7c9735ed3bf96ddbe466e4b6f44d33f1e1bed50e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 13 Sep 2019 20:29:29 +0200 Subject: [PATCH 07/27] #4709 Summary Plot Editor : Increase height for summary vector widgets --- .../RicSummaryCurveCreatorSplitterUi.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp index 4d5383fe32..73e05d6680 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp @@ -142,9 +142,13 @@ QWidget* RicSummaryCurveCreatorSplitterUi::createWidget(QWidget* parent) m_firstColumnSplitter->setHandleWidth(6); m_firstColumnSplitter->setStyleSheet("QSplitter::handle { image: url(:/SplitterH.png); }"); - m_firstColumnSplitter->insertWidget(0, firstRowFrame); - m_firstColumnSplitter->insertWidget(1, secondRowFrame); - m_firstColumnSplitter->setSizes(QList() << 1 << 2); + m_firstColumnSplitter->insertWidget( 0, firstRowFrame ); + m_firstColumnSplitter->insertWidget( 1, secondRowFrame ); + + const int firstRowPixelHeight = 500; + const int secondRowPixelHeight = 300; + + m_firstColumnSplitter->setSizes( QList() << firstRowPixelHeight << secondRowPixelHeight ); m_layout->addWidget(m_firstColumnSplitter); From d567ca0eac7ea6cd40247dfdfb2d778decae5c13 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 13 Sep 2019 18:39:23 +0200 Subject: [PATCH 08/27] #4713 Summary Case : Shortname is not used in plot title --- .../ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp index ef8f462c80..48c7e4a59f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp @@ -292,7 +292,7 @@ void RimSummaryPlotNameHelper::extractPlotTitleSubStrings() if (summaryCase) { - m_titleCaseName = summaryCase->caseName(); + m_titleCaseName = summaryCase->shortName(); } } else if (ensembleCases.size() == 1 && summaryCases.empty()) From 0b278aebd4ef229512ea7775255a6faafe8dc18c Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Tue, 17 Sep 2019 16:09:17 +0200 Subject: [PATCH 09/27] Merge pull request #4704 from OPM/bug-#4703-geomech-resultpos #4703 Fix changing result position in GeoMech result definition --- .../ProjectDataModel/Rim3dWellLogCurve.cpp | 17 +++------- .../ProjectDataModel/Rim3dWellLogCurve.h | 31 ++++++++++--------- .../Rim3dWellLogExtractionCurve.cpp | 6 ++-- .../Rim3dWellLogFileCurve.cpp | 3 +- .../ProjectDataModel/Rim3dWellLogRftCurve.cpp | 3 +- .../RimEclipseResultDefinition.cpp | 2 +- .../RimGeoMechResultDefinition.cpp | 14 ++------- 7 files changed, 32 insertions(+), 44 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp index 89c6017eaf..61fc4862ac 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp @@ -250,19 +250,10 @@ void Rim3dWellLogCurve::initAfterRead() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Rim3dWellLogCurve::resetMinMaxValuesAndUpdateUI() -{ - this->resetMinMaxValues(); - this->updateConnectedEditors(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool Rim3dWellLogCurve::findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, - cvf::Vec3d* closestPoint, - double* measuredDepthAtPoint, - double* valueAtPoint) const +bool Rim3dWellLogCurve::findClosestPointOnCurve( const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint ) const { if (m_geometryGenerator.notNull()) { diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h index df9145bf94..0f457dd392 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h @@ -75,25 +75,28 @@ class Rim3dWellLogCurve : public caf::PdmObject, public RimNameConfigHolderInter void setColor(const cvf::Color3f& color); - float minCurveUIValue() const; - float maxCurveUIValue() const; - void resetMinMaxValuesAndUpdateUI(); - bool findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, - cvf::Vec3d* closestPoint, - double* measuredDepthAtPoint, - double* valueAtPoint) const; + float minCurveUIValue() const; + float maxCurveUIValue() const; + void resetMinMaxValues(); + bool findClosestPointOnCurve( const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint ) const; void setGeometryGenerator(Riv3dWellLogCurveGeometryGenerator* generator); cvf::ref geometryGenerator(); protected: - caf::PdmFieldHandle* objectToggleField() override; - void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - void configurationUiOrdering(caf::PdmUiOrdering& uiOrdering); - void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - void initAfterRead() override; -private: - void resetMinMaxValues(); + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue ) override; + void configurationUiOrdering( caf::PdmUiOrdering& uiOrdering ); + void defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) override; + void initAfterRead() override; + protected: caf::PdmField m_drawPlane; caf::PdmField m_color; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp index f40afa0626..af326f699e 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp @@ -436,11 +436,13 @@ void Rim3dWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* ch m_geomResultDefinition->setGeoMechCase(geoMechCase); } - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } else if (changedField == &m_timeStep) { - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } Rim3dWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue); } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp index 47121f150c..da8564200a 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp @@ -187,7 +187,8 @@ void Rim3dWellLogFileCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedF { if (changedField == &m_wellLogFile || changedField == &m_wellLogChannelName) { - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } Rim3dWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue); } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp index 7665f3b1ff..78619b7a92 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp @@ -147,7 +147,8 @@ void Rim3dWellLogRftCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedFi { if (changedField == &m_wellLogChannelName || changedField == &m_timeStep) { - this->resetMinMaxValuesAndUpdateUI(); + this->resetMinMaxValues(); + this->updateConnectedEditors(); } Rim3dWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 7948395323..906836bc43 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -430,7 +430,7 @@ void RimEclipseResultDefinition::updateAnyFieldHasChanged() this->firstAncestorOrThisOfType(rim3dWellLogCurve); if (rim3dWellLogCurve) { - rim3dWellLogCurve->resetMinMaxValuesAndUpdateUI(); + rim3dWellLogCurve->resetMinMaxValues(); } RimEclipseContourMapProjection* contourMap = nullptr; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index 98f5c66a15..a3512369a0 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -353,20 +353,10 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha } } } - - if (propFilter) - { - propFilter->updateConnectedEditors(); - } - if (curve) + if ( rim3dWellLogCurve ) { - curve->updateConnectedEditors(); - } - - if (rim3dWellLogCurve) - { - rim3dWellLogCurve->resetMinMaxValuesAndUpdateUI(); + rim3dWellLogCurve->resetMinMaxValues(); } } From 008f7f87c4c6b057975fb27dc9aee520657cc202 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 18 Sep 2019 15:32:32 +0200 Subject: [PATCH 10/27] #4713 Summary Case : Use shortname in curve names and option items --- ApplicationCode/Application/RiaSummaryCurveDefinition.cpp | 2 +- .../ProjectDataModel/RimSummaryCalculationVariable.cpp | 2 +- ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp | 2 +- .../ProjectDataModel/Summary/RimSummaryCurve.cpp | 2 +- .../ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp | 4 ++-- .../Summary/RimSummaryPlotSourceStepping.cpp | 2 +- .../UserInterface/RiuSummaryCurveDefSelection.cpp | 6 +++--- ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp b/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp index 79285ac184..b48ddd246a 100644 --- a/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp +++ b/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp @@ -115,7 +115,7 @@ QString RiaSummaryCurveDefinition::curveDefinitionText() const { QString caseName; if (summaryCase()) - caseName = summaryCase()->caseName(); + caseName = summaryCase()->shortName(); else if (ensemble()) caseName = ensemble()->name(); diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp index 92d3de5e1d..276dc3202f 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp @@ -131,7 +131,7 @@ void RimSummaryCalculationVariable::fieldChangedByUi(const caf::PdmFieldHandle* QString RimSummaryCalculationVariable::summaryAddressDisplayString() const { QString caseName; - if (m_case() ) caseName = m_case()->caseName(); + if (m_case() ) caseName = m_case()->shortName(); return RiaSummaryCurveDefinition::curveDefinitionText(caseName, m_summaryAddress()->address()); } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp index 976427dc4a..1eaf372804 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp @@ -137,7 +137,7 @@ void RimSummaryCase::copyFrom(const RimSummaryCase& rhs) //-------------------------------------------------------------------------------------------------- bool RimSummaryCase::operator<(const RimSummaryCase& rhs) const { - return this->caseName() < rhs.caseName(); + return this->shortName() < rhs.shortName(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 521de1c23e..0ab6edd76d 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -382,7 +382,7 @@ QList RimSummaryCurve::calculateValueOptions(const caf:: for (RimSummaryCase* rimCase : cases) { - options.push_back(caf::PdmOptionItemInfo(rimCase->caseName(), rimCase)); + options.push_back(caf::PdmOptionItemInfo(rimCase->shortName(), rimCase)); } if (options.size() > 0) diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp index 2cd03a7725..20c9624b5a 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp @@ -102,7 +102,7 @@ QString RimSummaryCurveAutoName::curveNameY(const RifEclipseSummaryAddress& summ if (caseName.isEmpty() && summaryCurve && summaryCurve->summaryCaseY()) { - caseName = summaryCurve->summaryCaseY()->caseName(); + caseName = summaryCurve->summaryCaseY()->shortName(); } if (!caseName.isEmpty()) @@ -152,7 +152,7 @@ QString RimSummaryCurveAutoName::curveNameX(const RifEclipseSummaryAddress& summ if (m_caseName && !skipSubString) { - QString caseName = summaryCurve->summaryCaseX()->caseName(); + QString caseName = summaryCurve->summaryCaseX()->shortName(); if (!text.empty()) text += ", "; text += caseName.toStdString(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp index 46be431e15..65c9b0e60f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp @@ -195,7 +195,7 @@ QList RimSummaryPlotSourceStepping::calculateValueOption auto summaryCases = RimSummaryPlotSourceStepping::summaryCasesForSourceStepping(); for (auto sumCase : summaryCases) { - options.append(caf::PdmOptionItemInfo(sumCase->caseName(), sumCase)); + options.append(caf::PdmOptionItemInfo(sumCase->shortName(), sumCase)); } return options; diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp index 1a715cccec..ca130efc49 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp @@ -594,7 +594,7 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions // Top level cases for (const auto& sumCase : sumCaseMainColl->topLevelSummaryCases()) { - options.push_back(caf::PdmOptionItemInfo(sumCase->caseName(), sumCase)); + options.push_back(caf::PdmOptionItemInfo(sumCase->shortName(), sumCase)); } } @@ -629,7 +629,7 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions for (const auto& sumCase : sumCaseColl->allSummaryCases()) { - auto optionItem = caf::PdmOptionItemInfo(sumCase->caseName(), sumCase); + auto optionItem = caf::PdmOptionItemInfo(sumCase->shortName(), sumCase); optionItem.setLevel(1); options.push_back(optionItem); } @@ -643,7 +643,7 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions for (const auto& obsData : observedDataColl->allObservedData()) { - auto optionItem = caf::PdmOptionItemInfo(obsData->caseName(), obsData); + auto optionItem = caf::PdmOptionItemInfo(obsData->shortName(), obsData); optionItem.setLevel(1); options.push_back(optionItem); } diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index edeb0f96fd..f3358452d4 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -83,7 +83,7 @@ class EnsembleCurveInfoTextProvider : public IPlotCurveInfoTextProvider sumCurve = dynamic_cast(riuCurve->ownerRimCurve()); } - return sumCurve && sumCurve->summaryCaseY() ? sumCurve->summaryCaseY()->caseName() : ""; + return sumCurve && sumCurve->summaryCaseY() ? sumCurve->summaryCaseY()->shortName() : ""; } }; static EnsembleCurveInfoTextProvider ensembleCurveInfoTextProvider; From 646e3dd51cd4fe63b265c6c4c8fe925730900d1c Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 19 Sep 2019 09:08:19 +0200 Subject: [PATCH 11/27] #4707 Update web address for Help/User Guide/F1 --- .../Commands/ApplicationCommands/RicHelpFeatures.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp index b1330523c0..9872d38d52 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp +++ b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp @@ -218,7 +218,7 @@ void RicHelpOpenUsersGuideFeature::onActionTriggered(bool isChecked) { this->disableModelChangeContribution(); - QString usersGuideUrl = "http://resinsight.org/docs/home"; + QString usersGuideUrl = "https://resinsight.org/getting-started/"; if (!QDesktopServices::openUrl(usersGuideUrl)) { From b607ab895bdbb220f27c61a67b8190a46447d313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 23 Sep 2019 20:47:47 +0200 Subject: [PATCH 12/27] #4753 Fix selection of plot subitems jumps to parent plot by blocking the selection of the plot when window is activated --- ApplicationCode/UserInterface/RiuPlotMainWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp index 9e1d40998d..e7b8f9a1cd 100644 --- a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp @@ -757,7 +757,9 @@ void RiuPlotMainWindow::selectedObjectsChanged() { if (selectedWindow->viewWidget()) { + setBlockSlotSubWindowActivated(true); setActiveViewer(selectedWindow->viewWidget()); + setBlockSlotSubWindowActivated(false); } // The only way to get to this code is by selection change initiated from the project tree view // As we are activating an MDI-window, the focus is given to this MDI-window From 0fdd73d197ce2c419480ea6ae6e6abb95f3aa5bc Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Fri, 20 Sep 2019 12:23:34 +0200 Subject: [PATCH 13/27] Merge pull request #4738 from OPM/system-python-renames-pep8 #4736 Renames of python methods and variables to match PEP8 --- .../GrpcInterface/Python/rips/Case.py | 78 ++--- .../GrpcInterface/Python/rips/Commands.py | 317 +++++++++--------- .../Python/rips/GridCaseGroup.py | 31 +- .../GrpcInterface/Python/rips/Instance.py | 106 +++--- .../GrpcInterface/Python/rips/PdmObject.py | 122 +++---- .../GrpcInterface/Python/rips/Project.py | 66 ++-- .../GrpcInterface/Python/rips/Properties.py | 198 +++++------ .../Python/rips/PythonExamples/AllCases.py | 10 +- .../Python/rips/PythonExamples/AppInfo.py | 8 +- .../rips/PythonExamples/CaseGridGroup.py | 36 +- .../CaseInfoStreamingExample.py | 16 +- .../rips/PythonExamples/CommandExample.py | 22 +- .../rips/PythonExamples/ErrorHandling.py | 18 +- .../rips/PythonExamples/ExportSnapshots.py | 30 +- .../rips/PythonExamples/GridInformation.py | 4 +- .../rips/PythonExamples/InputPropTestAsync.py | 16 +- .../rips/PythonExamples/InputPropTestSync.py | 14 +- .../rips/PythonExamples/InstanceExample.py | 4 +- .../LaunchWithCommandLineOptions.py | 6 +- .../rips/PythonExamples/SelectedCases.py | 6 +- .../rips/PythonExamples/SetCellResult.py | 6 +- .../SetFlowDiagnosticsResult.py | 12 +- .../rips/PythonExamples/SetGridProperties.py | 10 +- .../rips/PythonExamples/SoilAverageAsync.py | 10 +- .../rips/PythonExamples/SoilAverageSync.py | 12 +- .../rips/PythonExamples/SoilPorvAsync.py | 30 +- .../rips/PythonExamples/SoilPorvSync.py | 18 +- .../Python/rips/PythonExamples/ViewExample.py | 18 +- .../GrpcInterface/Python/rips/View.py | 88 ++--- .../Python/rips/tests/conftest.py | 4 +- .../Python/rips/tests/test_cases.py | 92 ++--- .../Python/rips/tests/test_commands.py | 58 ++-- .../Python/rips/tests/test_grids.py | 6 +- .../Python/rips/tests/test_project.py | 2 +- .../Python/rips/tests/test_properties.py | 54 +-- 35 files changed, 771 insertions(+), 757 deletions(-) diff --git a/ApplicationCode/GrpcInterface/Python/rips/Case.py b/ApplicationCode/GrpcInterface/Python/rips/Case.py index 312bfab25d..1722a7e614 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/Case.py +++ b/ApplicationCode/GrpcInterface/Python/rips/Case.py @@ -31,13 +31,13 @@ def __init__(self, channel, id): self.id = id info = self.stub.GetCaseInfo(Case_pb2.CaseRequest(id=self.id)) self.name = info.name - self.groupId = info.group_id + self.group_id = info.group_id self.type = info.type self.properties = Properties(self) self.request = Case_pb2.CaseRequest(id=self.id) PdmObject.__init__(self, self.stub.GetPdmObject(self.request), self.channel) - def gridCount(self): + def grid_count(self): """Get number of grids in the case""" try: return self.stub.GetGridCount(self.request).count @@ -47,8 +47,8 @@ def gridCount(self): print("ERROR: ", e) return 0 - def gridPath(self): - return self.getValue("CaseFileName") + def grid_path(self): + return self.get_value("CaseFileName") def grid(self, index): """Get Grid of a given index. Returns a rips Grid object @@ -62,50 +62,50 @@ def grid(self, index): def grids(self): """Get a list of all rips Grid objects in the case""" - gridList = [] - for i in range(0, self.gridCount()): - gridList.append(Grid(i, self)) - return gridList + grid_list = [] + for i in range(0, self.grid_count()): + grid_list.append(Grid(i, self)) + return grid_list - def cellCount(self, porosityModel='MATRIX_MODEL'): + def cell_count(self, porosity_model='MATRIX_MODEL'): """Get a cell count object containing number of active cells and total number of cells Arguments: - porosityModel (str): String representing an enum. + porosity_model (str): String representing an enum. must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. Returns: Cell Count object with the following integer attributes: active_cell_count: number of active cells reservoir_cell_count: total number of reservoir cells """ - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Case_pb2.CellInfoRequest(case_request=self.request, - porosity_model=porosityModel) + porosity_model=porosity_model_enum) return self.stub.GetCellCount(request) - def cellInfoForActiveCellsAsync(self, porosityModel='MATRIX_MODEL'): + def cell_info_for_active_cells_async(self, porosity_model='MATRIX_MODEL'): """Get Stream of cell info objects for current case Arguments: - porosityModel(str): String representing an enum. + porosity_model(str): String representing an enum. must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. Returns: Stream of **CellInfo** objects - See cellInfoForActiveCells() for detalis on the **CellInfo** class. + See cell_info_for_active_cells() for detalis on the **CellInfo** class. """ - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Case_pb2.CellInfoRequest(case_request=self.request, - porosity_model=porosityModel) + porosity_model=porosity_model_enum) return self.stub.GetCellInfoForActiveCells(request) - def cellInfoForActiveCells(self, porosityModel='MATRIX_MODEL'): + def cell_info_for_active_cells(self, porosity_model='MATRIX_MODEL'): """Get list of cell info objects for current case Arguments: - porosityModel(str): String representing an enum. + porosity_model(str): String representing an enum. must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. Returns: @@ -130,14 +130,14 @@ def cellInfoForActiveCells(self, porosityModel='MATRIX_MODEL'): k | K grid index | Integer """ - activeCellInfoChunks = self.cellInfoForActiveCellsAsync() - receivedActiveCells = [] - for activeCellChunk in activeCellInfoChunks: - for activeCell in activeCellChunk.data: - receivedActiveCells.append(activeCell) - return receivedActiveCells - - def timeSteps(self): + active_cell_info_chunks = self.cell_info_for_active_cells_async() + received_active_cells = [] + for active_cell_chunk in active_cell_info_chunks: + for active_cell in active_cell_chunk.data: + received_active_cells.append(active_cell) + return received_active_cells + + def time_steps(self): """Get a list containing all time steps The time steps are defined by the class **TimeStepDate** : @@ -155,17 +155,17 @@ def timeSteps(self): """ return self.stub.GetTimeSteps(self.request).dates - def daysSinceStart(self): + def days_since_start(self): """Get a list of decimal values representing days since the start of the simulation""" return self.stub.GetDaysSinceStart(self.request).day_decimals def views(self): """Get a list of views belonging to a case""" - pbmObjects = self.children("ReservoirViews") - viewList = [] - for pbmObject in pbmObjects: - viewList.append(View(pbmObject)) - return viewList + pdm_objects = self.children("ReservoirViews") + view_list = [] + for pdm_object in pdm_objects: + view_list.append(View(pdm_object)) + return view_list def view(self, id): """Get a particular view belonging to a case by providing view id @@ -176,13 +176,13 @@ def view(self, id): """ views = self.views() - for viewObject in views: - if viewObject.id == id: - return viewObject + for view_object in views: + if view_object.id == id: + return view_object return None - def createView(self): + def create_view(self): """Create a new view in the current case""" - viewId = Commands(self.channel).createView(self.id) - return self.view(viewId) + view_id = Commands(self.channel).create_view(self.id) + return self.view(view_id) diff --git a/ApplicationCode/GrpcInterface/Python/rips/Commands.py b/ApplicationCode/GrpcInterface/Python/rips/Commands.py index b80d84405d..f7956ded4e 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/Commands.py +++ b/ApplicationCode/GrpcInterface/Python/rips/Commands.py @@ -23,14 +23,14 @@ def __init__(self, channel): self.channel = channel self.commands = CmdRpc.CommandsStub(channel) - def __execute(self, **commandParams): - return self.commands.Execute(Cmd.CommandParams(**commandParams)) + def __execute(self, **command_params): + return self.commands.Execute(Cmd.CommandParams(**command_params)) ######################## # Case Control Commands ######################## - def openProject(self, path): + def open_project(self, path): """Open a project Arguments: @@ -40,11 +40,11 @@ def openProject(self, path): """ return self.__execute(openProject=Cmd.FilePathRequest(path=path)) - def closeProject(self): + def close_project(self): """Close the current project (and reopen empty one)""" return self.__execute(closeProject=Empty()) - def setStartDir(self, path): + def set_start_dir(self, path): """Set current start directory Arguments: @@ -53,7 +53,7 @@ def setStartDir(self, path): """ return self.__execute(setStartDir=Cmd.FilePathRequest(path=path)) - def loadCase(self, path): + def load_case(self, path): """Load a case Arguments: @@ -63,234 +63,249 @@ def loadCase(self, path): A Case object """ - commandReply = self.__execute(loadCase=Cmd.FilePathRequest(path=path)) - return rips.Case(self.channel, commandReply.loadCaseResult.id) + command_reply = self.__execute(loadCase=Cmd.FilePathRequest(path=path)) + return rips.Case(self.channel, command_reply.loadCaseResult.id) - def replaceCase(self, newGridFile, caseId=0): + def replace_case(self, new_grid_file, case_id=0): """Replace the given case with a new case loaded from file Arguments: - newGridFile (str): path to EGRID file - caseId (int): case Id to replace + new_grid_file (str): path to EGRID file + case_id (int): case Id to replace """ - return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=newGridFile, - caseId=caseId)) + return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=new_grid_file, + caseId=case_id)) - def replaceSourceCases(self, gridListFile, caseGroupId=0): + def replace_source_cases(self, grid_list_file, case_group_id=0): """Replace all source cases within a case group Arguments: - gridListFile (str): path to file containing a list of cases - caseGroupId (int): id of the case group to replace + grid_list_file (str): path to file containing a list of cases + case_group_id (int): id of the case group to replace """ - return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=gridListFile, - caseGroupId=caseGroupId)) + return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=grid_list_file, + caseGroupId=case_group_id)) - def createGridCaseGroup(self, casePaths): + def create_grid_case_group(self, case_paths): """Create a Grid Case Group from a list of cases Arguments: - casePaths (list): list of file path strings + case_paths (list): list of file path strings Returns: A case group id and name """ - commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=casePaths)) + commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=case_paths)) return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName) - def createStatisticsCase(self, caseGroupId): - commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=caseGroupId)) - return commandReply.createStatisticsCaseResult.caseId; + def create_statistics_case(self, case_group_id): + """Create a Statistics case in a Grid Case Group + + Arguments: + case_group_id (int): id of the case group + + Returns: + A case id for the new case + """ + commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=case_group_id)) + return commandReply.createStatisticsCaseResult.caseId ################## # Export Commands ################## - def exportMultiCaseSnapshots(self, gridListFile): + def export_multi_case_snapshots(self, grid_list_file): """Export snapshots for a set of cases Arguments: - gridListFile (str): Path to a file containing a list of grids to export snapshot for + grid_list_file (str): Path to a file containing a list of grids to export snapshot for """ - return self.__execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=gridListFile)) + return self.__execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=grid_list_file)) - def exportSnapshots(self, type = 'ALL', prefix='', caseId = -1): + def export_snapshots(self, type = 'ALL', prefix='', case_id = -1): """ Export snapshots of a given type Arguments: type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS') prefix (str): Exported file name prefix - caseId (int): the case Id to export for. The default of -1 will export all cases + case_id (int): the case Id to export for. The default of -1 will export all cases """ return self.__execute(exportSnapshots=Cmd.ExportSnapshotsRequest(type=type, prefix=prefix, - caseId=caseId)) + caseId=case_id)) - def exportProperty(self, caseId, timeStep, property, eclipseKeyword=property, undefinedValue=0.0, exportFile=property): + def export_property(self, case_id, time_step, property, eclipse_keyword=property, undefined_value=0.0, export_file=property): """ Export an Eclipse property Arguments: - caseId (int): case id - timeStep (int): time step index + case_id (int): case id + time_step (int): time step index property (str): property to export - eclipseKeyword (str): Eclipse keyword used as text in export header. Defaults to the value of property parameter. - undefinedValue (double): Value to use for undefined values. Defaults to 0.0 - exportFile (str): Filename for export. Defaults to the value of property parameter + eclipse_keyword (str): Eclipse keyword used as text in export header. Defaults to the value of property parameter. + undefined_value (double): Value to use for undefined values. Defaults to 0.0 + export_file (str): File name for export. Defaults to the value of property parameter """ - return self.__execute(exportProperty=Cmd.ExportPropertyRequest(caseId=caseId, - timeStep=timeStep, + return self.__execute(exportProperty=Cmd.ExportPropertyRequest(caseId=case_id, + timeStep=time_step, property=property, - eclipseKeyword=eclipseKeyword, - undefinedValue=undefinedValue, - exportFile=exportFile)) - - def exportPropertyInViews(self, caseId, viewNames, undefinedValue): - if isinstance(viewNames, str): - viewNames = [viewNames] - - return self.__execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=caseId, - viewNames=viewNames, - undefinedValue=undefinedValue)) - - def exportWellPathCompletions(self, caseId, timeStep, wellPathNames, fileSplit, - compdatExport, includePerforations, includeFishbones, - excludeMainBoreForFishbones, combinationMode): - if (isinstance(wellPathNames, str)): - wellPathNames = [wellPathNames] - return self.__execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=caseId, - timeStep=timeStep, - wellPathNames=wellPathNames, - fileSplit=fileSplit, - compdatExport=compdatExport, - includePerforations=includePerforations, - includeFishbones=includeFishbones, - excludeMainBoreForFishbones=excludeMainBoreForFishbones, - combinationMode=combinationMode)) - - def exportSimWellFractureCompletions(self, caseId, viewName, timeStep, simulationWellNames, fileSplit, compdatExport): - if(isinstance(simulationWellNames, str)): - simulationWellNames = [simulationWellNames] - return self.__execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=caseId, - viewName=viewName, - timeStep=timeStep, - simulationWellNames=simulationWellNames, - fileSplit=fileSplit, - compdatExport=compdatExport)) - - def exportMsw(self, caseId, wellPath): - return self.__execute(exportMsw=Cmd.ExportMswRequest(caseId=caseId, - wellPath=wellPath)) - - def exportWellPaths(self, wellPaths=[], mdStepSize=5.0): - if isinstance(wellPaths, str): - wellPaths = [wellPaths] - return self.__execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=wellPaths, mdStepSize=mdStepSize)) - - def exportVisibleCells(self, caseId, viewName, exportKeyword='FLUXNUM', visibleActiveCellsValue=1, hiddenActiveCellsValue=0, inactiveCellsValue=0): - return self.__execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=caseId, - viewName=viewName, - exportKeyword=exportKeyword, - visibleActiveCellsValue=visibleActiveCellsValue, - hiddenActiveCellsValue=hiddenActiveCellsValue, - inactiveCellsValue=inactiveCellsValue)) - def setExportFolder(self, type, path, createFolder=False): + eclipseKeyword=eclipse_keyword, + undefinedValue=undefined_value, + exportFile=export_file)) + + def export_property_in_views(self, case_id, view_names, undefined_value): + """ Export the current Eclipse property from the given views + + Arguments: + case_id (int): case id + view_names (list): list of views + undefined_value (double): Value to use for undefined values. Defaults to 0.0 + """ + if isinstance(view_names, str): + view_names = [view_names] + + return self.__execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=case_id, + viewNames=view_names, + undefinedValue=undefined_value)) + + def export_well_path_completions(self, case_id, time_step, well_path_names, file_split, + compdat_export, include_perforations, include_fishbones, + exclude_main_bore_for_fishbones, combination_mode): + if (isinstance(well_path_names, str)): + well_path_names = [well_path_names] + return self.__execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=case_id, + timeStep=time_step, + wellPathNames=well_path_names, + fileSplit=file_split, + compdatExport=compdat_export, + includePerforations=include_perforations, + includeFishbones=include_fishbones, + excludeMainBoreForFishbones=exclude_main_bore_for_fishbones, + combinationMode=combination_mode)) + + def export_sim_well_fracture_completions(self, case_id, view_name, time_step, simulation_well_names, file_split, compdat_export): + if(isinstance(simulation_well_names, str)): + simulation_well_names = [simulation_well_names] + return self.__execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=case_id, + viewName=view_name, + timeStep=time_step, + simulationWellNames=simulation_well_names, + fileSplit=file_split, + compdatExport=compdat_export)) + + def export_msw(self, case_id, well_path): + return self.__execute(exportMsw=Cmd.ExportMswRequest(caseId=case_id, + wellPath=well_path)) + + def export_well_paths(self, well_paths=[], md_step_size=5.0): + if isinstance(well_paths, str): + well_paths = [well_paths] + return self.__execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=well_paths, mdStepSize=md_step_size)) + + def export_visible_cells(self, case_id, view_name, export_keyword='FLUXNUM', visible_active_cells_value=1, hidden_active_cells_value=0, inactive_cells_value=0): + return self.__execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=case_id, + viewName=view_name, + exportKeyword=export_keyword, + visibleActiveCellsValue=visible_active_cells_value, + hiddenActiveCellsValue=hidden_active_cells_value, + inactiveCellsValue=inactive_cells_value)) + def set_export_folder(self, type, path, create_folder=False): return self.__execute(setExportFolder=Cmd.SetExportFolderRequest(type=type, path=path, - createFolder=createFolder)) + createFolder=create_folder)) - def runOctaveScript(self, path, cases): + def run_octave_script(self, path, cases): caseIds = [] for case in cases: caseIds.append(case.id) return self.__execute(runOctaveScript=Cmd.RunOctaveScriptRequest(path=path, caseIds=caseIds)) - def setMainWindowSize(self, width, height): + def set_main_window_size(self, width, height): return self.__execute(setMainWindowSize=Cmd.SetMainWindowSizeParams(width=width, height=height)) - def computeCaseGroupStatistics(self, caseIds = [], caseGroupId = -1): - return self.__execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=caseIds, - caseGroupId=caseGroupId)) + def compute_case_group_statistics(self, case_ids = [], case_group_id = -1): + return self.__execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=case_ids, + caseGroupId=case_group_id)) - def setTimeStep(self, caseId, timeStep): - return self.__execute(setTimeStep=Cmd.SetTimeStepParams(caseId=caseId, timeStep=timeStep)) + def set_time_step(self, case_id, time_step): + return self.__execute(setTimeStep=Cmd.SetTimeStepParams(caseId=case_id, timeStep=time_step)) - def scaleFractureTemplate(self, id, halfLength, height, dFactor, conductivity): + def scale_fracture_template(self, id, half_length, height, dfactor, conductivity): return self.__execute(scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(id=id, - halfLength=halfLength, + halfLength=half_length, height=height, - dFactor=dFactor, + dFactor=dfactor, conductivity=conductivity)) - def setFractureContainment(self, id, topLayer, baseLayer): + def set_fracture_containment(self, id, top_layer, base_layer): return self.__execute(setFractureContainment=Cmd.SetFracContainmentRequest(id=id, - topLayer=topLayer, - baseLayer=baseLayer)) - - def createMultipleFractures(self, caseId, templateId, wellPathNames, minDistFromWellTd, - maxFracturesPerWell, topLayer, baseLayer, spacing, action): - if isinstance(wellPathNames, str): - wellPathNames = [wellPathNames] - return self.__execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=caseId, - templateId=templateId, - wellPathNames=wellPathNames, - minDistFromWellTd=minDistFromWellTd, - maxFracturesPerWell=maxFracturesPerWell, - topLayer=topLayer, - baseLayer=baseLayer, + topLayer=top_layer, + baseLayer=base_layer)) + + def create_multiple_fractures(self, case_id, template_id, well_path_names, min_dist_from_well_td, + max_fractures_per_well, top_layer, base_layer, spacing, action): + if isinstance(well_path_names, str): + well_path_names = [well_path_names] + return self.__execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=case_id, + templateId=template_id, + wellPathNames=well_path_names, + minDistFromWellTd=min_dist_from_well_td, + maxFracturesPerWell=max_fractures_per_well, + topLayer=top_layer, + baseLayer=base_layer, spacing=spacing, action=action)) - def createLgrForCompletions(self, caseId, timeStep, wellPathNames, refinementI, refinementJ, refinementK, splitType): - if isinstance(wellPathNames, str): - wellPathNames = [wellPathNames] - return self.__execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=caseId, - timeStep=timeStep, - wellPathNames=wellPathNames, - refinementI=refinementI, - refinementJ=refinementJ, - refinementK=refinementK, - splitType=splitType)) - - def createSaturationPressurePlots(self, caseIds): - if isinstance(caseIds, int): - caseIds = [caseIds] - return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=caseIds)) - - def exportFlowCharacteristics(self, caseId, timeSteps, injectors, producers, fileName, minimumCommunication=0.0, aquiferCellThreshold=0.1): + def create_lgr_for_completion(self, case_id, time_step, well_path_names, refinement_i, refinement_j, refinement_k, split_type): + if isinstance(well_path_names, str): + well_path_names = [well_path_names] + return self.__execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=case_id, + timeStep=time_step, + wellPathNames=well_path_names, + refinementI=refinement_i, + refinementJ=refinement_j, + refinementK=refinement_k, + splitType=split_type)) + + def create_saturation_pressure_plots(self, case_ids): + if isinstance(case_ids, int): + case_ids = [case_ids] + return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=case_ids)) + + def export_flow_characteristics(self, case_id, time_steps, injectors, producers, file_name, minimum_communication=0.0, aquifer_cell_threshold=0.1): """ Export Flow Characteristics data to text file in CSV format Parameter | Description | Type ------------------------- | --------------------------------------------- | ----- - caseId | ID of case | Integer - timeSteps | Time step indices | List of Integer + case_id | ID of case | Integer + time_steps | Time step indices | List of Integer injectors | Injector names | List of Strings producers | Producer names | List of Strings - fileName | Export file name | Integer - minimumCommunication | Minimum Communication, defaults to 0.0 | Integer - aquiferCellThreshold | Aquifer Cell Threshold, defaults to 0.1 | Integer + file_name | Export file name | Integer + minimum_communication | Minimum Communication, defaults to 0.0 | Integer + aquifer_cell_threshold | Aquifer Cell Threshold, defaults to 0.1 | Integer """ - if isinstance(timeSteps, int): - timeSteps = [timeSteps] + if isinstance(time_steps, int): + time_steps = [time_steps] if isinstance(injectors, str): injectors = [injectors] if isinstance(producers, str): producers = [producers] - return self.__execute(exportFlowCharacteristics=Cmd.ExportFlowInfoRequest(caseId=caseId, - timeSteps=timeSteps, + return self.__execute(exportFlowCharacteristics=Cmd.ExportFlowInfoRequest(caseId=case_id, + timeSteps=time_steps, injectors=injectors, producers=producers, - fileName=fileName, - minimumCommunication = minimumCommunication, - aquiferCellThreshold = aquiferCellThreshold)) + fileName=file_name, + minimumCommunication = minimum_communication, + aquiferCellThreshold = aquifer_cell_threshold)) - def createView(self, caseId): - return self.__execute(createView=Cmd.CreateViewRequest(caseId=caseId)).createViewResult.viewId + def create_view(self, case_id): + return self.__execute(createView=Cmd.CreateViewRequest(caseId=case_id)).createViewResult.viewId - def cloneView(self, viewId): - return self.__execute(cloneView=Cmd.CloneViewRequest(viewId=viewId)).createViewResult.viewId \ No newline at end of file + def clone_view(self, view_id): + return self.__execute(cloneView=Cmd.CloneViewRequest(viewId=view_id)).createViewResult.viewId \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py b/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py index d00d2f9e40..499e53f0e7 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py +++ b/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py @@ -14,25 +14,24 @@ class GridCaseGroup (PdmObject): Operate on a ResInsight case group specified by a Case Group Id integer. Attributes: - id (int): Grid Case Group Id corresponding to case group Id in ResInsight project. - name (str): Case name + group_id (int): Grid Case Group Id corresponding to case group Id in ResInsight project. """ - def __init__(self, pdmObject): - self.groupId = pdmObject.getValue("GroupId") - PdmObject.__init__(self, pdmObject.pb2Object, pdmObject.channel) + def __init__(self, pdm_object): + self.group_id = pdm_object.get_value("GroupId") + PdmObject.__init__(self, pdm_object.pb2Object, pdm_object.channel) - def statisticsCases(self): + def statistics_cases(self): """Get a list of all statistics cases in the Grid Case Group""" - statCaseCollection = self.children("StatisticsCaseCollection")[0] - return statCaseCollection.children("Reservoirs") + stat_case_collection = self.children("StatisticsCaseCollection")[0] + return stat_case_collection.children("Reservoirs") def views(self): """Get a list of views belonging to a grid case group""" - pbmObjects = self.descendants("ReservoirView") - viewList = [] - for pbmObject in pbmObjects: - viewList.append(View(pbmObject)) - return viewList + pdm_objects = self.descendants("ReservoirView") + view_list = [] + for pdm_object in pdm_objects: + view_list.append(View(pdm_object)) + return view_list def view(self, id): """Get a particular view belonging to a case group by providing view id @@ -43,7 +42,7 @@ def view(self, id): """ views = self.views() - for viewObject in views: - if viewObject.id == id: - return viewObject + for view_object in views: + if view_object.id == id: + return view_object return None diff --git a/ApplicationCode/GrpcInterface/Python/rips/Instance.py b/ApplicationCode/GrpcInterface/Python/rips/Instance.py index 08655f9616..c1902e7fae 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/Instance.py +++ b/ApplicationCode/GrpcInterface/Python/rips/Instance.py @@ -33,33 +33,33 @@ def __is_port_in_use(port): return s.connect_ex(('localhost', port)) == 0 @staticmethod - def launch(resInsightExecutable = '', console = False, launchPort = -1, commandLineParameters=[]): + def launch(resinsight_executable = '', console = False, launch_port = -1, command_line_parameters=[]): """ Launch a new Instance of ResInsight. This requires the environment variable - RESINSIGHT_EXECUTABLE to be set or the parameter resInsightExecutable to be provided. + RESINSIGHT_EXECUTABLE to be set or the parameter resinsight_executable to be provided. The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number. Args: - resInsightExecutable (str): Path to a valid ResInsight executable. If set + resinsight_executable (str): Path to a valid ResInsight executable. If set will take precedence over what is provided in the RESINSIGHT_EXECUTABLE environment variable. console (bool): If True, launch as console application, without GUI. - launchPort(int): If -1 will use the default port of 50051 or look for RESINSIGHT_GRPC_PORT + launch_port(int): If -1 will use the default port of 50051 or look for RESINSIGHT_GRPC_PORT if anything else, ResInsight will try to launch with this port - commandLineParameters(list): Additional command line parameters as string entries in the list. + command_line_parameters(list): Additional command line parameters as string entries in the list. Returns: Instance: an instance object if it worked. None if not. """ port = 50051 - portEnv = os.environ.get('RESINSIGHT_GRPC_PORT') - if portEnv: - port = int(portEnv) - if launchPort is not -1: - port = launchPort + port_env = os.environ.get('RESINSIGHT_GRPC_PORT') + if port_env: + port = int(port_env) + if launch_port is not -1: + port = launch_port - if not resInsightExecutable: - resInsightExecutable = os.environ.get('RESINSIGHT_EXECUTABLE') - if not resInsightExecutable: + if not resinsight_executable: + resinsight_executable = os.environ.get('RESINSIGHT_EXECUTABLE') + if not resinsight_executable: print('ERROR: Could not launch ResInsight because the environment variable' ' RESINSIGHT_EXECUTABLE is not set') return None @@ -68,12 +68,12 @@ def launch(resInsightExecutable = '', console = False, launchPort = -1, commandL port += 1 print('Port ' + str(port)) - print('Trying to launch', resInsightExecutable) + print('Trying to launch', resinsight_executable) - if isinstance(commandLineParameters, str): - commandLineParameters = [str] + if isinstance(command_line_parameters, str): + command_line_parameters = [str] - parameters = ["ResInsight", "--server", str(port)] + commandLineParameters + parameters = ["ResInsight", "--server", str(port)] + command_line_parameters if console: print("Launching as console app") parameters.append("--console") @@ -82,14 +82,14 @@ def launch(resInsightExecutable = '', console = False, launchPort = -1, commandL for i in range(0, len(parameters)): parameters[i] = str(parameters[i]) - pid = os.spawnv(os.P_NOWAIT, resInsightExecutable, parameters) + pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters) if pid: instance = Instance(port=port, launched=True) return instance return None @staticmethod - def find(startPort = 50051, endPort = 50071): + def find(start_port = 50051, end_port = 50071): """ Search for an existing Instance of ResInsight by testing ports. By default we search from port 50051 to 50071 or if the environment @@ -97,27 +97,27 @@ def find(startPort = 50051, endPort = 50071): RESINSIGHT_GRPC_PORT to RESINSIGHT_GRPC_PORT+20 Args: - startPort (int): start searching from this port - endPort (int): search up to but not including this port + start_port (int): start searching from this port + end_port (int): search up to but not including this port """ - portEnv = os.environ.get('RESINSIGHT_GRPC_PORT') - if portEnv: - startPort = int(portEnv) - endPort = startPort + 20 + port_env = os.environ.get('RESINSIGHT_GRPC_PORT') + if port_env: + start_port = int(port_env) + end_port = start_port + 20 - for tryPort in range(startPort, endPort): - if Instance.__is_port_in_use(tryPort): - return Instance(port=tryPort) + for try_port in range(start_port, end_port): + if Instance.__is_port_in_use(try_port): + return Instance(port=try_port) - print('Error: Could not find any ResInsight instances responding between ports ' + str(startPort) + ' and ' + str(endPort)) + print('Error: Could not find any ResInsight instances responding between ports ' + str(start_port) + ' and ' + str(end_port)) return None - def __checkVersion(self): + def __check_version(self): try: - majorVersionOk = self.majorVersion() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION) - minorVersionOk = self.minorVersion() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION) - return True, majorVersionOk and minorVersionOk - except grpc.RpcError as e: + major_version_ok = self.major_version() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION) + minor_version_ok = self.minor_version() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION) + return True, major_version_ok and minor_version_ok + except: return False, False def __init__(self, port = 50051, launched = False): @@ -135,25 +135,25 @@ def __init__(self, port = 50051, launched = False): # Main version check package self.app = self.app = App_pb2_grpc.AppStub(self.channel) - connectionOk = False - versionOk = False + connection_ok = False + version_ok = False if self.launched: for i in range(0, 10): - connectionOk, versionOk = self.__checkVersion() - if connectionOk: + connection_ok, version_ok = self.__check_version() + if connection_ok: break time.sleep(1.0) else: - connectionOk, versionOk = self.__checkVersion() + connection_ok, version_ok = self.__check_version() - if not connectionOk: + if not connection_ok: if self.launched: raise Exception('Error: Could not connect to resinsight at ', location, ' after trying 10 times with 1 second apart') else: raise Exception('Error: Could not connect to resinsight at ', location) exit(1) - if not versionOk: + if not version_ok: raise Exception('Error: Wrong Version of ResInsight at ', location) # Service packages @@ -161,36 +161,36 @@ def __init__(self, port = 50051, launched = False): self.project = Project(self.channel) path = os.getcwd() - self.commands.setStartDir(path=path) + self.commands.set_start_dir(path=path) - def __versionMessage(self): + def __version_message(self): return self.app.GetVersion(Empty()) - def majorVersion(self): + def major_version(self): """Get an integer with the major version number""" - return self.__versionMessage().major_version + return self.__version_message().major_version - def minorVersion(self): + def minor_version(self): """Get an integer with the minor version number""" - return self.__versionMessage().minor_version + return self.__version_message().minor_version - def patchVersion(self): + def patch_version(self): """Get an integer with the patch version number""" - return self.__versionMessage().patch_version + return self.__version_message().patch_version - def versionString(self): + def version_string(self): """Get a full version string, i.e. 2019.04.01""" - return str(self.majorVersion()) + "." + str(self.minorVersion()) + "." + str(self.patchVersion()) + return str(self.major_version()) + "." + str(self.minor_version()) + "." + str(self.patch_version()) def exit(self): """Tell ResInsight instance to quit""" print("Telling ResInsight to Exit") return self.app.Exit(Empty()) - def isConsole(self): + def is_console(self): """Returns true if the connected ResInsight instance is a console app""" return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('CONSOLE_APPLICATION') - def isGui(self): + def is_gui(self): """Returns true if the connected ResInsight instance is a GUI app""" return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('GUI_APPLICATION') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py b/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py index e3277e6ba5..d8aa4514bc 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py @@ -9,10 +9,10 @@ import PdmObject_pb2_grpc class PdmObject: - def __init__(self, pb2Object, channel): - self.pb2Object = pb2Object + def __init__(self, pb2_object, channel): + self.pb2_object = pb2_object self.channel = channel - self.pdmObjectStub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel) + self.pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel) def address(self): """Get the unique address of the PdmObject @@ -21,59 +21,59 @@ def address(self): A 64-bit unsigned integer address """ - return self.pb2Object.address + return self.pb2_object.address - def classKeyword(self): + def class_keyword(self): """Get the class keyword in the ResInsight Data Model for the given PdmObject""" - return self.pb2Object.class_keyword + return self.pb2_object.class_keyword def keywords(self): """Get a list of all parameter keywords available in the object""" - listOfKeywords = [] - for keyword in self.pb2Object.parameters: - listOfKeywords.append(keyword) - return listOfKeywords + list_of_keywords = [] + for keyword in self.pb2_object.parameters: + list_of_keywords.append(keyword) + return list_of_keywords - def printObjectInfo(self): + def print_object_info(self): """Print the structure and data content of the PdmObject""" - print ("Class Keyword: " + self.classKeyword()) + print ("Class Keyword: " + self.class_keyword()) for keyword in self.keywords(): - print(keyword + " [" + type(self.getValue(keyword)).__name__ + "]: " + str(self.getValue(keyword))) + print(keyword + " [" + type(self.get_value(keyword)).__name__ + "]: " + str(self.get_value(keyword))) - def __toValue(self, value): + def __to_value(self, value): if value.lower() == 'false': return False elif value.lower() == 'true': return True else: try: - intVal = int(value) - return intVal + int_val = int(value) + return int_val except ValueError: try: - floatVal = float(value) - return floatVal + float_val = float(value) + return float_val except ValueError: # We may have a string. Strip internal start and end quotes value = value.strip('\"') if self.__islist(value): return self.__makelist(value) return value - def __fromValue(self, value): + def __from_value(self, value): if isinstance(value, bool): if value: return "true" else: return "false" elif isinstance(value, list): - listofstrings = [] + list_of_strings = [] for val in value: - listofstrings.append(self.__fromValue('\"' + val + '\"')) - return "[" + ", ".join(listofstrings) + "]" + list_of_strings.append(self.__from_value('\"' + val + '\"')) + return "[" + ", ".join(list_of_strings) + "]" else: return str(value) - def getValue(self, keyword): + def get_value(self, keyword): """Get the value associated with the provided keyword Arguments: keyword(str): A string containing the parameter keyword @@ -81,72 +81,72 @@ def getValue(self, keyword): Returns: The value of the parameter. Can be int, str or list. """ - value = self.pb2Object.parameters[keyword] - return self.__toValue(value) + value = self.pb2_object.parameters[keyword] + return self.__to_value(value) def __islist(self, value): return value.startswith("[") and value.endswith("]") - def __makelist(self, liststring): - liststring = liststring.lstrip("[") - liststring = liststring.rstrip("]") - strings = liststring.split(", ") + def __makelist(self, list_string): + list_string = list_string.lstrip("[") + list_string = list_string.rstrip("]") + strings = list_string.split(", ") values = [] for string in strings: - values.append(self.__toValue(string)) + values.append(self.__to_value(string)) return values - def setValue(self, keyword, value): + def set_value(self, keyword, value): """Set the value associated with the provided keyword Arguments: keyword(str): A string containing the parameter keyword value(varying): A value matching the type of the parameter. - See keyword documentation and/or printObjectInfo() to find + See keyword documentation and/or print_object_info() to find the correct data type. """ - self.pb2Object.parameters[keyword] = self.__fromValue(value) + self.pb2_object.parameters[keyword] = self.__from_value(value) - def descendants(self, classKeyword): + def descendants(self, class_keyword): """Get a list of all project tree descendants matching the class keyword Arguments: - classKeyword[str]: A class keyword matching the type of class wanted + class_keyword[str]: A class keyword matching the type of class wanted Returns: A list of PdmObjects matching the keyword provided """ - request = PdmObject_pb2.PdmDescendantObjectRequest(object=self.pb2Object, child_keyword=classKeyword) - objectList = self.pdmObjectStub.GetDescendantPdmObjects(request).objects - childList = [] - for object in objectList: - childList.append(PdmObject(object, self.channel)) - return childList - - def children(self, childField): - """Get a list of all direct project tree children inside the provided childField + request = PdmObject_pb2.PdmDescendantObjectRequest(object=self.pb2_object, child_keyword=class_keyword) + object_list = self.pdm_object_stub.GetDescendantPdmObjects(request).objects + child_list = [] + for object in object_list: + child_list.append(PdmObject(object, self.channel)) + return child_list + + def children(self, child_field): + """Get a list of all direct project tree children inside the provided child_field Arguments: - childField[str]: A field name + child_field[str]: A field name Returns: - A list of PdmObjects inside the childField + A list of PdmObjects inside the child_field """ - request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2Object, child_field=childField) - objectList = self.pdmObjectStub.GetChildPdmObjects(request).objects - childList = [] - for object in objectList: - childList.append(PdmObject(object, self.channel)) - return childList - - def ancestor(self, classKeyword): - """Find the first ancestor that matches the provided classKeyword + request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2_object, child_field=child_field) + object_list = self.pdm_object_stub.GetChildPdmObjects(request).objects + child_list = [] + for object in object_list: + child_list.append(PdmObject(object, self.channel)) + return child_list + + def ancestor(self, class_keyword): + """Find the first ancestor that matches the provided class_keyword Arguments: - classKeyword[str]: A class keyword matching the type of class wanted + class_keyword[str]: A class keyword matching the type of class wanted """ - request = PdmObject_pb2.PdmParentObjectRequest(object=self.pb2Object, parent_keyword=classKeyword) - return PdmObject(self.pdmObjectStub.GetAncestorPdmObject(request), self.channel) + request = PdmObject_pb2.PdmParentObjectRequest(object=self.pb2_object, parent_keyword=class_keyword) + return PdmObject(self.pdm_object_stub.GetAncestorPdmObject(request), self.channel) def update(self): """Sync all fields from the Python Object to ResInsight""" - self.pdmObjectStub.UpdateExistingPdmObject(self.pb2Object) + self.pdm_object_stub.UpdateExistingPdmObject(self.pb2_object) -# def createChild(self, childField, childClassKeyword): -# childRequest = PdmObject_pb2.CreatePdmChildObjectRequest(object=self.pb2Object, child_field=childField, child_class=childClassKeyword) +# def createChild(self, child_field, childClassKeyword): +# childRequest = PdmObject_pb2.CreatePdmChildObjectRequest(object=self.pb2Object, child_field=child_field, child_class=childClassKeyword) # return PdmObject(self.pdmObjectStub.CreateChildPdmObject(childRequest), self.channel) diff --git a/ApplicationCode/GrpcInterface/Python/rips/Project.py b/ApplicationCode/GrpcInterface/Python/rips/Project.py index 23c8e7ab2e..3cc06935ad 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/Project.py +++ b/ApplicationCode/GrpcInterface/Python/rips/Project.py @@ -31,23 +31,23 @@ def open(self, path): path(str): path to project file """ - Commands(self.channel).openProject(path) + Commands(self.channel).open_project(path) return self def close(self): """Close the current project (and open new blank project)""" - Commands(self.channel).closeProject() + Commands(self.channel).close_project() - def selectedCases(self): + def selected_cases(self): """Get a list of all cases selected in the project tree Returns: A list of rips Case objects """ - caseInfos = self.project.GetSelectedCases(Empty()) + case_infos = self.project.GetSelectedCases(Empty()) cases = [] - for caseInfo in caseInfos.data: - cases.append(Case(self.channel, caseInfo.id)) + for case_info in case_infos.data: + cases.append(Case(self.channel, case_info.id)) return cases def cases(self): @@ -57,11 +57,11 @@ def cases(self): A list of rips Case objects """ try: - caseInfos = self.project.GetAllCases(Empty()) + case_infos = self.project.GetAllCases(Empty()) cases = [] - for caseInfo in caseInfos.data: - cases.append(Case(self.channel, caseInfo.id)) + for case_info in case_infos.data: + cases.append(Case(self.channel, case_info.id)) return cases except grpc.RpcError as e: if e.code() == grpc.StatusCode.NOT_FOUND: @@ -84,7 +84,7 @@ def case(self, id): except grpc.RpcError as e: return None - def loadCase(self, path): + def load_case(self, path): """Load a new case from the given file path Arguments: @@ -92,15 +92,15 @@ def loadCase(self, path): Returns: A rips Case object """ - return Commands(self.channel).loadCase(path) + return Commands(self.channel).load_case(path) def views(self): """Get a list of views belonging to a project""" - pdmObjects = self.descendants("ReservoirView") - viewList = [] - for pdmObject in pdmObjects: - viewList.append(View(pdmObject)) - return viewList + pdm_objects = self.descendants("ReservoirView") + view_list = [] + for pdm_object in pdm_objects: + view_list.append(View(pdm_object)) + return view_list def view(self, id): """Get a particular view belonging to a case by providing view id @@ -111,39 +111,39 @@ def view(self, id): """ views = self.views() - for viewObject in views: - if viewObject.id == id: - return viewObject + for view_object in views: + if view_object.id == id: + return view_object return None - def gridCaseGroups(self): + def grid_case_groups(self): """Get a list of all grid case groups in the project""" - caseGroups = self.descendants("RimIdenticalGridCaseGroup"); + case_groups = self.descendants("RimIdenticalGridCaseGroup") - caseGroupList = [] - for pb2Group in caseGroups: - caseGroupList.append(GridCaseGroup(pb2Group)) - return caseGroupList + case_group_list = [] + for pdm_group in case_groups: + case_group_list.append(GridCaseGroup(pdm_group)) + return case_group_list - def gridCaseGroup(self, groupId): + def grid_case_group(self, group_id): """Get a particular grid case group belonging to a project Arguments: groupId(int): group id Returns: a grid case group object """ - caseGroups = self.gridCaseGroups() - for caseGroup in caseGroups: - if caseGroup.groupId == groupId: - return caseGroup + case_groups = self.grid_case_groups() + for case_group in case_groups: + if case_group.groupId == group_id: + return case_group return None - def createGridCaseGroup(self, casePaths): + def create_grid_case_group(self, case_paths): """Create a new grid case group from the provided case paths Arguments: casePaths(list): a list of paths to the cases to be loaded and included in the group Returns: A new grid case group object """ - groupId, groupName = Commands(self.channel).createGridCaseGroup(casePaths) - return self.gridCaseGroup(groupId) \ No newline at end of file + group_id, group_name = Commands(self.channel).create_grid_case_group(case_paths) + return self.grid_case_group(group_id) \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/Properties.py b/ApplicationCode/GrpcInterface/Python/rips/Properties.py index 38af187e25..ae448ada8b 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/Properties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/Properties.py @@ -26,11 +26,11 @@ def __init__(self, case): case(Case): A rips case to handle properties for """ self.case = case - self.propertiesStub = Properties_pb2_grpc.PropertiesStub(self.case.channel) - self.chunkSize = 8160 + self._properties_stub = Properties_pb2_grpc.PropertiesStub(self.case.channel) + self.chunk_size = 8160 - def __generatePropertyInputIterator(self, values_iterator, parameters): + def __generate_property_input_iterator(self, values_iterator, parameters): chunk = Properties_pb2.PropertyInputChunk() chunk.params.CopyFrom(parameters) yield chunk @@ -40,7 +40,7 @@ def __generatePropertyInputIterator(self, values_iterator, parameters): chunk.values.CopyFrom(valmsg) yield chunk - def __generatePropertyInputChunks(self, array, parameters): + def __generate_property_input_chunks(self, array, parameters): index = -1 while index < len(array): @@ -49,20 +49,20 @@ def __generatePropertyInputChunks(self, array, parameters): chunk.params.CopyFrom(parameters) index += 1 else: - actualChunkSize = min(len(array) - index + 1, self.chunkSize) - chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actualChunkSize])) - index += actualChunkSize + actual_chunk_size = min(len(array) - index + 1, self.chunk_size) + chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actual_chunk_size])) + index += actual_chunk_size yield chunk # Final empty message to signal completion chunk = Properties_pb2.PropertyInputChunk() yield chunk - def available(self, propertyType, porosityModel = 'MATRIX_MODEL'): + def available(self, property_type, porosity_model = 'MATRIX_MODEL'): """Get a list of available properties Arguments: - propertyType (str): string corresponding to propertyType enum. Can be one of the following: + property_type (str): string corresponding to property_type enum. Can be one of the following: - DYNAMIC_NATIVE - STATIC_NATIVE - SOURSIMRL @@ -72,168 +72,168 @@ def available(self, propertyType, porosityModel = 'MATRIX_MODEL'): - FLOW_DIAGNOSTICS - INJECTION_FLOODING - porosityModel(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'. + porosity_model(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'. """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Properties_pb2.AvailablePropertiesRequest (case_request = Case_pb2.CaseRequest(id=self.case.id), - property_type = propertyTypeEnum, - porosity_model = porosityModelEnum) - return self.propertiesStub.GetAvailableProperties(request).property_names + property_type = property_type_enum, + porosity_model = porosity_model_enum) + return self._properties_stub.GetAvailableProperties(request).property_names - def activeCellPropertyAsync(self, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): + def active_cell_property_async(self, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): """Get a cell property for all active cells. Async, so returns an iterator Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(str): string enum. See available() + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() Returns: An iterator to a chunk object containing an array of double values You first loop through the chunks and then the values within the chunk to get all values. """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Properties_pb2.PropertyRequest(case_request = Case_pb2.CaseRequest(id=self.case.id), - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - porosity_model = porosityModelEnum) - for chunk in self.propertiesStub.GetActiveCellProperty(request): + property_type = property_type_enum, + property_name = property_name, + time_step = time_step, + porosity_model = porosity_model_enum) + for chunk in self._properties_stub.GetActiveCellProperty(request): yield chunk - def activeCellProperty(self, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): + def active_cell_property(self, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): """Get a cell property for all active cells. Sync, so returns a list Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(str): string enum. See available() + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() Returns: A list containing double values You first loop through the chunks and then the values within the chunk to get all values. """ - allValues = [] - generator = self.activeCellPropertyAsync(propertyType, propertyName, timeStep, porosityModel) + all_values = [] + generator = self.active_cell_property_async(property_type, property_name, time_step, porosity_model) for chunk in generator: for value in chunk.values: - allValues.append(value) - return allValues + all_values.append(value) + return all_values - def gridPropertyAsync(self, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'): + def grid_property_async(self, property_type, property_name, time_step, gridIndex = 0, porosity_model = 'MATRIX_MODEL'): """Get a cell property for all grid cells. Async, so returns an iterator Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for gridIndex(int): index to the grid we're getting values for - porosityModel(str): string enum. See available() + porosity_model(str): string enum. See available() Returns: An iterator to a chunk object containing an array of double values You first loop through the chunks and then the values within the chunk to get all values. """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, + property_type = property_type_enum, + property_name = property_name, + time_step = time_step, grid_index = gridIndex, - porosity_model = porosityModelEnum) - for chunk in self.propertiesStub.GetGridProperty(request): + porosity_model = porosity_model_enum) + for chunk in self._properties_stub.GetGridProperty(request): yield chunk - def gridProperty(self, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'): + def grid_property(self, property_type, property_name, time_step, grid_index = 0, porosity_model = 'MATRIX_MODEL'): """Get a cell property for all grid cells. Synchronous, so returns a list Arguments: - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - gridIndex(int): index to the grid we're getting values for - porosityModel(str): string enum. See available() + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + grid_index(int): index to the grid we're getting values for + porosity_model(str): string enum. See available() Returns: A list of double values """ - allValues = [] - generator = self.gridPropertyAsync(propertyType, propertyName, timeStep, gridIndex, porosityModel) + all_values = [] + generator = self.grid_property_async(property_type, property_name, time_step, grid_index, porosity_model) for chunk in generator: for value in chunk.values: - allValues.append(value) - return allValues + all_values.append(value) + return all_values - def setActiveCellPropertyAsync(self, values_iterator, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): + def set_active_cell_property_async(self, values_iterator, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): """Set a cell property for all active cells. Async, and so takes an iterator to the input values Arguments: values_iterator(iterator): an iterator to the properties to be set - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(str): string enum. See available() + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - porosity_model = porosityModelEnum) + property_type = property_type_enum, + property_name = property_name, + time_step = time_step, + porosity_model = porosity_model_enum) - request_iterator = self.__generatePropertyInputIterator(values_iterator, request) - self.propertiesStub.SetActiveCellProperty(request_iterator) + request_iterator = self.__generate_property_input_iterator(values_iterator, request) + self._properties_stub.SetActiveCellProperty(request_iterator) - def setActiveCellProperty(self, values, propertyType, propertyName, timeStep, porosityModel = 'MATRIX_MODEL'): + def set_active_cell_property(self, values, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): """Set a cell property for all active cells. Arguments: values(list): a list of double precision floating point numbers - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - porosityModel(str): string enum. See available() + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - porosity_model = porosityModelEnum) - request_iterator = self.__generatePropertyInputChunks(values, request) - reply = self.propertiesStub.SetActiveCellProperty(request_iterator) + property_type = property_type_enum, + property_name = property_name, + time_step = time_step, + porosity_model = porosity_model_enum) + request_iterator = self.__generate_property_input_chunks(values, request) + reply = self._properties_stub.SetActiveCellProperty(request_iterator) if reply.accepted_value_count < len(values): raise IndexError - def setGridProperty(self, values, propertyType, propertyName, timeStep, gridIndex = 0, porosityModel = 'MATRIX_MODEL'): + def set_grid_property(self, values, property_type, property_name, time_step, grid_index = 0, porosity_model = 'MATRIX_MODEL'): """Set a cell property for all grid cells. Arguments: values(list): a list of double precision floating point numbers - propertyType(str): string enum. See available() - propertyName(str): name of an Eclipse property - timeStep(int): the time step for which to get the property for - gridIndex(int): index to the grid we're setting values for - porosityModel(str): string enum. See available() + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + grid_index(int): index to the grid we're setting values for + porosity_model(str): string enum. See available() """ - propertyTypeEnum = Properties_pb2.PropertyType.Value(propertyType) - porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel) + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = propertyTypeEnum, - property_name = propertyName, - time_step = timeStep, - grid_index = gridIndex, - porosity_model = porosityModelEnum) - request_iterator = self.__generatePropertyInputChunks(values, request) - reply = self.propertiesStub.SetGridProperty(request_iterator) + property_type = property_type_enum, + property_name = property_name, + time_step = time_step, + grid_index = grid_index, + porosity_model = porosity_model_enum) + request_iterator = self.__generate_property_input_chunks(values, request) + reply = self._properties_stub.SetGridProperty(request_iterator) if reply.accepted_value_count < len(values): raise IndexError \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py index 51d07a0b44..7066682c32 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AllCases.py @@ -7,17 +7,17 @@ import rips # Connect to ResInsight -resInsight = rips.Instance.find() -if resInsight is not None: +resinsight = rips.Instance.find() +if resinsight is not None: # Get a list of all cases - cases = resInsight.project.cases() + cases = resinsight.project.cases() print ("Got " + str(len(cases)) + " cases: ") for case in cases: print("Case name: " + case.name) - print("Case grid path: " + case.gridPath()) + print("Case grid path: " + case.grid_path()) - timesteps = case.timeSteps() + timesteps = case.time_steps() for t in timesteps: print("Year: " + str(t.year)) print("Month: " + str(t.month)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py index 6e83e10b59..06ee6e6a66 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/AppInfo.py @@ -1,6 +1,6 @@ import rips -resInsight = rips.Instance.find() -if resInsight is not None: - print(resInsight.versionString()) - print("Is this a console run?", resInsight.isConsole()) +resinsight = rips.Instance.find() +if resinsight is not None: + print(resinsight.version_string()) + print("Is this a console run?", resinsight.is_console()) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py index afe8470d17..6285e823eb 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py @@ -1,29 +1,29 @@ import os import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -casePaths = [] -casePaths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") -casePaths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") -for casePath in casePaths: +case_paths = [] +case_paths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") +case_paths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") +for casePath in case_paths: assert os.path.exists(casePath), "You need to set valid case paths for this script to work" -caseGroup = resInsight.project.createGridCaseGroup(casePaths=casePaths) +case_group = resinsight.project.create_grid_case_group(case_paths=case_paths) -caseGroup.printObjectInfo() +case_group.print_object_info() -#statCases = caseGroup.statisticsCases() -#caseIds = [] -#for statCase in statCases: -# statCase.setValue("DynamicPropertiesToCalculate", ["SWAT"]) -# statCase.update() -# caseIds.append(statCase.getValue("CaseId")) +#stat_cases = caseGroup.statistics_cases() +#case_ids = [] +#for stat_case in stat_cases: +# stat_case.set_value("DynamicPropertiesToCalculate", ["SWAT"]) +# stat_case.update() +# case_ids.append(stat_case.get_value("CaseId")) -resInsight.commands.computeCaseGroupStatistics(caseGroupId=caseGroup.groupId) +resinsight.commands.compute_case_group_statistics(case_group_id=case_group.group_id) -view = caseGroup.views()[0] -cellResult = view.cellResult() -cellResult.setValue("ResultVariable", "PRESSURE_DEV") -cellResult.update() +view = case_group.views()[0] +cell_result = view.set_cell_result() +cell_result.set_value("ResultVariable", "PRESSURE_DEV") +cell_result.update() \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py index 6f81aa0693..6a5ce6d880 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py @@ -6,22 +6,22 @@ import rips # Connect to ResInsight -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() # Get the case with id == 0. This will fail if your project doesn't have a case with id == 0 -case = resInsight.project.case(id = 0) +case = resinsight.project.case(id = 0) # Get the cell count object -cellCounts = case.cellCount() -print("Number of active cells: " + str(cellCounts.active_cell_count)) -print("Total number of reservoir cells: " + str(cellCounts.reservoir_cell_count)) +cell_counts = case.cell_count() +print("Number of active cells: " + str(cell_counts.active_cell_count)) +print("Total number of reservoir cells: " + str(cell_counts.reservoir_cell_count)) # Get information for all active cells -activeCellInfos = case.cellInfoForActiveCells() +active_cell_infos = case.cell_info_for_active_cells() # A simple check on the size of the cell info -assert(cellCounts.active_cell_count == len(activeCellInfos)) +assert(cell_counts.active_cell_count == len(active_cell_infos)) # Print information for the first active cell print("First active cell: ") -print(activeCellInfos[0]) +print(active_cell_infos[0]) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py index a32760a367..6835ac7442 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py @@ -8,11 +8,11 @@ import rips # Load instance -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() # Run a couple of commands -resInsight.commands.setTimeStep(caseId=0, timeStep=3) -resInsight.commands.setMainWindowSize(width=800, height=500) +resinsight.commands.set_time_step(case_id=0, time_step=3) +resinsight.commands.set_main_window_size(width=800, height=500) # Create a temporary directory which will disappear at the end of this script # If you want to keep the files, provide a good path name instead of tmpdirname @@ -20,23 +20,23 @@ print("Temporary folder: ", tmpdirname) # Set export folder for snapshots and properties - resInsight.commands.setExportFolder(type='SNAPSHOTS', path=tmpdirname) - resInsight.commands.setExportFolder(type='PROPERTIES', path=tmpdirname) + resinsight.commands.set_export_folder(type='SNAPSHOTS', path=tmpdirname) + resinsight.commands.set_export_folder(type='PROPERTIES', path=tmpdirname) # Export snapshots - resInsight.commands.exportSnapshots() + resinsight.commands.export_snapshots() # Print contents of temporary folder print(os.listdir(tmpdirname)) assert(len(os.listdir(tmpdirname)) > 0) - case = resInsight.project.case(id=0) + case = resinsight.project.case(id=0) # Export properties in the view - resInsight.commands.exportPropertyInViews(0, "3D View", 0) + resinsight.commands.export_property_in_views(0, "3D View", 0) # Check that the exported file exists - expectedFileName = case.name + "-" + str("3D_View") + "-" + "T3" + "-SOIL" - fullPath = tmpdirname + "/" + expectedFileName - assert(os.path.exists(fullPath)) + expected_file_name = case.name + "-" + str("3D_View") + "-" + "T3" + "-SOIL" + full_path = tmpdirname + "/" + expected_file_name + assert(os.path.exists(full_path)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py index d36d99f923..d3605519f8 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py @@ -6,24 +6,24 @@ import rips import grpc -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() case = None # Try loading a non-existing case. We should get a grpc.RpcError exception from the server try: - case = resInsight.project.loadCase("Nonsense") + case = resinsight.project.load_case("Nonsense") except grpc.RpcError as e: print("Expected Server Exception Received: ", e) -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) if case is not None: - results = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0) - activeCellCount = len(results) + results = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0) + active_cell_count = len(results) # Send the results back to ResInsight inside try / except construct try: - case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0) + case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) print("Everything went well as expected") except: # Match any exception, but it should not happen print("Ooops!") @@ -33,7 +33,7 @@ # This time we should get a grpc.RpcError exception, which is a server side error. try: - case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0) + case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) print("Everything went well??") except grpc.RpcError as e: print("Expected Server Exception Received: ", e) @@ -43,10 +43,10 @@ # With a chunk size exactly matching the active cell count the server will not # be able to see any error as it will successfully close the stream after receiving # the correct number of values, even if the python client has more chunks to send - case.properties.chunkSize = activeCellCount + case.properties.chunk_size = active_cell_count try: - case.properties.setActiveCellProperty(results, 'GENERATED', 'POROAPPENDED', 0) + case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) print("Everything went well??") except grpc.RpcError as e: print("Got unexpected server exception", e, "This should not happen now") diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py index 69f71f80cc..380cfcff12 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py @@ -6,38 +6,38 @@ import rips # Load instance -resInsight = rips.Instance.find() -cases = resInsight.project.cases() +resinsight = rips.Instance.find() +cases = resinsight.project.cases() # Set main window size -resInsight.commands.setMainWindowSize(width=800, height=500) +resinsight.commands.set_main_window_size(width=800, height=500) -n = 5 # every n-th timestep for snapshot +n = 5 # every n-th time_step for snapshot property_list = ['SOIL', 'PRESSURE'] # list of parameter for snapshot print ("Looping through cases") for case in cases: # Get grid path and its folder name - casepath = case.gridPath() - foldername = os.path.dirname(casepath) + case_path = case.grid_path() + folder_name = os.path.dirname(case_path) # create a folder to hold the snapshots - dirname = os.path.join(foldername, 'snapshots') + dirname = os.path.join(folder_name, 'snapshots') if os.path.exists(dirname) is False: os.mkdir(dirname) print ("Exporting to folder: " + dirname) - resInsight.commands.setExportFolder(type='SNAPSHOTS', path=dirname) + resinsight.commands.set_export_folder(type='SNAPSHOTS', path=dirname) - timeSteps = case.timeSteps() - tss_snapshot = range(0, len(timeSteps), n) - print(case.name, case.id, 'Number of timesteps: ' + str(len(timeSteps))) - print('Number of timesteps for snapshoting: ' + str(len(tss_snapshot))) + time_steps = case.time_steps() + tss_snapshot = range(0, len(time_steps), n) + print(case.name, case.id, 'Number of time_steps: ' + str(len(time_steps))) + print('Number of time_steps for snapshoting: ' + str(len(tss_snapshot))) view = case.views()[0] for property in property_list: - view.applyCellResult(resultType='DYNAMIC_NATIVE', resultVariable=property) + view.apply_cell_result(result_type='DYNAMIC_NATIVE', result_variable=property) for ts_snapshot in tss_snapshot: - resInsight.commands.setTimeStep(caseId = case.id, timeStep = ts_snapshot) - resInsight.commands.exportSnapshots(type='VIEWS', caseId=case.id) # ‘ALL’, ‘VIEWS’ or ‘PLOTS’ default is 'ALL' + resinsight.commands.set_time_step(case_id = case.id, time_step = ts_snapshot) + resinsight.commands.export_snapshots(type='VIEWS', case_id=case.id) # ‘ALL’, ‘VIEWS’ or ‘PLOTS’ default is 'ALL' diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py index 52ec8c3fca..ee48208960 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/GridInformation.py @@ -4,9 +4,9 @@ import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -cases = resInsight.project.cases() +cases = resinsight.project.cases() print("Number of cases found: ", len(cases)) for case in cases: print(case.name) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py index 2db56bbf81..ca2390d92c 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py @@ -7,9 +7,9 @@ # Internal function for creating a result from a small chunk of poro and permx results # The return value of the function is a generator for the results rather than the result itself. -def createResult(poroChunks, permxChunks): +def create_result(poro_chunks, permx_chunks): # Loop through all the chunks of poro and permx in order - for (poroChunk, permxChunk) in zip(poroChunks, permxChunks): + for (poroChunk, permxChunk) in zip(poro_chunks, permx_chunks): resultChunk = [] # Loop through all the values inside the chunks, in order for (poro, permx) in zip(poroChunk.values, permxChunk.values): @@ -17,22 +17,22 @@ def createResult(poroChunks, permxChunks): # Return a generator object that behaves like a Python iterator yield resultChunk -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) # Get a generator for the poro results. The generator will provide a chunk each time it is iterated -poroChunks = case.properties.activeCellPropertyAsync('STATIC_NATIVE', 'PORO', 0) +poro_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORO', 0) # Get a generator for the permx results. The generator will provide a chunk each time it is iterated -permxChunks = case.properties.activeCellPropertyAsync('STATIC_NATIVE', 'PERMX', 0) +permx_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0) # Send back the result with the result provided by a generator object. # Iterating the result generator will cause the script to read from the poro and permx generators # And return the result of each iteration -case.properties.setActiveCellPropertyAsync(createResult(poroChunks, permxChunks), +case.properties.set_active_cell_property_async(create_result(poro_chunks, permx_chunks), 'GENERATED', 'POROPERMXAS', 0) end = time.time() print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'POROPERMXAS') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'POROPERMXAS') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py index 577880a1d6..b38de90a41 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py @@ -7,23 +7,23 @@ import time import grpc -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) # Read poro result into list -poroResults = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0) +poro_results = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0) # Read permx result into list -permxResults = case.properties.activeCellProperty('STATIC_NATIVE', 'PERMX', 0) +permx_results = case.properties.active_cell_property('STATIC_NATIVE', 'PERMX', 0) # Generate output result results = [] -for (poro, permx) in zip(poroResults, permxResults): +for (poro, permx) in zip(poro_results, permx_results): results.append(poro * permx) try: # Send back output result - case.properties.setActiveCellProperty(results, 'GENERATED', 'POROPERMXSY', 0) + case.properties.set_active_cell_property(results, 'GENERATED', 'POROPERMXSY', 0) except grpc.RpcError as e: print("Exception Received: ", e) @@ -32,4 +32,4 @@ print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'POROPERMXSY') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'POROPERMXSY') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py index bf72ff22b4..f2a7517ef2 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InstanceExample.py @@ -3,9 +3,9 @@ ####################################### import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -if resInsight is None: +if resinsight is None: print('ERROR: could not find ResInsight') else: print('Successfully connected to ResInsight') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py index ae6975408e..f6b85def3c 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/LaunchWithCommandLineOptions.py @@ -1,11 +1,11 @@ # Load ResInsight Processing Server Client Library import rips # Launch ResInsight with last project file and a Window size of 600x1000 pixels -resInsight = rips.Instance.launch(commandLineParameters=['--last', '--size', 600, 1000]) +resinsight = rips.Instance.launch(command_line_parameters=['--last', '--size', 600, 1000]) # Get a list of all cases -cases = resInsight.project.cases() +cases = resinsight.project.cases() print ("Got " + str(len(cases)) + " cases: ") for case in cases: print("Case name: " + case.name) - print("Case grid path: " + case.gridPath()) + print("Case grid path: " + case.grid_path()) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py index 80fc48d35b..be6431e2c1 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py @@ -7,9 +7,9 @@ import rips -resInsight = rips.Instance.find() -if resInsight is not None: - cases = resInsight.project.selectedCases() +resinsight = rips.Instance.find() +if resinsight is not None: + cases = resinsight.project.selected_cases() print ("Got " + str(len(cases)) + " cases: ") for case in cases: diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py index 5eea3d07f9..f527d6d3db 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py @@ -3,7 +3,7 @@ ###################################################################### import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -view = resInsight.project.view(0) -view.applyCellResult(resultType='STATIC_NATIVE', resultVariable='DX') +view = resinsight.project.view(0) +view.apply_cell_result(resultType='STATIC_NATIVE', resultVariable='DX') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py index 9e3523f44e..1fdbcc91e5 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py @@ -5,14 +5,14 @@ # Load ResInsight Processing Server Client Library import rips # Connect to ResInsight instance -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -view = resInsight.project.view(0) -#view.applyFlowDiagnosticsCellResult(resultVariable='Fraction', -# selectionMode='FLOW_TR_INJ_AND_PROD') +view = resinsight.project.view(0) +#view.apply_flow_diagnostics_cell_result(result_variable='Fraction', +# selection_mode='FLOW_TR_INJ_AND_PROD') # Example of setting individual wells. Commented out because well names are case specific. -view.applyFlowDiagnosticsCellResult(resultVariable='Fraction', - selectionMode='FLOW_TR_BY_SELECTION', +view.apply_flow_diagnostics_cell_result(result_variable='Fraction', + selection_mode='FLOW_TR_BY_SELECTION', injectors = ['C-1H', 'C-2H', 'F-2H'], producers = ['B-1AH', 'B-3H', 'D-1H']) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py index a7f8f7878b..837ccf0833 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py @@ -3,15 +3,15 @@ ###################################################################### import rips -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() -case = resInsight.project.case(id=0) -totalCellCount = case.cellCount().reservoir_cell_count +case = resinsight.project.case(id=0) +total_cell_count = case.cell_count().reservoir_cell_count values = [] -for i in range(0, totalCellCount): +for i in range(0, total_cell_count): values.append(i % 2 * 0.75); print("Applying values to full grid") -case.properties.setGridProperty(values, 'DYNAMIC_NATIVE', 'SOIL', 0) +case.properties.set_grid_property(values, 'DYNAMIC_NATIVE', 'SOIL', 0) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py index b6eccc186d..9aa25c50d3 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py @@ -6,27 +6,27 @@ import itertools import time -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() # Get the case with case id 0 -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) # Get a list of all time steps -timeSteps = case.timeSteps() +timeSteps = case.time_steps() averages = [] for i in range(0, len(timeSteps)): # Get the results from time step i asynchronously # It actually returns a generator object almost immediately - resultChunks = case.properties.activeCellPropertyAsync('DYNAMIC_NATIVE', 'SOIL', i) + result_chunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i) mysum = 0.0 count = 0 # Loop through and append the average. each time we loop resultChunks # We will trigger a read of the input data, meaning the script will start # Calculating averages before the whole resultValue for this time step has been received - for chunk in resultChunks: + for chunk in result_chunks: mysum += sum(chunk.values) count += len(chunk.values) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py index 7b3b879689..ca82dd4218 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py @@ -5,21 +5,21 @@ import itertools import time -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) # Get the case with case id 0 -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) # Get a list of all time steps -timeSteps = case.timeSteps() +time_steps = case.time_steps() averages = [] -for i in range(0, len(timeSteps)): +for i in range(0, len(time_steps)): # Get a list of all the results for time step i - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', i) + results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) mysum = sum(results) averages.append(mysum/len(results)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py index 2c8bd954de..fbc6369d9a 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py @@ -7,41 +7,41 @@ # Internal function for creating a result from a small chunk of soil and porv results # The return value of the function is a generator for the results rather than the result itself. -def createResult(soilChunks, porvChunks): - for (soilChunk, porvChunk) in zip(soilChunks, porvChunks): +def create_result(soil_chunks, porv_chunks): + for (soil_chunk, porv_chunk) in zip(soil_chunks, porv_chunks): resultChunk = [] number = 0 - for (soilValue, porvValue) in zip(soilChunk.values, porvChunk.values): - resultChunk.append(soilValue * porvValue) + for (soil_value, porv_value) in zip(soil_chunk.values, porv_chunk.values): + resultChunk.append(soil_value * porv_value) # Return a Python generator yield resultChunk -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() -case = resInsight.project.case(id=0) -timeStepInfo = case.timeSteps() +case = resinsight.project.case(id=0) +timeStepInfo = case.time_steps() # Get a generator for the porv results. The generator will provide a chunk each time it is iterated -porvChunks = case.properties.activeCellPropertyAsync('STATIC_NATIVE', 'PORV', 0) +porv_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORV', 0) # Read the static result into an array, so we don't have to transfer it for each iteration # Note we use the async method even if we synchronise here, because we need the values chunked # ... to match the soil chunks -porvArray = [] -for porvChunk in porvChunks: - porvArray.append(porvChunk) +porv_array = [] +for porv_chunk in porv_chunks: + porv_array.append(porv_chunk) for i in range (0, len(timeStepInfo)): # Get a generator object for the SOIL property for time step i - soilChunks = case.properties.activeCellPropertyAsync('DYNAMIC_NATIVE', 'SOIL', i) + soil_chunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i) # Create the generator object for the SOIL * PORV derived result - result_generator = createResult(soilChunks, iter(porvArray)) + result_generator = create_result(soil_chunks, iter(porv_array)) # Send back the result asynchronously with a generator object - case.properties.setActiveCellPropertyAsync(result_generator, 'GENERATED', 'SOILPORVAsync', i) + case.properties.set_active_cell_property_async(result_generator, 'GENERATED', 'SOILPORVAsync', i) end = time.time() print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'SOILPORVAsync') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'SOILPORVAsync') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py index 53684a211b..459ca922b1 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py @@ -5,29 +5,29 @@ import rips import time -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() start = time.time() -case = resInsight.project.case(id=0) +case = resinsight.project.case(id=0) # Read the full porv result -porvResults = case.properties.activeCellProperty('STATIC_NATIVE', 'PORV', 0) -timeStepInfo = case.timeSteps() +porv_results = case.properties.active_cell_property('STATIC_NATIVE', 'PORV', 0) +time_step_info = case.time_steps() -for i in range (0, len(timeStepInfo)): +for i in range (0, len(time_step_info)): # Read the full SOIl result for time step i - soilResults = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', i) + soil_results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) # Generate the result by looping through both lists in order results = [] - for (soil, porv) in zip(soilResults, porvResults): + for (soil, porv) in zip(soil_results, porv_results): results.append(soil * porv) # Send back result - case.properties.setActiveCellProperty(results, 'GENERATED', 'SOILPORVSync', i) + case.properties.set_active_cell_property(results, 'GENERATED', 'SOILPORVSync', i) end = time.time() print("Time elapsed: ", end - start) print("Transferred all results back") -view = case.views()[0].applyCellResult('GENERATED', 'SOILPORVSync') \ No newline at end of file +view = case.views()[0].apply_cell_result('GENERATED', 'SOILPORVSync') \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py index 3b03154125..99a1e0a5b8 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ViewExample.py @@ -5,23 +5,23 @@ ############################################################# import rips # Connect to ResInsight instance -resInsight = rips.Instance.find() +resinsight = rips.Instance.find() # Check if connection worked -if resInsight is not None: +if resinsight is not None: # Get a list of all cases - cases = resInsight.project.cases() + cases = resinsight.project.cases() for case in cases: # Get a list of all views views = case.views() for view in views: # Set some parameters for the view - view.setShowGridBox(not view.showGridBox()) - view.setBackgroundColor("#3388AA") + view.set_show_grid_box(not view.show_grid_box()) + view.set_background_color("#3388AA") # Update the view in ResInsight view.update() # Clone the first view - newView = views[0].clone() - view.setShowGridBox(False) - newView.setBackgroundColor("#FFAA33") - newView.update() \ No newline at end of file + new_view = views[0].clone() + view.set_show_grid_box(False) + new_view.set_background_color("#FFAA33") + new_view.update() diff --git a/ApplicationCode/GrpcInterface/Python/rips/View.py b/ApplicationCode/GrpcInterface/Python/rips/View.py index 5e55cda7e9..504d1387dc 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/View.py +++ b/ApplicationCode/GrpcInterface/Python/rips/View.py @@ -9,36 +9,36 @@ class View (PdmObject): id(int): View Id corresponding to the View Id in ResInsight project. """ - def __init__(self, pbmObject): - self.id = pbmObject.getValue("ViewId") + def __init__(self, pdm_object): + self.id = pdm_object.get_value("ViewId") - PdmObject.__init__(self, pbmObject.pb2Object, pbmObject.channel) + PdmObject.__init__(self, pdm_object.pb2_object, pdm_object.channel) - def showGridBox(self): + def show_grid_box(self): """Check if the grid box is meant to be shown in the view""" - return self.getValue("ShowGridBox") + return self.get_value("ShowGridBox") - def setShowGridBox(self, value): + def set_show_grid_box(self, value): """Set if the grid box is meant to be shown in the view""" - self.setValue("ShowGridBox", value) + self.set_value("ShowGridBox", value) - def backgroundColor(self): + def background_color(self): """Get the current background color in the view""" - return self.getValue("ViewBackgroundColor") + return self.get_value("ViewBackgroundColor") - def setBackgroundColor(self, bgColor): + def set_background_color(self, bgcolor): """Set the background color in the view""" - self.setValue("ViewBackgroundColor", bgColor) + self.set_value("ViewBackgroundColor", bgcolor) - def cellResult(self): + def set_cell_result(self): """Retrieve the current cell results""" return self.children("GridCellResult")[0] - def applyCellResult(self, resultType, resultVariable): + def apply_cell_result(self, result_type, result_variable): """Apply a regular cell result Arguments: - resultType (str): String representing the result category. The valid values are + result_type (str): String representing the result category. The valid values are - DYNAMIC_NATIVE - STATIC_NATIVE - SOURSIMRL @@ -47,54 +47,54 @@ def applyCellResult(self, resultType, resultVariable): - FORMATION_NAMES - FLOW_DIAGNOSTICS - INJECTION_FLOODING - resultVariable (str): String representing the result variable. + result_variable (str): String representing the result variable. """ - cellResult = self.cellResult() - cellResult.setValue("ResultType", resultType) - cellResult.setValue("ResultVariable", resultVariable) - cellResult.update() + cell_result = self.set_cell_result() + cell_result.set_value("ResultType", result_type) + cell_result.set_value("ResultVariable", result_variable) + cell_result.update() - def applyFlowDiagnosticsCellResult(self, - resultVariable = 'TOF', - selectionMode = 'FLOW_TR_BY_SELECTION', + def apply_flow_diagnostics_cell_result(self, + result_variable = 'TOF', + selection_mode = 'FLOW_TR_BY_SELECTION', injectors = [], producers = []): """Apply a flow diagnostics cell result Arguments: - resultVariable (str): String representing the result value + result_variable (str): String representing the result value The valid values are 'TOF', 'Fraction', 'MaxFractionTracer' and 'Communication'. - selectionMode (str): String specifying which tracers to select. + selection_mode (str): String specifying which tracers to select. The valid values are - FLOW_TR_INJ_AND_PROD (all injector and producer tracers), - FLOW_TR_PRODUCERS (all producers) - FLOW_TR_INJECTORS (all injectors), - FLOW_TR_BY_SELECTION (specify individual tracers in the - injectorTracers and producerTracers variables) - injectorTracers (list): List of injector names (strings) to select. - Requires selectionMode to be 'FLOW_TR_BY_SELECTION'. - producerTracers (list): List of producer tracers (strings) to select. - Requires selectionMode to be 'FLOW_TR_BY_SELECTION'. + injectors and producers variables) + injectors (list): List of injector names (strings) to select. + Requires selection_mode to be 'FLOW_TR_BY_SELECTION'. + producers (list): List of producer tracers (strings) to select. + Requires selection_mode to be 'FLOW_TR_BY_SELECTION'. """ - cellResult = self.cellResult() - cellResult.setValue("ResultType", "FLOW_DIAGNOSTICS") - cellResult.setValue("ResultVariable", resultVariable) - cellResult.setValue("FlowTracerSelectionMode", selectionMode) - if selectionMode == 'FLOW_TR_BY_SELECTION': - cellResult.setValue("SelectedInjectorTracers", injectors) - cellResult.setValue("SelectedProducerTracers", producers) - cellResult.update() + cell_result = self.set_cell_result() + cell_result.set_value("ResultType", "FLOW_DIAGNOSTICS") + cell_result.set_value("ResultVariable", result_variable) + cell_result.set_value("FlowTracerSelectionMode", selection_mode) + if selection_mode == 'FLOW_TR_BY_SELECTION': + cell_result.set_value("SelectedInjectorTracers", injectors) + cell_result.set_value("SelectedProducerTracers", producers) + cell_result.update() def case(self): """Get the case the view belongs to""" - pdmCase = self.ancestor("EclipseCase") - if pdmCase is None: - pdmCase = self.ancestor("ResInsightGeoMechCase") - if pdmCase is None: + pdm_case = self.ancestor("EclipseCase") + if pdm_case is None: + pdm_case = self.ancestor("ResInsightGeoMechCase") + if pdm_case is None: return None - return rips.Case(self.channel, pdmCase.getValue("CaseId")) + return rips.Case(self.channel, pdm_case.get_value("CaseId")) def clone(self): """Clone the current view""" - viewId = Commands(self.channel).cloneView(self.id) - return self.case().view(viewId) \ No newline at end of file + view_id = Commands(self.channel).clone_view(self.id) + return self.case().view(view_id) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py b/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py index b9d1efb2f3..ab02a62b6f 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/conftest.py @@ -13,9 +13,9 @@ def rips_instance(): return _rips_instance @pytest.fixture -def initializeTest(): +def initialize_test(): _rips_instance.project.close() # make sure ResInsight is clean before execution of test - yield initializeTest + yield initialize_test _rips_instance.project.close() # make sure ResInsight is clean after test def pytest_addoption(parser): diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py index 76e198ce05..fc74aa3a47 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py @@ -7,75 +7,75 @@ import dataroot -def test_Launch(rips_instance, initializeTest): +def test_Launch(rips_instance, initialize_test): assert(rips_instance is not None) -def test_EmptyProject(rips_instance, initializeTest): +def test_EmptyProject(rips_instance, initialize_test): cases = rips_instance.project.cases() assert(len(cases) is 0) -def test_OneCase(rips_instance, initializeTest): - case = rips_instance.project.loadCase(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") +def test_OneCase(rips_instance, initialize_test): + case = rips_instance.project.load_case(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") assert(case.name == "TEST10K_FLT_LGR_NNC") assert(case.id == 0) cases = rips_instance.project.cases() assert(len(cases) is 1) -def test_MultipleCases(rips_instance, initializeTest): - casePaths = [] - casePaths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") - casePaths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") - casePaths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") +def test_MultipleCases(rips_instance, initialize_test): + case_paths = [] + case_paths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") + case_paths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") + case_paths.append(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") - caseNames = [] - for casePath in casePaths: - caseName = os.path.splitext(os.path.basename(casePath))[0] - caseNames.append(caseName) - rips_instance.project.loadCase(path=casePath) + case_names = [] + for case_path in case_paths: + case_name = os.path.splitext(os.path.basename(case_path))[0] + case_names.append(case_name) + rips_instance.project.load_case(path=case_path) cases = rips_instance.project.cases() - assert(len(cases) == len(caseNames)) - for i, caseName in enumerate(caseNames): - assert(caseName == cases[i].name) + assert(len(cases) == len(case_names)) + for i, case_name in enumerate(case_names): + assert(case_name == cases[i].name) -def test_10k(rips_instance, initializeTest): - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.gridCount() == 2) - cellCountInfo = case.cellCount() - assert(cellCountInfo.active_cell_count == 11125) - assert(cellCountInfo.reservoir_cell_count == 316224) - timeSteps = case.timeSteps() - assert(len(timeSteps) == 9) - daysSinceStart = case.daysSinceStart() - assert(len(daysSinceStart) == 9) +def test_10k(rips_instance, initialize_test): + case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + case = rips_instance.project.load_case(path=case_path) + assert(case.grid_count() == 2) + cell_count_info = case.cell_count() + assert(cell_count_info.active_cell_count == 11125) + assert(cell_count_info.reservoir_cell_count == 316224) + time_steps = case.time_steps() + assert(len(time_steps) == 9) + days_since_start = case.days_since_start() + assert(len(days_since_start) == 9) -def test_PdmObject(rips_instance, initializeTest): - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) +def test_PdmObject(rips_instance, initialize_test): + case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + case = rips_instance.project.load_case(path=case_path) assert(case.id == 0) assert(case.address() is not 0) - assert(case.classKeyword() == "EclipseCase") - caseId = case.getValue('CaseId') - assert(caseId == case.id) + assert(case.class_keyword() == "EclipseCase") + case_id = case.get_value('CaseId') + assert(case_id == case.id) @pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") -def test_brugge_0010(rips_instance, initializeTest): - casePath = dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.gridCount() == 1) - cellCountInfo = case.cellCount() +def test_brugge_0010(rips_instance, initialize_test): + case_path = dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID" + case = rips_instance.project.load_case(path=case_path) + assert(case.grid_count() == 1) + cellCountInfo = case.cell_count() assert(cellCountInfo.active_cell_count == 43374) assert(cellCountInfo.reservoir_cell_count == 60048) - timeSteps = case.timeSteps() - assert(len(timeSteps) == 11) - daysSinceStart = case.daysSinceStart() - assert(len(daysSinceStart) == 11) + time_steps = case.time_steps() + assert(len(time_steps) == 11) + days_since_start = case.days_since_start() + assert(len(days_since_start) == 11) @pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") -def test_replaceCase(rips_instance, initializeTest): +def test_replaceCase(rips_instance, initialize_test): project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp") - casePath = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" + case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" case = project.case(id=0) assert(case is not None) assert(case.name == "TEST10K_FLT_LGR_NNC") @@ -83,7 +83,7 @@ def test_replaceCase(rips_instance, initializeTest): cases = rips_instance.project.cases() assert(len(cases) is 1) - rips_instance.commands.replaceCase(newGridFile=casePath, caseId=case.id) + rips_instance.commands.replace_case(new_grid_file=case_path, case_id=case.id) cases = rips_instance.project.cases() assert(len(cases) is 1) case = project.case(id=0) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py index 184b0e42e6..496942f4f8 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py @@ -9,50 +9,50 @@ import dataroot -def test_exportSnapshots(rips_instance, initializeTest): - if not rips_instance.isGui(): +def test_exportSnapshots(rips_instance, initialize_test): + if not rips_instance.is_gui(): pytest.skip("Cannot run test without a GUI") - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - rips_instance.project.loadCase(casePath) + case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + rips_instance.project.load_case(case_path) with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: print("Temporary folder: ", tmpdirname) - rips_instance.commands.setExportFolder(type='SNAPSHOTS', path=tmpdirname) - rips_instance.commands.exportSnapshots() + rips_instance.commands.set_export_folder(type='SNAPSHOTS', path=tmpdirname) + rips_instance.commands.export_snapshots() print(os.listdir(tmpdirname)) assert(len(os.listdir(tmpdirname)) > 0) for fileName in os.listdir(tmpdirname): assert(os.path.splitext(fileName)[1] == '.png') -def test_exportPropertyInView(rips_instance, initializeTest): - casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - rips_instance.project.loadCase(casePath) +def test_exportPropertyInView(rips_instance, initialize_test): + case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + rips_instance.project.load_case(case_path) with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: print("Temporary folder: ", tmpdirname) - rips_instance.commands.setExportFolder(type='PROPERTIES', path=tmpdirname) + rips_instance.commands.set_export_folder(type='PROPERTIES', path=tmpdirname) case = rips_instance.project.case(id=0) - rips_instance.commands.exportPropertyInViews(0, "3D View", 0) - expectedFileName = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL" - fullPath = tmpdirname + "/" + expectedFileName - assert(os.path.exists(fullPath)) + rips_instance.commands.export_property_in_views(0, "3D View", 0) + expected_file_name = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL" + full_path = tmpdirname + "/" + expected_file_name + assert(os.path.exists(full_path)) @pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") -def test_loadGridCaseGroup(rips_instance, initializeTest): - casePaths = [] - casePaths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") - casePaths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") - groupId, groupName = rips_instance.commands.createGridCaseGroup(casePaths=casePaths) - print(groupId, groupName) - -def test_exportFlowCharacteristics(rips_instance, initializeTest): - casePath = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" - rips_instance.project.loadCase(casePath) +def test_loadGridCaseGroup(rips_instance, initialize_test): + case_paths = [] + case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") + case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") + group_id, group_name = rips_instance.commands.create_grid_case_group(case_paths=case_paths) + print(group_id, group_name) + +def test_exportFlowCharacteristics(rips_instance, initialize_test): + case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" + rips_instance.project.load_case(case_path) with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: print("Temporary folder: ", tmpdirname) - fileName = tmpdirname + "/exportFlowChar.txt" - rips_instance.commands.exportFlowCharacteristics(caseId=0, timeSteps=8, producers=[], injectors = "I01", fileName = fileName) + file_name = tmpdirname + "/exportFlowChar.txt" + rips_instance.commands.export_flow_characteristics(case_id=0, time_steps=8, producers=[], injectors = "I01", file_name = file_name) -def test_loadNonExistingCase(rips_instance, initializeTest): - casePath = "Nonsense/Nonsense/Nonsense" +def test_loadNonExistingCase(rips_instance, initialize_test): + case_path = "Nonsense/Nonsense/Nonsense" with pytest.raises(grpc.RpcError): - assert rips_instance.project.loadCase(casePath) + assert rips_instance.project.load_case(case_path) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py index 52556d94da..918e37b537 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py @@ -6,10 +6,10 @@ import dataroot -def test_10k(rips_instance, initializeTest): +def test_10k(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) - assert(case.gridCount() == 2) + case = rips_instance.project.load_case(path=casePath) + assert(case.grid_count() == 2) grid = case.grid(index=0) dimensions = grid.dimensions() assert(dimensions.i == 90) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py index 9595923d4b..444ed41a43 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py @@ -7,7 +7,7 @@ import dataroot -def test_loadProject(rips_instance, initializeTest): +def test_loadProject(rips_instance, initialize_test): project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp") case = project.case(id=0) assert(case is not None) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py index fba9d6c125..7ba6c08340 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py @@ -8,11 +8,11 @@ import dataroot -def test_10kAsync(rips_instance, initializeTest): +def test_10kAsync(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - resultChunks = case.properties.activeCellPropertyAsync('DYNAMIC_NATIVE', 'SOIL', 1) + resultChunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', 1) mysum = 0.0 count = 0 for chunk in resultChunks: @@ -23,42 +23,42 @@ def test_10kAsync(rips_instance, initializeTest): assert(average != pytest.approx(0.0158893, abs=0.0000001)) assert(average == pytest.approx(0.0558893, abs=0.0000001)) -def test_10kSync(rips_instance, initializeTest): +def test_10kSync(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', 1) + results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) mysum = sum(results) average = mysum / len(results) assert(mysum == pytest.approx(621.768, abs=0.001)) assert(average != pytest.approx(0.0158893, abs=0.0000001)) assert(average == pytest.approx(0.0558893, abs=0.0000001)) -def test_10k_set(rips_instance, initializeTest): +def test_10k_set(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', 1) - case.properties.setActiveCellProperty(results, 'GENERATED', 'SOIL', 1) + results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) + case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) -def test_10k_set_out_of_bounds(rips_instance, initializeTest): +def test_10k_set_out_of_bounds(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', 1) + results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) results.append(5.0) with pytest.raises(grpc.RpcError): - assert case.properties.setActiveCellProperty(results, 'GENERATED', 'SOIL', 1) + assert case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) -def test_10k_set_out_of_bounds_client(rips_instance, initializeTest): +def test_10k_set_out_of_bounds_client(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - results = case.properties.activeCellProperty('DYNAMIC_NATIVE', 'SOIL', 1) - case.properties.chunkSize = len(results) + results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) + case.properties.chunk_size = len(results) results.append(5.0) with pytest.raises(IndexError): - assert case.properties.setActiveCellProperty(results, 'GENERATED', 'SOIL', 1) + assert case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) def createResult(poroChunks, permxChunks): for (poroChunk, permxChunk) in zip(poroChunks, permxChunks): @@ -72,18 +72,18 @@ def checkResults(poroValues, permxValues, poropermxValues): recalc = poro * permx assert(recalc == pytest.approx(poropermx, rel=1.0e-10)) -def test_10k_PoroPermX(rips_instance, initializeTest): +def test_10k_PoroPermX(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - case = rips_instance.project.loadCase(path=casePath) + case = rips_instance.project.load_case(path=casePath) - poroChunks = case.properties.activeCellPropertyAsync('STATIC_NATIVE', 'PORO', 0) - permxChunks = case.properties.activeCellPropertyAsync('STATIC_NATIVE', 'PERMX', 0) + poroChunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORO', 0) + permxChunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0) - case.properties.setActiveCellPropertyAsync(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0) + case.properties.set_active_cell_property_async(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0) - poro = case.properties.activeCellProperty('STATIC_NATIVE', 'PORO', 0) - permx = case.properties.activeCellProperty('STATIC_NATIVE', 'PERMX', 0) - poroPermX = case.properties.activeCellProperty('GENERATED', 'POROPERMXAS', 0) + poro = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0) + permx = case.properties.active_cell_property('STATIC_NATIVE', 'PERMX', 0) + poroPermX = case.properties.active_cell_property('GENERATED', 'POROPERMXAS', 0) checkResults(poro, permx, poroPermX) From 5954d7ab19fce5ea3d21eacd5540252c2c7071b7 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Mon, 23 Sep 2019 11:50:33 +0200 Subject: [PATCH 14/27] #4736 System python command refactor (#4743) * Move case loading commands from Commands to project and case * Major refactor * Fix problems with Python examples * Add ability to export snapshot from just one view + fixup * Case comments and black * Make all modules pass pylint test --- .../Application/RiaGuiApplication.cpp | 6 +- .../Tools/RiaRegressionTestRunner.cpp | 4 +- .../RicfApplicationTools.cpp | 22 + .../RicfApplicationTools.h | 7 +- .../RicfExportPropertyInViews.cpp | 32 +- .../RicfExportPropertyInViews.h | 1 + .../RicfExportSimWellFractureCompletions.cpp | 34 +- .../RicfExportSimWellFractureCompletions.h | 11 +- .../RicfExportSnapshots.cpp | 12 +- .../RicfExportSnapshots.h | 1 + .../RicfExportVisibleCells.cpp | 50 +- .../RicfExportVisibleCells.h | 1 + .../CommandFileInterface/RicfSetTimeStep.cpp | 22 +- .../CommandFileInterface/RicfSetTimeStep.h | 6 +- .../RicSnapshotAllViewsToFileFeature.cpp | 11 +- .../RicSnapshotAllViewsToFileFeature.h | 5 +- .../GrpcInterface/CMakeLists.cmake | 19 +- .../GrpcInterface/GrpcProtos/Commands.proto | 16 +- .../GrpcInterface/Python/rips/Case.py | 188 ----- .../GrpcInterface/Python/rips/Commands.py | 311 -------- .../GrpcInterface/Python/rips/Grid.py | 27 - .../Python/rips/GridCaseGroup.py | 48 -- .../GrpcInterface/Python/rips/Instance.py | 196 ----- .../GrpcInterface/Python/rips/Project.py | 149 ---- .../GrpcInterface/Python/rips/Properties.py | 239 ------ .../rips/PythonExamples/CaseGridGroup.py | 6 +- .../CaseInfoStreamingExample.py | 2 +- .../rips/PythonExamples/CommandExample.py | 49 +- .../rips/PythonExamples/ErrorHandling.py | 12 +- .../rips/PythonExamples/ExportSnapshots.py | 16 +- .../rips/PythonExamples/InputPropTestAsync.py | 8 +- .../rips/PythonExamples/InputPropTestSync.py | 8 +- .../rips/PythonExamples/SelectedCases.py | 2 +- .../rips/PythonExamples/SetCellResult.py | 4 +- .../SetFlowDiagnosticsResult.py | 2 +- .../rips/PythonExamples/SetGridProperties.py | 4 +- .../rips/PythonExamples/SoilAverageAsync.py | 4 +- .../rips/PythonExamples/SoilAverageSync.py | 5 +- .../rips/PythonExamples/SoilPorvAsync.py | 8 +- .../rips/PythonExamples/SoilPorvSync.py | 8 +- .../GrpcInterface/Python/rips/__init__.py | 19 +- .../GrpcInterface/Python/rips/case.py | 719 ++++++++++++++++++ .../GrpcInterface/Python/rips/grid.py | 33 + .../Python/rips/gridcasegroup.py | 73 ++ .../GrpcInterface/Python/rips/instance.py | 269 +++++++ .../rips/{PdmObject.py => pdmobject.py} | 121 +-- .../GrpcInterface/Python/rips/project.py | 209 +++++ .../Python/rips/tests/test_cases.py | 42 +- .../Python/rips/tests/test_commands.py | 47 -- .../Python/rips/tests/test_grids.py | 2 +- .../Python/rips/tests/test_project.py | 33 +- .../Python/rips/tests/test_properties.py | 45 +- .../Python/rips/{View.py => view.py} | 100 ++- .../UserInterface/RiuMainWindow.cpp | 4 +- 54 files changed, 1807 insertions(+), 1465 deletions(-) delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/Case.py delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/Commands.py delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/Grid.py delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/Instance.py delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/Project.py delete mode 100644 ApplicationCode/GrpcInterface/Python/rips/Properties.py create mode 100644 ApplicationCode/GrpcInterface/Python/rips/case.py create mode 100644 ApplicationCode/GrpcInterface/Python/rips/grid.py create mode 100644 ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py create mode 100644 ApplicationCode/GrpcInterface/Python/rips/instance.py rename ApplicationCode/GrpcInterface/Python/rips/{PdmObject.py => pdmobject.py} (56%) create mode 100644 ApplicationCode/GrpcInterface/Python/rips/project.py rename ApplicationCode/GrpcInterface/Python/rips/{View.py => view.py} (50%) diff --git a/ApplicationCode/Application/RiaGuiApplication.cpp b/ApplicationCode/Application/RiaGuiApplication.cpp index 88eabb6d4c..9c98a6a098 100644 --- a/ApplicationCode/Application/RiaGuiApplication.cpp +++ b/ApplicationCode/Application/RiaGuiApplication.cpp @@ -823,8 +823,8 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments(cvf::Progra // 2016-11-09 : Location of snapshot folder was previously located in 'snapshot' folder // relative to current working folder. Now harmonized to behave as RiuMainWindow::slotSnapshotAllViewsToFile() - QString absolutePathToSnapshotDir = createAbsolutePathFromProjectRelativePath("snapshots"); - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(absolutePathToSnapshotDir); + QString absolutePathToSnapshotDir = createAbsolutePathFromProjectRelativePath( "snapshots" ); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir ); mainWnd->loadWinGeoAndDockToolBarLayout(); } @@ -1787,7 +1787,7 @@ void RiaGuiApplication::runMultiCaseSnapshots(const QString& templateProje bool loadOk = loadProject(templateProjectFileName, PLA_NONE, &modifier); if (loadOk) { - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(snapshotFolderName); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( snapshotFolderName ); } } diff --git a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp index 29ad82e2b3..ade720b2d1 100644 --- a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp +++ b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp @@ -201,8 +201,8 @@ void RiaRegressionTestRunner::runRegressionTest() resizePlotWindows(); - QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName); - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder); + QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath( generatedFolderName ); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( fullPathGeneratedFolder ); RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder); diff --git a/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp b/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp index 3944fe2b43..8e6f1704d3 100644 --- a/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp +++ b/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp @@ -133,3 +133,25 @@ RimEclipseView* RicfApplicationTools::viewFromCaseIdAndViewName(int caseId, cons } return nullptr; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RicfApplicationTools::viewFromCaseIdAndViewId( int caseId, int viewId ) +{ + for ( RimEclipseCase* c : RiaApplication::instance()->project()->eclipseCases() ) + { + if ( c->caseId() == caseId ) + { + for ( auto v : c->views() ) + { + auto eclipseView = dynamic_cast( v ); + if ( eclipseView && eclipseView->id() == viewId ) + { + return eclipseView; + } + } + } + } + return nullptr; +} diff --git a/ApplicationCode/CommandFileInterface/RicfApplicationTools.h b/ApplicationCode/CommandFileInterface/RicfApplicationTools.h index 182aa0d78a..c0efab4c87 100644 --- a/ApplicationCode/CommandFileInterface/RicfApplicationTools.h +++ b/ApplicationCode/CommandFileInterface/RicfApplicationTools.h @@ -34,9 +34,10 @@ class QStringList; class RicfApplicationTools { public: - static std::vector wellPathsFromNames(const QStringList& wellPathNames, QStringList* wellsNotFound); - static RimEclipseCase* caseFromId(int caseId); - static RimEclipseView* viewFromCaseIdAndViewName(int caseId, const QString& viewName); + static std::vector wellPathsFromNames( const QStringList& wellPathNames, QStringList* wellsNotFound ); + static RimEclipseCase* caseFromId( int caseId ); + static RimEclipseView* viewFromCaseIdAndViewName( int caseId, const QString& viewName ); + static RimEclipseView* viewFromCaseIdAndViewId( int caseId, int viewId ); static std::vector toStringVector(const QStringList& stringList); static QStringList toQStringList(const std::vector& v); diff --git a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp index 7c95e141ef..a1e8e67f23 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp @@ -47,9 +47,10 @@ CAF_PDM_SOURCE_INIT(RicfExportPropertyInViews, "exportPropertyInViews"); //-------------------------------------------------------------------------------------------------- RicfExportPropertyInViews::RicfExportPropertyInViews() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_viewNames, "viewNames", std::vector(), "View Names", "", "", ""); - RICF_InitField(&m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", ""); + RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" ); + RICF_InitField( &m_viewIds, "viewIds", std::vector(), "View IDs", "", "", "" ); + RICF_InitField( &m_viewNames, "viewNames", std::vector(), "View Names", "", "", "" ); + RICF_InitField( &m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -74,22 +75,35 @@ RicfCommandResponse RicfExportPropertyInViews::execute() RimEclipseView* view = dynamic_cast(v); if (!view) continue; - if (m_viewNames().empty()) + if ( m_viewNames().empty() && m_viewIds().empty() ) { viewsForExport.push_back(view); } else { - bool matchingName = false; - for (const auto& viewName : m_viewNames()) + bool matchingIdOrName = false; + + for ( auto viewId : m_viewIds() ) + { + if ( view->id() == viewId ) + { + matchingIdOrName = true; + break; + } + } + + if ( !matchingIdOrName ) { - if (view->name().compare(viewName, Qt::CaseInsensitive) == 0) + for ( const auto& viewName : m_viewNames() ) { - matchingName = true; + if ( view->name().compare( viewName, Qt::CaseInsensitive ) == 0 ) + { + matchingIdOrName = true; + } } } - if (matchingName) + if ( matchingIdOrName ) { viewsForExport.push_back(view); } diff --git a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h index 896d489582..8e5a60d179 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h +++ b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h @@ -44,6 +44,7 @@ class RicfExportPropertyInViews : public RicfCommandObject private: caf::PdmField m_caseId; + caf::PdmField> m_viewIds; caf::PdmField> m_viewNames; caf::PdmField m_undefinedValue; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp index 0b233c5594..0fb5e7e048 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp @@ -45,12 +45,19 @@ CAF_PDM_SOURCE_INIT(RicfExportSimWellFractureCompletions, "exportSimWellFracture //-------------------------------------------------------------------------------------------------- RicfExportSimWellFractureCompletions::RicfExportSimWellFractureCompletions() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_viewName, "viewName", QString(""), "View Name", "", "", ""); - RICF_InitField(&m_timeStep, "timeStep", -1, "Time Step Index", "", "", ""); - RICF_InitField(&m_simWellNames, "simulationWellNames", std::vector(), "Simulation Well Names", "", "", ""); - RICF_InitField(&m_fileSplit, "fileSplit", RicExportCompletionDataSettingsUi::ExportSplitType(), "File Split", "", "", ""); - RICF_InitField(&m_compdatExport, "compdatExport", RicExportCompletionDataSettingsUi::CompdatExportType(), "Compdat Export", "", "", ""); + RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" ); + RICF_InitField( &m_viewId, "viewId", -1, "View ID", "", "", "" ); + RICF_InitField( &m_viewName, "viewName", QString( "" ), "View Name", "", "", "" ); + RICF_InitField( &m_timeStep, "timeStep", -1, "Time Step Index", "", "", "" ); + RICF_InitField( &m_simWellNames, "simulationWellNames", std::vector(), "Simulation Well Names", "", "", "" ); + RICF_InitField( &m_fileSplit, "fileSplit", RicExportCompletionDataSettingsUi::ExportSplitType(), "File Split", "", "", "" ); + RICF_InitField( &m_compdatExport, + "compdatExport", + RicExportCompletionDataSettingsUi::CompdatExportType(), + "Compdat Export", + "", + "", + "" ); } //-------------------------------------------------------------------------------------------------- @@ -88,17 +95,22 @@ RicfCommandResponse RicfExportSimWellFractureCompletions::execute() std::vector views; for (Rim3dView* v : exportSettings->caseToApply->views()) { - RimEclipseView* eclipseView = dynamic_cast(v); - if (eclipseView && eclipseView->name() == m_viewName()) + RimEclipseView* eclipseView = dynamic_cast( v ); + if ( eclipseView && ( eclipseView->id() == m_viewId() || eclipseView->name() == m_viewName() ) ) { views.push_back(eclipseView); } } if (views.empty()) { - QString error = QString("exportSimWellCompletions: Could not find any views named \"%1\" in the case with ID %2").arg(m_viewName).arg(m_caseId()); - RiaLogging::error(error); - return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, error); + QString error = + QString( + "exportSimWellCompletions: Could not find any views with id %1 or named \"%2\" in the case with ID %3" ) + .arg( m_viewId ) + .arg( m_viewName ) + .arg( m_caseId() ); + RiaLogging::error( error ); + return RicfCommandResponse( RicfCommandResponse::COMMAND_ERROR, error ); } RicfCommandResponse response; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h index 2b49b7d9f6..2bc202a972 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h +++ b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h @@ -40,11 +40,12 @@ class RicfExportSimWellFractureCompletions : public RicfCommandObject RicfCommandResponse execute() override; private: - caf::PdmField m_caseId; - caf::PdmField m_viewName; - caf::PdmField m_timeStep; - caf::PdmField< std::vector > m_simWellNames; - + caf::PdmField m_caseId; + caf::PdmField m_viewId; + caf::PdmField m_viewName; + caf::PdmField m_timeStep; + caf::PdmField> m_simWellNames; + caf::PdmField m_fileSplit; caf::PdmField m_compdatExport; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp index ee272ec0a1..54bdeec54c 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp @@ -49,9 +49,10 @@ void RicfExportSnapshots::SnapshotsTypeEnum::setUp() //-------------------------------------------------------------------------------------------------- RicfExportSnapshots::RicfExportSnapshots() { - RICF_InitField(&m_type, "type", RicfExportSnapshots::SnapshotsTypeEnum(), "Type", "", "", ""); - RICF_InitField(&m_prefix, "prefix", QString(), "Prefix", "", "", ""); - RICF_InitField(&m_caseId, "caseId", -1, "Case Id", "", "", ""); + RICF_InitField( &m_type, "type", RicfExportSnapshots::SnapshotsTypeEnum(), "Type", "", "", "" ); + RICF_InitField( &m_prefix, "prefix", QString(), "Prefix", "", "", "" ); + RICF_InitField( &m_caseId, "caseId", -1, "Case Id", "", "", "" ); + RICF_InitField( &m_viewId, "viewId", -1, "View Id", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -78,7 +79,10 @@ RicfCommandResponse RicfExportSnapshots::execute() } if (m_type == RicfExportSnapshots::VIEWS || m_type == RicfExportSnapshots::ALL) { - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(absolutePathToSnapshotDir, m_prefix, m_caseId()); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir, + m_prefix, + m_caseId(), + m_viewId() ); } if (m_type == RicfExportSnapshots::PLOTS || m_type == RicfExportSnapshots::ALL) { diff --git a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h index 47aa2123fa..bbad3c84ab 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h +++ b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h @@ -51,4 +51,5 @@ class RicfExportSnapshots : public RicfCommandObject caf::PdmField m_type; caf::PdmField m_prefix; caf::PdmField m_caseId; + caf::PdmField m_viewId; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp index e383e773b6..f32d1c48fe 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp @@ -63,13 +63,19 @@ void AppEnum::setUp() //-------------------------------------------------------------------------------------------------- RicfExportVisibleCells::RicfExportVisibleCells() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_viewName, "viewName", QString(), "View Name", "", "", ""); - RICF_InitField( - &m_exportKeyword, "exportKeyword", caf::AppEnum(), "Export Keyword", "", "", ""); - RICF_InitField(&m_visibleActiveCellsValue, "visibleActiveCellsValue", 1, "Visible Active Cells Value", "", "", ""); - RICF_InitField(&m_hiddenActiveCellsValue, "hiddenActiveCellsValue", 0, "Hidden Active Cells Value", "", "", ""); - RICF_InitField(&m_inactiveCellsValue, "inactiveCellsValue", 0, "Inactive Cells Value", "", "", ""); + RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" ); + RICF_InitField( &m_viewId, "viewId", -1, "View ID", "", "", "" ); + RICF_InitField( &m_viewName, "viewName", QString(), "View Name", "", "", "" ); + RICF_InitField( &m_exportKeyword, + "exportKeyword", + caf::AppEnum(), + "Export Keyword", + "", + "", + "" ); + RICF_InitField( &m_visibleActiveCellsValue, "visibleActiveCellsValue", 1, "Visible Active Cells Value", "", "", "" ); + RICF_InitField( &m_hiddenActiveCellsValue, "hiddenActiveCellsValue", 0, "Hidden Active Cells Value", "", "", "" ); + RICF_InitField( &m_inactiveCellsValue, "inactiveCellsValue", 0, "Inactive Cells Value", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -77,19 +83,29 @@ RicfExportVisibleCells::RicfExportVisibleCells() //-------------------------------------------------------------------------------------------------- RicfCommandResponse RicfExportVisibleCells::execute() { - if (m_caseId < 0 || m_viewName().isEmpty()) + if ( m_caseId < 0 || ( m_viewName().isEmpty() && m_viewId() < 0 ) ) { - QString error("exportVisibleCells: CaseId or view name not specified"); - RiaLogging::error(error); - return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, error); + QString error( "exportVisibleCells: CaseId or view name or view id not specified" ); + RiaLogging::error( error ); + return RicfCommandResponse( RicfCommandResponse::COMMAND_ERROR, error ); } - - auto eclipseView = RicfApplicationTools::viewFromCaseIdAndViewName(m_caseId, m_viewName); - if (!eclipseView) + RimEclipseView* eclipseView = nullptr; + if ( m_viewId() >= 0 ) + { + eclipseView = RicfApplicationTools::viewFromCaseIdAndViewId( m_caseId, m_viewId() ); + } + else + { + eclipseView = RicfApplicationTools::viewFromCaseIdAndViewName( m_caseId, m_viewName ); + } + if ( !eclipseView ) { - QString error(QString("exportVisibleCells: Could not find view '%1' in case ID %2").arg(m_viewName).arg(m_caseId)); - RiaLogging::error(error); - return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, error); + QString error( QString( "exportVisibleCells: Could not find view of id %1 or named '%2' in case ID %3" ) + .arg( m_viewId ) + .arg( m_viewName ) + .arg( m_caseId ) ); + RiaLogging::error( error ); + return RicfCommandResponse( RicfCommandResponse::COMMAND_ERROR, error ); } QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::CELLS); diff --git a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h index 1945090d47..79cec7ce46 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h +++ b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h @@ -51,6 +51,7 @@ class RicfExportVisibleCells : public RicfCommandObject void buildExportSettings(const QString& exportFolder, RicSaveEclipseInputVisibleCellsUi* exportSettings); caf::PdmField m_caseId; + caf::PdmField m_viewId; caf::PdmField m_viewName; caf::PdmField> m_exportKeyword; caf::PdmField m_visibleActiveCellsValue; diff --git a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp index 22655a6cdc..73534e1146 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp +++ b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp @@ -34,8 +34,9 @@ CAF_PDM_SOURCE_INIT(RicfSetTimeStep, "setTimeStep"); //-------------------------------------------------------------------------------------------------- RicfSetTimeStep::RicfSetTimeStep() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", ""); + RICF_InitField( &m_caseId, "caseId", -1, "Case ID", "", "", "" ); + RICF_InitField( &m_viewId, "viewId", -1, "View ID", "", "", "" ); + RICF_InitField( &m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", "" ); } //-------------------------------------------------------------------------------------------------- @@ -49,7 +50,15 @@ void RicfSetTimeStep::setCaseId(int caseId) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfSetTimeStep::setTimeStepIndex(int timeStepIndex) +void RicfSetTimeStep::setViewId( int viewId ) +{ + m_viewId = viewId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfSetTimeStep::setTimeStepIndex( int timeStepIndex ) { m_timeStepIndex = timeStepIndex; } @@ -93,8 +102,11 @@ RicfCommandResponse RicfSetTimeStep::execute() for (Rim3dView* view : eclipseCase->views()) { - view->setCurrentTimeStepAndUpdate(m_timeStepIndex); - view->createDisplayModelAndRedraw(); + if ( m_viewId() == -1 || view->id() == m_viewId() ) + { + view->setCurrentTimeStepAndUpdate( m_timeStepIndex ); + view->createDisplayModelAndRedraw(); + } } return RicfCommandResponse(); diff --git a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h index 69e7c9b89d..9d65e2309e 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h +++ b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h @@ -34,13 +34,15 @@ class RicfSetTimeStep : public RicfCommandObject public: RicfSetTimeStep(); - void setCaseId(int caseId); - void setTimeStepIndex(int timeStepIndex); + void setCaseId( int caseId ); + void setViewId( int viewId ); + void setTimeStepIndex( int timeStepIndex ); RicfCommandResponse execute() override; private: caf::PdmField m_caseId; + caf::PdmField m_viewId; caf::PdmField m_timeStepIndex; }; diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp index 6fe37816fd..223abfc03b 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp @@ -61,16 +61,19 @@ void RicSnapshotAllViewsToFileFeature::saveAllViews() // Save images in snapshot catalog relative to project directory QString snapshotFolderName = app->createAbsolutePathFromProjectRelativePath("snapshots"); - exportSnapshotOfAllViewsIntoFolder(snapshotFolderName); + exportSnapshotOfViewsIntoFolder( snapshotFolderName ); QString text = QString("Exported snapshots to folder : \n%1").arg(snapshotFolderName); RiaLogging::info(text); } //-------------------------------------------------------------------------------------------------- -/// Export all snapshots of a given case (or caseId == -1 for all cases) +/// Export snapshots of a given view (or viewId == -1 for all views) for the given case (or caseId == -1 for all cases) //-------------------------------------------------------------------------------------------------- -void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(const QString& snapshotFolderName, const QString& prefix /*= ""*/, int caseId /*= -1*/) +void RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( const QString& snapshotFolderName, + const QString& prefix /*= ""*/, + int caseId /*= -1*/, + int viewId /*= -1*/ ) { RimProject* project = RiaApplication::instance()->project(); @@ -103,7 +106,7 @@ void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(const { Rim3dView* riv = views[j]; - if (riv && riv->viewer()) + if ( riv && riv->viewer() && ( viewId == -1 || viewId == riv->id() ) ) { RiaApplication::instance()->setActiveReservoirView(riv); diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h index 705566be1f..a0f9ea1c24 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h @@ -32,7 +32,10 @@ class RicSnapshotAllViewsToFileFeature : public caf::CmdFeature public: static void saveAllViews(); - static void exportSnapshotOfAllViewsIntoFolder(const QString& snapshotFolderName, const QString& prefix = "", int caseId = -1); + static void exportSnapshotOfViewsIntoFolder( const QString& snapshotFolderName, + const QString& prefix = "", + int caseId = -1, + int viewId = -1 ); protected: // Overrides diff --git a/ApplicationCode/GrpcInterface/CMakeLists.cmake b/ApplicationCode/GrpcInterface/CMakeLists.cmake index 6271a0ad20..bbe88eca91 100644 --- a/ApplicationCode/GrpcInterface/CMakeLists.cmake +++ b/ApplicationCode/GrpcInterface/CMakeLists.cmake @@ -85,7 +85,7 @@ set(PROTO_FILES "Commands" "App" "Properties" - "Grid" + "grid" ) set(GRPC_PYTHON_SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}/Python") @@ -162,15 +162,13 @@ if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE) list(APPEND GRPC_PYTHON_SOURCES "rips/generated/RiaVersionInfo.py" "rips/__init__.py" - "rips/Case.py" - "rips/Commands.py" - "rips/Grid.py" - "rips/GridCaseGroup.py" - "rips/Project.py" - "rips/Properties.py" - "rips/Instance.py" - "rips/PdmObject.py" - "rips/View.py" + "rips/case.py" + "rips/grid.py" + "rips/gridcasegroup.py" + "rips/project.py" + "rips/instance.py" + "rips/pdmobject.py" + "rips/view.py" "rips/PythonExamples/InstanceExample.py" "rips/PythonExamples/CommandExample.py" "rips/PythonExamples/CaseGridGroup.py" @@ -191,7 +189,6 @@ if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE) "rips/PythonExamples/SoilAverageSync.py" "rips/PythonExamples/ViewExample.py" "rips/tests/test_cases.py" - "rips/tests/test_commands.py" "rips/tests/test_grids.py" "rips/tests/test_properties.py" "rips/tests/test_project.py" diff --git a/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto b/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto index 8676996ecf..7c3506bd38 100644 --- a/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto +++ b/ApplicationCode/GrpcInterface/GrpcProtos/Commands.proto @@ -53,6 +53,7 @@ message ExportSnapshotsRequest SnapshotType type = 1; string prefix = 2; int32 caseId = 3; + int32 viewId = 4; } message ExportPropertyRequest @@ -67,9 +68,9 @@ message ExportPropertyRequest message ExportPropertyInViewsRequest { - int32 caseId = 1; - repeated string viewNames = 2; - double undefinedValue = 3; + int32 caseId = 1; + repeated int32 viewIds = 2; + double undefinedValue = 3; } enum CompdatExportSplit @@ -89,7 +90,7 @@ enum CompdatExportType enum CompdatCombinationMode { INDIVIDUALLY = 0; - caCOMBINED = 1; + COMBINED = 1; } message ExportWellPathCompRequest @@ -108,7 +109,7 @@ message ExportWellPathCompRequest message ExportSimWellPathFracRequest { int32 caseId = 1; - string viewName = 2; + int32 viewId = 2; int32 timeStep = 3; repeated string simulationWellNames = 4; CompdatExportSplit fileSplit = 5; @@ -130,7 +131,7 @@ message ExportWellPathRequest message ExportVisibleCellsRequest { int32 caseId = 1; - string viewName = 2; + int32 viewId = 2; string exportKeyword = 3; int32 visibleActiveCellsValue = 4; int32 hiddenActiveCellsValue = 5; @@ -175,7 +176,8 @@ message ComputeCaseGroupStatRequest message SetTimeStepParams { int32 caseId = 1; - int32 timeStep = 2; + int32 viewId = 2; + int32 timeStep = 3; } message ScaleFractureTemplateRequest diff --git a/ApplicationCode/GrpcInterface/Python/rips/Case.py b/ApplicationCode/GrpcInterface/Python/rips/Case.py deleted file mode 100644 index 1722a7e614..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Case.py +++ /dev/null @@ -1,188 +0,0 @@ -import grpc -import os -import sys -from rips.Commands import Commands -from rips.Grid import Grid -from rips.Properties import Properties -from rips.PdmObject import PdmObject -from rips.View import View - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -import Case_pb2 -import Case_pb2_grpc -import PdmObject_pb2 - -class Case (PdmObject): - """ResInsight case class - - Operate on a ResInsight case specified by a Case Id integer. - Not meant to be constructed separately but created by one of the following - methods in Project: loadCase, case, allCases, selectedCases - - Attributes: - id (int): Case Id corresponding to case Id in ResInsight project. - name (str): Case name - groupId (int): Case Group id - """ - def __init__(self, channel, id): - self.channel = channel - self.stub = Case_pb2_grpc.CaseStub(channel) - self.id = id - info = self.stub.GetCaseInfo(Case_pb2.CaseRequest(id=self.id)) - self.name = info.name - self.group_id = info.group_id - self.type = info.type - self.properties = Properties(self) - self.request = Case_pb2.CaseRequest(id=self.id) - PdmObject.__init__(self, self.stub.GetPdmObject(self.request), self.channel) - - def grid_count(self): - """Get number of grids in the case""" - try: - return self.stub.GetGridCount(self.request).count - except grpc.RpcError as e: - if e.code() == grpc.StatusCode.NOT_FOUND: - return 0 - print("ERROR: ", e) - return 0 - - def grid_path(self): - return self.get_value("CaseFileName") - - def grid(self, index): - """Get Grid of a given index. Returns a rips Grid object - - Arguments: - index (int): The grid index - - Returns: Grid object - """ - return Grid(index, self) - - def grids(self): - """Get a list of all rips Grid objects in the case""" - grid_list = [] - for i in range(0, self.grid_count()): - grid_list.append(Grid(i, self)) - return grid_list - - def cell_count(self, porosity_model='MATRIX_MODEL'): - """Get a cell count object containing number of active cells and - total number of cells - - Arguments: - porosity_model (str): String representing an enum. - must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. - Returns: - Cell Count object with the following integer attributes: - active_cell_count: number of active cells - reservoir_cell_count: total number of reservoir cells - """ - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Case_pb2.CellInfoRequest(case_request=self.request, - porosity_model=porosity_model_enum) - return self.stub.GetCellCount(request) - - def cell_info_for_active_cells_async(self, porosity_model='MATRIX_MODEL'): - """Get Stream of cell info objects for current case - - Arguments: - porosity_model(str): String representing an enum. - must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. - - Returns: - Stream of **CellInfo** objects - - See cell_info_for_active_cells() for detalis on the **CellInfo** class. - """ - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Case_pb2.CellInfoRequest(case_request=self.request, - porosity_model=porosity_model_enum) - return self.stub.GetCellInfoForActiveCells(request) - - def cell_info_for_active_cells(self, porosity_model='MATRIX_MODEL'): - """Get list of cell info objects for current case - - Arguments: - porosity_model(str): String representing an enum. - must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. - - Returns: - List of **CellInfo** objects - - ### CellInfo class description - - Parameter | Description | Type - ------------------------- | --------------------------------------------- | ----- - grid_index | Index to grid | Integer - parent_grid_index | Index to parent grid | Integer - coarsening_box_index | Index to coarsening box | Integer - local_ijk | Cell index in IJK directions of local grid | Vec3i - parent_ijk | Cell index in IJK directions of parent grid | Vec3i - - ### Vec3i class description - - Parameter | Description | Type - ---------------- | -------------------------------------------- | ----- - i | I grid index | Integer - j | J grid index | Integer - k | K grid index | Integer - - """ - active_cell_info_chunks = self.cell_info_for_active_cells_async() - received_active_cells = [] - for active_cell_chunk in active_cell_info_chunks: - for active_cell in active_cell_chunk.data: - received_active_cells.append(active_cell) - return received_active_cells - - def time_steps(self): - """Get a list containing all time steps - - The time steps are defined by the class **TimeStepDate** : - - Type | Name - --------- | ---------- - int | year - int | month - int | day - int | hour - int | minute - int | second - - - """ - return self.stub.GetTimeSteps(self.request).dates - - def days_since_start(self): - """Get a list of decimal values representing days since the start of the simulation""" - return self.stub.GetDaysSinceStart(self.request).day_decimals - - def views(self): - """Get a list of views belonging to a case""" - pdm_objects = self.children("ReservoirViews") - view_list = [] - for pdm_object in pdm_objects: - view_list.append(View(pdm_object)) - return view_list - - def view(self, id): - """Get a particular view belonging to a case by providing view id - Arguments: - id(int): view id - - Returns: a view object - - """ - views = self.views() - for view_object in views: - if view_object.id == id: - return view_object - return None - - def create_view(self): - """Create a new view in the current case""" - view_id = Commands(self.channel).create_view(self.id) - return self.view(view_id) - diff --git a/ApplicationCode/GrpcInterface/Python/rips/Commands.py b/ApplicationCode/GrpcInterface/Python/rips/Commands.py deleted file mode 100644 index f7956ded4e..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Commands.py +++ /dev/null @@ -1,311 +0,0 @@ -import grpc -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -from Definitions_pb2 import Empty -import Commands_pb2 as Cmd -import Commands_pb2_grpc as CmdRpc -import rips.Case - -class Commands: - """Command executor which can run ResInsight Command File commands nearly verbatim. See - [ Command File Interface ]({{< ref "commandfile.md" >}}) - - The differences are: - - - Enum values have to be provided as strings. I.e. "ALL" instead of ALL. - - Booleans have to be specified as correct Python. True instead of true. - - """ - def __init__(self, channel): - self.channel = channel - self.commands = CmdRpc.CommandsStub(channel) - - def __execute(self, **command_params): - return self.commands.Execute(Cmd.CommandParams(**command_params)) - - ######################## - # Case Control Commands - ######################## - - def open_project(self, path): - """Open a project - - Arguments: - path (str): path to project file - - - """ - return self.__execute(openProject=Cmd.FilePathRequest(path=path)) - - def close_project(self): - """Close the current project (and reopen empty one)""" - return self.__execute(closeProject=Empty()) - - def set_start_dir(self, path): - """Set current start directory - - Arguments: - path (str): path to directory - - """ - return self.__execute(setStartDir=Cmd.FilePathRequest(path=path)) - - def load_case(self, path): - """Load a case - - Arguments: - path (str): path to EGRID file - - Returns: - A Case object - - """ - command_reply = self.__execute(loadCase=Cmd.FilePathRequest(path=path)) - return rips.Case(self.channel, command_reply.loadCaseResult.id) - - def replace_case(self, new_grid_file, case_id=0): - """Replace the given case with a new case loaded from file - - Arguments: - new_grid_file (str): path to EGRID file - case_id (int): case Id to replace - - """ - return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=new_grid_file, - caseId=case_id)) - - def replace_source_cases(self, grid_list_file, case_group_id=0): - """Replace all source cases within a case group - - Arguments: - grid_list_file (str): path to file containing a list of cases - case_group_id (int): id of the case group to replace - - """ - return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=grid_list_file, - caseGroupId=case_group_id)) - - def create_grid_case_group(self, case_paths): - """Create a Grid Case Group from a list of cases - - Arguments: - case_paths (list): list of file path strings - - Returns: - A case group id and name - """ - commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=case_paths)) - return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName) - - def create_statistics_case(self, case_group_id): - """Create a Statistics case in a Grid Case Group - - Arguments: - case_group_id (int): id of the case group - - Returns: - A case id for the new case - """ - commandReply = self.__execute(createStatisticsCase=Cmd.CreateStatisticsCaseRequest(caseGroupId=case_group_id)) - return commandReply.createStatisticsCaseResult.caseId - - ################## - # Export Commands - ################## - - def export_multi_case_snapshots(self, grid_list_file): - """Export snapshots for a set of cases - - Arguments: - grid_list_file (str): Path to a file containing a list of grids to export snapshot for - - """ - return self.__execute(exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(gridListFile=grid_list_file)) - - def export_snapshots(self, type = 'ALL', prefix='', case_id = -1): - """ Export snapshots of a given type - - Arguments: - type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS') - prefix (str): Exported file name prefix - case_id (int): the case Id to export for. The default of -1 will export all cases - - """ - return self.__execute(exportSnapshots=Cmd.ExportSnapshotsRequest(type=type, - prefix=prefix, - caseId=case_id)) - - def export_property(self, case_id, time_step, property, eclipse_keyword=property, undefined_value=0.0, export_file=property): - """ Export an Eclipse property - - Arguments: - case_id (int): case id - time_step (int): time step index - property (str): property to export - eclipse_keyword (str): Eclipse keyword used as text in export header. Defaults to the value of property parameter. - undefined_value (double): Value to use for undefined values. Defaults to 0.0 - export_file (str): File name for export. Defaults to the value of property parameter - """ - return self.__execute(exportProperty=Cmd.ExportPropertyRequest(caseId=case_id, - timeStep=time_step, - property=property, - eclipseKeyword=eclipse_keyword, - undefinedValue=undefined_value, - exportFile=export_file)) - - def export_property_in_views(self, case_id, view_names, undefined_value): - """ Export the current Eclipse property from the given views - - Arguments: - case_id (int): case id - view_names (list): list of views - undefined_value (double): Value to use for undefined values. Defaults to 0.0 - """ - if isinstance(view_names, str): - view_names = [view_names] - - return self.__execute(exportPropertyInViews=Cmd.ExportPropertyInViewsRequest(caseId=case_id, - viewNames=view_names, - undefinedValue=undefined_value)) - - def export_well_path_completions(self, case_id, time_step, well_path_names, file_split, - compdat_export, include_perforations, include_fishbones, - exclude_main_bore_for_fishbones, combination_mode): - if (isinstance(well_path_names, str)): - well_path_names = [well_path_names] - return self.__execute(exportWellPathCompletions=Cmd.ExportWellPathCompRequest(caseId=case_id, - timeStep=time_step, - wellPathNames=well_path_names, - fileSplit=file_split, - compdatExport=compdat_export, - includePerforations=include_perforations, - includeFishbones=include_fishbones, - excludeMainBoreForFishbones=exclude_main_bore_for_fishbones, - combinationMode=combination_mode)) - - def export_sim_well_fracture_completions(self, case_id, view_name, time_step, simulation_well_names, file_split, compdat_export): - if(isinstance(simulation_well_names, str)): - simulation_well_names = [simulation_well_names] - return self.__execute(exportSimWellFractureCompletions=Cmd.ExportSimWellPathFraqRequest(caseId=case_id, - viewName=view_name, - timeStep=time_step, - simulationWellNames=simulation_well_names, - fileSplit=file_split, - compdatExport=compdat_export)) - - def export_msw(self, case_id, well_path): - return self.__execute(exportMsw=Cmd.ExportMswRequest(caseId=case_id, - wellPath=well_path)) - - def export_well_paths(self, well_paths=[], md_step_size=5.0): - if isinstance(well_paths, str): - well_paths = [well_paths] - return self.__execute(exportWellPaths=Cmd.ExportWellPathRequest(wellPathNames=well_paths, mdStepSize=md_step_size)) - - def export_visible_cells(self, case_id, view_name, export_keyword='FLUXNUM', visible_active_cells_value=1, hidden_active_cells_value=0, inactive_cells_value=0): - return self.__execute(exportVisibleCells=Cmd.ExportVisibleCellsRequest(caseId=case_id, - viewName=view_name, - exportKeyword=export_keyword, - visibleActiveCellsValue=visible_active_cells_value, - hiddenActiveCellsValue=hidden_active_cells_value, - inactiveCellsValue=inactive_cells_value)) - def set_export_folder(self, type, path, create_folder=False): - return self.__execute(setExportFolder=Cmd.SetExportFolderRequest(type=type, - path=path, - createFolder=create_folder)) - - def run_octave_script(self, path, cases): - caseIds = [] - for case in cases: - caseIds.append(case.id) - return self.__execute(runOctaveScript=Cmd.RunOctaveScriptRequest(path=path, - caseIds=caseIds)) - - def set_main_window_size(self, width, height): - return self.__execute(setMainWindowSize=Cmd.SetMainWindowSizeParams(width=width, height=height)) - - def compute_case_group_statistics(self, case_ids = [], case_group_id = -1): - return self.__execute(computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(caseIds=case_ids, - caseGroupId=case_group_id)) - - def set_time_step(self, case_id, time_step): - return self.__execute(setTimeStep=Cmd.SetTimeStepParams(caseId=case_id, timeStep=time_step)) - - def scale_fracture_template(self, id, half_length, height, dfactor, conductivity): - return self.__execute(scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(id=id, - halfLength=half_length, - height=height, - dFactor=dfactor, - conductivity=conductivity)) - - def set_fracture_containment(self, id, top_layer, base_layer): - return self.__execute(setFractureContainment=Cmd.SetFracContainmentRequest(id=id, - topLayer=top_layer, - baseLayer=base_layer)) - - def create_multiple_fractures(self, case_id, template_id, well_path_names, min_dist_from_well_td, - max_fractures_per_well, top_layer, base_layer, spacing, action): - if isinstance(well_path_names, str): - well_path_names = [well_path_names] - return self.__execute(createMultipleFractures=Cmd.MultipleFracAction(caseId=case_id, - templateId=template_id, - wellPathNames=well_path_names, - minDistFromWellTd=min_dist_from_well_td, - maxFracturesPerWell=max_fractures_per_well, - topLayer=top_layer, - baseLayer=base_layer, - spacing=spacing, - action=action)) - - def create_lgr_for_completion(self, case_id, time_step, well_path_names, refinement_i, refinement_j, refinement_k, split_type): - if isinstance(well_path_names, str): - well_path_names = [well_path_names] - return self.__execute(createLgrForCompletions=Cmd.CreateLgrForCompRequest(caseId=case_id, - timeStep=time_step, - wellPathNames=well_path_names, - refinementI=refinement_i, - refinementJ=refinement_j, - refinementK=refinement_k, - splitType=split_type)) - - def create_saturation_pressure_plots(self, case_ids): - if isinstance(case_ids, int): - case_ids = [case_ids] - return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=case_ids)) - - def export_flow_characteristics(self, case_id, time_steps, injectors, producers, file_name, minimum_communication=0.0, aquifer_cell_threshold=0.1): - """ Export Flow Characteristics data to text file in CSV format - - Parameter | Description | Type - ------------------------- | --------------------------------------------- | ----- - case_id | ID of case | Integer - time_steps | Time step indices | List of Integer - injectors | Injector names | List of Strings - producers | Producer names | List of Strings - file_name | Export file name | Integer - minimum_communication | Minimum Communication, defaults to 0.0 | Integer - aquifer_cell_threshold | Aquifer Cell Threshold, defaults to 0.1 | Integer - - """ - if isinstance(time_steps, int): - time_steps = [time_steps] - if isinstance(injectors, str): - injectors = [injectors] - if isinstance(producers, str): - producers = [producers] - return self.__execute(exportFlowCharacteristics=Cmd.ExportFlowInfoRequest(caseId=case_id, - timeSteps=time_steps, - injectors=injectors, - producers=producers, - fileName=file_name, - minimumCommunication = minimum_communication, - aquiferCellThreshold = aquifer_cell_threshold)) - - def create_view(self, case_id): - return self.__execute(createView=Cmd.CreateViewRequest(caseId=case_id)).createViewResult.viewId - - def clone_view(self, view_id): - return self.__execute(cloneView=Cmd.CloneViewRequest(viewId=view_id)).createViewResult.viewId \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/Grid.py b/ApplicationCode/GrpcInterface/Python/rips/Grid.py deleted file mode 100644 index 3a8ab8d77f..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Grid.py +++ /dev/null @@ -1,27 +0,0 @@ -import grpc -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -import Grid_pb2 -import Grid_pb2_grpc - -class Grid: - """Grid Information. Not meant to be constructed separately - - Create Grid objects using mathods on Case: Grid() and Grids() - """ - def __init__(self, index, case): - self.case = case - self.index = index - self.stub = Grid_pb2_grpc.GridStub(self.case.channel) - - def dimensions(self): - """The dimensions in i, j, k direction - - Returns: - Vec3i: class with integer attributes i, j, k representing the extent in all three dimensions. - """ - return self.stub.GetDimensions(Grid_pb2.GridRequest(case_request = self.case.request, grid_index = self.index)).dimensions - diff --git a/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py b/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py deleted file mode 100644 index 499e53f0e7..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/GridCaseGroup.py +++ /dev/null @@ -1,48 +0,0 @@ -import grpc -import os -import sys -from rips.PdmObject import PdmObject -from rips.View import View - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -import PdmObject_pb2 - -class GridCaseGroup (PdmObject): - """ResInsight Grid Case Group class - - Operate on a ResInsight case group specified by a Case Group Id integer. - - Attributes: - group_id (int): Grid Case Group Id corresponding to case group Id in ResInsight project. - """ - def __init__(self, pdm_object): - self.group_id = pdm_object.get_value("GroupId") - PdmObject.__init__(self, pdm_object.pb2Object, pdm_object.channel) - - def statistics_cases(self): - """Get a list of all statistics cases in the Grid Case Group""" - stat_case_collection = self.children("StatisticsCaseCollection")[0] - return stat_case_collection.children("Reservoirs") - - def views(self): - """Get a list of views belonging to a grid case group""" - pdm_objects = self.descendants("ReservoirView") - view_list = [] - for pdm_object in pdm_objects: - view_list.append(View(pdm_object)) - return view_list - - def view(self, id): - """Get a particular view belonging to a case group by providing view id - Arguments: - id(int): view id - - Returns: a view object - - """ - views = self.views() - for view_object in views: - if view_object.id == id: - return view_object - return None diff --git a/ApplicationCode/GrpcInterface/Python/rips/Instance.py b/ApplicationCode/GrpcInterface/Python/rips/Instance.py deleted file mode 100644 index c1902e7fae..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Instance.py +++ /dev/null @@ -1,196 +0,0 @@ -import grpc -import os -import sys -import socket -import logging -import time - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) -import App_pb2 -import App_pb2_grpc -from Definitions_pb2 import Empty - -import RiaVersionInfo - -from rips.Commands import Commands -from rips.Project import Project - -class Instance: - """The ResInsight Instance class. Use to launch or find existing ResInsight instances - - Attributes: - launched (bool): Tells us whether the application was launched as a new process. - If the application was launched we may need to close it when exiting the script. - commands (Commands): Command executor. Set when creating an instance. - project (Project): Current project in ResInsight. - Set when creating an instance and updated when opening/closing projects. - """ - - @staticmethod - def __is_port_in_use(port): - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.settimeout(0.2) - return s.connect_ex(('localhost', port)) == 0 - - @staticmethod - def launch(resinsight_executable = '', console = False, launch_port = -1, command_line_parameters=[]): - """ Launch a new Instance of ResInsight. This requires the environment variable - RESINSIGHT_EXECUTABLE to be set or the parameter resinsight_executable to be provided. - The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number. - - Args: - resinsight_executable (str): Path to a valid ResInsight executable. If set - will take precedence over what is provided in the RESINSIGHT_EXECUTABLE - environment variable. - console (bool): If True, launch as console application, without GUI. - launch_port(int): If -1 will use the default port of 50051 or look for RESINSIGHT_GRPC_PORT - if anything else, ResInsight will try to launch with this port - command_line_parameters(list): Additional command line parameters as string entries in the list. - Returns: - Instance: an instance object if it worked. None if not. - """ - - port = 50051 - port_env = os.environ.get('RESINSIGHT_GRPC_PORT') - if port_env: - port = int(port_env) - if launch_port is not -1: - port = launch_port - - if not resinsight_executable: - resinsight_executable = os.environ.get('RESINSIGHT_EXECUTABLE') - if not resinsight_executable: - print('ERROR: Could not launch ResInsight because the environment variable' - ' RESINSIGHT_EXECUTABLE is not set') - return None - - while Instance.__is_port_in_use(port): - port += 1 - - print('Port ' + str(port)) - print('Trying to launch', resinsight_executable) - - if isinstance(command_line_parameters, str): - command_line_parameters = [str] - - parameters = ["ResInsight", "--server", str(port)] + command_line_parameters - if console: - print("Launching as console app") - parameters.append("--console") - - # Stringify all parameters - for i in range(0, len(parameters)): - parameters[i] = str(parameters[i]) - - pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters) - if pid: - instance = Instance(port=port, launched=True) - return instance - return None - - @staticmethod - def find(start_port = 50051, end_port = 50071): - """ Search for an existing Instance of ResInsight by testing ports. - - By default we search from port 50051 to 50071 or if the environment - variable RESINSIGHT_GRPC_PORT is set we search - RESINSIGHT_GRPC_PORT to RESINSIGHT_GRPC_PORT+20 - - Args: - start_port (int): start searching from this port - end_port (int): search up to but not including this port - """ - port_env = os.environ.get('RESINSIGHT_GRPC_PORT') - if port_env: - start_port = int(port_env) - end_port = start_port + 20 - - for try_port in range(start_port, end_port): - if Instance.__is_port_in_use(try_port): - return Instance(port=try_port) - - print('Error: Could not find any ResInsight instances responding between ports ' + str(start_port) + ' and ' + str(end_port)) - return None - - def __check_version(self): - try: - major_version_ok = self.major_version() == int(RiaVersionInfo.RESINSIGHT_MAJOR_VERSION) - minor_version_ok = self.minor_version() == int(RiaVersionInfo.RESINSIGHT_MINOR_VERSION) - return True, major_version_ok and minor_version_ok - except: - return False, False - - def __init__(self, port = 50051, launched = False): - """ Attempts to connect to ResInsight at aa specific port on localhost - - Args: - port(int): port number - """ - logging.basicConfig() - location = "localhost:" + str(port) - - self.channel = grpc.insecure_channel(location, options=[('grpc.enable_http_proxy', False)]) - self.launched = launched - - # Main version check package - self.app = self.app = App_pb2_grpc.AppStub(self.channel) - - connection_ok = False - version_ok = False - - if self.launched: - for i in range(0, 10): - connection_ok, version_ok = self.__check_version() - if connection_ok: - break - time.sleep(1.0) - else: - connection_ok, version_ok = self.__check_version() - - if not connection_ok: - if self.launched: - raise Exception('Error: Could not connect to resinsight at ', location, ' after trying 10 times with 1 second apart') - else: - raise Exception('Error: Could not connect to resinsight at ', location) - exit(1) - if not version_ok: - raise Exception('Error: Wrong Version of ResInsight at ', location) - - # Service packages - self.commands = Commands(self.channel) - self.project = Project(self.channel) - - path = os.getcwd() - self.commands.set_start_dir(path=path) - - def __version_message(self): - return self.app.GetVersion(Empty()) - - def major_version(self): - """Get an integer with the major version number""" - return self.__version_message().major_version - - def minor_version(self): - """Get an integer with the minor version number""" - return self.__version_message().minor_version - - def patch_version(self): - """Get an integer with the patch version number""" - return self.__version_message().patch_version - - def version_string(self): - """Get a full version string, i.e. 2019.04.01""" - return str(self.major_version()) + "." + str(self.minor_version()) + "." + str(self.patch_version()) - - def exit(self): - """Tell ResInsight instance to quit""" - print("Telling ResInsight to Exit") - return self.app.Exit(Empty()) - - def is_console(self): - """Returns true if the connected ResInsight instance is a console app""" - return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('CONSOLE_APPLICATION') - - def is_gui(self): - """Returns true if the connected ResInsight instance is a GUI app""" - return self.app.GetRuntimeInfo(Empty()).app_type == App_pb2.ApplicationTypeEnum.Value('GUI_APPLICATION') diff --git a/ApplicationCode/GrpcInterface/Python/rips/Project.py b/ApplicationCode/GrpcInterface/Python/rips/Project.py deleted file mode 100644 index 3cc06935ad..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Project.py +++ /dev/null @@ -1,149 +0,0 @@ -import grpc -import os -import sys - -from rips.Case import Case -from rips.Commands import Commands -from rips.GridCaseGroup import GridCaseGroup -from rips.PdmObject import PdmObject -from rips.View import View - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -from Definitions_pb2 import Empty -import Project_pb2 -import Project_pb2_grpc - -class Project (PdmObject): - """ResInsight project. Not intended to be created separately. - - Automatically created and assigned to Instance. - """ - def __init__(self, channel): - self.channel = channel - self.project = Project_pb2_grpc.ProjectStub(channel) - PdmObject.__init__(self, self.project.GetPdmObject(Empty()), self.channel) - - def open(self, path): - """Open a new project from the given path - - Arguments: - path(str): path to project file - - """ - Commands(self.channel).open_project(path) - return self - - def close(self): - """Close the current project (and open new blank project)""" - Commands(self.channel).close_project() - - def selected_cases(self): - """Get a list of all cases selected in the project tree - - Returns: - A list of rips Case objects - """ - case_infos = self.project.GetSelectedCases(Empty()) - cases = [] - for case_info in case_infos.data: - cases.append(Case(self.channel, case_info.id)) - return cases - - def cases(self): - """Get a list of all cases in the project - - Returns: - A list of rips Case objects - """ - try: - case_infos = self.project.GetAllCases(Empty()) - - cases = [] - for case_info in case_infos.data: - cases.append(Case(self.channel, case_info.id)) - return cases - except grpc.RpcError as e: - if e.code() == grpc.StatusCode.NOT_FOUND: - return [] - else: - print("ERROR: ", e) - return [] - - def case(self, id): - """Get a specific case from the provided case Id - - Arguments: - id(int): case id - Returns: - A rips Case object - """ - try: - case = Case(self.channel, id) - return case - except grpc.RpcError as e: - return None - - def load_case(self, path): - """Load a new case from the given file path - - Arguments: - path(str): file path to case - Returns: - A rips Case object - """ - return Commands(self.channel).load_case(path) - - def views(self): - """Get a list of views belonging to a project""" - pdm_objects = self.descendants("ReservoirView") - view_list = [] - for pdm_object in pdm_objects: - view_list.append(View(pdm_object)) - return view_list - - def view(self, id): - """Get a particular view belonging to a case by providing view id - Arguments: - id(int): view id - - Returns: a view object - - """ - views = self.views() - for view_object in views: - if view_object.id == id: - return view_object - return None - - def grid_case_groups(self): - """Get a list of all grid case groups in the project""" - case_groups = self.descendants("RimIdenticalGridCaseGroup") - - case_group_list = [] - for pdm_group in case_groups: - case_group_list.append(GridCaseGroup(pdm_group)) - return case_group_list - - def grid_case_group(self, group_id): - """Get a particular grid case group belonging to a project - Arguments: - groupId(int): group id - - Returns: a grid case group object - """ - case_groups = self.grid_case_groups() - for case_group in case_groups: - if case_group.groupId == group_id: - return case_group - return None - - def create_grid_case_group(self, case_paths): - """Create a new grid case group from the provided case paths - Arguments: - casePaths(list): a list of paths to the cases to be loaded and included in the group - Returns: - A new grid case group object - """ - group_id, group_name = Commands(self.channel).create_grid_case_group(case_paths) - return self.grid_case_group(group_id) \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/Properties.py b/ApplicationCode/GrpcInterface/Python/rips/Properties.py deleted file mode 100644 index ae448ada8b..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/Properties.py +++ /dev/null @@ -1,239 +0,0 @@ -import grpc -import os -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -import Properties_pb2 -import Properties_pb2_grpc -import Case_pb2 -import Case_pb2_grpc -from Definitions_pb2 import ClientToServerStreamReply - -class Properties: - """ Class for streaming properties to and from ResInsight - - Attributes: - chunkSize(int): The size of each chunk during value streaming. - A good chunk size is 64KiB = 65536B. - Meaning the ideal number of doubles would be 8192. - However we need overhead space, so the default is 8160. - This leaves 256B for overhead. - """ - def __init__(self, case): - """ - Arguments: - case(Case): A rips case to handle properties for - """ - self.case = case - self._properties_stub = Properties_pb2_grpc.PropertiesStub(self.case.channel) - self.chunk_size = 8160 - - - def __generate_property_input_iterator(self, values_iterator, parameters): - chunk = Properties_pb2.PropertyInputChunk() - chunk.params.CopyFrom(parameters) - yield chunk - - for values in values_iterator: - valmsg = Properties_pb2.PropertyChunk(values = values) - chunk.values.CopyFrom(valmsg) - yield chunk - - def __generate_property_input_chunks(self, array, parameters): - - index = -1 - while index < len(array): - chunk = Properties_pb2.PropertyInputChunk() - if index is -1: - chunk.params.CopyFrom(parameters) - index += 1 - else: - actual_chunk_size = min(len(array) - index + 1, self.chunk_size) - chunk.values.CopyFrom(Properties_pb2.PropertyChunk(values = array[index:index+actual_chunk_size])) - index += actual_chunk_size - - yield chunk - # Final empty message to signal completion - chunk = Properties_pb2.PropertyInputChunk() - yield chunk - - def available(self, property_type, porosity_model = 'MATRIX_MODEL'): - """Get a list of available properties - - Arguments: - property_type (str): string corresponding to property_type enum. Can be one of the following: - - DYNAMIC_NATIVE - - STATIC_NATIVE - - SOURSIMRL - - GENERATED - - INPUT_PROPERTY - - FORMATION_NAMES - - FLOW_DIAGNOSTICS - - INJECTION_FLOODING - - porosity_model(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'. - """ - - property_type_enum = Properties_pb2.PropertyType.Value(property_type) - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Properties_pb2.AvailablePropertiesRequest (case_request = Case_pb2.CaseRequest(id=self.case.id), - property_type = property_type_enum, - porosity_model = porosity_model_enum) - return self._properties_stub.GetAvailableProperties(request).property_names - - def active_cell_property_async(self, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): - """Get a cell property for all active cells. Async, so returns an iterator - - Arguments: - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - porosity_model(str): string enum. See available() - - Returns: - An iterator to a chunk object containing an array of double values - You first loop through the chunks and then the values within the chunk to get all values. - """ - property_type_enum = Properties_pb2.PropertyType.Value(property_type) - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Properties_pb2.PropertyRequest(case_request = Case_pb2.CaseRequest(id=self.case.id), - property_type = property_type_enum, - property_name = property_name, - time_step = time_step, - porosity_model = porosity_model_enum) - for chunk in self._properties_stub.GetActiveCellProperty(request): - yield chunk - - def active_cell_property(self, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): - """Get a cell property for all active cells. Sync, so returns a list - - Arguments: - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - porosity_model(str): string enum. See available() - - Returns: - A list containing double values - You first loop through the chunks and then the values within the chunk to get all values. - """ - all_values = [] - generator = self.active_cell_property_async(property_type, property_name, time_step, porosity_model) - for chunk in generator: - for value in chunk.values: - all_values.append(value) - return all_values - - def grid_property_async(self, property_type, property_name, time_step, gridIndex = 0, porosity_model = 'MATRIX_MODEL'): - """Get a cell property for all grid cells. Async, so returns an iterator - - Arguments: - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - gridIndex(int): index to the grid we're getting values for - porosity_model(str): string enum. See available() - - Returns: - An iterator to a chunk object containing an array of double values - You first loop through the chunks and then the values within the chunk to get all values. - """ - property_type_enum = Properties_pb2.PropertyType.Value(property_type) - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = property_type_enum, - property_name = property_name, - time_step = time_step, - grid_index = gridIndex, - porosity_model = porosity_model_enum) - for chunk in self._properties_stub.GetGridProperty(request): - yield chunk - - def grid_property(self, property_type, property_name, time_step, grid_index = 0, porosity_model = 'MATRIX_MODEL'): - """Get a cell property for all grid cells. Synchronous, so returns a list - - Arguments: - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - grid_index(int): index to the grid we're getting values for - porosity_model(str): string enum. See available() - - Returns: - A list of double values - """ - all_values = [] - generator = self.grid_property_async(property_type, property_name, time_step, grid_index, porosity_model) - for chunk in generator: - for value in chunk.values: - all_values.append(value) - return all_values - - def set_active_cell_property_async(self, values_iterator, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): - """Set a cell property for all active cells. Async, and so takes an iterator to the input values - - Arguments: - values_iterator(iterator): an iterator to the properties to be set - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - porosity_model(str): string enum. See available() - """ - property_type_enum = Properties_pb2.PropertyType.Value(property_type) - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = property_type_enum, - property_name = property_name, - time_step = time_step, - porosity_model = porosity_model_enum) - - request_iterator = self.__generate_property_input_iterator(values_iterator, request) - self._properties_stub.SetActiveCellProperty(request_iterator) - - def set_active_cell_property(self, values, property_type, property_name, time_step, porosity_model = 'MATRIX_MODEL'): - """Set a cell property for all active cells. - - Arguments: - values(list): a list of double precision floating point numbers - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - porosity_model(str): string enum. See available() - """ - property_type_enum = Properties_pb2.PropertyType.Value(property_type) - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = property_type_enum, - property_name = property_name, - time_step = time_step, - porosity_model = porosity_model_enum) - request_iterator = self.__generate_property_input_chunks(values, request) - reply = self._properties_stub.SetActiveCellProperty(request_iterator) - if reply.accepted_value_count < len(values): - raise IndexError - - def set_grid_property(self, values, property_type, property_name, time_step, grid_index = 0, porosity_model = 'MATRIX_MODEL'): - """Set a cell property for all grid cells. - - Arguments: - values(list): a list of double precision floating point numbers - property_type(str): string enum. See available() - property_name(str): name of an Eclipse property - time_step(int): the time step for which to get the property for - grid_index(int): index to the grid we're setting values for - porosity_model(str): string enum. See available() - """ - property_type_enum = Properties_pb2.PropertyType.Value(property_type) - porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) - request = Properties_pb2.PropertyRequest(case_request = self.case.request, - property_type = property_type_enum, - property_name = property_name, - time_step = time_step, - grid_index = grid_index, - porosity_model = porosity_model_enum) - request_iterator = self.__generate_property_input_chunks(values, request) - reply = self._properties_stub.SetGridProperty(request_iterator) - if reply.accepted_value_count < len(values): - raise IndexError - \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py index 6285e823eb..1e136c8916 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseGridGroup.py @@ -6,8 +6,8 @@ case_paths = [] case_paths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") case_paths.append("C:/Users/lindk/source/repos/ResInsight/TestModels/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") -for casePath in case_paths: - assert os.path.exists(casePath), "You need to set valid case paths for this script to work" +for case_path in case_paths: + assert os.path.exists(case_path), "You need to set valid case paths for this script to work" case_group = resinsight.project.create_grid_case_group(case_paths=case_paths) @@ -20,7 +20,7 @@ # stat_case.update() # case_ids.append(stat_case.get_value("CaseId")) -resinsight.commands.compute_case_group_statistics(case_group_id=case_group.group_id) +case_group.compute_statistics() view = case_group.views()[0] cell_result = view.set_cell_result() diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py index 6a5ce6d880..7c839a8d14 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CaseInfoStreamingExample.py @@ -9,7 +9,7 @@ resinsight = rips.Instance.find() # Get the case with id == 0. This will fail if your project doesn't have a case with id == 0 -case = resinsight.project.case(id = 0) +case = resinsight.project.case(id=0) # Get the cell count object cell_counts = case.cell_count() diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py index 6835ac7442..28e3839e30 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/CommandExample.py @@ -1,7 +1,5 @@ ############################################################################### -# This example will run a few ResInsight command file commands -# .. which are exposed in the Python interface. -# Including setting time step, window size and export snapshots and properties +# This example will show setting time step, window size and export snapshots and properties ############################################################################### import os import tempfile @@ -10,9 +8,24 @@ # Load instance resinsight = rips.Instance.find() -# Run a couple of commands -resinsight.commands.set_time_step(case_id=0, time_step=3) -resinsight.commands.set_main_window_size(width=800, height=500) +# Set window size +resinsight.set_main_window_size(width=800, height=500) + +# Retrieve first case +case = resinsight.project.cases()[0] + +# Get a view +view1 = case.view(view_id=0) + +# Clone the view +view2 = view1.clone() + +# Set the time step for view1 only +view1.set_time_step(time_step=2) + +# Set cell result to SOIL +view1.apply_cell_result(result_type='DYNAMIC_NATIVE', result_variable='SOIL') + # Create a temporary directory which will disappear at the end of this script # If you want to keep the files, provide a good path name instead of tmpdirname @@ -20,23 +33,23 @@ print("Temporary folder: ", tmpdirname) # Set export folder for snapshots and properties - resinsight.commands.set_export_folder(type='SNAPSHOTS', path=tmpdirname) - resinsight.commands.set_export_folder(type='PROPERTIES', path=tmpdirname) - - # Export snapshots - resinsight.commands.export_snapshots() - - # Print contents of temporary folder - print(os.listdir(tmpdirname)) + resinsight.set_export_folder(export_type='SNAPSHOTS', path=tmpdirname) + resinsight.set_export_folder(export_type='PROPERTIES', path=tmpdirname) + # Export all snapshots + resinsight.project.export_snapshots() + assert(len(os.listdir(tmpdirname)) > 0) - case = resinsight.project.case(id=0) # Export properties in the view - resinsight.commands.export_property_in_views(0, "3D View", 0) - + view1.export_property() + # Check that the exported file exists - expected_file_name = case.name + "-" + str("3D_View") + "-" + "T3" + "-SOIL" + expected_file_name = case.name + "-" + str("3D_View") + "-" + "T2" + "-SOIL" full_path = tmpdirname + "/" + expected_file_name + + # Print contents of temporary folder + print(os.listdir(tmpdirname)) + assert(os.path.exists(full_path)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py index d3605519f8..84866dccab 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ErrorHandling.py @@ -16,14 +16,14 @@ except grpc.RpcError as e: print("Expected Server Exception Received: ", e) -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) if case is not None: - results = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0) + results = case.active_cell_property('STATIC_NATIVE', 'PORO', 0) active_cell_count = len(results) # Send the results back to ResInsight inside try / except construct try: - case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) + case.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) print("Everything went well as expected") except: # Match any exception, but it should not happen print("Ooops!") @@ -33,7 +33,7 @@ # This time we should get a grpc.RpcError exception, which is a server side error. try: - case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) + case.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) print("Everything went well??") except grpc.RpcError as e: print("Expected Server Exception Received: ", e) @@ -43,10 +43,10 @@ # With a chunk size exactly matching the active cell count the server will not # be able to see any error as it will successfully close the stream after receiving # the correct number of values, even if the python client has more chunks to send - case.properties.chunk_size = active_cell_count + case.chunk_size = active_cell_count try: - case.properties.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) + case.set_active_cell_property(results, 'GENERATED', 'POROAPPENDED', 0) print("Everything went well??") except grpc.RpcError as e: print("Got unexpected server exception", e, "This should not happen now") diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py index 380cfcff12..c6e715f5f2 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/ExportSnapshots.py @@ -10,13 +10,15 @@ cases = resinsight.project.cases() # Set main window size -resinsight.commands.set_main_window_size(width=800, height=500) +resinsight.set_main_window_size(width=800, height=500) n = 5 # every n-th time_step for snapshot property_list = ['SOIL', 'PRESSURE'] # list of parameter for snapshot print ("Looping through cases") for case in cases: + print("Case name: ", case.name) + print("Case id: ", case.case_id) # Get grid path and its folder name case_path = case.grid_path() folder_name = os.path.dirname(case_path) @@ -28,16 +30,14 @@ os.mkdir(dirname) print ("Exporting to folder: " + dirname) - resinsight.commands.set_export_folder(type='SNAPSHOTS', path=dirname) + resinsight.set_export_folder(export_type='SNAPSHOTS', path=dirname) time_steps = case.time_steps() - tss_snapshot = range(0, len(time_steps), n) - print(case.name, case.id, 'Number of time_steps: ' + str(len(time_steps))) - print('Number of time_steps for snapshoting: ' + str(len(tss_snapshot))) + print('Number of time_steps: ' + str(len(time_steps))) view = case.views()[0] for property in property_list: view.apply_cell_result(result_type='DYNAMIC_NATIVE', result_variable=property) - for ts_snapshot in tss_snapshot: - resinsight.commands.set_time_step(case_id = case.id, time_step = ts_snapshot) - resinsight.commands.export_snapshots(type='VIEWS', case_id=case.id) # ‘ALL’, ‘VIEWS’ or ‘PLOTS’ default is 'ALL' + for time_step in range(0, len(time_steps), 10): + view.set_time_step(time_step = time_step) + view.export_snapshot() diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py index ca2390d92c..8b1f43dcef 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestAsync.py @@ -19,17 +19,17 @@ def create_result(poro_chunks, permx_chunks): resinsight = rips.Instance.find() start = time.time() -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) # Get a generator for the poro results. The generator will provide a chunk each time it is iterated -poro_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORO', 0) +poro_chunks = case.active_cell_property_async('STATIC_NATIVE', 'PORO', 0) # Get a generator for the permx results. The generator will provide a chunk each time it is iterated -permx_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0) +permx_chunks = case.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0) # Send back the result with the result provided by a generator object. # Iterating the result generator will cause the script to read from the poro and permx generators # And return the result of each iteration -case.properties.set_active_cell_property_async(create_result(poro_chunks, permx_chunks), +case.set_active_cell_property_async(create_result(poro_chunks, permx_chunks), 'GENERATED', 'POROPERMXAS', 0) end = time.time() diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py index b38de90a41..a295824fd8 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/InputPropTestSync.py @@ -9,12 +9,12 @@ resinsight = rips.Instance.find() start = time.time() -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) # Read poro result into list -poro_results = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0) +poro_results = case.active_cell_property('STATIC_NATIVE', 'PORO', 0) # Read permx result into list -permx_results = case.properties.active_cell_property('STATIC_NATIVE', 'PERMX', 0) +permx_results = case.active_cell_property('STATIC_NATIVE', 'PERMX', 0) # Generate output result results = [] @@ -23,7 +23,7 @@ try: # Send back output result - case.properties.set_active_cell_property(results, 'GENERATED', 'POROPERMXSY', 0) + case.set_active_cell_property(results, 'GENERATED', 'POROPERMXSY', 0) except grpc.RpcError as e: print("Exception Received: ", e) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py index be6431e2c1..1f83cee761 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SelectedCases.py @@ -14,7 +14,7 @@ print ("Got " + str(len(cases)) + " cases: ") for case in cases: print(case.name) - for property in case.properties.available('DYNAMIC_NATIVE'): + for property in case.available_properties('DYNAMIC_NATIVE'): print(property) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py index f527d6d3db..1c216bed5a 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetCellResult.py @@ -5,5 +5,5 @@ resinsight = rips.Instance.find() -view = resinsight.project.view(0) -view.apply_cell_result(resultType='STATIC_NATIVE', resultVariable='DX') +view = resinsight.project.view(view_id=0) +view.apply_cell_result(result_type='STATIC_NATIVE', result_variable='DX') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py index 1fdbcc91e5..521548eccc 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetFlowDiagnosticsResult.py @@ -7,7 +7,7 @@ # Connect to ResInsight instance resinsight = rips.Instance.find() -view = resinsight.project.view(0) +view = resinsight.project.view(view_id=0) #view.apply_flow_diagnostics_cell_result(result_variable='Fraction', # selection_mode='FLOW_TR_INJ_AND_PROD') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py index 837ccf0833..12f6d29449 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SetGridProperties.py @@ -5,7 +5,7 @@ resinsight = rips.Instance.find() -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) total_cell_count = case.cell_count().reservoir_cell_count values = [] @@ -13,5 +13,5 @@ values.append(i % 2 * 0.75); print("Applying values to full grid") -case.properties.set_grid_property(values, 'DYNAMIC_NATIVE', 'SOIL', 0) +case.set_grid_property(values, 'DYNAMIC_NATIVE', 'SOIL', 0) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py index 9aa25c50d3..e8c5f064c9 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageAsync.py @@ -11,7 +11,7 @@ start = time.time() # Get the case with case id 0 -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) # Get a list of all time steps timeSteps = case.time_steps() @@ -20,7 +20,7 @@ for i in range(0, len(timeSteps)): # Get the results from time step i asynchronously # It actually returns a generator object almost immediately - result_chunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i) + result_chunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i) mysum = 0.0 count = 0 # Loop through and append the average. each time we loop resultChunks diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py index ca82dd4218..92b763c8be 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilAverageSync.py @@ -8,10 +8,9 @@ resinsight = rips.Instance.find() start = time.time() -case = resinsight.project.case(id=0) # Get the case with case id 0 -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) # Get a list of all time steps time_steps = case.time_steps() @@ -19,7 +18,7 @@ averages = [] for i in range(0, len(time_steps)): # Get a list of all the results for time step i - results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) + results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) mysum = sum(results) averages.append(mysum/len(results)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py index fbc6369d9a..531a8c1b10 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvAsync.py @@ -18,11 +18,11 @@ def create_result(soil_chunks, porv_chunks): resinsight = rips.Instance.find() start = time.time() -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) timeStepInfo = case.time_steps() # Get a generator for the porv results. The generator will provide a chunk each time it is iterated -porv_chunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORV', 0) +porv_chunks = case.active_cell_property_async('STATIC_NATIVE', 'PORV', 0) # Read the static result into an array, so we don't have to transfer it for each iteration # Note we use the async method even if we synchronise here, because we need the values chunked @@ -33,11 +33,11 @@ def create_result(soil_chunks, porv_chunks): for i in range (0, len(timeStepInfo)): # Get a generator object for the SOIL property for time step i - soil_chunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i) + soil_chunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', i) # Create the generator object for the SOIL * PORV derived result result_generator = create_result(soil_chunks, iter(porv_array)) # Send back the result asynchronously with a generator object - case.properties.set_active_cell_property_async(result_generator, 'GENERATED', 'SOILPORVAsync', i) + case.set_active_cell_property_async(result_generator, 'GENERATED', 'SOILPORVAsync', i) end = time.time() print("Time elapsed: ", end - start) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py index 459ca922b1..13a51f0d97 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/SoilPorvSync.py @@ -7,15 +7,15 @@ resinsight = rips.Instance.find() start = time.time() -case = resinsight.project.case(id=0) +case = resinsight.project.case(case_id=0) # Read the full porv result -porv_results = case.properties.active_cell_property('STATIC_NATIVE', 'PORV', 0) +porv_results = case.active_cell_property('STATIC_NATIVE', 'PORV', 0) time_step_info = case.time_steps() for i in range (0, len(time_step_info)): # Read the full SOIl result for time step i - soil_results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) + soil_results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', i) # Generate the result by looping through both lists in order results = [] @@ -23,7 +23,7 @@ results.append(soil * porv) # Send back result - case.properties.set_active_cell_property(results, 'GENERATED', 'SOILPORVSync', i) + case.set_active_cell_property(results, 'GENERATED', 'SOILPORVSync', i) end = time.time() print("Time elapsed: ", end - start) diff --git a/ApplicationCode/GrpcInterface/Python/rips/__init__.py b/ApplicationCode/GrpcInterface/Python/rips/__init__.py index 1988c72ad2..f004c2a2a3 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/__init__.py +++ b/ApplicationCode/GrpcInterface/Python/rips/__init__.py @@ -1,9 +1,12 @@ name = "rips" -from rips.Case import Case -from rips.Grid import Grid -from rips.Properties import Properties -from rips.Instance import Instance -from rips.Commands import Commands -from rips.PdmObject import PdmObject -from rips.View import View -from rips.Project import Project \ No newline at end of file + +import os +import sys +sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) + +from rips.case import Case +from rips.grid import Grid +from rips.instance import Instance +from rips.pdmobject import PdmObject +from rips.view import View +from rips.project import Project \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/case.py b/ApplicationCode/GrpcInterface/Python/rips/case.py new file mode 100644 index 0000000000..263bfda163 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/case.py @@ -0,0 +1,719 @@ +# pylint: disable=no-member +# pylint: disable=too-many-arguments +# pylint: disable=too-many-public-methods +# pylint: disable=no-self-use + +""" +Module containing the Case class +""" + +import grpc + +import rips.generated.Case_pb2 as Case_pb2 +import rips.generated.Case_pb2_grpc as Case_pb2_grpc +import rips.generated.Commands_pb2 as Cmd +import rips.generated.Properties_pb2 as Properties_pb2 +import rips.generated.Properties_pb2_grpc as Properties_pb2_grpc + +from rips.grid import Grid +from rips.pdmobject import PdmObject +from rips.view import View + +class Case(PdmObject): + """ResInsight case class + + Operate on a ResInsight case specified by a Case Id integer. + Not meant to be constructed separately but created by one of the following + methods in Project: loadCase, case, allCases, selectedCasesq + + Attributes: + id (int): Case Id corresponding to case Id in ResInsight project. + name (str): Case name + group_id (int): Case Group id + chunkSize(int): The size of each chunk during value streaming. + A good chunk size is 64KiB = 65536B. + Meaning the ideal number of doubles would be 8192. + However we need overhead space, so the default is 8160. + This leaves 256B for overhead. + """ + def __init__(self, channel, case_id): + # Private properties + self.__channel = channel + self.__case_stub = Case_pb2_grpc.CaseStub(channel) + self.__request = Case_pb2.CaseRequest(id=case_id) + + info = self.__case_stub.GetCaseInfo(self.__request) + self.__properties_stub = Properties_pb2_grpc.PropertiesStub( + self.__channel) + PdmObject.__init__(self, self.__case_stub.GetPdmObject(self.__request), + self.__channel) + + # Public properties + self.case_id = case_id + self.name = info.name + self.chunk_size = 8160 + + def __grid_count(self): + """Get number of grids in the case""" + try: + return self.__case_stub.GetGridCount(self.__request).count + except grpc.RpcError as exception: + if exception.code() == grpc.StatusCode.NOT_FOUND: + return 0 + print("ERROR: ", exception) + return 0 + + def __generate_property_input_iterator(self, values_iterator, parameters): + chunk = Properties_pb2.PropertyInputChunk() + chunk.params.CopyFrom(parameters) + yield chunk + + for values in values_iterator: + valmsg = Properties_pb2.PropertyChunk(values=values) + chunk.values.CopyFrom(valmsg) + yield chunk + + def __generate_property_input_chunks(self, array, parameters): + index = -1 + while index < len(array): + chunk = Properties_pb2.PropertyInputChunk() + if index is -1: + chunk.params.CopyFrom(parameters) + index += 1 + else: + actual_chunk_size = min(len(array) - index + 1, self.chunk_size) + chunk.values.CopyFrom( + Properties_pb2.PropertyChunk(values=array[index:index + + actual_chunk_size])) + index += actual_chunk_size + + yield chunk + # Final empty message to signal completion + chunk = Properties_pb2.PropertyInputChunk() + yield chunk + + def grid_path(self): + """Get path of the current grid case + + Returns: path string + """ + return self.get_value("CaseFileName") + + def grid(self, index): + """Get Grid of a given index. Returns a rips Grid object + + Arguments: + index (int): The grid index + + Returns: Grid object + """ + return Grid(index, self, self.__channel) + + def grids(self): + """Get a list of all rips Grid objects in the case""" + grid_list = [] + for i in range(0, self.__grid_count()): + grid_list.append(Grid(i, self, self.__channel)) + return grid_list + + def replace(self, new_grid_file): + """Replace the current case grid with a new grid loaded from file + + Arguments: + new_egrid_file (str): path to EGRID file + """ + self._execute_command(replaceCase=Cmd.ReplaceCaseRequest( + newGridFile=new_grid_file, caseId=self.case_id)) + self.__init__(self.__channel, self.case_id) + + def cell_count(self, porosity_model="MATRIX_MODEL"): + """Get a cell count object containing number of active cells and + total number of cells + + Arguments: + porosity_model (str): String representing an enum. + must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. + Returns: + Cell Count object with the following integer attributes: + active_cell_count: number of active cells + reservoir_cell_count: total number of reservoir cells + """ + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Case_pb2.CellInfoRequest(case_request=self.__request, + porosity_model=porosity_model_enum) + return self.__case_stub.GetCellCount(request) + + def cell_info_for_active_cells_async(self, porosity_model="MATRIX_MODEL"): + """Get Stream of cell info objects for current case + + Arguments: + porosity_model(str): String representing an enum. + must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. + + Returns: + Stream of **CellInfo** objects + + See cell_info_for_active_cells() for detalis on the **CellInfo** class. + """ + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Case_pb2.CellInfoRequest(case_request=self.__request, + porosity_model=porosity_model_enum) + return self.__case_stub.GetCellInfoForActiveCells(request) + + def cell_info_for_active_cells(self, porosity_model="MATRIX_MODEL"): + """Get list of cell info objects for current case + + Arguments: + porosity_model(str): String representing an enum. + must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'. + + Returns: + List of **CellInfo** objects + + ### CellInfo class description + + Parameter | Description | Type + ------------------------- | --------------------------------------------- | ----- + grid_index | Index to grid | Integer + parent_grid_index | Index to parent grid | Integer + coarsening_box_index | Index to coarsening box | Integer + local_ijk | Cell index in IJK directions of local grid | Vec3i + parent_ijk | Cell index in IJK directions of parent grid | Vec3i + + ### Vec3i class description + + Parameter | Description | Type + ---------------- | -------------------------------------------- | ----- + i | I grid index | Integer + j | J grid index | Integer + k | K grid index | Integer + + """ + active_cell_info_chunks = self.cell_info_for_active_cells_async( + porosity_model=porosity_model) + received_active_cells = [] + for active_cell_chunk in active_cell_info_chunks: + for active_cell in active_cell_chunk.data: + received_active_cells.append(active_cell) + return received_active_cells + + def time_steps(self): + """Get a list containing all time steps + + The time steps are defined by the class **TimeStepDate** : + + Type | Name + --------- | ---------- + int | year + int | month + int | day + int | hour + int | minute + int | second + + + """ + return self.__case_stub.GetTimeSteps(self.__request).dates + + def days_since_start(self): + """Get a list of decimal values representing days since the start of the simulation""" + return self.__case_stub.GetDaysSinceStart(self.__request).day_decimals + + def views(self): + """Get a list of views belonging to a case""" + pdm_objects = self.children("ReservoirViews") + view_list = [] + for pdm_object in pdm_objects: + view_list.append(View(pdm_object)) + return view_list + + def view(self, view_id): + """Get a particular view belonging to a case by providing view id + Arguments: + view_id(int): view id + + Returns: a view object + + """ + views = self.views() + for view_object in views: + if view_object.view_id == view_id: + return view_object + return None + + def create_view(self): + """Create a new view in the current case""" + return self.view( + self._execute_command(createView=Cmd.CreateViewRequest( + caseId=self.case_id)).createViewResult.viewId) + + def export_snapshots_of_all_views(self, prefix=""): + """ Export snapshots for all views in the case + + Arguments: + prefix (str): Exported file name prefix + + """ + return self._execute_command( + exportSnapshots=Cmd.ExportSnapshotsRequest( + type="VIEWS", prefix=prefix, caseId=self.case_id, viewId=-1)) + + def export_well_path_completions( + self, + time_step, + well_path_names, + file_split, + compdat_export="TRANSMISSIBILITIES", + include_perforations=True, + include_fishbones=True, + fishbones_exclude_main_bore=True, + combination_mode="INDIVIDUALLY", + ): + """ + Export well path completions for the current case to file + + Parameter | Description | Type + ----------------------------| ------------------------------------------------ | ----- + time_step | Time step to export for | Integer + well_path_names | List of well path names | List + file_split | Split type: +
    +
  • 'UNIFIED_FILE'
  • +
  • 'SPLIT_ON_WELL'
  • +
  • 'SPLIT_ON_WELL_AND_COMPLETION_TYPE'
  • +
| String enum + compdat_export | Compdat export type: +
    +
  • 'TRANSMISSIBILITIES'
  • +
  • 'WPIMULT_AND_DEFAULT_CONNECTION_FACTORS'
  • +
| String enum + include_perforations | Export perforations? | bool + include_fishbones | Export fishbones? | bool + fishbones_exclude_main_bore | Exclude main bore when exporting fishbones? | bool + combination_mode | Combination mode: +
    +
  • 'INDIVIDUALLY'
  • +
  • 'COMBINED'
  • +
| String enum + """ + if isinstance(well_path_names, str): + well_path_names = [well_path_names] + return self._execute_command( + exportWellPathCompletions=Cmd.ExportWellPathCompRequest( + caseId=self.case_id, + timeStep=time_step, + wellPathNames=well_path_names, + fileSplit=file_split, + compdatExport=compdat_export, + includePerforations=include_perforations, + includeFishbones=include_fishbones, + excludeMainBoreForFishbones=fishbones_exclude_main_bore, + combinationMode=combination_mode, + )) + + def export_msw(self, well_path): + """ + Export Eclipse Multi-segment-well model to file + + Arguments: + well_path(str): Well path name + """ + return self._execute_command(exportMsw=Cmd.ExportMswRequest( + caseId=self.case_id, wellPath=well_path)) + + def create_multiple_fractures( + self, + template_id, + well_path_names, + min_dist_from_well_td, + max_fractures_per_well, + top_layer, + base_layer, + spacing, + action, + ): + """ + Create Multiple Fractures in one go + + Parameter | Description | Type + -----------------------| ---------------------------------- -| ----- + template_id | Id of the template | Integer + well_path_names | List of well path names | List of Strings + min_dist_from_well_td | Minimum distance from well TD | Double + max_fractures_per_well | Max number of fractures per well | Integer + top_layer | Top grid k-level for fractures | Integer + base_layer | Base grid k-level for fractures | Integer + spacing | Spacing between fractures | Double + action | 'APPEND_FRACTURES' or 'REPLACE_FRACTURES' | String enum + """ + if isinstance(well_path_names, str): + well_path_names = [well_path_names] + return self._execute_command( + createMultipleFractures=Cmd.MultipleFracRequest( + caseId=self.case_id, + templateId=template_id, + wellPathNames=well_path_names, + minDistFromWellTd=min_dist_from_well_td, + maxFracturesPerWell=max_fractures_per_well, + topLayer=top_layer, + baseLayer=base_layer, + spacing=spacing, + action=action, + )) + + def create_lgr_for_completion( + self, + time_step, + well_path_names, + refinement_i, + refinement_j, + refinement_k, + split_type, + ): + """ + Create a local grid refinement for the completions on the given well paths + + Parameter | Description | Type + --------------- | -------------------------------------- | ----- + time_steps | Time step index | Integer + well_path_names | List of well path names | List of Strings + refinement_i | Refinment in x-direction | Integer + refinement_j | Refinment in y-direction | Integer + refinement_k | Refinment in z-direction | Integer + split_type | Type of LGR split: +
    +
  • 'LGR_PER_CELL'
  • +
  • 'LGR_PER_COMPLETION'
  • +
  • 'LGR_PER_WELL'
  • +
| String enum + """ + if isinstance(well_path_names, str): + well_path_names = [well_path_names] + return self._execute_command( + createLgrForCompletions=Cmd.CreateLgrForCompRequest( + caseId=self.case_id, + timeStep=time_step, + wellPathNames=well_path_names, + refinementI=refinement_i, + refinementJ=refinement_j, + refinementK=refinement_k, + splitType=split_type, + )) + + def create_saturation_pressure_plots(self): + """ + Create saturation pressure plots for the current case + """ + case_ids = [self.case_id] + return self._execute_command( + createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest( + caseIds=case_ids)) + + def export_flow_characteristics( + self, + time_steps, + injectors, + producers, + file_name, + minimum_communication=0.0, + aquifer_cell_threshold=0.1, + ): + """ Export Flow Characteristics data to text file in CSV format + + Parameter | Description | Type + ------------------------- | --------------------------------------------- | ----- + time_steps | Time step indices | List of Integer + injectors | Injector names | List of Strings + producers | Producer names | List of Strings + file_name | Export file name | Integer + minimum_communication | Minimum Communication, defaults to 0.0 | Integer + aquifer_cell_threshold | Aquifer Cell Threshold, defaults to 0.1 | Integer + + """ + if isinstance(time_steps, int): + time_steps = [time_steps] + if isinstance(injectors, str): + injectors = [injectors] + if isinstance(producers, str): + producers = [producers] + return self._execute_command( + exportFlowCharacteristics=Cmd.ExportFlowInfoRequest( + caseId=self.case_id, + timeSteps=time_steps, + injectors=injectors, + producers=producers, + fileName=file_name, + minimumCommunication=minimum_communication, + aquiferCellThreshold=aquifer_cell_threshold, + )) + + def available_properties(self, + property_type, + porosity_model="MATRIX_MODEL"): + """Get a list of available properties + + Arguments: + property_type (str): string corresponding to property_type enum. Choices: + - DYNAMIC_NATIVE + - STATIC_NATIVE + - SOURSIMRL + - GENERATED + - INPUT_PROPERTY + - FORMATION_NAMES + - FLOW_DIAGNOSTICS + - INJECTION_FLOODING + + porosity_model(str): 'MATRIX_MODEL' or 'FRACTURE_MODEL'. + """ + + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Properties_pb2.AvailablePropertiesRequest( + case_request=self.__request, + property_type=property_type_enum, + porosity_model=porosity_model_enum, + ) + return self.__properties_stub.GetAvailableProperties( + request).property_names + + def active_cell_property_async(self, + property_type, + property_name, + time_step, + porosity_model="MATRIX_MODEL"): + """Get a cell property for all active cells. Async, so returns an iterator + + Arguments: + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() + + Returns: + An iterator to a chunk object containing an array of double values + Loop through the chunks and then the values within the chunk to get all values. + """ + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Properties_pb2.PropertyRequest( + case_request=self.__request, + property_type=property_type_enum, + property_name=property_name, + time_step=time_step, + porosity_model=porosity_model_enum, + ) + for chunk in self.__properties_stub.GetActiveCellProperty(request): + yield chunk + + def active_cell_property(self, + property_type, + property_name, + time_step, + porosity_model="MATRIX_MODEL"): + """Get a cell property for all active cells. Sync, so returns a list + + Arguments: + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() + + Returns: + A list containing double values + Loop through the chunks and then the values within the chunk to get all values. + """ + all_values = [] + generator = self.active_cell_property_async(property_type, + property_name, time_step, + porosity_model) + for chunk in generator: + for value in chunk.values: + all_values.append(value) + return all_values + + def grid_property_async( + self, + property_type, + property_name, + time_step, + grid_index=0, + porosity_model="MATRIX_MODEL", + ): + """Get a cell property for all grid cells. Async, so returns an iterator + + Arguments: + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + gridIndex(int): index to the grid we're getting values for + porosity_model(str): string enum. See available() + + Returns: + An iterator to a chunk object containing an array of double values + Loop through the chunks and then the values within the chunk to get all values. + """ + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Properties_pb2.PropertyRequest( + case_request=self.__request, + property_type=property_type_enum, + property_name=property_name, + time_step=time_step, + grid_index=grid_index, + porosity_model=porosity_model_enum, + ) + for chunk in self.__properties_stub.GetGridProperty(request): + yield chunk + + def grid_property( + self, + property_type, + property_name, + time_step, + grid_index=0, + porosity_model="MATRIX_MODEL", + ): + """Get a cell property for all grid cells. Synchronous, so returns a list + + Arguments: + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + grid_index(int): index to the grid we're getting values for + porosity_model(str): string enum. See available() + + Returns: + A list of double values + """ + all_values = [] + generator = self.grid_property_async(property_type, property_name, + time_step, grid_index, + porosity_model) + for chunk in generator: + for value in chunk.values: + all_values.append(value) + return all_values + + def set_active_cell_property_async( + self, + values_iterator, + property_type, + property_name, + time_step, + porosity_model="MATRIX_MODEL", + ): + """Set cell property for all active cells Async. Takes an iterator to the input values + + Arguments: + values_iterator(iterator): an iterator to the properties to be set + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() + """ + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Properties_pb2.PropertyRequest( + case_request=self.__request, + property_type=property_type_enum, + property_name=property_name, + time_step=time_step, + porosity_model=porosity_model_enum, + ) + + request_iterator = self.__generate_property_input_iterator( + values_iterator, request) + self.__properties_stub.SetActiveCellProperty(request_iterator) + + def set_active_cell_property( + self, + values, + property_type, + property_name, + time_step, + porosity_model="MATRIX_MODEL", + ): + """Set a cell property for all active cells. + + Arguments: + values(list): a list of double precision floating point numbers + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + porosity_model(str): string enum. See available() + """ + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Properties_pb2.PropertyRequest( + case_request=self.__request, + property_type=property_type_enum, + property_name=property_name, + time_step=time_step, + porosity_model=porosity_model_enum, + ) + request_iterator = self.__generate_property_input_chunks( + values, request) + reply = self.__properties_stub.SetActiveCellProperty(request_iterator) + if reply.accepted_value_count < len(values): + raise IndexError + + def set_grid_property( + self, + values, + property_type, + property_name, + time_step, + grid_index=0, + porosity_model="MATRIX_MODEL", + ): + """Set a cell property for all grid cells. + + Arguments: + values(list): a list of double precision floating point numbers + property_type(str): string enum. See available() + property_name(str): name of an Eclipse property + time_step(int): the time step for which to get the property for + grid_index(int): index to the grid we're setting values for + porosity_model(str): string enum. See available() + """ + property_type_enum = Properties_pb2.PropertyType.Value(property_type) + porosity_model_enum = Case_pb2.PorosityModelType.Value(porosity_model) + request = Properties_pb2.PropertyRequest( + case_request=self.__request, + property_type=property_type_enum, + property_name=property_name, + time_step=time_step, + grid_index=grid_index, + porosity_model=porosity_model_enum, + ) + request_iterator = self.__generate_property_input_chunks( + values, request) + reply = self.__properties_stub.SetGridProperty(request_iterator) + if reply.accepted_value_count < len(values): + raise IndexError + + def export_property( + self, + time_step, + property_name, + eclipse_keyword=property, + undefined_value=0.0, + export_file=property, + ): + """ Export an Eclipse property + + Arguments: + time_step (int): time step index + property_name (str): property to export + eclipse_keyword (str): Keyword used in export header. Defaults: value of property + undefined_value (double): Value to use for undefined values. Defaults to 0.0 + export_file (str): File name for export. Defaults to the value of property parameter + """ + return self._execute_command(exportProperty=Cmd.ExportPropertyRequest( + caseId=self.case_id, + timeStep=time_step, + property=property_name, + eclipseKeyword=eclipse_keyword, + undefinedValue=undefined_value, + exportFile=export_file, + )) diff --git a/ApplicationCode/GrpcInterface/Python/rips/grid.py b/ApplicationCode/GrpcInterface/Python/rips/grid.py new file mode 100644 index 0000000000..5858f58429 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/grid.py @@ -0,0 +1,33 @@ +# pylint: disable=too-few-public-methods + +""" +Module containing the Grid class, containing information +about Case grids. +""" + +import rips.generated.Case_pb2 as Case_pb2 +import rips.generated.Grid_pb2 as Grid_pb2 +import rips.generated.Grid_pb2_grpc as Grid_pb2_grpc + +class Grid: + """Grid Information. Not meant to be constructed separately + + Create Grid objects using mathods on Case: Grid() and Grids() + """ + def __init__(self, index, case, channel): + self.__channel = channel + self.__stub = Grid_pb2_grpc.GridStub(self.__channel) + + self.case = case + self.index = index + + def dimensions(self): + """The dimensions in i, j, k direction + + Returns: + Vec3i: class with integer attributes i, j, k giving extent in all three dimensions. + """ + case_request = Case_pb2.CaseRequest(id=self.case.case_id) + return self.__stub.GetDimensions( + Grid_pb2.GridRequest(case_request=case_request, + grid_index=self.index)).dimensions diff --git a/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py new file mode 100644 index 0000000000..7c11e7a439 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py @@ -0,0 +1,73 @@ +""" +Grid Case Group statistics module +""" + +from rips.pdmobject import PdmObject +from rips.view import View +from rips.case import Case + +import rips.generated.Commands_pb2 as Cmd + +class GridCaseGroup(PdmObject): + """ResInsight Grid Case Group class + + Operate on a ResInsight case group specified by a Case Group Id integer. + + Attributes: + group_id (int): Grid Case Group Id corresponding to case group Id in ResInsight project. + """ + def __init__(self, pdm_object): + self.group_id = pdm_object.get_value("GroupId") + PdmObject.__init__(self, pdm_object._pb2_object, pdm_object._channel) + + def create_statistics_case(self): + """Create a Statistics case in the Grid Case Group + + Returns: + A new Case + """ + command_reply = self._execute_command( + createStatisticsCase=Cmd.CreateStatisticsCaseRequest( + caseGroupId=self.group_id)) + return Case(self.channel, + command_reply.createStatisticsCaseResult.caseId) + + def statistics_cases(self): + """Get a list of all statistics cases in the Grid Case Group""" + stat_case_collection = self.children("StatisticsCaseCollection")[0] + return stat_case_collection.children("Reservoirs") + + def views(self): + """Get a list of views belonging to a grid case group""" + pdm_objects = self.descendants("ReservoirView") + view_list = [] + for pdm_object in pdm_objects: + view_list.append(View(pdm_object)) + return view_list + + def view(self, view_id): + """Get a particular view belonging to a case group by providing view id + Arguments: + id(int): view id + + Returns: a view object + + """ + views = self.views() + for view_object in views: + if view_object.id == view_id: + return view_object + return None + + def compute_statistics(self, case_ids=None): + """ Compute statistics for the given case ids + + Arguments: + case_ids(list): list of case ids. If this is None all cases in group are included + + """ + if case_ids is None: + case_ids = [] + return self._execute_command( + computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest( + caseIds=case_ids, caseGroupId=self.group_id)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/instance.py b/ApplicationCode/GrpcInterface/Python/rips/instance.py new file mode 100644 index 0000000000..d1d87a2f75 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/instance.py @@ -0,0 +1,269 @@ +# pylint: disable=no-self-use +""" +The main entry point for ResInsight connections +The Instance class contained have static methods launch and find for +creating connections to ResInsight +""" + +import os +import socket +import logging +import time + +import grpc + +import rips.generated.App_pb2 as App_pb2 +import rips.generated.App_pb2_grpc as App_pb2_grpc +import rips.generated.Commands_pb2 as Cmd +import rips.generated.Commands_pb2_grpc as CmdRpc +from rips.generated.Definitions_pb2 import Empty + +import rips.generated.RiaVersionInfo as RiaVersionInfo + +from rips.project import Project + + +class Instance: + """The ResInsight Instance class. Use to launch or find existing ResInsight instances + + Attributes: + launched (bool): Tells us whether the application was launched as a new process. + If the application was launched we may need to close it when exiting the script. + commands (Commands): Command executor. Set when creating an instance. + project (Project): Current project in ResInsight. + Set when creating an instance and updated when opening/closing projects. + """ + @staticmethod + def __is_port_in_use(port): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as my_socket: + my_socket.settimeout(0.2) + return my_socket.connect_ex(('localhost', port)) == 0 + + @staticmethod + def launch(resinsight_executable='', + console=False, + launch_port=-1, + command_line_parameters=None): + """ Launch a new Instance of ResInsight. This requires the environment variable + RESINSIGHT_EXECUTABLE to be set or the parameter resinsight_executable to be provided. + The RESINSIGHT_GRPC_PORT environment variable can be set to an alternative port number. + + Args: + resinsight_executable (str): Path to a valid ResInsight executable. If set + will take precedence over what is provided in the RESINSIGHT_EXECUTABLE + environment variable. + console (bool): If True, launch as console application, without GUI. + launch_port(int): If -1 will use the default port 50051 or RESINSIGHT_GRPC_PORT + if anything else, ResInsight will try to launch with this port + command_line_parameters(list): Additional parameters as string entries in the list. + Returns: + Instance: an instance object if it worked. None if not. + """ + + port = 50051 + port_env = os.environ.get('RESINSIGHT_GRPC_PORT') + if port_env: + port = int(port_env) + if launch_port is not -1: + port = launch_port + + if not resinsight_executable: + resinsight_executable = os.environ.get('RESINSIGHT_EXECUTABLE') + if not resinsight_executable: + print( + 'ERROR: Could not launch ResInsight because the environment variable' + ' RESINSIGHT_EXECUTABLE is not set') + return None + + while Instance.__is_port_in_use(port): + port += 1 + + print('Port ' + str(port)) + print('Trying to launch', resinsight_executable) + + if command_line_parameters is None: + command_line_parameters = [] + elif isinstance(command_line_parameters, str): + command_line_parameters = [str] + + parameters = ["ResInsight", "--server", + str(port)] + command_line_parameters + if console: + print("Launching as console app") + parameters.append("--console") + + # Stringify all parameters + for i in enumerate(parameters): + parameters[i] = str(parameters[i]) + + pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters) + if pid: + instance = Instance(port=port, launched=True) + return instance + return None + + @staticmethod + def find(start_port=50051, end_port=50071): + """ Search for an existing Instance of ResInsight by testing ports. + + By default we search from port 50051 to 50071 or if the environment + variable RESINSIGHT_GRPC_PORT is set we search + RESINSIGHT_GRPC_PORT to RESINSIGHT_GRPC_PORT+20 + + Args: + start_port (int): start searching from this port + end_port (int): search up to but not including this port + """ + port_env = os.environ.get('RESINSIGHT_GRPC_PORT') + if port_env: + start_port = int(port_env) + end_port = start_port + 20 + + for try_port in range(start_port, end_port): + if Instance.__is_port_in_use(try_port): + return Instance(port=try_port) + + print( + 'Error: Could not find any ResInsight instances responding between ports ' + + str(start_port) + ' and ' + str(end_port)) + return None + + def __execute_command(self, **command_params): + return self.commands.Execute(Cmd.CommandParams(**command_params)) + + def __check_version(self): + try: + major_version_ok = self.major_version() == int( + RiaVersionInfo.RESINSIGHT_MAJOR_VERSION) + minor_version_ok = self.minor_version() == int( + RiaVersionInfo.RESINSIGHT_MINOR_VERSION) + return True, major_version_ok and minor_version_ok + except grpc.RpcError: + return False, False + + def __init__(self, port=50051, launched=False): + """ Attempts to connect to ResInsight at aa specific port on localhost + + Args: + port(int): port number + """ + logging.basicConfig() + location = "localhost:" + str(port) + + self.channel = grpc.insecure_channel(location, + options=[ + ('grpc.enable_http_proxy', + False) + ]) + self.launched = launched + self.commands = CmdRpc.CommandsStub(self.channel) + + # Main version check package + self.app = self.app = App_pb2_grpc.AppStub(self.channel) + + connection_ok = False + version_ok = False + + if self.launched: + for _ in range(0, 10): + connection_ok, version_ok = self.__check_version() + if connection_ok: + break + time.sleep(1.0) + else: + connection_ok, version_ok = self.__check_version() + + if not connection_ok: + if self.launched: + raise Exception('Error: Could not connect to resinsight at ', + location, + ' after trying 10 times with 1 second apart') + raise Exception('Error: Could not connect to resinsight at ', location) + if not version_ok: + raise Exception('Error: Wrong Version of ResInsight at ', location, + self.version_string(), " ", + self.client_version_string()) + + # Service packages + self.project = Project(self.channel) + + path = os.getcwd() + self.set_start_dir(path=path) + + def __version_message(self): + return self.app.GetVersion(Empty()) + + def set_start_dir(self, path): + """Set current start directory + + Arguments: + path (str): path to directory + + """ + return self.__execute_command(setStartDir=Cmd.FilePathRequest(path=path)) + + def set_export_folder(self, export_type, path, create_folder=False): + """ + Set the export folder used for all export functions + + Parameter | Description | Type + ---------------- | -------------------------------------------- | ----- + export_type | Type of export: 'COMPLETIONS', 'SNAPSHOTS' + 'PROPERTIES' or 'STATISTICS' | String + path | Path to folder | String + create_folder | Create folder if it doesn't exist? | Boolean + """ + return self.__execute_command(setExportFolder=Cmd.SetExportFolderRequest( + type=export_type, path=path, createFolder=create_folder)) + + def set_main_window_size(self, width, height): + """ + Set the main window size in pixels + Parameter | Description | Type + --------- | ---------------- | ----- + width | Width in pixels | Integer + height | Height in pixels | Integer + """ + return self.__execute_command(setMainWindowSize=Cmd.SetMainWindowSizeParams( + width=width, height=height)) + + def major_version(self): + """Get an integer with the major version number""" + return self.__version_message().major_version + + def minor_version(self): + """Get an integer with the minor version number""" + return self.__version_message().minor_version + + def patch_version(self): + """Get an integer with the patch version number""" + return self.__version_message().patch_version + + def version_string(self): + """Get a full version string, i.e. 2019.04.01""" + return str(self.major_version()) + "." + str( + self.minor_version()) + "." + str(self.patch_version()) + + def client_version_string(self): + """Get a full version string, i.e. 2019.04.01""" + version_string = RiaVersionInfo.RESINSIGHT_MAJOR_VERSION + "." + version_string += RiaVersionInfo.RESINSIGHT_MINOR_VERSION + "." + version_string += RiaVersionInfo.RESINSIGHT_PATCH_VERSION + return version_string + + def exit(self): + """Tell ResInsight instance to quit""" + print("Telling ResInsight to Exit") + return self.app.Exit(Empty()) + + def is_console(self): + """Returns true if the connected ResInsight instance is a console app""" + return self.app.GetRuntimeInfo( + Empty()).app_type == App_pb2.ApplicationTypeEnum.Value( + 'CONSOLE_APPLICATION') + + def is_gui(self): + """Returns true if the connected ResInsight instance is a GUI app""" + return self.app.GetRuntimeInfo( + Empty()).app_type == App_pb2.ApplicationTypeEnum.Value( + 'GUI_APPLICATION') diff --git a/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py similarity index 56% rename from ApplicationCode/GrpcInterface/Python/rips/PdmObject.py rename to ApplicationCode/GrpcInterface/Python/rips/pdmobject.py index d8aa4514bc..b2dedcac3d 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PdmObject.py +++ b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py @@ -1,87 +1,95 @@ -import grpc -import os -import sys +# pylint: disable=no-self-use +""" +ResInsight caf::PdmObject connection module +""" +import rips.generated.PdmObject_pb2 as PdmObject_pb2 +import rips.generated.PdmObject_pb2_grpc as PdmObject_pb2_grpc +import rips.generated.Commands_pb2 as Cmd +import rips.generated.Commands_pb2_grpc as CmdRpc -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated')) - -from Definitions_pb2 import Empty -import PdmObject_pb2 -import PdmObject_pb2_grpc class PdmObject: + """ + Generic ResInsight object. Corresponds to items in the Project Tree + """ + + def _execute_command(self, **command_params): + return self._commands.Execute(Cmd.CommandParams(**command_params)) + def __init__(self, pb2_object, channel): - self.pb2_object = pb2_object - self.channel = channel - self.pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel) - + self._pb2_object = pb2_object + self._channel = channel + self._pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub( + self._channel) + self._commands = CmdRpc.CommandsStub(channel) + def address(self): """Get the unique address of the PdmObject - + Returns: A 64-bit unsigned integer address """ - return self.pb2_object.address + return self._pb2_object.address def class_keyword(self): """Get the class keyword in the ResInsight Data Model for the given PdmObject""" - return self.pb2_object.class_keyword + return self._pb2_object.class_keyword def keywords(self): """Get a list of all parameter keywords available in the object""" list_of_keywords = [] - for keyword in self.pb2_object.parameters: + for keyword in self._pb2_object.parameters: list_of_keywords.append(keyword) return list_of_keywords - + def print_object_info(self): """Print the structure and data content of the PdmObject""" - print ("Class Keyword: " + self.class_keyword()) + print("Class Keyword: " + self.class_keyword()) for keyword in self.keywords(): - print(keyword + " [" + type(self.get_value(keyword)).__name__ + "]: " + str(self.get_value(keyword))) + print(keyword + " [" + type(self.get_value(keyword)).__name__ + + "]: " + str(self.get_value(keyword))) def __to_value(self, value): if value.lower() == 'false': - return False - elif value.lower() == 'true': + return False + if value.lower() == 'true': return True - else: + try: + int_val = int(value) + return int_val + except ValueError: try: - int_val = int(value) - return int_val + float_val = float(value) + return float_val except ValueError: - try: - float_val = float(value) - return float_val - except ValueError: - # We may have a string. Strip internal start and end quotes - value = value.strip('\"') - if self.__islist(value): - return self.__makelist(value) - return value + # We may have a string. Strip internal start and end quotes + value = value.strip('\"') + if self.__islist(value): + return self.__makelist(value) + return value + def __from_value(self, value): if isinstance(value, bool): if value: return "true" - else: - return "false" - elif isinstance(value, list): + return "false" + if isinstance(value, list): list_of_strings = [] for val in value: list_of_strings.append(self.__from_value('\"' + val + '\"')) return "[" + ", ".join(list_of_strings) + "]" - else: - return str(value) + return str(value) def get_value(self, keyword): """Get the value associated with the provided keyword Arguments: keyword(str): A string containing the parameter keyword - + Returns: The value of the parameter. Can be int, str or list. """ - value = self.pb2_object.parameters[keyword] + value = self._pb2_object.parameters[keyword] return self.__to_value(value) def __islist(self, value): @@ -104,7 +112,7 @@ def set_value(self, keyword, value): See keyword documentation and/or print_object_info() to find the correct data type. """ - self.pb2_object.parameters[keyword] = self.__from_value(value) + self._pb2_object.parameters[keyword] = self.__from_value(value) def descendants(self, class_keyword): """Get a list of all project tree descendants matching the class keyword @@ -114,11 +122,13 @@ def descendants(self, class_keyword): Returns: A list of PdmObjects matching the keyword provided """ - request = PdmObject_pb2.PdmDescendantObjectRequest(object=self.pb2_object, child_keyword=class_keyword) - object_list = self.pdm_object_stub.GetDescendantPdmObjects(request).objects + request = PdmObject_pb2.PdmDescendantObjectRequest( + object=self._pb2_object, child_keyword=class_keyword) + object_list = self._pdm_object_stub.GetDescendantPdmObjects( + request).objects child_list = [] - for object in object_list: - child_list.append(PdmObject(object, self.channel)) + for pdm_object in object_list: + child_list.append(PdmObject(pdm_object, self._channel)) return child_list def children(self, child_field): @@ -128,11 +138,12 @@ def children(self, child_field): Returns: A list of PdmObjects inside the child_field """ - request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2_object, child_field=child_field) - object_list = self.pdm_object_stub.GetChildPdmObjects(request).objects + request = PdmObject_pb2.PdmChildObjectRequest(object=self._pb2_object, + child_field=child_field) + object_list = self._pdm_object_stub.GetChildPdmObjects(request).objects child_list = [] - for object in object_list: - child_list.append(PdmObject(object, self.channel)) + for pdm_object in object_list: + child_list.append(PdmObject(pdm_object, self._channel)) return child_list def ancestor(self, class_keyword): @@ -140,13 +151,11 @@ def ancestor(self, class_keyword): Arguments: class_keyword[str]: A class keyword matching the type of class wanted """ - request = PdmObject_pb2.PdmParentObjectRequest(object=self.pb2_object, parent_keyword=class_keyword) - return PdmObject(self.pdm_object_stub.GetAncestorPdmObject(request), self.channel) + request = PdmObject_pb2.PdmParentObjectRequest( + object=self._pb2_object, parent_keyword=class_keyword) + return PdmObject(self._pdm_object_stub.GetAncestorPdmObject(request), + self._channel) def update(self): """Sync all fields from the Python Object to ResInsight""" - self.pdm_object_stub.UpdateExistingPdmObject(self.pb2_object) - -# def createChild(self, child_field, childClassKeyword): -# childRequest = PdmObject_pb2.CreatePdmChildObjectRequest(object=self.pb2Object, child_field=child_field, child_class=childClassKeyword) -# return PdmObject(self.pdmObjectStub.CreateChildPdmObject(childRequest), self.channel) + self._pdm_object_stub.UpdateExistingPdmObject(self._pb2_object) diff --git a/ApplicationCode/GrpcInterface/Python/rips/project.py b/ApplicationCode/GrpcInterface/Python/rips/project.py new file mode 100644 index 0000000000..3aebff0dcf --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/project.py @@ -0,0 +1,209 @@ +# pylint: disable=too-many-arguments +# pylint: disable=no-member +""" +The ResInsight project module +""" +import grpc + +from rips.case import Case +from rips.gridcasegroup import GridCaseGroup +from rips.pdmobject import PdmObject +from rips.view import View + +import rips.generated.Commands_pb2 as Cmd +from rips.generated.Definitions_pb2 import Empty +import rips.generated.Project_pb2_grpc as Project_pb2_grpc + + +class Project(PdmObject): + """ResInsight project. Not intended to be created separately. + + Automatically created and assigned to Instance. + """ + def __init__(self, channel): + self._project_stub = Project_pb2_grpc.ProjectStub(channel) + PdmObject.__init__(self, self._project_stub.GetPdmObject(Empty()), + channel) + + def open(self, path): + """Open a new project from the given path + + Arguments: + path(str): path to project file + + """ + self._execute_command(openProject=Cmd.FilePathRequest(path=path)) + return self + + def close(self): + """Close the current project (and open new blank project)""" + self._execute_command(closeProject=Empty()) + + def load_case(self, path): + """Load a new case from the given file path + + Arguments: + path(str): file path to case + Returns: + A rips Case object + """ + command_reply = self._execute_command(loadCase=Cmd.FilePathRequest( + path=path)) + return Case(self._channel, command_reply.loadCaseResult.id) + + def selected_cases(self): + """Get a list of all cases selected in the project tree + + Returns: + A list of rips Case objects + """ + case_infos = self._project_stub.GetSelectedCases(Empty()) + cases = [] + for case_info in case_infos.data: + cases.append(Case(self._channel, case_info.id)) + return cases + + def cases(self): + """Get a list of all cases in the project + + Returns: + A list of rips Case objects + """ + try: + case_infos = self._project_stub.GetAllCases(Empty()) + + cases = [] + for case_info in case_infos.data: + cases.append(Case(self._channel, case_info.id)) + return cases + except grpc.RpcError as rpc_error: + if rpc_error.code() == grpc.StatusCode.NOT_FOUND: + return [] + print("ERROR: ", rpc_error) + return [] + + def case(self, case_id): + """Get a specific case from the provided case Id + + Arguments: + id(int): case id + Returns: + A rips Case object + """ + try: + case = Case(self._channel, case_id) + return case + except grpc.RpcError: + return None + + def replace_source_cases(self, grid_list_file, case_group_id=0): + """Replace all source cases within a case group + Arguments: + grid_list_file (str): path to file containing a list of cases + case_group_id (int): id of the case group to replace + """ + return self._execute_command( + replaceSourceCases=Cmd.ReplaceSourceCasesRequest( + gridListFile=grid_list_file, caseGroupId=case_group_id)) + + def create_grid_case_group(self, case_paths): + """Create a Grid Case Group from a list of cases + Arguments: + case_paths (list): list of file path strings + Returns: + A case group id and name + """ + command_reply = self._execute_command( + createGridCaseGroup=Cmd.CreateGridCaseGroupRequest( + casePaths=case_paths)) + return self.grid_case_group( + command_reply.createGridCaseGroupResult.groupId) + + def views(self): + """Get a list of views belonging to a project""" + pdm_objects = self.descendants("ReservoirView") + view_list = [] + for pdm_object in pdm_objects: + view_list.append(View(pdm_object)) + return view_list + + def view(self, view_id): + """Get a particular view belonging to a case by providing view id + Arguments: + id(int): view id + Returns: a view object + """ + views = self.views() + for view_object in views: + if view_object.view_id == view_id: + return view_object + return None + + def grid_case_groups(self): + """Get a list of all grid case groups in the project""" + case_groups = self.descendants("RimIdenticalGridCaseGroup") + + case_group_list = [] + for pdm_group in case_groups: + case_group_list.append(GridCaseGroup(pdm_group)) + return case_group_list + + def grid_case_group(self, group_id): + """Get a particular grid case group belonging to a project + Arguments: + groupId(int): group id + + Returns: a grid case group object + """ + case_groups = self.grid_case_groups() + for case_group in case_groups: + if case_group.group_id == group_id: + return case_group + return None + + def export_multi_case_snapshots(self, grid_list_file): + """Export snapshots for a set of cases + Arguments: + grid_list_file (str): Path to a file containing a list of grids to export snapshot for + """ + return self._execute_command( + exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest( + gridListFile=grid_list_file)) + + def export_snapshots(self, snapshot_type='ALL', prefix=''): + """ Export all snapshots of a given type + Arguments: + snapshot_type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS') + prefix (str): Exported file name prefix + """ + return self._execute_command( + exportSnapshots=Cmd.ExportSnapshotsRequest( + type=snapshot_type, prefix=prefix, caseId=-1)) + + def export_well_paths(self, well_paths=None, md_step_size=5.0): + """ Export a set of well paths + Arguments: + well_paths(list): List of strings of well paths. If none, export all. + md_step_size(double): resolution of the exported well path + """ + if well_paths is None: + well_paths = [] + elif isinstance(well_paths, str): + well_paths = [well_paths] + return self._execute_command(exportWellPaths=Cmd.ExportWellPathRequest( + wellPathNames=well_paths, mdStepSize=md_step_size)) + + def scale_fracture_template(self, template_id, half_length, height, dfactor, + conductivity): + return self._execute_command( + scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest( + id=template_id, + halfLength=half_length, + height=height, + dFactor=dfactor, + conductivity=conductivity)) + + def set_fracture_containment(self, fracture_id, top_layer, base_layer): + return self._execute_command( + setFractureContainment=Cmd.SetFracContainmentRequest( + id=fracture_id, topLayer=top_layer, baseLayer=base_layer)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py index fc74aa3a47..257ab20fb0 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py @@ -1,6 +1,8 @@ import sys import os import pytest +import grpc +import tempfile sys.path.insert(1, os.path.join(sys.path[0], '../../')) import rips @@ -17,7 +19,7 @@ def test_EmptyProject(rips_instance, initialize_test): def test_OneCase(rips_instance, initialize_test): case = rips_instance.project.load_case(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID") assert(case.name == "TEST10K_FLT_LGR_NNC") - assert(case.id == 0) + assert(case.case_id == 0) cases = rips_instance.project.cases() assert(len(cases) is 1) @@ -41,7 +43,7 @@ def test_MultipleCases(rips_instance, initialize_test): def test_10k(rips_instance, initialize_test): case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=case_path) - assert(case.grid_count() == 2) + assert(len(case.grids()) == 2) cell_count_info = case.cell_count() assert(cell_count_info.active_cell_count == 11125) assert(cell_count_info.reservoir_cell_count == 316224) @@ -53,17 +55,17 @@ def test_10k(rips_instance, initialize_test): def test_PdmObject(rips_instance, initialize_test): case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=case_path) - assert(case.id == 0) + assert(case.case_id == 0) assert(case.address() is not 0) assert(case.class_keyword() == "EclipseCase") case_id = case.get_value('CaseId') - assert(case_id == case.id) + assert(case_id == case.case_id) @pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") def test_brugge_0010(rips_instance, initialize_test): case_path = dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID" case = rips_instance.project.load_case(path=case_path) - assert(case.grid_count() == 1) + assert(len(case.grids()) == 1) cellCountInfo = case.cell_count() assert(cellCountInfo.active_cell_count == 43374) assert(cellCountInfo.reservoir_cell_count == 60048) @@ -76,16 +78,36 @@ def test_brugge_0010(rips_instance, initialize_test): def test_replaceCase(rips_instance, initialize_test): project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp") case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" - case = project.case(id=0) + case = project.case(case_id=0) assert(case is not None) assert(case.name == "TEST10K_FLT_LGR_NNC") - assert(case.id == 0) + assert(case.case_id == 0) cases = rips_instance.project.cases() assert(len(cases) is 1) - rips_instance.commands.replace_case(new_grid_file=case_path, case_id=case.id) + case.replace(new_grid_file=case_path) + # Check that the case object has been changed + assert(case.name == "Real0--BRUGGE_0000.EGRID") + assert(case.case_id == 0) + cases = rips_instance.project.cases() assert(len(cases) is 1) - case = project.case(id=0) + # Check that retrieving the case object again will yield the changed object + case = project.case(case_id=0) assert(case.name == "Real0--BRUGGE_0000.EGRID") - assert(case.id == 0) + assert(case.case_id == 0) + +def test_loadNonExistingCase(rips_instance, initialize_test): + case_path = "Nonsense/Nonsense/Nonsense" + with pytest.raises(grpc.RpcError): + assert rips_instance.project.load_case(case_path) + +@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") +def test_exportFlowCharacteristics(rips_instance, initialize_test): + case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" + case = rips_instance.project.load_case(case_path) + with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: + print("Temporary folder: ", tmpdirname) + file_name = tmpdirname + "/exportFlowChar.txt" + case.export_flow_characteristics(time_steps=8, producers=[], injectors = "I01", file_name = file_name) + diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py index 496942f4f8..5fdef57c34 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_commands.py @@ -9,50 +9,3 @@ import dataroot -def test_exportSnapshots(rips_instance, initialize_test): - if not rips_instance.is_gui(): - pytest.skip("Cannot run test without a GUI") - - case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - rips_instance.project.load_case(case_path) - with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: - print("Temporary folder: ", tmpdirname) - rips_instance.commands.set_export_folder(type='SNAPSHOTS', path=tmpdirname) - rips_instance.commands.export_snapshots() - print(os.listdir(tmpdirname)) - assert(len(os.listdir(tmpdirname)) > 0) - for fileName in os.listdir(tmpdirname): - assert(os.path.splitext(fileName)[1] == '.png') - -def test_exportPropertyInView(rips_instance, initialize_test): - case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" - rips_instance.project.load_case(case_path) - with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: - print("Temporary folder: ", tmpdirname) - rips_instance.commands.set_export_folder(type='PROPERTIES', path=tmpdirname) - case = rips_instance.project.case(id=0) - rips_instance.commands.export_property_in_views(0, "3D View", 0) - expected_file_name = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL" - full_path = tmpdirname + "/" + expected_file_name - assert(os.path.exists(full_path)) - -@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") -def test_loadGridCaseGroup(rips_instance, initialize_test): - case_paths = [] - case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") - case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") - group_id, group_name = rips_instance.commands.create_grid_case_group(case_paths=case_paths) - print(group_id, group_name) - -def test_exportFlowCharacteristics(rips_instance, initialize_test): - case_path = dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID" - rips_instance.project.load_case(case_path) - with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: - print("Temporary folder: ", tmpdirname) - file_name = tmpdirname + "/exportFlowChar.txt" - rips_instance.commands.export_flow_characteristics(case_id=0, time_steps=8, producers=[], injectors = "I01", file_name = file_name) - -def test_loadNonExistingCase(rips_instance, initialize_test): - case_path = "Nonsense/Nonsense/Nonsense" - with pytest.raises(grpc.RpcError): - assert rips_instance.project.load_case(case_path) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py index 918e37b537..80ad582d16 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_grids.py @@ -9,7 +9,7 @@ def test_10k(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - assert(case.grid_count() == 2) + assert(len(case.grids()) == 2) grid = case.grid(index=0) dimensions = grid.dimensions() assert(dimensions.i == 90) diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py index 444ed41a43..592142bd0a 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_project.py @@ -1,6 +1,8 @@ import sys import os -import pytest +import pytest +import grpc +import tempfile sys.path.insert(1, os.path.join(sys.path[0], '../../')) import rips @@ -9,9 +11,32 @@ def test_loadProject(rips_instance, initialize_test): project = rips_instance.project.open(dataroot.PATH + "/TEST10K_FLT_LGR_NNC/10KWithWellLog.rsp") - case = project.case(id=0) + case = project.case(case_id=0) assert(case is not None) assert(case.name == "TEST10K_FLT_LGR_NNC") - assert(case.id == 0) + assert(case.case_id == 0) cases = rips_instance.project.cases() - assert(len(cases) is 1) \ No newline at end of file + assert(len(cases) is 1) + +@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") +def test_loadGridCaseGroup(rips_instance, initialize_test): + case_paths = [] + case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID") + case_paths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID") + grid_case_group = rips_instance.project.create_grid_case_group(case_paths=case_paths) + assert(grid_case_group is not None and grid_case_group.group_id == 0) + +def test_exportSnapshots(rips_instance, initialize_test): + if not rips_instance.is_gui(): + pytest.skip("Cannot run test without a GUI") + + case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + rips_instance.project.load_case(case_path) + with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: + print("Temporary folder: ", tmpdirname) + rips_instance.set_export_folder(export_type='SNAPSHOTS', path=tmpdirname) + rips_instance.project.export_snapshots() + print(os.listdir(tmpdirname)) + assert(len(os.listdir(tmpdirname)) > 0) + for fileName in os.listdir(tmpdirname): + assert(os.path.splitext(fileName)[1] == '.png') diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py index 7ba6c08340..1c197bbe92 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_properties.py @@ -2,6 +2,7 @@ import os import grpc import pytest +import tempfile sys.path.insert(1, os.path.join(sys.path[0], '../../')) import rips @@ -12,7 +13,7 @@ def test_10kAsync(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - resultChunks = case.properties.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', 1) + resultChunks = case.active_cell_property_async('DYNAMIC_NATIVE', 'SOIL', 1) mysum = 0.0 count = 0 for chunk in resultChunks: @@ -27,7 +28,7 @@ def test_10kSync(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) + results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) mysum = sum(results) average = mysum / len(results) assert(mysum == pytest.approx(621.768, abs=0.001)) @@ -38,27 +39,27 @@ def test_10k_set(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) - case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) + results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) + case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) def test_10k_set_out_of_bounds(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) + results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) results.append(5.0) with pytest.raises(grpc.RpcError): - assert case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) + assert case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) def test_10k_set_out_of_bounds_client(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - results = case.properties.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) - case.properties.chunk_size = len(results) + results = case.active_cell_property('DYNAMIC_NATIVE', 'SOIL', 1) + case.chunk_size = len(results) results.append(5.0) with pytest.raises(IndexError): - assert case.properties.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) + assert case.set_active_cell_property(results, 'GENERATED', 'SOIL', 1) def createResult(poroChunks, permxChunks): for (poroChunk, permxChunk) in zip(poroChunks, permxChunks): @@ -76,16 +77,26 @@ def test_10k_PoroPermX(rips_instance, initialize_test): casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" case = rips_instance.project.load_case(path=casePath) - poroChunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PORO', 0) - permxChunks = case.properties.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0) + poroChunks = case.active_cell_property_async('STATIC_NATIVE', 'PORO', 0) + permxChunks = case.active_cell_property_async('STATIC_NATIVE', 'PERMX', 0) - case.properties.set_active_cell_property_async(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0) + case.set_active_cell_property_async(createResult(poroChunks, permxChunks), 'GENERATED', 'POROPERMXAS', 0) - poro = case.properties.active_cell_property('STATIC_NATIVE', 'PORO', 0) - permx = case.properties.active_cell_property('STATIC_NATIVE', 'PERMX', 0) - poroPermX = case.properties.active_cell_property('GENERATED', 'POROPERMXAS', 0) + poro = case.active_cell_property('STATIC_NATIVE', 'PORO', 0) + permx = case.active_cell_property('STATIC_NATIVE', 'PERMX', 0) + poroPermX = case.active_cell_property('GENERATED', 'POROPERMXAS', 0) checkResults(poro, permx, poroPermX) - - \ No newline at end of file +def test_exportPropertyInView(rips_instance, initialize_test): + case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID" + rips_instance.project.load_case(case_path) + with tempfile.TemporaryDirectory(prefix="rips") as tmpdirname: + print("Temporary folder: ", tmpdirname) + rips_instance.set_export_folder(export_type='PROPERTIES', path=tmpdirname) + case = rips_instance.project.case(case_id=0) + view = case.view(view_id=0) + view.export_property() + expected_file_name = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL" + full_path = tmpdirname + "/" + expected_file_name + assert(os.path.exists(full_path)) \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/View.py b/ApplicationCode/GrpcInterface/Python/rips/view.py similarity index 50% rename from ApplicationCode/GrpcInterface/Python/rips/View.py rename to ApplicationCode/GrpcInterface/Python/rips/view.py index 504d1387dc..99f30aa38f 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/View.py +++ b/ApplicationCode/GrpcInterface/Python/rips/view.py @@ -1,8 +1,13 @@ -import rips.Case # Circular import of Case, which already imports View. Use full name. -from rips.Commands import Commands -from rips.PdmObject import PdmObject +""" +ResInsight 3d view module +""" +import rips.generated.Commands_pb2 as Cmd -class View (PdmObject): +import rips.case # Circular import of Case, which already imports View. Use full name. +from rips.pdmobject import PdmObject + + +class View(PdmObject): """ResInsight view class Attributes: @@ -10,9 +15,9 @@ class View (PdmObject): """ def __init__(self, pdm_object): - self.id = pdm_object.get_value("ViewId") + self.view_id = pdm_object.get_value("ViewId") - PdmObject.__init__(self, pdm_object.pb2_object, pdm_object.channel) + PdmObject.__init__(self, pdm_object._pb2_object, pdm_object._channel) def show_grid_box(self): """Check if the grid box is meant to be shown in the view""" @@ -36,7 +41,7 @@ def set_cell_result(self): def apply_cell_result(self, result_type, result_variable): """Apply a regular cell result - + Arguments: result_type (str): String representing the result category. The valid values are - DYNAMIC_NATIVE @@ -54,11 +59,12 @@ def apply_cell_result(self, result_type, result_variable): cell_result.set_value("ResultVariable", result_variable) cell_result.update() - def apply_flow_diagnostics_cell_result(self, - result_variable = 'TOF', - selection_mode = 'FLOW_TR_BY_SELECTION', - injectors = [], - producers = []): + def apply_flow_diagnostics_cell_result( + self, + result_variable='TOF', + selection_mode='FLOW_TR_BY_SELECTION', + injectors=None, + producers=None): """Apply a flow diagnostics cell result Arguments: @@ -66,7 +72,7 @@ def apply_flow_diagnostics_cell_result(self, The valid values are 'TOF', 'Fraction', 'MaxFractionTracer' and 'Communication'. selection_mode (str): String specifying which tracers to select. The valid values are - - FLOW_TR_INJ_AND_PROD (all injector and producer tracers), + - FLOW_TR_INJ_AND_PROD (all injector and producer tracers), - FLOW_TR_PRODUCERS (all producers) - FLOW_TR_INJECTORS (all injectors), - FLOW_TR_BY_SELECTION (specify individual tracers in the @@ -76,6 +82,10 @@ def apply_flow_diagnostics_cell_result(self, producers (list): List of producer tracers (strings) to select. Requires selection_mode to be 'FLOW_TR_BY_SELECTION'. """ + if injectors is None: + injectors = [] + if producers is None: + producers = [] cell_result = self.set_cell_result() cell_result.set_value("ResultType", "FLOW_DIAGNOSTICS") cell_result.set_value("ResultVariable", result_variable) @@ -92,9 +102,69 @@ def case(self): pdm_case = self.ancestor("ResInsightGeoMechCase") if pdm_case is None: return None - return rips.Case(self.channel, pdm_case.get_value("CaseId")) + return rips.case.Case(self._channel, pdm_case.get_value("CaseId")) def clone(self): """Clone the current view""" - view_id = Commands(self.channel).clone_view(self.id) + view_id = self._execute_command(cloneView=Cmd.CloneViewRequest( + viewId=self.view_id)).createViewResult.viewId return self.case().view(view_id) + + def set_time_step(self, time_step): + case_id = self.case().case_id + return self._execute_command(setTimeStep=Cmd.SetTimeStepParams( + caseId=case_id, viewId=self.view_id, timeStep=time_step)) + + def export_sim_well_fracture_completions(self, time_step, + simulation_well_names, file_split, + compdat_export): + if isinstance(simulation_well_names, str): + simulation_well_names = [simulation_well_names] + + case_id = self.case().case_id + return self._execute_command( + exportSimWellFractureCompletions=Cmd.ExportSimWellPathFracRequest( + caseId=case_id, + viewId=self.view_id, + timeStep=time_step, + simulationWellNames=simulation_well_names, + fileSplit=file_split, + compdatExport=compdat_export)) + + def export_visible_cells(self, + export_keyword='FLUXNUM', + visible_active_cells_value=1, + hidden_active_cells_value=0, + inactive_cells_value=0): + case_id = self.case().case_id + return self._execute_command( + exportVisibleCells=Cmd.ExportVisibleCellsRequest( + caseId=case_id, + viewId=self.view_id, + exportKeyword=export_keyword, + visibleActiveCellsValue=visible_active_cells_value, + hiddenActiveCellsValue=hidden_active_cells_value, + inactiveCellsValue=inactive_cells_value)) + + def export_property(self, undefined_value=0.0): + """ Export the current Eclipse property from the view + + Arguments: + undefined_value (double): Value to use for undefined values. Defaults to 0.0 + """ + case_id = self.case().case_id + return self._execute_command( + exportPropertyInViews=Cmd.ExportPropertyInViewsRequest( + caseId=case_id, + viewIds=[self.view_id], + undefinedValue=undefined_value)) + + def export_snapshot(self, prefix=''): + """ Export snapshot for the current view + Arguments: + prefix (str): Exported file name prefix + """ + case_id = self.case().case_id + return self._execute_command( + exportSnapshots=Cmd.ExportSnapshotsRequest( + type='VIEWS', prefix=prefix, caseId=case_id, viewId=self.view_id)) diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index f581892150..094a3c0c30 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -1490,8 +1490,8 @@ void RiuMainWindow::slotSnapshotAllViewsToFile() RiaApplication* app = RiaApplication::instance(); // Save images in snapshot catalog relative to project directory - QString absolutePathToSnapshotDir = app->createAbsolutePathFromProjectRelativePath("snapshots"); - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(absolutePathToSnapshotDir); + QString absolutePathToSnapshotDir = app->createAbsolutePathFromProjectRelativePath( "snapshots" ); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( absolutePathToSnapshotDir ); } //-------------------------------------------------------------------------------------------------- From 3d9ea3902d04df870dce820ffdc0e89a6760da27 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Mon, 23 Sep 2019 15:26:49 +0200 Subject: [PATCH 15/27] Additional python PEP 8 fixes --- ApplicationCode/GrpcInterface/Python/rips/case.py | 1 + ApplicationCode/GrpcInterface/Python/rips/grid.py | 1 + .../GrpcInterface/Python/rips/gridcasegroup.py | 1 + ApplicationCode/GrpcInterface/Python/rips/pdmobject.py | 8 ++++++++ ApplicationCode/GrpcInterface/Python/rips/view.py | 3 +-- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/GrpcInterface/Python/rips/case.py b/ApplicationCode/GrpcInterface/Python/rips/case.py index 263bfda163..ba325c6bbc 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/case.py +++ b/ApplicationCode/GrpcInterface/Python/rips/case.py @@ -19,6 +19,7 @@ from rips.pdmobject import PdmObject from rips.view import View + class Case(PdmObject): """ResInsight case class diff --git a/ApplicationCode/GrpcInterface/Python/rips/grid.py b/ApplicationCode/GrpcInterface/Python/rips/grid.py index 5858f58429..ba306d932e 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/grid.py +++ b/ApplicationCode/GrpcInterface/Python/rips/grid.py @@ -9,6 +9,7 @@ import rips.generated.Grid_pb2 as Grid_pb2 import rips.generated.Grid_pb2_grpc as Grid_pb2_grpc + class Grid: """Grid Information. Not meant to be constructed separately diff --git a/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py index 7c11e7a439..b9feb7de23 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py +++ b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py @@ -8,6 +8,7 @@ import rips.generated.Commands_pb2 as Cmd + class GridCaseGroup(PdmObject): """ResInsight Grid Case Group class diff --git a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py index b2dedcac3d..2d8f9cdc0c 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py +++ b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py @@ -23,6 +23,14 @@ def __init__(self, pb2_object, channel): self._channel) self._commands = CmdRpc.CommandsStub(channel) + def pb2_object(self): + """ Private method""" + return self._pb2_object + + def channel(self): + """ Private method""" + return self._channel + def address(self): """Get the unique address of the PdmObject diff --git a/ApplicationCode/GrpcInterface/Python/rips/view.py b/ApplicationCode/GrpcInterface/Python/rips/view.py index 99f30aa38f..3e9aabb67b 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/view.py +++ b/ApplicationCode/GrpcInterface/Python/rips/view.py @@ -15,10 +15,9 @@ class View(PdmObject): """ def __init__(self, pdm_object): + PdmObject.__init__(self, pdm_object.pb2_object(), pdm_object.channel()) self.view_id = pdm_object.get_value("ViewId") - PdmObject.__init__(self, pdm_object._pb2_object, pdm_object._channel) - def show_grid_box(self): """Check if the grid box is meant to be shown in the view""" return self.get_value("ShowGridBox") From 02733cac8ccf4df047faba611315c67f4dbef5f0 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Tue, 24 Sep 2019 08:58:46 +0200 Subject: [PATCH 16/27] Fix wrong Grid->grid rename in GRPC CMakeLists.cmake --- ApplicationCode/GrpcInterface/CMakeLists.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/GrpcInterface/CMakeLists.cmake b/ApplicationCode/GrpcInterface/CMakeLists.cmake index bbe88eca91..79a801f311 100644 --- a/ApplicationCode/GrpcInterface/CMakeLists.cmake +++ b/ApplicationCode/GrpcInterface/CMakeLists.cmake @@ -85,7 +85,7 @@ set(PROTO_FILES "Commands" "App" "Properties" - "grid" + "Grid" ) set(GRPC_PYTHON_SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}/Python") From 249752ca8b00ea51b290d69fed4370029307a970 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Tue, 24 Sep 2019 09:58:50 +0200 Subject: [PATCH 17/27] Python: Fix wrong use of enumerate --- ApplicationCode/GrpcInterface/Python/rips/instance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/GrpcInterface/Python/rips/instance.py b/ApplicationCode/GrpcInterface/Python/rips/instance.py index d1d87a2f75..d7844cd044 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/instance.py +++ b/ApplicationCode/GrpcInterface/Python/rips/instance.py @@ -93,7 +93,7 @@ def launch(resinsight_executable='', parameters.append("--console") # Stringify all parameters - for i in enumerate(parameters): + for i in range(0, len(parameters)): parameters[i] = str(parameters[i]) pid = os.spawnv(os.P_NOWAIT, resinsight_executable, parameters) From 5c55af4234724ffd69e717bfb32d2d464bcb2f92 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 24 Sep 2019 11:06:24 +0200 Subject: [PATCH 18/27] Python doc adjustments (#4756) * Doc and adjustments of project.py * Doc and adjustments view.py * Python doc cleanup * Python : Add copy of files to deployment folder * Python : Several updates to doc * Python : Limit line lenghts * Minor adjustments --- .../Python/doc/make_and_copy.bat | 39 ++++++++++ .../Python/doc/source/PythonExamples.rst | 57 ++++++++------ .../GrpcInterface/Python/doc/source/rips.rst | 30 ++------ .../GrpcInterface/Python/rips/case.py | 60 +++++++++------ .../Python/rips/gridcasegroup.py | 3 +- .../GrpcInterface/Python/rips/instance.py | 14 +++- .../GrpcInterface/Python/rips/project.py | 35 +++++++-- .../GrpcInterface/Python/rips/view.py | 74 ++++++++++++++----- 8 files changed, 218 insertions(+), 94 deletions(-) create mode 100644 ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat diff --git a/ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat b/ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat new file mode 100644 index 0000000000..665d65bedc --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/doc/make_and_copy.bat @@ -0,0 +1,39 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd + +REM Copy files to deployment folder using second parameter +REM Example "d:\gitroot\ResInsight-UserDocumentation\content\scripting" +xcopy /Y build\markdown %2 \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst b/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst index 56d9a7e97b..a7b83b5caa 100644 --- a/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst +++ b/ApplicationCode/GrpcInterface/Python/doc/source/PythonExamples.rst @@ -10,70 +10,85 @@ This pages is created based on the content in the **PythonExamples** folder loca AllCases ------- +-------- .. literalinclude:: ../../rips/PythonExamples/AllCases.py AppInfo ------- +------- .. literalinclude:: ../../rips/PythonExamples/AppInfo.py CaseGridGroup ------- +------------- .. literalinclude:: ../../rips/PythonExamples/CaseGridGroup.py CaseInfoStreamingExample ------- +------------------------ .. literalinclude:: ../../rips/PythonExamples/CaseInfoStreamingExample.py CommandExample ------- +-------------- .. literalinclude:: ../../rips/PythonExamples/CommandExample.py + ErrorHandling ------- +------------- .. literalinclude:: ../../rips/PythonExamples/ErrorHandling.py + ExportSnapshots ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/ExportSnapshots.py + GridInformation ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/GridInformation.py + InputPropTestAsync ------- +------------------ .. literalinclude:: ../../rips/PythonExamples/InputPropTestAsync.py + InputPropTestSync ------- +----------------- .. literalinclude:: ../../rips/PythonExamples/InputPropTestSync.py + InstanceExample ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/InstanceExample.py LaunchWithCommandLineOptions ------- +---------------------------- .. literalinclude:: ../../rips/PythonExamples/LaunchWithCommandLineOptions.py + SelectedCases ------- +------------- .. literalinclude:: ../../rips/PythonExamples/SelectedCases.py + SetCellResult ------- +------------- .. literalinclude:: ../../rips/PythonExamples/SetCellResult.py + SetFlowDiagnosticsResult ------- +------------------------ .. literalinclude:: ../../rips/PythonExamples/SetFlowDiagnosticsResult.py + SetGridProperties ------- +----------------- .. literalinclude:: ../../rips/PythonExamples/SetGridProperties.py + SoilAverageAsync ------- +---------------- .. literalinclude:: ../../rips/PythonExamples/SoilAverageAsync.py + SoilAverageSync ------- +--------------- .. literalinclude:: ../../rips/PythonExamples/SoilAverageSync.py + SoilPorvAsync ------- +------------- .. literalinclude:: ../../rips/PythonExamples/SoilPorvAsync.py + SoilPorvSync ------- +------------ .. literalinclude:: ../../rips/PythonExamples/SoilPorvSync.py + ViewExample ------- +----------- .. literalinclude:: ../../rips/PythonExamples/ViewExample.py diff --git a/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst b/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst index 6e5e14daa5..a10a3a0e68 100644 --- a/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst +++ b/ApplicationCode/GrpcInterface/Python/doc/source/rips.rst @@ -1,7 +1,7 @@ Instance Module =============== -.. autoclass:: rips.Instance +.. autoclass:: rips.instance.Instance :members: Example @@ -14,7 +14,7 @@ Example Case Module =========== -.. autoclass:: rips.Case +.. autoclass:: rips.case.Case :members: Example @@ -25,23 +25,10 @@ Example :lines: 5- :emphasize-lines: 5 -Commands Module -=============== - -.. autoclass:: rips.Commands - :members: - :undoc-members: - -Example -------- -.. literalinclude:: ../../rips/PythonExamples/CommandExample.py - :language: python - :lines: 5- - Grid Module =========== -.. autoclass:: rips.Grid +.. autoclass:: rips.grid.Grid :members: Example @@ -60,26 +47,21 @@ Example GridCaseGroup Module ==================== -.. autoclass:: rips.GridCaseGroup +.. autoclass:: rips.gridcasegroup.GridCaseGroup :members: Project Module ============== -.. autoclass:: rips.Project +.. autoclass:: rips.project.Project :members: -Properties Module -================= - -.. autoclass:: rips.Properties - :members: View Module =========== -.. autoclass:: rips.View +.. autoclass:: rips.view.View :members: Synchronous Example diff --git a/ApplicationCode/GrpcInterface/Python/rips/case.py b/ApplicationCode/GrpcInterface/Python/rips/case.py index ba325c6bbc..0384b91369 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/case.py +++ b/ApplicationCode/GrpcInterface/Python/rips/case.py @@ -277,25 +277,35 @@ def export_well_path_completions( ----------------------------| ------------------------------------------------ | ----- time_step | Time step to export for | Integer well_path_names | List of well path names | List - file_split | Split type: -
    -
  • 'UNIFIED_FILE'
  • -
  • 'SPLIT_ON_WELL'
  • -
  • 'SPLIT_ON_WELL_AND_COMPLETION_TYPE'
  • -
| String enum - compdat_export | Compdat export type: -
    -
  • 'TRANSMISSIBILITIES'
  • -
  • 'WPIMULT_AND_DEFAULT_CONNECTION_FACTORS'
  • -
| String enum + file_split | Controls how export data is split into files | String enum + compdat_export | Compdat export type | String enum include_perforations | Export perforations? | bool include_fishbones | Export fishbones? | bool fishbones_exclude_main_bore | Exclude main bore when exporting fishbones? | bool - combination_mode | Combination mode: -
    -
  • 'INDIVIDUALLY'
  • -
  • 'COMBINED'
  • -
| String enum + combination_mode | Settings for multiple completions in same cell | String Enum + + ##### Enum file_split + + Option | Description + ----------------------------------- | ------------ + "UNIFIED_FILE" | A single file with all combined transmissibilities + "SPLIT_ON_WELL" | One file for each well with combined transmissibilities + "SPLIT_ON_WELL_AND_COMPLETION_TYPE" | One file for each completion type for each well + + ##### Enum compdat_export + + Option | Description + ------------------------------------------- | ------------ + "TRANSMISSIBILITIES" | Direct export of transmissibilities + "WPIMULT_AND_DEFAULT_CONNECTION_FACTORS" | Include WPIMULT in addition to transmissibilities + + ##### Enum combination_mode + + Option | Description + ------------------- | ------------ + "INDIVIDUALLY" | Exports the different completion types into separate sections + "COMBINED" | Export one combined transmissibility for each cell + """ if isinstance(well_path_names, str): well_path_names = [well_path_names] @@ -337,7 +347,7 @@ def create_multiple_fractures( Create Multiple Fractures in one go Parameter | Description | Type - -----------------------| ---------------------------------- -| ----- + -----------------------| ----------------------------------------- | ----- template_id | Id of the template | Integer well_path_names | List of well path names | List of Strings min_dist_from_well_td | Minimum distance from well TD | Double @@ -381,12 +391,16 @@ def create_lgr_for_completion( refinement_i | Refinment in x-direction | Integer refinement_j | Refinment in y-direction | Integer refinement_k | Refinment in z-direction | Integer - split_type | Type of LGR split: -
    -
  • 'LGR_PER_CELL'
  • -
  • 'LGR_PER_COMPLETION'
  • -
  • 'LGR_PER_WELL'
  • -
| String enum + split_type | Defines how to split LGRS | String enum + + ##### Enum split_type + + Option | Description + ------------------------| ------------ + "LGR_PER_CELL" | One LGR for each completed cell + "LGR_PER_COMPLETION" | One LGR for each completion (fracture, perforation, ...) + "LGR_PER_WELL" | One LGR for each well + """ if isinstance(well_path_names, str): well_path_names = [well_path_names] diff --git a/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py index b9feb7de23..d2fe59fb3b 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py +++ b/ApplicationCode/GrpcInterface/Python/rips/gridcasegroup.py @@ -64,7 +64,8 @@ def compute_statistics(self, case_ids=None): """ Compute statistics for the given case ids Arguments: - case_ids(list): list of case ids. If this is None all cases in group are included + case_ids(list of integers): list of case ids. + If this is None all cases in group are included """ if case_ids is None: diff --git a/ApplicationCode/GrpcInterface/Python/rips/instance.py b/ApplicationCode/GrpcInterface/Python/rips/instance.py index d7844cd044..2b03a0caae 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/instance.py +++ b/ApplicationCode/GrpcInterface/Python/rips/instance.py @@ -208,10 +208,19 @@ def set_export_folder(self, export_type, path, create_folder=False): Parameter | Description | Type ---------------- | -------------------------------------------- | ----- - export_type | Type of export: 'COMPLETIONS', 'SNAPSHOTS' - 'PROPERTIES' or 'STATISTICS' | String + export_type | String specifying what to export | String path | Path to folder | String create_folder | Create folder if it doesn't exist? | Boolean + + ##### Enum export_type + + Option | Description + --------------- | ------------ + "COMPLETIONS" | + "SNAPSHOTS" | + "PROPERTIES" | + "STATISTICS" | + """ return self.__execute_command(setExportFolder=Cmd.SetExportFolderRequest( type=export_type, path=path, createFolder=create_folder)) @@ -219,6 +228,7 @@ def set_export_folder(self, export_type, path, create_folder=False): def set_main_window_size(self, width, height): """ Set the main window size in pixels + Parameter | Description | Type --------- | ---------------- | ----- width | Width in pixels | Integer diff --git a/ApplicationCode/GrpcInterface/Python/rips/project.py b/ApplicationCode/GrpcInterface/Python/rips/project.py index 3aebff0dcf..a13c703201 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/project.py +++ b/ApplicationCode/GrpcInterface/Python/rips/project.py @@ -23,7 +23,7 @@ class Project(PdmObject): def __init__(self, channel): self._project_stub = Project_pb2_grpc.ProjectStub(channel) PdmObject.__init__(self, self._project_stub.GetPdmObject(Empty()), - channel) + channel) def open(self, path): """Open a new project from the given path @@ -98,6 +98,7 @@ def case(self, case_id): def replace_source_cases(self, grid_list_file, case_group_id=0): """Replace all source cases within a case group + Arguments: grid_list_file (str): path to file containing a list of cases case_group_id (int): id of the case group to replace @@ -108,6 +109,7 @@ def replace_source_cases(self, grid_list_file, case_group_id=0): def create_grid_case_group(self, case_paths): """Create a Grid Case Group from a list of cases + Arguments: case_paths (list): list of file path strings Returns: @@ -129,6 +131,7 @@ def views(self): def view(self, view_id): """Get a particular view belonging to a case by providing view id + Arguments: id(int): view id Returns: a view object @@ -150,6 +153,7 @@ def grid_case_groups(self): def grid_case_group(self, group_id): """Get a particular grid case group belonging to a project + Arguments: groupId(int): group id @@ -163,6 +167,7 @@ def grid_case_group(self, group_id): def export_multi_case_snapshots(self, grid_list_file): """Export snapshots for a set of cases + Arguments: grid_list_file (str): Path to a file containing a list of grids to export snapshot for """ @@ -172,6 +177,7 @@ def export_multi_case_snapshots(self, grid_list_file): def export_snapshots(self, snapshot_type='ALL', prefix=''): """ Export all snapshots of a given type + Arguments: snapshot_type (str): Enum string ('ALL', 'VIEWS' or 'PLOTS') prefix (str): Exported file name prefix @@ -182,6 +188,7 @@ def export_snapshots(self, snapshot_type='ALL', prefix=''): def export_well_paths(self, well_paths=None, md_step_size=5.0): """ Export a set of well paths + Arguments: well_paths(list): List of strings of well paths. If none, export all. md_step_size(double): resolution of the exported well path @@ -193,17 +200,33 @@ def export_well_paths(self, well_paths=None, md_step_size=5.0): return self._execute_command(exportWellPaths=Cmd.ExportWellPathRequest( wellPathNames=well_paths, mdStepSize=md_step_size)) - def scale_fracture_template(self, template_id, half_length, height, dfactor, - conductivity): + def scale_fracture_template(self, template_id, half_length, height, + d_factor, conductivity): + """ Scale fracture template parameters + + Arguments: + template_id(int): ID of fracture template + half_length (double): Half Length scale factor + height (double): Height scale factor + d_factor (double): D-factor scale factor + conductivity (double): Conductivity scale factor + """ return self._execute_command( scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest( id=template_id, halfLength=half_length, height=height, - dFactor=dfactor, + dFactor=d_factor, conductivity=conductivity)) - def set_fracture_containment(self, fracture_id, top_layer, base_layer): + def set_fracture_containment(self, template_id, top_layer, base_layer): + """ Set fracture template containment parameters + + Arguments: + template_id(int): ID of fracture template + top_layer (int): Top layer containment + base_layer (int): Base layer containment + """ return self._execute_command( setFractureContainment=Cmd.SetFracContainmentRequest( - id=fracture_id, topLayer=top_layer, baseLayer=base_layer)) + id=template_id, topLayer=top_layer, baseLayer=base_layer)) diff --git a/ApplicationCode/GrpcInterface/Python/rips/view.py b/ApplicationCode/GrpcInterface/Python/rips/view.py index 3e9aabb67b..1c31cc7703 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/view.py +++ b/ApplicationCode/GrpcInterface/Python/rips/view.py @@ -66,20 +66,22 @@ def apply_flow_diagnostics_cell_result( producers=None): """Apply a flow diagnostics cell result - Arguments: - result_variable (str): String representing the result value - The valid values are 'TOF', 'Fraction', 'MaxFractionTracer' and 'Communication'. - selection_mode (str): String specifying which tracers to select. - The valid values are - - FLOW_TR_INJ_AND_PROD (all injector and producer tracers), - - FLOW_TR_PRODUCERS (all producers) - - FLOW_TR_INJECTORS (all injectors), - - FLOW_TR_BY_SELECTION (specify individual tracers in the - injectors and producers variables) - injectors (list): List of injector names (strings) to select. - Requires selection_mode to be 'FLOW_TR_BY_SELECTION'. - producers (list): List of producer tracers (strings) to select. - Requires selection_mode to be 'FLOW_TR_BY_SELECTION'. + Parameter | Description | Type + ------------------- | ------------------------------------------------------ | ----- + result_variable | String representing the result value | String + selection_mode | String specifying which tracers to select | String + injectors | List of injector names, used by 'FLOW_TR_BY_SELECTION' | String List + producers | List of injector names, used by 'FLOW_TR_BY_SELECTION' | String List + + ##### Enum compdat_export + + Option | Description + ------------------------| ------------ + "TOF" | Time of flight + "Fraction" | Fraction + "MaxFractionTracer" | Max Fraction Tracer + "Communication" | Communication + """ if injectors is None: injectors = [] @@ -110,6 +112,7 @@ def clone(self): return self.case().view(view_id) def set_time_step(self, time_step): + """Set the time step for current view""" case_id = self.case().case_id return self._execute_command(setTimeStep=Cmd.SetTimeStepParams( caseId=case_id, viewId=self.view_id, timeStep=time_step)) @@ -117,6 +120,31 @@ def set_time_step(self, time_step): def export_sim_well_fracture_completions(self, time_step, simulation_well_names, file_split, compdat_export): + """Export fracture completions for simulation wells + + Parameter | Description | Type + ----------------------------| ------------------------------------------------ | ----- + time_step | Time step to export for | Integer + simulation_well_names | List of simulation well names | List + file_split | Controls how export data is split into files | String enum + compdat_export | Compdat export type | String enum + + ##### Enum file_split + + Option | Description + ----------------------------------- | ------------ + "UNIFIED_FILE" Default Option| A single file with all transmissibilities + "SPLIT_ON_WELL" | One file for each well transmissibilities + "SPLIT_ON_WELL_AND_COMPLETION_TYPE" | One file for each completion type for each well + + ##### Enum compdat_export + + Option | Description + -----------------------------------------| ------------ + "TRANSMISSIBILITIES"Default Option| Direct export of transmissibilities + "WPIMULT_AND_DEFAULT_CONNECTION_FACTORS" | Include export of WPIMULT + + """ if isinstance(simulation_well_names, str): simulation_well_names = [simulation_well_names] @@ -135,6 +163,15 @@ def export_visible_cells(self, visible_active_cells_value=1, hidden_active_cells_value=0, inactive_cells_value=0): + """Export special properties for all visible cells. + + Arguments: + export_keyword (string): The keyword to export. + Choices: 'FLUXNUM' or 'MULTNUM'. Default: 'FLUXNUM' + visible_active_cells_value (int): Value to export forvisible active cells. Default: 1 + hidden_active_cells_value (int): Value to export for hidden active cells. Default: 0 + inactive_cells_value (int): Value to export for inactive cells. Default: 0 + """ case_id = self.case().case_id return self._execute_command( exportVisibleCells=Cmd.ExportVisibleCellsRequest( @@ -149,7 +186,7 @@ def export_property(self, undefined_value=0.0): """ Export the current Eclipse property from the view Arguments: - undefined_value (double): Value to use for undefined values. Defaults to 0.0 + undefined_value (double): Value to use for undefined values. Defaults to 0.0 """ case_id = self.case().case_id return self._execute_command( @@ -160,10 +197,13 @@ def export_property(self, undefined_value=0.0): def export_snapshot(self, prefix=''): """ Export snapshot for the current view + Arguments: prefix (str): Exported file name prefix """ case_id = self.case().case_id return self._execute_command( - exportSnapshots=Cmd.ExportSnapshotsRequest( - type='VIEWS', prefix=prefix, caseId=case_id, viewId=self.view_id)) + exportSnapshots=Cmd.ExportSnapshotsRequest(type='VIEWS', + prefix=prefix, + caseId=case_id, + viewId=self.view_id)) From 6694ad40f30d54cf5c8322e4abc58dbbc6040565 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 24 Sep 2019 18:18:07 +0200 Subject: [PATCH 19/27] Set version to 2019.08.2-rc1 --- ResInsightVersion.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 86c856eba2..0b7809462e 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,10 +1,10 @@ set(RESINSIGHT_MAJOR_VERSION 2019) set(RESINSIGHT_MINOR_VERSION 08) -set(RESINSIGHT_PATCH_VERSION 1) +set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions -#set(RESINSIGHT_VERSION_TEXT "-rc1") +set(RESINSIGHT_VERSION_TEXT "-rc1") # Optional text # Must be unique and increasing within one combination of major/minor/patch version From d6e669b188f2a5fd8f594988cdac3bb8d7222a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 25 Sep 2019 15:49:23 +0200 Subject: [PATCH 20/27] #4767 Fix selection of view subitems jumps to view --- ApplicationCode/UserInterface/RiuMainWindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 094a3c0c30..88834d1437 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -1441,7 +1441,10 @@ void RiuMainWindow::selectedObjectsChanged() // Set focus in MDI area to this window if it exists if (selectedReservoirView->viewer()) { + setBlockSlotSubWindowActivated(true); setActiveViewer(selectedReservoirView->viewer()->layoutWidget()); + setBlockSlotSubWindowActivated(false); + isActiveViewChanged = true; } } From 67b156848b59fec98587af0b37d3f4273504936f Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 27 Sep 2019 14:40:03 +0200 Subject: [PATCH 21/27] Merge pull request #4768 from OPM/bug-libecl-crash2 #4762 Fix reset_actnum libecl crash on load --- ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp index 09cd1a0d6b..2396395372 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp @@ -290,17 +290,13 @@ const int * ecl_coarse_cell_get_box_ptr( const ecl_coarse_cell_type * coarse_cel void ecl_coarse_cell_update_index( ecl_coarse_cell_type * coarse_cell , int global_index , int * active_index , int * active_fracture_index , int active_value) { if (active_value & CELL_ACTIVE_MATRIX) { - if (coarse_cell->active_index == -1) { - coarse_cell->active_index = *active_index; - (*active_index) += 1; - } + coarse_cell->active_index = *active_index; + (*active_index) += 1; } if (active_value & CELL_ACTIVE_FRACTURE) { - if (coarse_cell->active_fracture_index == -1) { - coarse_cell->active_fracture_index = *active_fracture_index; - (*active_fracture_index) += 1; - } + coarse_cell->active_fracture_index = *active_fracture_index; + (*active_fracture_index) += 1; } int_vector_append( coarse_cell->active_cells , global_index ); From 1fce817d0787ed940fff6765b307bd860ecc2027 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 27 Sep 2019 14:47:27 +0200 Subject: [PATCH 22/27] Merge pull request #4791 from OPM/fix-e300-wrong-date --- .../RifEclipseOutputFileTools.cpp | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp index 0d8771893b..461d4595cc 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp @@ -153,6 +153,32 @@ void RifEclipseOutputFileTools::timeSteps(const ecl_file_type* ecl_file, std::ve } } + bool allTimeStepsOnSameDate = true; + { + // See https://github.com/OPM/ResInsight/issues/4770 + + std::set days; + std::set months; + std::set years; + for ( int i = 0; i < numINTEHEAD; i++ ) + { + ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw( ecl_file, INTEHEAD_KW, i ); + CVF_ASSERT( kwINTEHEAD ); + int day = 0; + int month = 0; + int year = 0; + getDayMonthYear( kwINTEHEAD, &day, &month, &year ); + + days.insert( day ); + months.insert( month ); + years.insert( year ); + } + + if ( days.size() > 1 ) allTimeStepsOnSameDate = false; + if ( months.size() > 1 ) allTimeStepsOnSameDate = false; + if ( years.size() > 1 ) allTimeStepsOnSameDate = false; + } + std::set existingTimesteps; for (int i = 0; i < numINTEHEAD; i++) @@ -167,8 +193,14 @@ void RifEclipseOutputFileTools::timeSteps(const ecl_file_type* ecl_file, std::ve QDateTime reportDateTime = RiaQDateTimeTools::createUtcDateTime(QDate(year, month, day)); CVF_ASSERT(reportDateTime.isValid()); - double dayValue = dayValues[i]; - double dayFraction = dayValue - cvf::Math::floor(dayValue); + double dayDoubleValue = dayValues[i]; + int dayValue = cvf::Math::floor( dayDoubleValue ); + if ( allTimeStepsOnSameDate ) + { + reportDateTime = reportDateTime.addDays( dayValue ); + } + + double dayFraction = dayDoubleValue - dayValue; double milliseconds = dayFraction * 24.0 * 60.0 * 60.0 * 1000.0; reportDateTime = reportDateTime.addMSecs(milliseconds); From d05d8f5ee3715bf26d2ae815536149501100f589 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Oct 2019 11:03:51 +0200 Subject: [PATCH 23/27] #4766 Crash when Show plot data for ensemble with a stopped simulation --- .../Application/Tools/RiaTimeHistoryCurveResampler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp index 5162476970..a51523ba7d 100644 --- a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp @@ -54,6 +54,11 @@ RiaTimeHistoryCurveResampler::RiaTimeHistoryCurveResampler() //-------------------------------------------------------------------------------------------------- void RiaTimeHistoryCurveResampler::setCurveData(const std::vector& values, const std::vector& timeSteps) { + if (values.empty() || timeSteps.empty()) + { + return; + } + CVF_ASSERT(values.size() == timeSteps.size()); clearData(); From ad7e2ff7177ecf64605669ef63e939daaf3c5e77 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Oct 2019 11:04:36 +0200 Subject: [PATCH 24/27] Upped to version 2019.08.2-rc1 --- ResInsightVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 0b7809462e..bca2610b86 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -4,7 +4,7 @@ set(RESINSIGHT_MINOR_VERSION 08) set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions -set(RESINSIGHT_VERSION_TEXT "-rc1") +set(RESINSIGHT_VERSION_TEXT "-rc2") # Optional text # Must be unique and increasing within one combination of major/minor/patch version From c976dcebc8b7c902af576905b9525c15671c6b9b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Oct 2019 12:57:51 +0200 Subject: [PATCH 25/27] #4713 Summary Case : Use "Calculated" as shortname for calculated case Seen by running regression tests --- .../ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp index e8c8075ced..a04c556fe3 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp @@ -32,6 +32,7 @@ RimCalculatedSummaryCase::RimCalculatedSummaryCase() CAF_PDM_InitObject("Calculated",":/SummaryCase48x48.png","",""); m_calculatedCurveReader = nullptr; + m_shortName = "Calculated"; } //-------------------------------------------------------------------------------------------------- From 1025a0f6b79eeb82239261e61269051c0b8c75a3 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Oct 2019 12:58:25 +0200 Subject: [PATCH 26/27] Upped to version 2019.08.2-rc3 --- ResInsightVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index bca2610b86..8167d74005 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -4,7 +4,7 @@ set(RESINSIGHT_MINOR_VERSION 08) set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions -set(RESINSIGHT_VERSION_TEXT "-rc2") +set(RESINSIGHT_VERSION_TEXT "-rc3") # Optional text # Must be unique and increasing within one combination of major/minor/patch version From 459f4709135e9ed4f7066761f64da4b731a17a64 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 1 Oct 2019 13:08:09 +0200 Subject: [PATCH 27/27] Upped to version 2019.08.2 --- ResInsightVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 8167d74005..8af8784a2a 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -4,7 +4,7 @@ set(RESINSIGHT_MINOR_VERSION 08) set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions -set(RESINSIGHT_VERSION_TEXT "-rc3") +#set(RESINSIGHT_VERSION_TEXT "-rc3") # Optional text # Must be unique and increasing within one combination of major/minor/patch version