Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mt_metadata \ mt_metadata \ transfer_functions \ io \ zfiles \ metadata \ channel.py: 90%

50 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-10 00:11 -0800

1# ===================================================== 

2# Imports 

3# ===================================================== 

4from typing import Annotated 

5 

6from pydantic import Field 

7 

8from mt_metadata.base import MetadataBase 

9from mt_metadata.common.enumerations import ChannelEnum 

10 

11 

12# ===================================================== 

13 

14 

15class Channel(MetadataBase): 

16 number: Annotated[ 

17 int | None, 

18 Field( 

19 default=None, 

20 description="Channel number", 

21 alias=None, 

22 json_schema_extra={ 

23 "units": None, 

24 "required": True, 

25 "examples": ["1"], 

26 }, 

27 ), 

28 ] 

29 

30 azimuth: Annotated[ 

31 float, 

32 Field( 

33 default=0.0, 

34 description="channel azimuth", 

35 alias=None, 

36 json_schema_extra={ 

37 "units": "degrees", 

38 "required": True, 

39 "examples": ["90"], 

40 }, 

41 ), 

42 ] 

43 

44 tilt: Annotated[ 

45 float, 

46 Field( 

47 default=0.0, 

48 description="channel tilt relative to horizontal.", 

49 alias=None, 

50 json_schema_extra={ 

51 "units": "degrees", 

52 "required": True, 

53 "examples": ["100.0"], 

54 }, 

55 ), 

56 ] 

57 

58 dl: Annotated[ 

59 float | str, 

60 Field( 

61 default=0.0, 

62 description="dipole length in meters", 

63 alias=None, 

64 json_schema_extra={ 

65 "units": "meters", 

66 "required": True, 

67 "examples": ["0.0"], 

68 }, 

69 ), 

70 ] 

71 

72 channel: Annotated[ 

73 ChannelEnum, 

74 Field( 

75 default="", 

76 description="channel name", 

77 alias=None, 

78 json_schema_extra={ 

79 "units": None, 

80 "required": True, 

81 "examples": ["hx"], 

82 }, 

83 ), 

84 ] 

85 

86 @property 

87 def channel_string(self) -> str: 

88 """Return the channel name as a string for indexing purposes.""" 

89 if hasattr(self.channel, "value"): 

90 return self.channel.value 

91 return str(self.channel) 

92 

93 def __str__(self): 

94 lines = ["Channel Metadata:"] 

95 for key in ["channel", "number", "dl", "azimuth", "tilt"]: 

96 try: 

97 value = getattr(self, key) 

98 # Special formatting for different field types 

99 if key == "channel" and hasattr(value, "value"): 

100 # For enums, use the string value 

101 if value.value == "": 

102 display_value = "None" 

103 else: 

104 display_value = value.value 

105 elif key == "number" and value is None: 

106 # Skip None number field completely 

107 continue 

108 else: 

109 display_value = value 

110 lines.append(f"\t{key.capitalize()}: {display_value:<12}") 

111 except TypeError: 

112 pass 

113 return "\n".join(lines) 

114 

115 def __repr__(self): 

116 return self.__str__() 

117 

118 @property 

119 def index(self): 

120 if self.number is not None: 

121 return self.number - 1 

122 else: 

123 return None 

124 

125 def from_dict(self, channel_dict): 

126 """ 

127 fill attributes from a dictionary 

128 """ 

129 

130 for key, value in channel_dict.items(): 

131 if key in ["azm", "azimuth", "measurement_azimuth"]: 

132 self.azimuth = value 

133 elif key in ["chn_num", "number"]: 

134 self.number = value 

135 elif key in ["tilt", "measurement_tilt"]: 

136 self.tilt = value 

137 elif key in ["dl", "dipole_length"]: 

138 self.dl = value 

139 elif key in ["channel", "component"]: 

140 self.channel = value