Skip to content

Commit 56ee74c

Browse files
committed
added validators for value warnings and unimplemented behaviour
1 parent 427e289 commit 56ee74c

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

RATapi/models.py

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""The models module. Contains the pydantic models used by RAT to store project parameters."""
22

33
import pathlib
4+
import warnings
45
from itertools import count
56
from typing import Any
67

@@ -60,7 +61,7 @@ class Background(RATModel):
6061
- if type is 'function', this should be the name of a custom function defined in `Project.custom_files`.
6162
value_1, value_2, ..., value_5 : str
6263
Values required by the background.
63-
- if type is 'constant', this should be blank.
64+
- if type is 'constant', all values will be ignored.
6465
- if type is 'data', value_1 may be the parameter name for an optional offset. Other values are ignored.
6566
- if type is 'function', these values may be the names of up to 5 parameters which are passed to the function.
6667
@@ -75,6 +76,26 @@ class Background(RATModel):
7576
value_4: str = ""
7677
value_5: str = ""
7778

79+
@model_validator(mode="after")
80+
def warn_parameters(self):
81+
"""Raise a warning if the parameters given are not expected for the given type."""
82+
if self.type == TypeOptions.Constant:
83+
expected_empty_fields = ["value_1", "value_2", "value_3", "value_4", "value_5"]
84+
elif self.type == TypeOptions.Data:
85+
expected_empty_fields = ["value_2", "value_3", "value_4", "value_5"]
86+
else:
87+
return self
88+
89+
non_empty_fields = [v for v in expected_empty_fields if getattr(self, v) != ""]
90+
if non_empty_fields:
91+
warnings.warn(
92+
"The following values are not recognised by this background type and will be ignored: "
93+
f"{', '.join(non_empty_fields)}",
94+
stacklevel=2,
95+
)
96+
97+
return self
98+
7899

79100
class Contrast(RATModel):
80101
"""A group of all of the components of a model.
@@ -515,19 +536,20 @@ class Resolution(RATModel):
515536
Parameters
516537
----------
517538
name : str
518-
The name of the background.
539+
The name of the resolution.
519540
type : TypeOptions
520-
The type of background (constant, function or data)
541+
The type of resolution: 'constant', 'data', or (NOT YET IMPLEMENTED) 'function'.
521542
source : str
522-
The source data for the background;
543+
The source data for the resolution;
523544
- if type is 'constant', this should be the name of a background parameter.
524-
- if type is 'data', this should be the name of a dataset defined in `Project.data`.
525-
- if type is 'function', this should be the name of a custom function defined in `Project.custom_files`.
545+
- if type is 'data', this should be empty (resolution data is in the contrast data).
546+
- if type is 'function' (NOT YET IMPLEMENTED),
547+
this should be the name of a custom function defined in `Project.custom_files`.
526548
value_1, value_2, ..., value_5 : str
527549
Values required by the background.
528-
- if type is 'constant', this should be blank.
529-
- if type is 'data', value_1 may be the parameter name for an optional offset. Other values are ignored.
530-
- if type is 'function', these values may be the names of up to 5 parameters which are passed to the function.
550+
- if type is 'constant' or 'data', all values will be ignored.
551+
- if type is 'function' (NOT YET IMPLEMENTED),
552+
these values may be the names of up to 5 parameters which are passed to the function.
531553
532554
"""
533555

@@ -539,3 +561,34 @@ class Resolution(RATModel):
539561
value_3: str = ""
540562
value_4: str = ""
541563
value_5: str = ""
564+
565+
@field_validator("type")
566+
@classmethod
567+
def validate_unimplemented_resolutions(cls, type: TypeOptions):
568+
"""Raise an error if currently unsupported function resolutions are used."""
569+
# when function resolutions are added, fix the commented-out parts of
570+
# test_project.py::test_rename_models
571+
# and test_project.py::test_allowed_resolutions
572+
if type == TypeOptions.Function:
573+
raise NotImplementedError("Function resolutions are not yet supported.")
574+
return type
575+
576+
@model_validator(mode="after")
577+
def warn_parameters(self):
578+
"""Raise a warning if the parameters given are not expected for the given type."""
579+
if self.type == TypeOptions.Constant:
580+
expected_empty_fields = ["value_1", "value_2", "value_3", "value_4", "value_5"]
581+
elif self.type == TypeOptions.Data:
582+
expected_empty_fields = ["source", "value_1", "value_2", "value_3", "value_4", "value_5"]
583+
else:
584+
return self
585+
586+
non_empty_fields = [v for v in expected_empty_fields if getattr(self, v) != ""]
587+
if non_empty_fields:
588+
warnings.warn(
589+
"The following values are not recognised by this resolution type and will be ignored: "
590+
f"{', '.join(non_empty_fields)}",
591+
stacklevel=2,
592+
)
593+
594+
return self

tests/test_project.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,10 @@ def test_rename_models(test_project, model: str, fields: list[str]) -> None:
648648
test_project.resolutions[0] = RATapi.models.Resolution(type="data", source="Simulation")
649649
if model == "custom_files":
650650
test_project.backgrounds[0] = RATapi.models.Background(type="function", source="Test Custom File")
651-
test_project.resolutions[0] = RATapi.models.Resolution(type="function", source="Test Custom File")
651+
# workaround until function resolutions are added
652+
#test_project.resolutions[0] = RATapi.models.Resolution(type="function", source="Test Custom File")
653+
test_project.resolutions[0] = RATapi.models.Resolution(type="function", source="New Name")
654+
652655
getattr(test_project, model).set_fields(-1, name="New Name")
653656
model_name_lists = RATapi.project.model_names_used_in[model]
654657
for model_name_list, field in zip(model_name_lists, fields):
@@ -750,7 +753,8 @@ def test_allowed_absorption_layers(field: str) -> None:
750753
[
751754
[TypeOptions.Constant, "resolution_parameters"],
752755
[TypeOptions.Data, "data"],
753-
[TypeOptions.Function, "custom_files"],
756+
# uncomment when function resolutions are added!
757+
#[TypeOptions.Function, "custom_files"],
754758
],
755759
)
756760
def test_allowed_resolutions(resolution_type, expected_field) -> None:

0 commit comments

Comments
 (0)