Skip to content

Commit

Permalink
ENH: Faultroom export - add mapping of juxt.pos. to SMDA names (equin…
Browse files Browse the repository at this point in the history
  • Loading branch information
ErichSuter committed Dec 19, 2024
1 parent a2194ec commit 8e69a67
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 7 deletions.
15 changes: 15 additions & 0 deletions src/fmu/dataio/_model/global_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,21 @@ def __iter__(self) -> Any:
def __getitem__(self, item: str) -> StratigraphyElement:
return self.root[item]

def get_stratigraphic_name(self, name: str) -> str:
"""
Get the name of a stratigraphic element from the strat. column
provided by the user in the global config.
name: name of stratigraphic element
"""
if name in self:
return self[name].name

warnings.warn(
"Stratigraphic element '{name}' not found in the stratigraphic column "
"in global config"
)
return ""


class GlobalConfiguration(BaseModel):
"""
Expand Down
28 changes: 25 additions & 3 deletions src/fmu/dataio/providers/objectdata/_faultroom.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
from fmu.dataio._logging import null_logger
from fmu.dataio._model.data import BoundingBox3D
from fmu.dataio._model.enums import FMUClass, Layout
from fmu.dataio._model.global_configuration import (
GlobalConfiguration,
)
from fmu.dataio._model.specification import FaultRoomSurfaceSpecification
from fmu.dataio.readers import FaultRoomSurface

from ._base import (
ObjectDataProvider,
Expand Down Expand Up @@ -66,11 +68,31 @@ def get_bbox(self) -> BoundingBox3D:
def get_spec(self) -> FaultRoomSurfaceSpecification:
"""Derive data.spec for FaultRoomSurface"""
logger.info("Get spec for FaultRoomSurface")

# Juxtapositions are already ordered according to the strat. column
# in global config

juxtaposition_hw = []
juxtaposition_fw = []
if isinstance(self.dataio.config, GlobalConfiguration) and (
strat := self.dataio.config.stratigraphy
):
# Use the name in the juxtaposition list if it doesn't exist
# in the strat. column
juxtaposition_hw = [
strat.get_stratigraphic_name(juxt) or juxt
for juxt in self.obj.juxtaposition_hw
]
juxtaposition_fw = [
strat.get_stratigraphic_name(juxt) or juxt
for juxt in self.obj.juxtaposition_fw
]

return FaultRoomSurfaceSpecification(
horizons=self.obj.horizons,
faults=self.obj.faults,
juxtaposition_hw=self.obj.juxtaposition_hw,
juxtaposition_fw=self.obj.juxtaposition_fw,
juxtaposition_hw=juxtaposition_hw,
juxtaposition_fw=juxtaposition_fw,
properties=self.obj.properties,
name=self.obj.name,
)
31 changes: 31 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
import os
import shutil
from copy import deepcopy
from pathlib import Path

import numpy as np
Expand All @@ -18,6 +19,7 @@
from fmu.dataio._model import Root, fields, global_configuration
from fmu.dataio.dataio import ExportData, read_metadata
from fmu.dataio.providers._fmu import FmuEnv
from fmu.dataio.readers import FaultRoomSurface

from .utils import _get_nested_pydantic_models, _metadata_examples

Expand Down Expand Up @@ -460,6 +462,35 @@ def fixture_regsurf():
return xtgeo.RegularSurface(ncol=12, nrow=10, xinc=20, yinc=20, values=1234.0)


@pytest.fixture(name="faultroom_object", scope="module")
def fixture_faultroom_object(globalconfig2):
"""Create a faultroom object."""
logger.debug("Ran %s", _current_function_name())
cfg = deepcopy(globalconfig2)

horizons = cfg["rms"]["horizons"]["TOP_RES"]
faults = ["F1", "F2", "F3", "F4", "F5", "F6"]
juxtaposition_hw = cfg["rms"]["zones"]["ZONE_RES"]
juxtaposition_fw = cfg["rms"]["zones"]["ZONE_RES"]
juxtaposition = {"fw": juxtaposition_fw, "hw": juxtaposition_hw}
properties = [
"Juxtaposition",
]
coordinates = [[[1.1, 1.2, 1.3], [2.1, 2.2, 2.3]]]
features = [{"geometry": {"coordinates": coordinates}}]
name = cfg["access"]["asset"]["name"]

faultroom_data = {
"horizons": horizons,
"faults": {"default": faults},
"juxtaposition": juxtaposition,
"properties": properties,
"name": name,
}

return FaultRoomSurface({"metadata": faultroom_data, "features": features})


@pytest.fixture(name="polygons", scope="module")
def fixture_polygons():
"""Create an xtgeo polygons."""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_units/test_checksum_md5.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def test_checksum_md5_for_dictionary(monkeypatch, tmp_path, globalconfig1):
assert meta["file"]["checksum_md5"] == md5sum(export_path)


def test_checksum_md5_for_faultroom(monkeypatch, tmp_path, globalconfig1, rootpath):
def test_checksum_md5_for_faultroom(monkeypatch, tmp_path, globalconfig2, rootpath):
"""
Test that the MD5 hash in the metadata is equal to one computed for
the exported file for a FaultRoomSurface
Expand All @@ -194,7 +194,7 @@ def test_checksum_md5_for_faultroom(monkeypatch, tmp_path, globalconfig1, rootpa

export_path = Path(
ExportData(
config=globalconfig1,
config=globalconfig2,
content="depth",
name="myname",
).export(fault_room_surface)
Expand Down
19 changes: 19 additions & 0 deletions tests/test_units/test_global_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,22 @@ def test_access_classification_logic():
"ssdl": {"rep_include": False},
}
)


def test_stratigraphy(edataobj2):
"""Test the stratigraphy."""

strat = edataobj2.config.stratigraphy

###### Test get stratigraphic name ######

# Correct name
assert strat.get_stratigraphic_name("Valysar") == "Valysar Fm."

# Incorrect name
with pytest.warns(UserWarning, match="not found in the stratigraphic column"):
assert strat.get_stratigraphic_name("Ile") == ""

# Empty name
with pytest.warns(UserWarning, match="not found in the stratigraphic column"):
assert strat.get_stratigraphic_name("") == ""
24 changes: 22 additions & 2 deletions tests/test_units/test_objectdataprovider_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import fmu.dataio as dataio
from fmu.dataio._definitions import ConfigurationError, ValidFormats
from fmu.dataio._model.specification import FaultRoomSurfaceSpecification
from fmu.dataio.providers.objectdata._faultroom import FaultRoomSurfaceProvider
from fmu.dataio.providers.objectdata._provider import (
objectdata_provider_factory,
)
Expand All @@ -23,7 +25,7 @@

def test_objectdata_regularsurface_derive_named_stratigraphy(regsurf, edataobj1):
"""Get name and some stratigaphic keys for a valid RegularSurface object ."""
# mimic the stripped parts of configuations for testing here
# mimic the stripped parts of configurations for testing here
objdata = objectdata_provider_factory(regsurf, edataobj1)

res = objdata._get_stratigraphy_element()
Expand All @@ -35,7 +37,7 @@ def test_objectdata_regularsurface_derive_named_stratigraphy(regsurf, edataobj1)

def test_objectdata_regularsurface_get_stratigraphy_element_differ(regsurf, edataobj2):
"""Get name and some stratigaphic keys for a valid RegularSurface object ."""
# mimic the stripped parts of configuations for testing here
# mimic the stripped parts of configurations for testing here
objdata = objectdata_provider_factory(regsurf, edataobj2)

res = objdata._get_stratigraphy_element()
Expand All @@ -45,6 +47,24 @@ def test_objectdata_regularsurface_get_stratigraphy_element_differ(regsurf, edat
assert res.stratigraphic is True


def test_objectdata_faultroom_fault_juxtaposition_get_stratigraphy_differ(
faultroom_object, edataobj2
):
"""
Fault juxtaposition is a list of formations on the footwall and hangingwall sides.
Ensure that each name is converted to the names given in the stratigraphic column
in the global config.
"""
objdata = objectdata_provider_factory(faultroom_object, edataobj2)
assert isinstance(objdata, FaultRoomSurfaceProvider)

frss = objdata.get_spec()
assert isinstance(frss, FaultRoomSurfaceSpecification)

assert frss.juxtaposition_fw == ["Valysar Fm.", "Therys Fm.", "Volon Fm."]
assert frss.juxtaposition_hw == ["Valysar Fm.", "Therys Fm.", "Volon Fm."]


def test_objectdata_regularsurface_validate_extension(regsurf, edataobj1):
"""Test a valid extension for RegularSurface object."""

Expand Down

0 comments on commit 8e69a67

Please sign in to comment.