Merge pull request #4680 from OPM/patch-2019.08.1

#4660 Cherry-pick commits for patch 2019.08.1
This commit is contained in:
Gaute Lindkvist 2019-09-04 14:24:28 +02:00 committed by GitHub
commit 800a7dd5f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 354 additions and 86 deletions

View File

@ -105,6 +105,7 @@ RiaPreferences::RiaPreferences(void)
CAF_PDM_InitField(&pythonExecutable, "pythonExecutable", QString("python"), "Python Executable Location", "", "", "");
pythonExecutable.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
pythonExecutable.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP);
CAF_PDM_InitField(&showPythonDebugInfo, "pythonDebugInfo", false, "Show Python Debug Info", "", "", "");
CAF_PDM_InitField(&ssihubAddress, "ssihubAddress", QString("http://"), "SSIHUB Address", "", "", "");
ssihubAddress.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP);
@ -318,8 +319,9 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
#ifdef ENABLE_GRPC
caf::PdmUiGroup* pythonGroup = uiOrdering.addNewGroup("Python");
pythonGroup->add(&enableGrpcServer);
pythonGroup->add(&showPythonDebugInfo);
pythonGroup->add(&defaultGrpcPortNumber);
pythonGroup->add(&pythonExecutable);
pythonGroup->add(&pythonExecutable);
#endif
caf::PdmUiGroup* scriptGroup = uiOrdering.addNewGroup("Script files");
scriptGroup->add(&scriptDirectories);

View File

@ -89,6 +89,7 @@ public: // Pdm Fields
caf::PdmField<bool> octaveShowHeaderInfoWhenExecutingScripts;
caf::PdmField<QString> pythonExecutable;
caf::PdmField<bool> showPythonDebugInfo;
caf::PdmField<QString> ssihubAddress;

View File

@ -13,8 +13,8 @@ if (RESINSIGHT_BUILD_WITH_QT5)
endif(RESINSIGHT_BUILD_WITH_QT5)
if (Qt5Core_FOUND)
find_package(Qt5 CONFIG REQUIRED Core Gui OpenGL Network Script Widgets)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Widgets)
find_package(Qt5 CONFIG REQUIRED Core Gui OpenGL Network Script Widgets Xml Concurrent PrintSupport)
set(QT_LIBRARIES Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Widgets Qt5::Xml Qt5::Concurrent Qt5::PrintSupport)
else()
set (QT_COMPONENTS_REQUIRED QtCore QtGui QtMain QtOpenGl QtNetwork QtScript)
find_package(Qt4 COMPONENTS ${QT_COMPONENTS_REQUIRED} REQUIRED)
@ -713,7 +713,7 @@ if (RESINSIGHT_PRIVATE_INSTALL)
add_custom_command(
TARGET ResInsight
POST_BUILD
COMMAND ${RESINSIGHT_GRPC_PYTHON_EXECUTABLE} -m pip install --target=${GRPC_PYTHON_SOURCE_PATH} grpcio
COMMAND ${RESINSIGHT_GRPC_PYTHON_EXECUTABLE} -m pip install --target=${GRPC_PYTHON_SOURCE_PATH} grpcio-tools
)
endif()
install(DIRECTORY ${GRPC_PYTHON_SOURCE_PATH}/ DESTINATION ${RESINSIGHT_INSTALL_FOLDER}/Python)

View File

@ -21,9 +21,12 @@
#include "RicScriptFeatureImpl.h"
#include "RimCalcScript.h"
#include "RiaApplication.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
#include "RimCalcScript.h"
#include "RiuMainWindow.h"
#include "RiuProcessMonitor.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
@ -31,6 +34,8 @@
#include <QAction>
#include <QFileInfo>
#include <iostream>
CAF_CMD_SOURCE_INIT(RicExecuteScriptFeature, "RicExecuteScriptFeature");
//--------------------------------------------------------------------------------------------------
@ -71,7 +76,35 @@ void RicExecuteScriptFeature::onActionTriggered(bool isChecked)
if (!pythonPath.isEmpty())
{
QStringList arguments = RimCalcScript::createCommandLineArguments(calcScript->absoluteFileName());
RiaApplication::instance()->launchProcess(pythonPath, arguments, app->pythonProcessEnvironment());
QProcessEnvironment penv = app->pythonProcessEnvironment();
RiuProcessMonitor* processMonitor = RiuMainWindow::instance()->processMonitor();
if (RiaApplication::instance()->preferences()->showPythonDebugInfo() && processMonitor)
{
QStringList debugInfo;
debugInfo << "----- Launching Python interpreter -----";
debugInfo << "Python interpreter path: " + pythonPath;
debugInfo << "Using arguments: ";
for (QString argument : arguments)
{
debugInfo << "* " + argument;
}
QStringList envList = penv.toStringList();
debugInfo << "Using environment: ";
for (QString envVariable : envList)
{
debugInfo << "* " + envVariable;
}
debugInfo << "------------------------------------";
for (QString debugString : debugInfo)
{
std::cout << debugString.toStdString() << std::endl;
processMonitor->addStringToLog(debugString + "\n");
}
}
RiaApplication::instance()->launchProcess(pythonPath, arguments, penv);
}
}
}

View File

@ -7,4 +7,12 @@ rips.egg-info
setup.py
grpc
grpcio*
six*
six*
easy_install*
bin*
grpc_tools
pkg_resources
google
protobuf*
setuptools*
extern*

View File

@ -0,0 +1,26 @@
######################################################################
# All this is based on the MANIFEST.in and setup.py in Python-folder
######################################################################
# 1. Make sure dist folder is clear
del dist/*
# 2. Update rips-version tag in setup.py (".N after ResInsight version"). This is generated from setup.py.cmake
# So that you for instance have version 2019.08.1 of rips.
# 3. Build source distribution
python setup.py sdist
# 4. Test upload to test.pypi.org. This requires a ResInsight testpypi-user and you will be prompted for username and password
python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
# 5. Test install rips module.
pip install --index-url https://test.pypi.org/simple/ rips
# 6. Test the newly installed module
# 8. If anything is wrong, start again from 1. with an incremented rips-version (ResInsightVersion.2+)
# These incremented versions are just for testpypi and you can reset back to the wanted version before real upload
# 9. Upload to real Pypi. This requires a ResInsight pypi-user.
python -m twine upload dist/*

View File

@ -0,0 +1,79 @@
+++
title = "Python Examples"
published = true
weight = 40
+++
![]({{< relref "" >}}images/scripting/python-logo-master-v3-TM.png)
This pages is created based on the content in the **PythonExamples** folder located inside the **rips** module, made available online for convenience.
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

View File

@ -1,2 +1,9 @@
.. include:: header.rst
+++
title = "Python API - rips"
published = true
weight = 42
+++
![]({{< relref "" >}}images/scripting/python-logo-master-v3-TM.png)
.. include:: rips.rst

View File

@ -1,20 +0,0 @@
+++
title = "Python API - rips"
published = true
weight = 40
+++
ResInsight has a `gRPC Remote Procedure Call <https://www.grpc.io/>`_ interface with a Python Client interface. This interface allows you to interact with a running ResInsight instance from a Python script.
The Python client package is available for install via the Python PIP package system with ``pip install rips`` as admin user, or ``pip install --user rips`` as a regular user.
On some systems the ``pip`` command may have to be replaced by ``python -m pip``.
In order for gRPC to be available, ResInsight needs to be built with the ``RESINSIGHT_ENABLE_GRPC`` option set. A valid gRPC build will show a message in the About dialog confirming gRPC is available:
.. image:: {{< relref "" >}}images/scripting/AboutGrpc.png
Furthermore, gRPC needs to be enabled in the Scripting tab of the Preference dialog:
.. image:: {{< relref "" >}}images/scripting/PrefGrpc.png

View File

@ -92,13 +92,9 @@ class Case (PdmObject):
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
Returns:
Stream of cell info objects with the following attributes:
grid_index(int): grid the cell belongs to
parent_grid_index(int): parent of the grid the cell belongs to
coarsening_box_index(int): the coarsening box index
local_ijk(Vec3i: i(int), j(int), k(int)): local cell index in i, j, k directions.
parent_ijk(Vec3i: i(int), j(int), k(int)): cell index in parent grid in i, j, k.
Stream of **CellInfo** objects
See cellInfoForActiveCells() for detalis on the **CellInfo** class.
"""
porosityModelEnum = Case_pb2.PorosityModelType.Value(porosityModel)
request = Case_pb2.CellInfoRequest(case_request=self.request,
@ -113,12 +109,26 @@ class Case (PdmObject):
must be 'MATRIX_MODEL' or 'FRACTURE_MODEL'.
Returns:
List of cell info objects with the following attributes:
grid_index(int): grid the cell belongs to
parent_grid_index(int): parent of the grid the cell belongs to
coarsening_box_index(int): the coarsening box index
local_ijk(Vec3i: i(int), j(int), k(int)): local cell index in i, j, k directions.
parent_ijk(Vec3i: i(int), j(int), k(int)): cell index in parent grid in i, j, k.
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
"""
activeCellInfoChunks = self.cellInfoForActiveCellsAsync()
receivedActiveCells = []
@ -128,7 +138,21 @@ class Case (PdmObject):
return receivedActiveCells
def timeSteps(self):
"""Get a list containing time step strings for all time steps"""
"""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 daysSinceStart(self):

View File

@ -10,14 +10,13 @@ import Commands_pb2_grpc as CmdRpc
import rips.Case
class Commands:
"""Command executor which can run ResInsight Command File commands nearly verbatim
Documentation Command File Interface:
https://resinsight.org/docs/commandfile/
"""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.
- 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):
@ -263,6 +262,19 @@ class Commands:
return self.__execute(createSaturationPressurePlots=Cmd.CreateSatPressPlotRequest(caseIds=caseIds))
def exportFlowCharacteristics(self, caseId, timeSteps, injectors, producers, fileName, minimumCommunication=0.0, aquiferCellThreshold=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
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
"""
if isinstance(timeSteps, int):
timeSteps = [timeSteps]
if isinstance(injectors, str):

View File

@ -1,6 +1,6 @@
###################################################################################
# This example will connect to ResInsight, retrieve a list of cases and print info
# Also creates a new view for all cases
#
###################################################################################
# Import the ResInsight Processing Server Module
@ -16,7 +16,11 @@ if resInsight is not None:
for case in cases:
print("Case name: " + case.name)
print("Case grid path: " + case.gridPath())
# Create a new view
view = case.createView()
timesteps = case.timeSteps()
for t in timesteps:
print("Year: " + str(t.year))
print("Month: " + str(t.month))

View File

@ -2,5 +2,5 @@ import rips
resInsight = rips.Instance.find()
if resInsight is not None:
print(resInsight.app.versionString())
print("Is this a console run?", resInsight.app.isConsole())
print(resInsight.versionString())
print("Is this a console run?", resInsight.isConsole())

View File

@ -1,9 +1,9 @@
name = "rips"
from .Case import Case
from .Grid import Grid
from .Properties import Properties
from .Instance import Instance
from .Commands import Commands
from .PdmObject import PdmObject
from .View import View
from .Project import Project
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

View File

@ -6,7 +6,7 @@ with open('README.md') as f:
with open('LICENSE') as f:
license = f.read()
RIPS_DIST_VERSION = '9'
RIPS_DIST_VERSION = '1'
setup(
name='rips',
@ -17,6 +17,6 @@ setup(
author_email='info@ceetronsolutions.com',
url='http://www.resinsight.org',
license=license,
include_package_data=True,
packages=['rips', 'rips.generated', 'rips.examples', 'rips.tests']
packages=['rips'],
package_data={'rips': ['*.py', 'generated/*.py', 'PythonExamples/*.py', 'tests/*.py']}
)

View File

@ -54,8 +54,8 @@ public:
///
//--------------------------------------------------------------------------------------------------
RiaCellResultsStateHandler(bool clientStreamer = false)
: m_request(nullptr)
, m_eclipseCase(nullptr)
: m_eclipseCase(nullptr)
, m_porosityModel(RiaDefines::MATRIX_MODEL)
, m_streamedValueCount(0u)
, m_cellCount(0u)
, m_clientStreamer(clientStreamer)
@ -83,26 +83,24 @@ public:
//--------------------------------------------------------------------------------------------------
Status init(const PropertyRequest* request)
{
m_request = request;
int caseId = request->case_request().id();
m_eclipseCase = dynamic_cast<RimEclipseCase*>(RiaGrpcServiceInterface::findCase(caseId));
if (m_eclipseCase)
{
auto porosityModel = static_cast<RiaDefines::PorosityModelType>(request->porosity_model());
auto caseData = m_eclipseCase->eclipseCaseData();
auto resultData = caseData->results(porosityModel);
auto resultType = static_cast<RiaDefines::ResultCatType>(request->property_type());
size_t timeStep = static_cast<size_t>(request->time_step());
m_resultAddress = RigEclipseResultAddress(resultType, QString::fromStdString(request->property_name()));
m_porosityModel = static_cast<RiaDefines::PorosityModelType>(request->porosity_model());
auto caseData = m_eclipseCase->eclipseCaseData();
auto resultData = caseData->results(m_porosityModel);
auto resultType = static_cast<RiaDefines::ResultCatType>(request->property_type());
size_t timeStep = static_cast<size_t>(request->time_step());
m_resultAddress = RigEclipseResultAddress(resultType, QString::fromStdString(request->property_name()));
if (resultData->ensureKnownResultLoaded(m_resultAddress))
{
if (timeStep < resultData->timeStepCount(m_resultAddress))
{
initResultAccess(caseData, request->grid_index(), porosityModel, timeStep, m_resultAddress);
initResultAccess(caseData, request->grid_index(), m_porosityModel, timeStep, m_resultAddress);
return grpc::Status::OK;
}
return grpc::Status(grpc::NOT_FOUND, "No such time step");
@ -120,7 +118,7 @@ public:
scalarResultFrames.resize(timeStepCount);
if (timeStep < resultData->timeStepCount(m_resultAddress))
{
initResultAccess(caseData, request->grid_index(), porosityModel, timeStep, m_resultAddress);
initResultAccess(caseData, request->grid_index(), m_porosityModel, timeStep, m_resultAddress);
return grpc::Status::OK;
}
return grpc::Status(grpc::NOT_FOUND, "No such time step");
@ -198,9 +196,8 @@ public:
{
if (m_eclipseCase)
{
auto porosityModel = static_cast<RiaDefines::PorosityModelType>(m_request->porosity_model());
auto caseData = m_eclipseCase->eclipseCaseData();
auto resultData = caseData->results(porosityModel);
auto resultData = caseData->results(m_porosityModel);
resultData->recalculateStatistics(m_resultAddress);
for (Rim3dView* view : m_eclipseCase->views())
@ -221,12 +218,12 @@ protected:
virtual void setCellResult(size_t currentCellIndex, double value) = 0;
protected:
const rips::PropertyRequest* m_request;
RimEclipseCase* m_eclipseCase;
size_t m_streamedValueCount;
size_t m_cellCount;
bool m_clientStreamer;
RigEclipseResultAddress m_resultAddress;
RimEclipseCase* m_eclipseCase;
RiaDefines::PorosityModelType m_porosityModel;
size_t m_streamedValueCount;
size_t m_cellCount;
bool m_clientStreamer;
RigEclipseResultAddress m_resultAddress;
};
class RiaActiveCellResultsStateHandler : public RiaCellResultsStateHandler

View File

@ -437,7 +437,12 @@ const RigActiveCellInfo* RigCaseCellResultsData::activeCellInfo() const
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::recalculateStatistics(const RigEclipseResultAddress& resVarAddr)
{
m_statisticsDataCache[findScalarResultIndexFromAddress(resVarAddr)]->clearAllStatistics();
size_t scalarResultIndex = findScalarResultIndexFromAddress(resVarAddr);
CVF_TIGHT_ASSERT(scalarResultIndex < m_cellScalarResults.size());
if (scalarResultIndex < m_cellScalarResults.size())
{
m_statisticsDataCache[scalarResultIndex]->clearAllStatistics();
}
}
//--------------------------------------------------------------------------------------------------

90
Fwk/AppFwk/.clang-format Normal file
View File

@ -0,0 +1,90 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 130
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: true
JavaScriptQuotes: Leave
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...