Source code for dataio.export.rms.structure_depth_fault_surfaces
from __future__ import annotations
from pathlib import Path
from typing import Any, Final, Self
from xtgeo import TriangulatedSurface
from fmu.dataio._export import ExportConfig, export_with_metadata
from fmu.dataio._logging import null_logger
from fmu.dataio.export._base import SimpleExportBase
from fmu.dataio.export._export_result import ExportResult, ExportResultItem
from fmu.dataio.export.rms._utils import get_rms_project_units
from fmu.datamodels.common.enums import Classification
from fmu.datamodels.fmu_results.enums import (
Content,
DomainReference,
VerticalDomain,
)
from fmu.datamodels.standard_results.enums import StandardResultName
_logger: Final = null_logger(__name__)
class _ExportStructureDepthFaultSurfaces(SimpleExportBase):
def __init__(
self: Self,
project: Any,
structural_model_name: str,
) -> None:
super().__init__()
_logger.debug("Process data, establish state prior to export.")
self._unit = "m" if get_rms_project_units(project) == "metric" else "ft"
self._surfaces = _get_fault_surfaces_from_rms(project, structural_model_name)
_logger.debug("Process data... DONE")
def _get_export_config(self, name: str) -> ExportConfig:
"""Export config for the standard result."""
return (
ExportConfig.builder()
.content(Content.fault_surface)
.domain(VerticalDomain.depth, DomainReference.msl)
.unit(self._unit)
.file_config(
name=name,
subfolder=StandardResultName.structure_depth_fault_surface.value,
)
.access(Classification.internal, rep_include=True)
.global_config(self._config)
.standard_result(StandardResultName.structure_depth_fault_surface)
.build()
)
def _export_surface(self: Self, surf: TriangulatedSurface) -> ExportResultItem:
export_config = self._get_export_config(name=surf.name)
absolute_export_path = export_with_metadata(export_config, surf)
_logger.debug("Surface exported to: %s", absolute_export_path)
return ExportResultItem(
absolute_path=Path(absolute_export_path),
)
def _export_data_as_standard_result(self) -> ExportResult:
"""Export the fault surfaces as a standard result."""
return ExportResult(
items=[self._export_surface(surf) for surf in self._surfaces]
)
def _validate_data_pre_export(self) -> None:
"""Surface validations before export."""
# The surfaces are Pydantic models and are automatically validated
def _get_fault_surfaces_from_rms(
project: Any,
structural_model_name: str,
) -> list[TriangulatedSurface]:
"""
Fetch triangulated fault surfaces as TriangulatedSurface from RMS.
Args:
project: the 'magic' project variable in RMS
structural_model_name: name of the structural model
Returns:
List of TriangulatedSurface objects representing
all fault surfaces in the structural model as triangulations.
"""
if structural_model_name not in project.structural_models:
raise ValueError(
f"Project does not contain a structural model named: "
f"'{structural_model_name}'."
)
fault_model = project.structural_models[structural_model_name].fault_model
fault_surfaces = []
for fault_name in fault_model.fault_names:
fault_surface = fault_model.get_fault_triangle_surface(name=fault_name)
tsurf = TriangulatedSurface(
name=fault_name,
vertices=fault_surface.get_vertices(),
triangles=fault_surface.get_triangles(),
)
# To get coordinate system info in the GOCAD TSurf file
# it must be set using metadata in the xtgeo object
unit = "m" if get_rms_project_units(project) == "metric" else "ft"
tsurf.metadata.freeform = {
"tsurf_coord_sys": {
"name": "Default",
"axis_name": ("X", "Y", "Z"),
"axis_unit": (unit, unit, unit),
"zpositive": "depth",
}
}
fault_surfaces.append(tsurf)
return fault_surfaces
[docs]
def export_structure_depth_fault_surfaces(
project: Any, structural_model_name: str
) -> ExportResult:
"""
Simplified interface when exporting triangulated fault surfaces from RMS.
Args:
project: the 'magic' project variable in RMS
structural_model_name: name of the structural model
Examples:
Example usage in an RMS script::
from fmu.dataio.export.rms import export_structure_depth_fault_surfaces
export_results = export_structure_depth_fault_surfaces(
project,
"structural_model_name"
)
for result in export_results.items:
print(f"Output surfaces to {result.absolute_path}")
"""
return _ExportStructureDepthFaultSurfaces(project, structural_model_name).export()