From 113fcaf3f387557173cf2e9b1f7251269530641e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Therese=20Natter=C3=B8y?= <61694854+tnatt@users.noreply.github.com> Date: Thu, 4 Jul 2024 14:02:34 +0200 Subject: [PATCH] FIX: Allow user input on vertical_domain (#733) --- schema/definitions/0.8.0/schema/fmu_meta.json | 674 ++++++++++++------ src/fmu/dataio/dataio.py | 35 +- src/fmu/dataio/datastructure/meta/content.py | 37 +- src/fmu/dataio/datastructure/meta/enums.py | 11 + src/fmu/dataio/providers/objectdata/_base.py | 4 +- .../dataio/providers/objectdata/_provider.py | 2 +- tests/test_units/test_dataio.py | 69 ++ 7 files changed, 613 insertions(+), 219 deletions(-) diff --git a/schema/definitions/0.8.0/schema/fmu_meta.json b/schema/definitions/0.8.0/schema/fmu_meta.json index 16ef6b680..3653ee515 100644 --- a/schema/definitions/0.8.0/schema/fmu_meta.json +++ b/schema/definitions/0.8.0/schema/fmu_meta.json @@ -658,15 +658,6 @@ "const": "depth", "title": "Content" }, - "depth_reference": { - "enum": [ - "msl", - "sb", - "rkb" - ], - "title": "Depth Reference", - "type": "string" - }, "description": { "anyOf": [ { @@ -682,6 +673,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -878,23 +885,7 @@ "type": "string" }, "vertical_domain": { - "anyOf": [ - { - "enum": [ - "depth", - "time" - ], - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "examples": [ - "depth", - "time" - ], + "const": "depth", "title": "Vertical Domain" } }, @@ -905,7 +896,7 @@ "format", "is_observation", "is_prediction", - "depth_reference" + "vertical_domain" ], "title": "DepthData", "type": "object" @@ -955,6 +946,15 @@ "title": "Display", "type": "object" }, + "DomainReference": { + "enum": [ + "msl", + "sb", + "rkb" + ], + "title": "DomainReference", + "type": "string" + }, "FMUAttributes": { "dependencies": { "aggregation": { @@ -1126,6 +1126,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -1324,11 +1340,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -1338,8 +1350,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -1416,6 +1427,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -1614,11 +1641,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -1628,8 +1651,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -1706,6 +1728,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -1904,11 +1942,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -1918,8 +1952,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -2090,6 +2123,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "field_outline": { "$ref": "#/$defs/FieldOutline" }, @@ -2291,11 +2340,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -2305,8 +2350,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -2398,6 +2442,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "field_region": { "$ref": "#/$defs/FieldRegion" }, @@ -2599,11 +2659,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -2613,8 +2669,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -2804,6 +2859,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "fluid_contact": { "$ref": "#/$defs/FluidContact" }, @@ -3005,11 +3076,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -3019,8 +3086,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -3194,6 +3260,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -3392,11 +3474,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -3406,8 +3484,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -3524,6 +3601,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -3722,11 +3815,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -3736,8 +3825,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -3867,6 +3955,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -4065,11 +4169,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -4079,8 +4179,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -4273,6 +4372,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -4471,11 +4586,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -4485,8 +4596,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -4584,6 +4694,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -4782,11 +4908,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -4796,8 +4918,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -4874,6 +4995,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -5072,11 +5209,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -5086,8 +5219,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -5211,6 +5343,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -5409,11 +5557,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -5423,8 +5567,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -5501,6 +5644,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -5699,11 +5858,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -5713,8 +5868,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -5843,6 +5997,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -6041,11 +6211,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -6055,8 +6221,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -6133,6 +6298,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -6331,11 +6512,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -6345,8 +6522,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -6511,6 +6687,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -6712,11 +6904,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -6726,8 +6914,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -6918,6 +7105,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -7116,11 +7319,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -7130,8 +7329,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -7333,6 +7531,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -7531,11 +7745,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -7545,8 +7755,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -7652,6 +7861,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -7848,23 +8073,7 @@ "type": "string" }, "vertical_domain": { - "anyOf": [ - { - "enum": [ - "depth", - "time" - ], - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "examples": [ - "depth", - "time" - ], + "const": "time", "title": "Vertical Domain" } }, @@ -7874,7 +8083,8 @@ "stratigraphic", "format", "is_observation", - "is_prediction" + "is_prediction", + "vertical_domain" ], "title": "TimeData", "type": "object" @@ -7942,6 +8152,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -8140,11 +8366,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -8154,8 +8376,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -8332,6 +8553,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -8530,11 +8767,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -8544,8 +8777,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -8573,6 +8805,14 @@ "title": "Version", "type": "object" }, + "VerticalDomain": { + "enum": [ + "depth", + "time" + ], + "title": "VerticalDomain", + "type": "string" + }, "VolumesData": { "description": "The ``data`` block contains information about the data contained in this object.\nThis class contains metadata for volumes.", "properties": { @@ -8636,6 +8876,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -8834,11 +9090,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -8848,8 +9100,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ @@ -8926,6 +9177,22 @@ "default": null, "title": "Description" }, + "domain_reference": { + "anyOf": [ + { + "$ref": "#/$defs/DomainReference" + }, + { + "type": "null" + } + ], + "default": null, + "examples": [ + "msl", + "sb", + "rkb" + ] + }, "format": { "examples": [ "irap_binary" @@ -9124,11 +9391,7 @@ "vertical_domain": { "anyOf": [ { - "enum": [ - "depth", - "time" - ], - "type": "string" + "$ref": "#/$defs/VerticalDomain" }, { "type": "null" @@ -9138,8 +9401,7 @@ "examples": [ "depth", "time" - ], - "title": "Vertical Domain" + ] } }, "required": [ diff --git a/src/fmu/dataio/dataio.py b/src/fmu/dataio/dataio.py index 46f1e116d..1cc4b38b5 100644 --- a/src/fmu/dataio/dataio.py +++ b/src/fmu/dataio/dataio.py @@ -220,6 +220,10 @@ class ExportData: fmu_context ``case`` the case directory needs to be provided through the argument ``casepath``. + domain_reference: Optional, reference for the vertical scale of the data. + Valid references are "msl"/"sb"/"rkb", and the default is "msl". + Note use the ``vertical_domain`` key to set the domain (depth or time). + description: A multiline description of the data either as a string or a list of strings. @@ -290,8 +294,10 @@ class ExportData: [[20200101, "monitor"], [20180101, "base"]] or just [[2021010]]. The output to metadata will from version 0.9 be different (API change) - vertical_domain: This is dictionary with a key and a reference e.g. - {"depth": "msl"} which is default if missing. + vertical_domain: Optional. String with vertical domain either "time" or "depth". + It is also possible to provide a reference for the vertical scale, see the + domain_reference key. Note that if the ``content`` is "depth" or "time" + the vertical_domain will be set accordingly. workflow: Short tag desciption of workflow (as description) @@ -360,7 +366,8 @@ class ExportData: classification: Optional[str] = None config: dict = field(default_factory=dict) content: Optional[Union[dict, str]] = None - depth_reference: str = "msl" + depth_reference: str = "msl" # deprecated + domain_reference: str = "msl" description: Union[str, list] = "" display_name: Optional[str] = None fmu_context: Optional[str] = None @@ -382,7 +389,7 @@ class ExportData: timedata: Optional[List[list]] = None unit: Optional[str] = "" verbosity: str = "DEPRECATED" # remove in version 2 - vertical_domain: dict = field(default_factory=dict) + vertical_domain: Optional[Union[str, dict]] = None # dict input is deprecated workflow: Optional[Union[str, Dict[str, str]]] = None table_index: Optional[list] = None @@ -410,9 +417,6 @@ def __post_init__(self) -> None: self._fmurun = get_fmu_context_from_environment() is not None - # set defaults for mutable keys - self.vertical_domain = {"depth": "msl"} - # if input is provided as an ENV variable pointing to a YAML file; will override if SETTINGS_ENVNAME in os.environ: warnings.warn( @@ -542,6 +546,17 @@ def _show_deprecations_or_notimplemented(self) -> None: "removal in fmu-dataio version 2. Use 'casepath' instead!", UserWarning, ) + if isinstance(self.vertical_domain, dict): + warn( + "Using the 'vertical_domain' argument to set both the vertical domain " + "and the reference will be deprecated. Set the 'vertical_domain' " + "argument to a string with value either 'time'/'depth', and provide " + "the domain reference through the 'domain_reference' argument instead.", + FutureWarning, + ) + self.vertical_domain, self.domain_reference = list( + self.vertical_domain.items() + )[0] if self.grid_model: warn( @@ -613,6 +628,12 @@ def _show_deprecations_or_notimplemented(self) -> None: "The 'include_ertjobs' option is deprecated and should be removed.", UserWarning, ) + if self.depth_reference: + warn( + "The 'depth_reference' key has no function. Use the 'domain_reference' " + "key instead to set the reference for the given 'vertical_domain'.", + UserWarning, + ) def _validate_and_establish_fmucontext(self) -> None: """ diff --git a/src/fmu/dataio/datastructure/meta/content.py b/src/fmu/dataio/datastructure/meta/content.py index dbf4cccf8..5448b74d6 100644 --- a/src/fmu/dataio/datastructure/meta/content.py +++ b/src/fmu/dataio/datastructure/meta/content.py @@ -282,12 +282,18 @@ class Data(BaseModel): unit: str = Field(default="", examples=["m"]) """A reference to a known unit.""" - vertical_domain: Optional[Literal["depth", "time"]] = Field( + vertical_domain: Optional[enums.VerticalDomain] = Field( default=None, examples=["depth", "time"], ) """A reference to a known vertical domain.""" + domain_reference: Optional[enums.DomainReference] = Field( + default=None, + examples=["msl", "sb", "rkb"], + ) + """The reference for the vertical scale of the data.""" + table_index: Optional[List[str]] = Field( default=None, examples=[["ZONE", "REGION"]], @@ -317,8 +323,19 @@ class DepthData(Data): content: Literal[enums.Content.depth] """The type of content these data represent.""" - depth_reference: Literal["msl", "sb", "rkb"] - """A reference to a known depth reference.""" + vertical_domain: Literal[enums.VerticalDomain.depth] + """A reference to a known vertical domain.""" + + @field_validator("vertical_domain", mode="before") + @classmethod + def set_vertical_domain(cls, v: str) -> Literal[enums.VerticalDomain.depth]: + """For DepthData the domain should be 'depth'""" + if v and v != enums.VerticalDomain.depth: + warnings.warn( + f"The value of 'vertical_domain' is '{v}'. Since this is a " + "'depth' content the 'vertical_domain' will be set to 'depth'." + ) + return enums.VerticalDomain.depth class FaciesThicknessData(Data): @@ -532,6 +549,20 @@ class TimeData(Data): content: Literal[enums.Content.time] """The type of content these data represent.""" + vertical_domain: Literal[enums.VerticalDomain.time] + """A reference to a known vertical domain.""" + + @field_validator("vertical_domain", mode="before") + @classmethod + def set_vertical_domain(cls, v: str) -> Literal[enums.VerticalDomain.time]: + """For TimeData the domain should be 'time'""" + if v and v != enums.VerticalDomain.time: + warnings.warn( + f"The value of 'vertical_domain' is '{v}'. Since this is a " + "'time' content the 'vertical_domain' will be set to 'time'." + ) + return enums.VerticalDomain.time + class TimeSeriesData(Data): """ diff --git a/src/fmu/dataio/datastructure/meta/enums.py b/src/fmu/dataio/datastructure/meta/enums.py index 6d0d54d9a..6a0d55f1e 100644 --- a/src/fmu/dataio/datastructure/meta/enums.py +++ b/src/fmu/dataio/datastructure/meta/enums.py @@ -88,3 +88,14 @@ class FMUContext(str, Enum): case = "case" iteration = "iteration" realization = "realization" + + +class VerticalDomain(str, Enum): + depth = "depth" + time = "time" + + +class DomainReference(str, Enum): + msl = "msl" + sb = "sb" + rkb = "rkb" diff --git a/src/fmu/dataio/providers/objectdata/_base.py b/src/fmu/dataio/providers/objectdata/_base.py index 321f3d1c3..47dcf4f89 100644 --- a/src/fmu/dataio/providers/objectdata/_base.py +++ b/src/fmu/dataio/providers/objectdata/_base.py @@ -103,8 +103,8 @@ def __post_init__(self) -> None: metadata["format"] = self.fmt metadata["layout"] = self.layout metadata["unit"] = self.dataio.unit or "" - metadata["vertical_domain"] = list(self.dataio.vertical_domain.keys())[0] - metadata["depth_reference"] = list(self.dataio.vertical_domain.values())[0] + metadata["vertical_domain"] = self.dataio.vertical_domain + metadata["domain_reference"] = self.dataio.domain_reference metadata["spec"] = self.get_spec() metadata["geometry"] = self.get_geometry() diff --git a/src/fmu/dataio/providers/objectdata/_provider.py b/src/fmu/dataio/providers/objectdata/_provider.py index 458193642..7e69629db 100644 --- a/src/fmu/dataio/providers/objectdata/_provider.py +++ b/src/fmu/dataio/providers/objectdata/_provider.py @@ -49,7 +49,7 @@ layout: regular # / cornerpoint / structured / etc unit: m vertical_domain: depth # / time / null - depth_reference: msl # / seabed / etc # mandatory when vertical_domain is depth? + domain_reference: msl # / seabed / etc # mandatory when vertical_domain is depth? grid_model: # Making this an object to allow for expanding in the future name: MyGrid # important for data identification, also for other data types spec: # class/layout dependent, optional? Can spec be expanded to work for all diff --git a/tests/test_units/test_dataio.py b/tests/test_units/test_dataio.py index 9b8a7d3db..e791ff18a 100644 --- a/tests/test_units/test_dataio.py +++ b/tests/test_units/test_dataio.py @@ -485,6 +485,75 @@ def test_workflow_as_string(fmurun_w_casemetadata, monkeypatch, globalconfig1, r assert meta["fmu"]["workflow"]["reference"] == workflow +def test_vertical_domain(regsurf, globalconfig1): + """test inputting vertical_domain and domain_reference in various ways""" + + # test that giving vertical_domain and domain_reference as strings + mymeta = ExportData( + config=globalconfig1, + vertical_domain="time", + domain_reference="rkb", + ).generate_metadata(regsurf) + assert mymeta["data"]["vertical_domain"] == "time" + assert mymeta["data"]["domain_reference"] == "rkb" + + # test giving vertical_domain as dictionary + with pytest.warns(FutureWarning, match="deprecated"): + mymeta = ExportData( + config=globalconfig1, vertical_domain={"time": "sb"} + ).generate_metadata(regsurf) + assert mymeta["data"]["vertical_domain"] == "time" + assert mymeta["data"]["domain_reference"] == "sb" + + # test excluding vertical_domain and domain_reference + mymeta = ExportData(config=globalconfig1).generate_metadata(regsurf) + assert "vertical_domain" not in mymeta["data"] + assert mymeta["data"]["domain_reference"] == "msl" # default value + + # test invalid input + with pytest.raises(pydantic.ValidationError, match="vertical_domain"): + ExportData(config=globalconfig1, vertical_domain="wrong").generate_metadata( + regsurf + ) + with pytest.raises(pydantic.ValidationError, match="domain_reference"): + ExportData(config=globalconfig1, domain_reference="wrong").generate_metadata( + regsurf + ) + with pytest.raises(pydantic.ValidationError, match="2 validation errors"): + ExportData( + config=globalconfig1, vertical_domain={"invalid": 5} + ).generate_metadata(regsurf) + + +def test_vertical_domain_vs_depth_time_content(regsurf, globalconfig1): + """Test the vertical_domain vs content depth/time""" + + # test content depth/time sets vertical_domain + eobj = ExportData(config=globalconfig1, content="depth") + mymeta = eobj.generate_metadata(regsurf) + assert mymeta["data"]["vertical_domain"] == "depth" + assert mymeta["data"]["domain_reference"] == "msl" # default value + + eobj = ExportData(config=globalconfig1, content="depth", domain_reference="sb") + mymeta = eobj.generate_metadata(regsurf) + assert mymeta["data"]["vertical_domain"] == "depth" + assert mymeta["data"]["domain_reference"] == "sb" + + eobj = ExportData(config=globalconfig1, content="time") + mymeta = eobj.generate_metadata(regsurf) + assert mymeta["data"]["vertical_domain"] == "time" + assert mymeta["data"]["domain_reference"] == "msl" # default value + + # test mismatch between content and vertical_domain + with pytest.warns(UserWarning, match="'vertical_domain' will be set to 'depth'"): + eobj = ExportData(config=globalconfig1, content="depth", vertical_domain="time") + mymeta = eobj.generate_metadata(regsurf) + + with pytest.warns(UserWarning, match="'vertical_domain' will be set to 'time'"): + eobj = ExportData(config=globalconfig1, content="time", vertical_domain="depth") + mymeta = eobj.generate_metadata(regsurf) + + def test_set_display_name(regsurf, globalconfig2): """Test that giving the display_name argument sets display.name.""" eobj = ExportData(