1# =====================================================
2# Imports
3# =====================================================
4from typing import Annotated
5from xml.etree import cElementTree as et
6
7from loguru import logger
8from pydantic import Field, field_validator
9
10from mt_metadata.base import MetadataBase
11from mt_metadata.base.helpers import element_to_string
12
13from . import Estimate
14
15
16# =====================================================
17class StatisticalEstimates(MetadataBase):
18 estimates_list: Annotated[
19 list[Estimate | dict] | dict,
20 Field(
21 default_factory=list,
22 description="list of statistical estimates",
23 alias=None,
24 json_schema_extra={
25 "units": None,
26 "required": True,
27 "examples": ["[var cov]"],
28 },
29 ),
30 ]
31
32 @field_validator("estimates_list", mode="before")
33 @classmethod
34 def validate_estimates_list(cls, value: list) -> list[Estimate]:
35 if not isinstance(value, list):
36 value = [value]
37 estimates_list = []
38 for item in value:
39 est = Estimate() # type: ignore
40 if isinstance(item, dict):
41 est.from_dict(item)
42 elif isinstance(item, Estimate):
43 est = item
44 else:
45 est.name = item
46 estimates_list.append(est)
47 return estimates_list
48
49 def read_dict(self, input_dict: dict) -> None:
50 """
51 Read in statistical estimate descriptions
52
53 :param input_dict: input dictionary containing statistical estimates
54 :type input_dict: dict
55 :return: None
56 :rtype: None
57
58 """
59
60 try:
61 self.estimates_list = input_dict["statistical_estimates"]["estimate"]
62 except KeyError:
63 logger.warning("Could not statistical estimates")
64
65 def to_xml(self, string: bool = False, required: bool = True) -> str | et.Element:
66 """
67 Convert the StatisticalEstimates instance to XML format.
68
69 Parameters
70 ----------
71 string : bool, optional
72 If True, return the XML as a string, by default False
73 required : bool, optional
74 If True, include required fields in the XML, by default True
75
76 Returns
77 -------
78 str | et.Element
79 The XML representation of the instance
80 """
81
82 root = et.Element(self.__class__.__name__)
83
84 for estimate in self.estimates_list:
85 root.append(estimate.to_xml(required=required)) # type: ignore
86
87 if string:
88 return element_to_string(root)
89 return root