1# =====================================================
2# Imports
3# =====================================================
4from typing import Annotated
5from xml.etree import cElementTree as et
6
7from pydantic import Field
8
9from mt_metadata.base import MetadataBase
10from mt_metadata.transfer_functions.io.emtfxml.metadata.helpers import element_to_string
11
12
13# =====================================================
14class Magnetic(MetadataBase):
15 name: Annotated[
16 str,
17 Field(
18 default="",
19 description="Name of the channel",
20 alias=None,
21 json_schema_extra={
22 "units": None,
23 "required": True,
24 "examples": ["hx"],
25 },
26 ),
27 ]
28
29 orientation: Annotated[
30 float,
31 Field(
32 default=0.0,
33 description="orientation angle relative to geographic north",
34 alias=None,
35 json_schema_extra={
36 "units": "degrees",
37 "required": True,
38 "examples": ["11.9"],
39 },
40 ),
41 ]
42
43 x: Annotated[
44 float,
45 Field(
46 default=0.0,
47 description="location of sensor relative center point in north direction",
48 alias=None,
49 json_schema_extra={
50 "units": "meters",
51 "required": True,
52 "examples": ["100.0"],
53 },
54 ),
55 ]
56
57 y: Annotated[
58 float,
59 Field(
60 default=0.0,
61 description="location of sensor relative center point in east direction",
62 alias=None,
63 json_schema_extra={
64 "units": "meters",
65 "required": True,
66 "examples": ["100.0"],
67 },
68 ),
69 ]
70
71 z: Annotated[
72 float,
73 Field(
74 default=0.0,
75 description="location of sensor relative center point in depth",
76 alias=None,
77 json_schema_extra={
78 "units": "meters",
79 "required": True,
80 "examples": ["100.0"],
81 },
82 ),
83 ]
84
85 def to_xml(self, string: bool = False, required: bool = True) -> str | et.Element:
86 """
87
88 :param string: Whether to return the XML as a string, defaults to False
89 :type string: bool, optional
90 :param required: Whether to include required fields, defaults to True
91 :type required: bool, optional
92 :return: The XML representation of the object
93 :rtype: str | et.Element
94
95 """
96 for attr in ["orientation", "x", "y", "z"]:
97 value = getattr(self, attr)
98 if value is None:
99 setattr(self, attr, 0)
100 root = et.Element(
101 self.__class__.__name__.capitalize(),
102 {
103 "name": self.name,
104 "orientation": f"{self.orientation:.3f}",
105 "x": f"{self.x:.3f}",
106 "y": f"{self.y:.3f}",
107 "z": f"{self.z:.3f}",
108 },
109 )
110
111 if string:
112 return element_to_string(root)
113 return root