mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4817 #4830 #4832 #4837 #4839 Python commands for WBS creation, well path import and well log file import (#4838)
* Better minimum width for well log tracks * Fix alignment of scrollbar in Well log plots * Better Well Log Plot export * Hide scroll bar before plotting * Better borders * Create plots through Python * #4817 Create WBS plots with Python * Rebase Summary and WellLogPlot on top of a new RimPlot * Also Python: Allow setting folder as a parameter to export_snapshots * #4832 Prepare for well path import command * Well Path import WIP * #4830 #4832 Import well paths and well log files from file using Python. * #4837 Implement import of formation names in Python * Fix debug build issue * Fix RiaLogging build issue * Fix warnings * Yet another RiaLogging.h import added * #4839 Import exporting of las and ascii files from well log plots
This commit is contained in:
@@ -14,7 +14,9 @@ if resinsight is not None:
|
||||
|
||||
print ("Got " + str(len(cases)) + " cases: ")
|
||||
for case in cases:
|
||||
print("Case id: " + str(case.case_id))
|
||||
print("Case name: " + case.name)
|
||||
print("Case type: " + case.type)
|
||||
print("Case grid path: " + case.grid_path())
|
||||
|
||||
timesteps = case.time_steps()
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import os
|
||||
# Load ResInsight Processing Server Client Library
|
||||
import rips
|
||||
# Connect to ResInsight instance
|
||||
resInsight = rips.Instance.find()
|
||||
|
||||
cases = resInsight.project.cases()
|
||||
|
||||
well_paths = resInsight.project.import_well_paths(well_path_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_LessWellPaths')
|
||||
well_log_files = resInsight.project.import_well_log_files(well_log_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_PLT_LAS')
|
||||
|
||||
if len(well_paths) < 1:
|
||||
print("No well paths in project")
|
||||
exit(1)
|
||||
print(well_paths)
|
||||
|
||||
for case in cases:
|
||||
if case.type == "GeoMechCase":
|
||||
print (case.case_id)
|
||||
case_path = case.grid_path()
|
||||
folder_name = os.path.dirname(case_path)
|
||||
case.import_formation_names(formation_files=['D:/Projects/ResInsight-regression-test/ModelData/norne/Norne_ATW2013.lyr'])
|
||||
|
||||
# create a folder to hold the snapshots
|
||||
dirname = os.path.join(folder_name, 'snapshots')
|
||||
print("Exporting to: " + dirname)
|
||||
|
||||
for well_path in well_paths:
|
||||
wbsplot = case.create_well_bore_stability_plot(well_path=well_path, time_step=0)
|
||||
wbsplot.export_snapshot(export_folder=dirname)
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import rips
|
||||
import grpc
|
||||
import tempfile
|
||||
|
||||
resinsight = rips.Instance.find()
|
||||
|
||||
@@ -14,7 +15,25 @@ case = None
|
||||
try:
|
||||
case = resinsight.project.load_case("Nonsense")
|
||||
except grpc.RpcError as e:
|
||||
print("Expected Server Exception Received: ", e)
|
||||
print("Expected Server Exception Received while loading case: ", e)
|
||||
|
||||
# Try loading well paths from a non-existing folder. We should get a grpc.RpcError exception from the server
|
||||
try:
|
||||
well_path_files = resinsight.project.import_well_paths(well_path_folder="NONSENSE/NONSENSE")
|
||||
except grpc.RpcError as e:
|
||||
print("Expected Server Exception Received while loading wellpaths: ", e)
|
||||
|
||||
# Try loading well paths from an existing but empty folder. We should get a warning.
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
well_path_files = resinsight.project.import_well_paths(well_path_folder=tmpdirname)
|
||||
assert(len(well_path_files) == 0)
|
||||
assert(resinsight.project.has_warnings())
|
||||
print("Should get warnings below")
|
||||
for warning in resinsight.project.warnings():
|
||||
print (warning)
|
||||
except grpc.RpcError as e:
|
||||
print("Unexpected Server Exception caught!!!", e)
|
||||
|
||||
case = resinsight.project.case(case_id=0)
|
||||
if case is not None:
|
||||
@@ -53,5 +72,5 @@ if case is not None:
|
||||
except IndexError:
|
||||
print ("Got expected index out of bounds error on client side")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Import the tempfile module
|
||||
import tempfile
|
||||
# Load ResInsight Processing Server Client Library
|
||||
import rips
|
||||
# Connect to ResInsight instance
|
||||
resInsight = rips.Instance.find()
|
||||
|
||||
# Get a list of all plots
|
||||
plots = resInsight.project.plots()
|
||||
|
||||
export_folder = tempfile.mkdtemp()
|
||||
|
||||
print("Exporting to: " + export_folder)
|
||||
|
||||
for plot in plots:
|
||||
plot.export_snapshot(export_folder=export_folder)
|
||||
plot.export_data_as_las(export_folder=export_folder)
|
||||
plot.export_data_as_ascii(export_folder=export_folder)
|
||||
@@ -0,0 +1,32 @@
|
||||
# Load ResInsight Processing Server Client Library
|
||||
import rips
|
||||
# Connect to ResInsight instance
|
||||
resInsight = rips.Instance.find()
|
||||
|
||||
well_path_names = resInsight.project.import_well_paths(well_path_folder='D:/Projects/ResInsight-regression-test/ModelData/norne/wellpaths')
|
||||
if resInsight.project.has_warnings():
|
||||
for warning in resInsight.project.warnings():
|
||||
print(warning)
|
||||
|
||||
|
||||
for well_path_name in well_path_names:
|
||||
print("Imported from folder: " + well_path_name)
|
||||
|
||||
well_path_names = resInsight.project.import_well_paths(well_path_files=['D:/Projects/ResInsight-regression-test/ModelData/Norne_WellPaths/E-3H.json',
|
||||
'D:/Projects/ResInsight-regression-test/ModelData/Norne_WellPaths/C-1H.json'])
|
||||
if resInsight.project.has_warnings():
|
||||
for warning in resInsight.project.warnings():
|
||||
print(warning)
|
||||
|
||||
|
||||
for well_path_name in well_path_names:
|
||||
print("Imported from indivdual files: " + well_path_name)
|
||||
|
||||
|
||||
well_path_names = resInsight.project.import_well_log_files(well_log_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_PLT_LAS')
|
||||
if resInsight.project.has_warnings():
|
||||
for warning in resInsight.project.warnings():
|
||||
print(warning)
|
||||
|
||||
for well_path_name in well_path_names:
|
||||
print("Imported well log file for: " + well_path_name)
|
||||
@@ -9,4 +9,5 @@ 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
|
||||
from rips.project import Project
|
||||
from rips.plot import Plot
|
||||
@@ -25,7 +25,7 @@ class Case(PdmObject):
|
||||
|
||||
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
|
||||
methods in Project: loadCase, case, allCases, selectedCases
|
||||
|
||||
Attributes:
|
||||
id (int): Case Id corresponding to case Id in ResInsight project.
|
||||
@@ -37,11 +37,12 @@ class Case(PdmObject):
|
||||
However we need overhead space, so the default is 8160.
|
||||
This leaves 256B for overhead.
|
||||
"""
|
||||
def __init__(self, channel, case_id):
|
||||
def __init__(self, channel, case_id, project):
|
||||
# Private properties
|
||||
self.__channel = channel
|
||||
self.__case_stub = Case_pb2_grpc.CaseStub(channel)
|
||||
self.__request = Case_pb2.CaseRequest(id=case_id)
|
||||
self.__project = project
|
||||
|
||||
info = self.__case_stub.GetCaseInfo(self.__request)
|
||||
self.__properties_stub = Properties_pb2_grpc.PropertiesStub(
|
||||
@@ -51,7 +52,9 @@ class Case(PdmObject):
|
||||
|
||||
# Public properties
|
||||
self.case_id = case_id
|
||||
self.group_id = info.group_id
|
||||
self.name = info.name
|
||||
self.type = info.type
|
||||
self.chunk_size = 8160
|
||||
|
||||
def __grid_count(self):
|
||||
@@ -248,16 +251,17 @@ class Case(PdmObject):
|
||||
self._execute_command(createView=Cmd.CreateViewRequest(
|
||||
caseId=self.case_id)).createViewResult.viewId)
|
||||
|
||||
def export_snapshots_of_all_views(self, prefix=""):
|
||||
def export_snapshots_of_all_views(self, prefix="", export_folder=""):
|
||||
""" Export snapshots for all views in the case
|
||||
|
||||
Arguments:
|
||||
prefix (str): Exported file name prefix
|
||||
export_folder(str): The path to export to. By default will use the global export folder
|
||||
|
||||
"""
|
||||
return self._execute_command(
|
||||
exportSnapshots=Cmd.ExportSnapshotsRequest(
|
||||
type="VIEWS", prefix=prefix, caseId=self.case_id, viewId=-1))
|
||||
type="VIEWS", prefix=prefix, caseId=self.case_id, viewId=-1, exportFolder=export_folder))
|
||||
|
||||
def export_well_path_completions(
|
||||
self,
|
||||
@@ -732,3 +736,33 @@ class Case(PdmObject):
|
||||
undefinedValue=undefined_value,
|
||||
exportFile=export_file,
|
||||
))
|
||||
|
||||
def create_well_bore_stability_plot(self, well_path, time_step):
|
||||
""" Create a new well bore stability plot
|
||||
|
||||
Arguments:
|
||||
well_path(str): well path name
|
||||
time_step(int): time step
|
||||
|
||||
Returns:
|
||||
A new plot object
|
||||
"""
|
||||
plot_result = self._execute_command(createWellBoreStabilityPlot=Cmd.CreateWbsPlotRequest(caseId=self.case_id,
|
||||
wellPath=well_path,
|
||||
timeStep=time_step))
|
||||
return self.__project.plot(view_id=plot_result.createWbsPlotResult.viewId)
|
||||
|
||||
def import_formation_names(self, formation_files=None):
|
||||
""" Import formation names into project and apply it to the current case
|
||||
|
||||
Arguments:
|
||||
formation_files(list): list of files to import
|
||||
|
||||
"""
|
||||
if formation_files is None:
|
||||
formation_files = []
|
||||
elif isinstance(formation_files, str):
|
||||
formation_files = [formation_files]
|
||||
|
||||
res = self._execute_command(importFormationNames=Cmd.ImportFormationNamesRequest(formationFiles=formation_files,
|
||||
applyToCaseId=self.case_id))
|
||||
@@ -14,14 +14,27 @@ class PdmObject:
|
||||
"""
|
||||
|
||||
def _execute_command(self, **command_params):
|
||||
return self._commands.Execute(Cmd.CommandParams(**command_params))
|
||||
self.__warnings = []
|
||||
response, call = self._commands.Execute.with_call(Cmd.CommandParams(**command_params))
|
||||
for key, value in call.trailing_metadata():
|
||||
value = value.replace(';;', '\n')
|
||||
if key == 'warning':
|
||||
self.__warnings.append(value)
|
||||
|
||||
return response
|
||||
|
||||
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._pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self._channel)
|
||||
self._commands = CmdRpc.CommandsStub(channel)
|
||||
self.__warnings = []
|
||||
|
||||
def warnings(self):
|
||||
return self.__warnings
|
||||
|
||||
def has_warnings(self):
|
||||
return len(self.__warnings) > 0
|
||||
|
||||
def pb2_object(self):
|
||||
""" Private method"""
|
||||
|
||||
73
ApplicationCode/GrpcInterface/Python/rips/plot.py
Normal file
73
ApplicationCode/GrpcInterface/Python/rips/plot.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
ResInsight 2d plot module
|
||||
"""
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
|
||||
from rips.pdmobject import PdmObject
|
||||
|
||||
class Plot(PdmObject):
|
||||
"""ResInsight plot class
|
||||
|
||||
Attributes:
|
||||
view_id(int): View Id corresponding to the View Id in ResInsight project.
|
||||
|
||||
"""
|
||||
def __init__(self, pdm_object):
|
||||
PdmObject.__init__(self, pdm_object.pb2_object(), pdm_object.channel())
|
||||
self.view_id = pdm_object.get_value("ViewId")
|
||||
|
||||
def export_snapshot(self, export_folder='', file_prefix='', ):
|
||||
""" Export snapshot for the current plot
|
||||
|
||||
Arguments:
|
||||
export_folder(str): The path to export to. By default will use the global export folder
|
||||
prefix (str): Exported file name prefix
|
||||
|
||||
"""
|
||||
return self._execute_command(
|
||||
exportSnapshots=Cmd.ExportSnapshotsRequest(type='PLOTS',
|
||||
prefix=file_prefix,
|
||||
viewId=self.view_id,
|
||||
exportFolder=export_folder))
|
||||
|
||||
def export_data_as_las(self, export_folder, file_prefix='', export_tvdrkb=False, capitalize_file_names=False, resample_interval=0.0):
|
||||
""" Export LAS file(s) for the current plot
|
||||
|
||||
Arguments:
|
||||
export_folder(str): The path to export to. By default will use the global export folder
|
||||
file_prefix (str): Exported file name prefix
|
||||
export_tvdrkb(bool): Export in TVD-RKB format
|
||||
capitalize_file_names(bool): Make all file names upper case
|
||||
resample_interval(double): if > 0.0 the files will be resampled
|
||||
|
||||
Returns:
|
||||
A list of files exported
|
||||
"""
|
||||
res = self._execute_command(exportWellLogPlotData=Cmd.ExportWellLogPlotDataRequest(exportFormat='LAS',
|
||||
viewId=self.view_id,
|
||||
exportFolder=export_folder,
|
||||
filePrefix=file_prefix,
|
||||
exportTvdRkb=export_tvdrkb,
|
||||
capitalizeFileNames=capitalize_file_names,
|
||||
resampleInterval=resample_interval))
|
||||
return res.exportWellLogPlotDataResult.exportedFiles
|
||||
|
||||
def export_data_as_ascii(self, export_folder, file_prefix='', capitalize_file_names=False):
|
||||
""" Export LAS file(s) for the current plot
|
||||
|
||||
Arguments:
|
||||
export_folder(str): The path to export to. By default will use the global export folder
|
||||
file_prefix (str): Exported file name prefix
|
||||
capitalize_file_names(bool): Make all file names upper case
|
||||
|
||||
Returns:
|
||||
A list of files exported
|
||||
"""
|
||||
res = self._execute_command(exportWellLogPlotData=Cmd.ExportWellLogPlotDataRequest(exportFormat='ASCII',
|
||||
viewId=self.view_id,
|
||||
exportFolder=export_folder,
|
||||
filePrefix=file_prefix,
|
||||
exportTvdRkb=False,
|
||||
capitalizeFileNames=capitalize_file_names,
|
||||
resampleInterval=0.0))
|
||||
return res.exportWellLogPlotDataResult.exportedFiles
|
||||
@@ -8,6 +8,7 @@ import grpc
|
||||
from rips.case import Case
|
||||
from rips.gridcasegroup import GridCaseGroup
|
||||
from rips.pdmobject import PdmObject
|
||||
from rips.plot import Plot
|
||||
from rips.view import View
|
||||
|
||||
import rips.generated.Commands_pb2 as Cmd
|
||||
@@ -49,7 +50,7 @@ class Project(PdmObject):
|
||||
"""
|
||||
command_reply = self._execute_command(loadCase=Cmd.FilePathRequest(
|
||||
path=path))
|
||||
return Case(self._channel, command_reply.loadCaseResult.id)
|
||||
return Case(self._channel, command_reply.loadCaseResult.id, self)
|
||||
|
||||
def selected_cases(self):
|
||||
"""Get a list of all cases selected in the project tree
|
||||
@@ -60,7 +61,7 @@ class Project(PdmObject):
|
||||
case_infos = self._project_stub.GetSelectedCases(Empty())
|
||||
cases = []
|
||||
for case_info in case_infos.data:
|
||||
cases.append(Case(self._channel, case_info.id))
|
||||
cases.append(Case(self._channel, case_info.id, self))
|
||||
return cases
|
||||
|
||||
def cases(self):
|
||||
@@ -74,7 +75,7 @@ class Project(PdmObject):
|
||||
|
||||
cases = []
|
||||
for case_info in case_infos.data:
|
||||
cases.append(Case(self._channel, case_info.id))
|
||||
cases.append(Case(self._channel, case_info.id, self))
|
||||
return cases
|
||||
except grpc.RpcError as rpc_error:
|
||||
if rpc_error.code() == grpc.StatusCode.NOT_FOUND:
|
||||
@@ -91,7 +92,7 @@ class Project(PdmObject):
|
||||
A rips Case object
|
||||
"""
|
||||
try:
|
||||
case = Case(self._channel, case_id)
|
||||
case = Case(self._channel, case_id, self)
|
||||
return case
|
||||
except grpc.RpcError:
|
||||
return None
|
||||
@@ -133,7 +134,7 @@ class Project(PdmObject):
|
||||
"""Get a particular view belonging to a case by providing view id
|
||||
|
||||
Arguments:
|
||||
id(int): view id
|
||||
view_id(int): view id
|
||||
Returns: a view object
|
||||
"""
|
||||
views = self.views()
|
||||
@@ -142,6 +143,34 @@ class Project(PdmObject):
|
||||
return view_object
|
||||
return None
|
||||
|
||||
def plots(self):
|
||||
"""Get a list of all plots belonging to a project"""
|
||||
pdm_objects = self.descendants("RimPlot")
|
||||
plot_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
plot_list.append(Plot(pdm_object))
|
||||
return plot_list
|
||||
|
||||
def plot(self, view_id):
|
||||
"""Get a particular plot by providing view id
|
||||
Arguments:
|
||||
view_id(int): view id
|
||||
Returns: a plot object
|
||||
"""
|
||||
plots = self.plots()
|
||||
for plot_object in plots:
|
||||
if plot_object.view_id == view_id:
|
||||
return plot_object
|
||||
return None
|
||||
|
||||
def well_paths(self):
|
||||
"""Get a list of all the well path names in the project"""
|
||||
pdm_objects = self.descendants("WellPathBase")
|
||||
well_path_list = []
|
||||
for pdm_object in pdm_objects:
|
||||
well_path_list.append(pdm_object.get_value("WellPathName"))
|
||||
return well_path_list
|
||||
|
||||
def grid_case_groups(self):
|
||||
"""Get a list of all grid case groups in the project"""
|
||||
case_groups = self.descendants("RimIdenticalGridCaseGroup")
|
||||
@@ -230,3 +259,52 @@ class Project(PdmObject):
|
||||
return self._execute_command(
|
||||
setFractureContainment=Cmd.SetFracContainmentRequest(
|
||||
id=template_id, topLayer=top_layer, baseLayer=base_layer))
|
||||
|
||||
def import_well_paths(self, well_path_files=None, well_path_folder=''):
|
||||
""" Import well paths into project
|
||||
|
||||
Arguments:
|
||||
well_path_files(list): List of file paths to import
|
||||
well_path_folder(str): A folder path containing files to import
|
||||
|
||||
Returns:
|
||||
A list of well path names (strings)
|
||||
"""
|
||||
if well_path_files is None:
|
||||
well_path_files = []
|
||||
|
||||
res = self._execute_command(importWellPaths=Cmd.ImportWellPathsRequest(wellPathFolder=well_path_folder,
|
||||
wellPathFiles=well_path_files))
|
||||
return res.importWellPathsResult.wellPathNames
|
||||
|
||||
def import_well_log_files(self, well_log_files=None, well_log_folder=''):
|
||||
""" Import well log files into project
|
||||
|
||||
Arguments:
|
||||
well_log_files(list): List of file paths to import
|
||||
well_log_folder(str): A folder path containing files to import
|
||||
|
||||
Returns:
|
||||
A list of well path names (strings) that had logs imported
|
||||
"""
|
||||
|
||||
if well_log_files is None:
|
||||
well_log_files = []
|
||||
res = self._execute_command(importWellLogFiles=Cmd.ImportWellLogFilesRequest(wellLogFolder=well_log_folder,
|
||||
wellLogFiles=well_log_files))
|
||||
return res.importWellLogFilesResult.wellPathNames
|
||||
|
||||
def import_formation_names(self, formation_files=None):
|
||||
""" Import formation names into project
|
||||
|
||||
Arguments:
|
||||
formation_files(list): list of files to import
|
||||
|
||||
"""
|
||||
if formation_files is None:
|
||||
formation_files = []
|
||||
elif isinstance(formation_files, str):
|
||||
formation_files = [formation_files]
|
||||
|
||||
res = self._execute_command(importFormationNames=Cmd.ImportFormationNamesRequest(formationFiles=formation_files,
|
||||
applyToCaseId=-1))
|
||||
@@ -11,7 +11,7 @@ class View(PdmObject):
|
||||
"""ResInsight view class
|
||||
|
||||
Attributes:
|
||||
id(int): View Id corresponding to the View Id in ResInsight project.
|
||||
view_id(int): View Id corresponding to the View Id in ResInsight project.
|
||||
|
||||
"""
|
||||
def __init__(self, pdm_object):
|
||||
@@ -195,15 +195,17 @@ class View(PdmObject):
|
||||
viewIds=[self.view_id],
|
||||
undefinedValue=undefined_value))
|
||||
|
||||
def export_snapshot(self, prefix=''):
|
||||
def export_snapshot(self, prefix='', export_folder=''):
|
||||
""" Export snapshot for the current view
|
||||
|
||||
Arguments:
|
||||
prefix (str): Exported file name prefix
|
||||
export_folder(str): The path to export to. By default will use the global export folder
|
||||
"""
|
||||
case_id = self.case().case_id
|
||||
return self._execute_command(
|
||||
exportSnapshots=Cmd.ExportSnapshotsRequest(type='VIEWS',
|
||||
prefix=prefix,
|
||||
caseId=case_id,
|
||||
viewId=self.view_id))
|
||||
viewId=self.view_id,
|
||||
exportFolder=export_folder))
|
||||
|
||||
Reference in New Issue
Block a user