From 9aa52e1bbe92e354781678ff767d292089021474 Mon Sep 17 00:00:00 2001 From: Tim Lorsbach Date: Wed, 10 Jun 2026 13:58:30 +0200 Subject: [PATCH] Added ais --- bayer/additional_information/__init__.py | 178 +++++++++++++++++++++++ bayer/epdb_hooks.py | 3 +- 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 bayer/additional_information/__init__.py diff --git a/bayer/additional_information/__init__.py b/bayer/additional_information/__init__.py new file mode 100644 index 00000000..49b083b8 --- /dev/null +++ b/bayer/additional_information/__init__.py @@ -0,0 +1,178 @@ +import enum +from typing import Optional + +from envipy_additional_information import GroupEnum as G +from envipy_additional_information import SubcategoryEnum as S +from envipy_additional_information import ( + register, + register_parser_command, + EnviPyModel, + # EnviPyModelParser, + Interval, + UIConfig, + IntervalConfig, + WidgetType, + registry, +) + + +@register(keyname="compoundlabel", groups=[S.MISC, G.SLUDGE, G.SEDIMENT, G.SOIL]) +class CompoundLabel(EnviPyModel): + label: str + + class UI: + title = "Compound Label" + label = UIConfig(widget=WidgetType.TEXT, label="Label", order=1) + + +# TODO Expose EnviPyModelParser in lib and subclass +@register_parser_command("compoundlabel") +class CompoundLabelParser: + @staticmethod + def from_string(data: str) -> CompoundLabel: + return CompoundLabel(label=data) + + +@register(keyname="studywaterstoragecapacity", groups=[S.MISC, G.SLUDGE, G.SEDIMENT, G.SOIL]) +class StudyWaterStorageCapacity(EnviPyModel): + capacity: str + + class UI: + title = "Study Water Storage Capacity" + capacity = UIConfig(widget=WidgetType.TEXT, label="Study Water Storage Capacity", order=1) + + +# TODO Expose EnviPyModelParser in lib and subclass +@register_parser_command("studywst") +class StudyWaterStorageCapacityParser: + @staticmethod + def from_string(data: str) -> StudyWaterStorageCapacity: + return StudyWaterStorageCapacity(capacity=data) + + +class ObservationType(enum.Enum): + OBSERVED = "observed" + APPLIED = "applied" + NA = 'NA' + + +@register(keyname="observation", groups=[S.MISC, G.SLUDGE, G.SEDIMENT, G.SOIL]) +class Observation(EnviPyModel): + type: ObservationType + min_value: Optional[float] = None + max_value: Optional[float] = None + + class UI: + title = "Observation" + type = UIConfig(widget=WidgetType.SELECT, label="Observed or Applied", order=1) + min_value = UIConfig(widget=WidgetType.NUMBER, label="Min Value", order=2) + max_value = UIConfig(widget=WidgetType.NUMBER, label="Max Value", order=3) + + +# TODO Expose EnviPyModelParser in lib and subclass +@register_parser_command("observation") +class ObservationParser: + @staticmethod + def from_string(data: str) -> Observation: + parts = data.split(";") + + observation_type = ObservationType(parts[0]) + min_value = None + if parts[1]: + try: + min_value = float(parts[1]) + except ValueError: + pass + + max_value = None + if parts[2]: + try: + max_value = float(parts[2]) + except ValueError: + pass + + return Observation(type=observation_type, min_value=min_value, max_value=max_value) + + +@register(keyname="kinetics", groups=[S.MISC, G.SLUDGE, G.SEDIMENT, G.SOIL]) +class Kinetics(EnviPyModel): + dt50: Interval[float] + normalized_dt50: bool + chi2err: Optional[float] = None + t_test: Optional[float] = None + swarc: Optional[float] = None + visual_fit: Optional[int] = None + comment: str + source: str + kinetic_model: str + k1: Optional[float] = None + k2: Optional[float] = None + g: Optional[float] = None + tb: Optional[float] = None + alpha: Optional[float] = None + beta: Optional[float] = None + + class UI: + title = "Kinetics" + + # Field config + dt50 = IntervalConfig(label="DT50 Range", order=1, unit="d") + normalized_dt50 = UIConfig(widget=WidgetType.CHECKBOX, label="Normalized DT50", order=2) + chi2err = UIConfig(widget=WidgetType.NUMBER, label="Chi2err", order=3) + t_test = UIConfig(widget=WidgetType.NUMBER, label="T-Test", order=4) + swarc = UIConfig(widget=WidgetType.NUMBER, label="SWARC", order=5) + visual_fit = UIConfig(widget=WidgetType.NUMBER, label="Visual Fit", order=6) + comment = UIConfig(widget=WidgetType.TEXTAREA, label="Comments", order=7) + source = UIConfig(widget=WidgetType.TEXT, label="Source", order=8) + kinetic_model = UIConfig(widget=WidgetType.SELECT, label="Kinetic Model", order=9) + k1 = UIConfig(widget=WidgetType.NUMBER, label="K1", order=10) + k2 = UIConfig(widget=WidgetType.NUMBER, label="K2", order=11) + g = UIConfig(widget=WidgetType.NUMBER, label="G", order=12) + tb = UIConfig(widget=WidgetType.NUMBER, label="TB", order=13) + alpha = UIConfig(widget=WidgetType.NUMBER, label="Alpha", order=14) + beta = UIConfig(widget=WidgetType.NUMBER, label="Beta", order=15) + + +# TODO Expose EnviPyModelParser in lib and subclass +@register_parser_command("kineticevaluation") +class KinecticsParser: + @staticmethod + def from_string(data: str) -> Kinetics: + parts = data.split(";") + dt50 = registry.get_parser("interval").from_string(parts[0]) + normalized_dt50 = parts[1] == "true" + chi2err = float(parts[2]) if parts[2] else None + t_test = float(parts[3]) if parts[3] else None + swarc = float(parts[4]) if parts[4] else None + visual_fit = int(parts[5]) if parts[5] else None + comment = parts[6] + source = parts[7] + kinetic_model = parts[8] + k1 = float(parts[9]) if parts[9] else None + k2 = float(parts[10]) if parts[10] else None + g = float(parts[11]) if parts[11] else None + tb = float(parts[12]) if parts[12] else None + alpha = float(parts[13]) if parts[13] else None + beta = float(parts[14]) if parts[14] else None + + return Kinetics( + dt50=dt50, + normalized_dt50=normalized_dt50, + chi2err=chi2err, + t_test=t_test, + swarc=swarc, + visual_fit=visual_fit, + comment=comment, + source=source, + kinetic_model=kinetic_model, + k1=k1, + k2=k2, + g=g, + tb=tb, + alpha=alpha, + beta=beta, + ) + + +if __name__ == '__main__': + print(KinecticsParser.from_string("187.0 - 187.0;false;;;;;;;AFO;;;;;;")) diff --git a/bayer/epdb_hooks.py b/bayer/epdb_hooks.py index a5279572..92e71e7a 100644 --- a/bayer/epdb_hooks.py +++ b/bayer/epdb_hooks.py @@ -1,5 +1,6 @@ import logging +from bayer import additional_information # noqa: F401 from epdb.template_registry import register_template logger = logging.getLogger(__name__) @@ -36,4 +37,4 @@ register_template( register_template( "epdb.objects.node.viz", "objects/node_viz.html", -) \ No newline at end of file +)