diff --git a/src/fmu/dataio/_definitions.py b/src/fmu/dataio/_definitions.py index f3bf35eab..f45c20ba3 100644 --- a/src/fmu/dataio/_definitions.py +++ b/src/fmu/dataio/_definitions.py @@ -59,6 +59,16 @@ class ValidFormats(Enum): } +class ExportFolder(str, Enum): + cubes = "cubes" + dictionaries = "dictionaries" + grids = "grids" + maps = "maps" + points = "points" + polygons = "polygons" + tables = "tables" + + STANDARD_TABLE_INDEX_COLUMNS: Final[dict[str, list[str]]] = { "volumes": ["ZONE", "REGION", "FACIES", "LICENCE"], "rft": ["measured_depth", "well", "time"], diff --git a/src/fmu/dataio/providers/objectdata/_base.py b/src/fmu/dataio/providers/objectdata/_base.py index aa6dbedd8..4bc47d6f9 100644 --- a/src/fmu/dataio/providers/objectdata/_base.py +++ b/src/fmu/dataio/providers/objectdata/_base.py @@ -24,7 +24,7 @@ from fmu.dataio.datastructure.meta.content import BoundingBox2D, BoundingBox3D from fmu.dataio.datastructure.meta.enums import FMUClassEnum from fmu.dataio.datastructure.meta.specification import AnySpecification - from fmu.dataio.types import Efolder, Inferrable, Layout + from fmu.dataio.types import Inferrable, Layout logger: Final = null_logger(__name__) @@ -32,7 +32,6 @@ @dataclass class DerivedObjectDescriptor: layout: Layout - efolder: Efolder | str table_index: list[str] | None @@ -70,7 +69,6 @@ class ObjectDataProvider(Provider): # as instance properties in addition (for simplicity in other classes/functions) _metadata: dict = field(default_factory=dict) name: str = field(default="") - efolder: str = field(default="") time0: datetime | None = field(default=None) time1: datetime | None = field(default=None) @@ -80,16 +78,14 @@ def __post_init__(self) -> None: obj_data = self.get_objectdata() self.name = named_stratigraphy.name - self.efolder = obj_data.efolder if self.dataio.forcefolder: if self.dataio.forcefolder.startswith("/"): raise ValueError("Can't use absolute path as 'forcefolder'") msg = ( - f"The standard folder name is overrided from {obj_data.efolder} to " + f"The standard folder name is overrided from {self.efolder} to " f"{self.dataio.forcefolder}" ) - self.efolder = self.dataio.forcefolder logger.info(msg) warn(msg, UserWarning) @@ -145,6 +141,11 @@ def __post_init__(self) -> None: def classname(self) -> FMUClassEnum: raise NotImplementedError + @property + @abstractmethod + def efolder(self) -> str: + raise NotImplementedError + @property @abstractmethod def extension(self) -> str: diff --git a/src/fmu/dataio/providers/objectdata/_faultroom.py b/src/fmu/dataio/providers/objectdata/_faultroom.py index a55b1732d..635fc4275 100644 --- a/src/fmu/dataio/providers/objectdata/_faultroom.py +++ b/src/fmu/dataio/providers/objectdata/_faultroom.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from typing import Final -from fmu.dataio._definitions import ValidFormats +from fmu.dataio._definitions import ExportFolder, ValidFormats from fmu.dataio._logging import null_logger from fmu.dataio.datastructure.meta.content import BoundingBox3D from fmu.dataio.datastructure.meta.enums import FMUClassEnum @@ -26,6 +26,10 @@ class FaultRoomSurfaceProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.surface + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.maps.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.dictionary) @@ -62,6 +66,5 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for FaultRoomSurface""" return DerivedObjectDescriptor( layout="faultroom_triangulated", - efolder="maps", table_index=None, ) diff --git a/src/fmu/dataio/providers/objectdata/_provider.py b/src/fmu/dataio/providers/objectdata/_provider.py index ac0b8b292..21f789ade 100644 --- a/src/fmu/dataio/providers/objectdata/_provider.py +++ b/src/fmu/dataio/providers/objectdata/_provider.py @@ -92,7 +92,7 @@ import pandas as pd import xtgeo -from fmu.dataio._definitions import ValidFormats +from fmu.dataio._definitions import ExportFolder, ValidFormats from fmu.dataio._logging import null_logger from fmu.dataio.datastructure.meta.enums import FMUClassEnum from fmu.dataio.readers import FaultRoomSurface @@ -168,6 +168,10 @@ class DictionaryDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.dictionary + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.dictionaries.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.dictionary) @@ -186,6 +190,5 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for dict.""" return DerivedObjectDescriptor( layout="dictionary", - efolder="dictionaries", table_index=None, ) diff --git a/src/fmu/dataio/providers/objectdata/_tables.py b/src/fmu/dataio/providers/objectdata/_tables.py index 5b6a30940..4b2d065ea 100644 --- a/src/fmu/dataio/providers/objectdata/_tables.py +++ b/src/fmu/dataio/providers/objectdata/_tables.py @@ -5,7 +5,11 @@ import pandas as pd -from fmu.dataio._definitions import STANDARD_TABLE_INDEX_COLUMNS, ValidFormats +from fmu.dataio._definitions import ( + STANDARD_TABLE_INDEX_COLUMNS, + ExportFolder, + ValidFormats, +) from fmu.dataio._logging import null_logger from fmu.dataio.datastructure.meta.enums import FMUClassEnum from fmu.dataio.datastructure.meta.specification import TableSpecification @@ -64,6 +68,10 @@ class DataFrameDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.table + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.tables.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.table) @@ -88,7 +96,6 @@ def get_objectdata(self) -> DerivedObjectDescriptor: table_index = _derive_index(self.dataio.table_index, list(self.obj.columns)) return DerivedObjectDescriptor( layout="table", - efolder="tables", table_index=table_index, ) @@ -101,6 +108,10 @@ class ArrowTableDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.table + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.tables.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.table) @@ -125,6 +136,5 @@ def get_objectdata(self) -> DerivedObjectDescriptor: table_index = _derive_index(self.dataio.table_index, self.obj.column_names) return DerivedObjectDescriptor( layout="table", - efolder="tables", table_index=table_index, ) diff --git a/src/fmu/dataio/providers/objectdata/_xtgeo.py b/src/fmu/dataio/providers/objectdata/_xtgeo.py index 34afba29d..1606bcd54 100644 --- a/src/fmu/dataio/providers/objectdata/_xtgeo.py +++ b/src/fmu/dataio/providers/objectdata/_xtgeo.py @@ -7,7 +7,7 @@ import pandas as pd import xtgeo -from fmu.dataio._definitions import ValidFormats +from fmu.dataio._definitions import ExportFolder, ValidFormats from fmu.dataio._logging import null_logger from fmu.dataio._utils import npfloat_to_float from fmu.dataio.datastructure.meta.content import BoundingBox2D, BoundingBox3D @@ -40,6 +40,10 @@ class RegularSurfaceDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.surface + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.maps.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.surface) @@ -94,7 +98,6 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for xtgeo.RegularSurface.""" return DerivedObjectDescriptor( layout="regular", - efolder="maps", table_index=None, ) @@ -107,6 +110,10 @@ class PolygonsDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.polygons + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.polygons.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.polygons) @@ -143,7 +150,6 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for xtgeo.Polygons.""" return DerivedObjectDescriptor( layout="unset", - efolder="polygons", table_index=None, ) @@ -156,6 +162,10 @@ class PointsDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.points + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.points.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.points) @@ -197,7 +207,6 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for xtgeo.Points.""" return DerivedObjectDescriptor( layout="unset", - efolder="points", table_index=None, ) @@ -210,6 +219,10 @@ class CubeDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.cube + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.cubes.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.cube) @@ -273,7 +286,6 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for xtgeo.Cube.""" return DerivedObjectDescriptor( layout="regular", - efolder="cubes", table_index=None, ) @@ -286,6 +298,10 @@ class CPGridDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.cpgrid + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.grids.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.grid) @@ -333,7 +349,6 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for xtgeo.Grid.""" return DerivedObjectDescriptor( layout="cornerpoint", - efolder="grids", table_index=None, ) @@ -346,6 +361,10 @@ class CPGridPropertyDataProvider(ObjectDataProvider): def classname(self) -> FMUClassEnum: return FMUClassEnum.cpgrid_property + @property + def efolder(self) -> str: + return self.dataio.forcefolder or ExportFolder.grids.value + @property def extension(self) -> str: return self._validate_get_ext(self.fmt, ValidFormats.grid) @@ -371,6 +390,5 @@ def get_objectdata(self) -> DerivedObjectDescriptor: """Derive object data for xtgeo.GridProperty.""" return DerivedObjectDescriptor( layout="cornerpoint", - efolder="grids", table_index=None, ) diff --git a/tests/test_units/test_filedataprovider_class.py b/tests/test_units/test_filedataprovider_class.py index b2bd2cde4..15c59f8f1 100644 --- a/tests/test_units/test_filedataprovider_class.py +++ b/tests/test_units/test_filedataprovider_class.py @@ -7,6 +7,7 @@ import pytest from fmu.dataio import ExportData +from fmu.dataio._definitions import ExportFolder from fmu.dataio.datastructure.meta import meta from fmu.dataio.providers._filedata import FileDataProvider from fmu.dataio.providers.objectdata._provider import objectdata_provider_factory @@ -175,16 +176,17 @@ def test_get_share_folders(regsurf): objdata = objectdata_provider_factory(regsurf, edataobj1) objdata.name = "some" - objdata.efolder = "efolder" fdata = FileDataProvider(edataobj1, objdata) share_folders = fdata._get_share_folders() assert isinstance(share_folders, Path) - assert share_folders == Path("share/results/efolder") + assert share_folders == Path(f"share/results/{ExportFolder.maps.value}") # check that the path present in the metadata matches the share folders fmeta = fdata.get_metadata() - assert str(fmeta.absolute_path.parent).endswith("share/results/efolder") + assert str(fmeta.absolute_path.parent).endswith( + f"share/results/{ExportFolder.maps.value}" + ) def test_get_share_folders_with_subfolder(regsurf): @@ -194,15 +196,14 @@ def test_get_share_folders_with_subfolder(regsurf): objdata = objectdata_provider_factory(regsurf, edataobj1) objdata.name = "some" - objdata.efolder = "efolder" fdata = FileDataProvider(edataobj1, objdata) share_folders = fdata._get_share_folders() - assert share_folders == Path("share/results/efolder/sub") + assert share_folders == Path("share/results/maps/sub") # check that the path present in the metadata matches the share folders fmeta = fdata.get_metadata() - assert str(fmeta.absolute_path.parent).endswith("share/results/efolder/sub") + assert str(fmeta.absolute_path.parent).endswith("share/results/maps/sub") def test_filedata_provider(regsurf, tmp_path): @@ -210,11 +211,10 @@ def test_filedata_provider(regsurf, tmp_path): os.chdir(tmp_path) - cfg = ExportData(name="", parent="parent", tagname="tag") + cfg = ExportData(name="", parent="parent", tagname="tag", forcefolder="efolder") objdata = objectdata_provider_factory(regsurf, cfg) objdata.name = "name" - objdata.efolder = "efolder" t1 = "19000101" t2 = "20240101" objdata.time0 = datetime.strptime(t1, "%Y%m%d")