Source code for xtgeo.roxutils.roxutils

"""Module for simplifying various operation in the Roxar python interface."""

import contextlib

from packaging.version import parse as versionparse

with contextlib.suppress(ImportError):
    import roxar

from xtgeo.common.log import null_logger
from xtgeo.common.xtgeo_dialog import XTGeoDialog

from . import _roxutils_etc

xtg = XTGeoDialog()
logger = null_logger(__name__)


[docs] class RoxUtils(object): """Class RoxUtils, for accessing project level methods:: import xtgeo xr = xtgeo.RoxUtils(project) xr.create_horizon_category('DS_extracted_run3') xr.delete_horizon_category('DS_extracted_run2') The project itself can be a reference to an existing project, typically the magic ``project`` wording inside RMS python, or a file path to a RMS project (for external access). Args: project (roxar.Project or str): Reference to a RMS project either an existing instance or a RMS project folder path. readonly (bool). Default is False. If readonly, then it cannot be saved to this project (which is the case for "secondary" projects). Examples:: import xgeo path = '/some/path/to/rmsprject.rmsx' ext = xtgeo.RoxUtils(path, readonly=True) # ...do something ext.safe_close() """
[docs] def __init__(self, project, readonly=False): self._project = None self._version = roxar.__version__ if versionparse(self._version) < versionparse("1.5"): raise RuntimeError("XTGeo >= 3.0 requires Roxar API >= 1.5") self._roxexternal = True self._versions = { "1.0": ["10.0.x"], "1.1": ["10.1.0", "10.1.1", "10.1.2"], "1.1.1": ["10.1.3"], "1.2": ["11.0.0"], "1.2.1": ["11.0.1"], "1.3": ["11.1.0", "11.1.1", "11.1.2"], "1.4": ["12.0.0", "12.0.1", "12.0.2"], "1.5": ["12.1"], "1.6": ["13.0"], "1.7": ["13.1"], } if project is not None and isinstance(project, str): projectname = project if readonly: self._project = roxar.Project.open_import(projectname) else: self._project = roxar.Project.open(projectname) logger.info("Open RMS project from %s", projectname) elif isinstance(project, roxar.Project): # this will happen for _current_ project inside RMS or if # project is opened already e.g. by roxar.Project.open(). In the latter # case, the user should also close the project by project.close() as # an explicit action. self._roxexternal = False self._project = project logger.info("RMS project instance is already open as <%s>", project) else: raise RuntimeError("Project is not valid")
@property def roxversion(self): """Roxar API version (read only)""" return self._version @property def project(self): """The Roxar project instance (read only)""" return self._project
[docs] def safe_close(self): """Close the project but only if roxarapps (external) mode, i.e. not current RMS project In case roxar.Project.open() is done explicitly, safe_close() will do nothing. """ if self._roxexternal: try: self._project.close() logger.info("RMS project instance is closed") except TypeError as msg: xtg.warn(msg) else: logger.info("Close request, but skip for good reasons...") logger.debug("... either in RMS GUI or in a sequence of running roxarapps")
[docs] def version_required(self, targetversion): """Defines a minimum ROXAPI version for some feature (True or False). Args: targetversion (str): Minimum version to compare with. Example:: rox = RoxUtils(project) if rox.version_required('1.5'): somefunction() else: print('Not supported in this version') """ return versionparse(self._version) >= versionparse(targetversion)
[docs] def rmsversion(self, apiversion): """Get the actual RMS version(s) given an API version. Args: apiversion (str): ROXAPI version to ask for Returns: A list of RMS version(s) for the given API version, None if not any match. Example:: rox = RoxUtils(project) rmsver = rox.rmsversion('1.5') print('The supported RMS version are {}'.format(rmsver)) """ return self._versions.get(apiversion, None)
[docs] def create_horizons_category(self, category, domain="depth", htype="surface"): """Create one or more a Horizons category entries. Args: category (str or list): Name(s) of category to make, either as a simple string or a list of strings. domain (str): 'depth' (default) or 'time' htype (str): Horizon type: surface/lines/points """ _roxutils_etc.create_whatever_category( self, category, stype="horizons", domain=domain, htype=htype )
[docs] def create_zones_category(self, category, domain="thickness", htype="surface"): """Create one or more a Horizons category entries. Args: category (str or list): Name(s) of category to make, either as a simple string or a list of strings. domain (str): 'thickness' (default) or ...? htype (str): Horizon type: surface/lines/points """ _roxutils_etc.create_whatever_category( self, category, stype="zones", domain=domain, htype=htype )
[docs] def delete_horizons_category(self, category): """Delete on or more horizons or zones categories""" _roxutils_etc.delete_whatever_category(self, category, stype="horizons")
[docs] def delete_zones_category(self, category): """Delete on or more horizons or zones categories. See previous""" _roxutils_etc.delete_whatever_category(self, category, stype="zones")
[docs] def clear_horizon_category(self, category): """Clear (or make empty) the content of one or more horizon categories. Args: category (str or list): Name(s) of category to empty, either as a simple string or a list of strings. .. versionadded:: 2.1 """ _roxutils_etc.clear_whatever_category(self, category, stype="horizons")
[docs] def clear_zone_category(self, category): """Clear (or make empty) the content of one or more zone categories. Args: category (str or list): Name(s) of category to empty, either as a simple string or a list of strings. .. versionadded:: 2.1 """ _roxutils_etc.clear_whatever_category(self, category, stype="zones")