Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mth5 \ mth5 \ io \ phoenix \ readers \ config.py: 49%

91 statements  

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

1# -*- coding: utf-8 -*- 

2""" 

3 

4Created on Fri Jun 10 07:52:03 2022 

5 

6:author: Jared Peacock 

7 

8:license: MIT 

9 

10""" 

11 

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

13# Imports 

14# ============================================================================= 

15from __future__ import annotations 

16 

17from pathlib import Path 

18from typing import Any, TYPE_CHECKING 

19 

20from loguru import logger 

21from mt_metadata.timeseries import Station 

22 

23from .helpers import read_json_to_object 

24 

25 

26if TYPE_CHECKING: 

27 from loguru import Logger 

28 

29 

30# ============================================================================= 

31 

32 

33class PhoenixConfig: 

34 """ 

35 Phoenix Geophysics configuration file reader and metadata container. 

36 

37 This class reads and provides access to Phoenix MTU-5C instrument 

38 configuration data stored in JSON format. The configuration file contains 

39 recording parameters, instrument settings, and metadata used to control 

40 data acquisition. 

41 

42 Parameters 

43 ---------- 

44 fn : str, pathlib.Path, or None, optional 

45 Path to the Phoenix configuration file (typically config.json). 

46 If provided, the file will be validated for existence. 

47 **kwargs : Any 

48 Additional keyword arguments (currently unused). 

49 

50 Attributes 

51 ---------- 

52 fn : pathlib.Path or None 

53 Path to the configuration file. 

54 obj : Any or None 

55 Parsed configuration object containing all settings. 

56 logger : loguru.Logger 

57 Logger instance for debugging and error reporting. 

58 

59 Examples 

60 -------- 

61 >>> config = PhoenixConfig("config.json") 

62 >>> config.read() 

63 >>> station = config.station_metadata() 

64 >>> print(f"Station ID: {station.id}") 

65 """ 

66 

67 def __init__(self, fn: str | Path | None = None, **kwargs: Any) -> None: 

68 self._fn: Path | None = None 

69 self.obj: Any = None 

70 self.logger: Logger = logger 

71 self.fn = fn 

72 

73 @property 

74 def fn(self) -> Path | None: 

75 """ 

76 Path to the Phoenix configuration file. 

77 

78 Returns 

79 ------- 

80 pathlib.Path or None 

81 The path to the configuration file, or None if not set. 

82 """ 

83 return self._fn 

84 

85 @fn.setter 

86 def fn(self, fn: str | Path | None) -> None: 

87 """ 

88 Set the configuration file path with validation. 

89 

90 Parameters 

91 ---------- 

92 fn : str, pathlib.Path, or None 

93 Path to the configuration file. If None, clears the current path. 

94 If provided, validates that the file exists. 

95 

96 Raises 

97 ------ 

98 ValueError 

99 If the specified file does not exist. 

100 """ 

101 if fn is None: 

102 self._fn = None 

103 else: 

104 fn = Path(fn) 

105 if fn.exists(): 

106 self._fn = Path(fn) 

107 else: 

108 raise ValueError(f"Could not find {fn}") 

109 

110 def read(self, fn: str | Path | None = None) -> None: 

111 """ 

112 Read and parse a Phoenix configuration file. 

113 

114 Loads and parses a Phoenix MTU-5C configuration file in JSON format. 

115 The parsed configuration is stored in the obj attribute and provides 

116 access to all recording parameters and instrument settings. 

117 

118 Parameters 

119 ---------- 

120 fn : str, pathlib.Path, or None, optional 

121 Path to the configuration file to read. If None, uses the 

122 previously set file path from the fn property. 

123 

124 Raises 

125 ------ 

126 ValueError 

127 If no file path is provided and none was previously set. 

128 IOError 

129 If the configuration file cannot be read or parsed. 

130 

131 Notes 

132 ----- 

133 The configuration file should be in Phoenix JSON format containing 

134 recording parameters, instrument settings, and metadata. 

135 """ 

136 if fn is not None: 

137 self.fn = fn 

138 self.obj = read_json_to_object(self.fn) 

139 

140 def has_obj(self) -> bool: 

141 """ 

142 Check if configuration data has been loaded. 

143 

144 Returns 

145 ------- 

146 bool 

147 True if configuration data is loaded, False otherwise. 

148 """ 

149 return self.obj is not None 

150 

151 @property 

152 def auto_power_enabled(self) -> Any | None: 

153 """ 

154 Auto power enabled setting from configuration. 

155 

156 Returns 

157 ------- 

158 Any or None 

159 The auto power enabled setting, or None if no configuration is loaded. 

160 """ 

161 if self.has_obj(): 

162 return self.obj.auto_power_enabled 

163 return None 

164 

165 @property 

166 def config(self) -> Any | None: 

167 """ 

168 Main configuration section from the configuration file. 

169 

170 Returns 

171 ------- 

172 Any or None 

173 The first configuration object containing recording parameters, 

174 or None if no configuration is loaded. 

175 """ 

176 if self.has_obj(): 

177 return self.obj.config[0] 

178 return None 

179 

180 @property 

181 def empower_version(self) -> Any | None: 

182 """ 

183 EMPower software version from configuration. 

184 

185 Returns 

186 ------- 

187 Any or None 

188 The EMPower software version, or None if no configuration is loaded. 

189 """ 

190 if self.has_obj(): 

191 return self.obj.empower_version 

192 return None 

193 

194 @property 

195 def mtc150_reset(self) -> Any | None: 

196 """ 

197 MTC150 reset setting from configuration. 

198 

199 Returns 

200 ------- 

201 Any or None 

202 The MTC150 reset setting, or None if no configuration is loaded. 

203 """ 

204 if self.has_obj(): 

205 return self.obj.mtc150_reset 

206 return None 

207 

208 @property 

209 def network(self) -> Any | None: 

210 """ 

211 Network configuration from configuration file. 

212 

213 Returns 

214 ------- 

215 Any or None 

216 The network configuration settings, or None if no configuration is loaded. 

217 """ 

218 if self.has_obj(): 

219 return self.obj.network 

220 return None 

221 

222 @property 

223 def receiver(self) -> Any | None: 

224 """ 

225 Receiver configuration from configuration file. 

226 

227 Returns 

228 ------- 

229 Any or None 

230 The receiver configuration settings, or None if no configuration is loaded. 

231 """ 

232 if self.has_obj(): 

233 return self.obj.receiver 

234 return None 

235 

236 @property 

237 def schedule(self) -> Any | None: 

238 """ 

239 Recording schedule from configuration file. 

240 

241 Returns 

242 ------- 

243 Any or None 

244 The recording schedule configuration, or None if no configuration is loaded. 

245 """ 

246 if self.has_obj(): 

247 return self.obj.schedule 

248 return None 

249 

250 @property 

251 def surveyTechnique(self) -> Any | None: 

252 """ 

253 Survey technique setting from configuration file. 

254 

255 Returns 

256 ------- 

257 Any or None 

258 The survey technique setting, or None if no configuration is loaded. 

259 """ 

260 if self.has_obj(): 

261 return self.obj.surveyTechnique 

262 return None 

263 

264 @property 

265 def timezone(self) -> Any | None: 

266 """ 

267 Timezone setting from configuration file. 

268 

269 Returns 

270 ------- 

271 Any or None 

272 The timezone setting, or None if no configuration is loaded. 

273 """ 

274 if self.has_obj(): 

275 return self.obj.timezone 

276 return None 

277 

278 @property 

279 def timezone_offset(self) -> Any | None: 

280 """ 

281 Timezone offset from configuration file. 

282 

283 Returns 

284 ------- 

285 Any or None 

286 The timezone offset in hours, or None if no configuration is loaded. 

287 """ 

288 if self.has_obj(): 

289 return self.obj.timezone_offset 

290 return None 

291 

292 @property 

293 def version(self) -> Any | None: 

294 """ 

295 Configuration file version from configuration file. 

296 

297 Returns 

298 ------- 

299 Any or None 

300 The configuration file version, or None if no configuration is loaded. 

301 """ 

302 if self.has_obj(): 

303 return self.obj.version 

304 return None 

305 

306 def station_metadata(self) -> Station: 

307 """ 

308 Create a Station metadata object from configuration data. 

309 

310 Extracts station information from the loaded configuration and creates 

311 a standardized Station metadata object with basic station parameters. 

312 

313 Returns 

314 ------- 

315 Station 

316 A Station metadata object populated with configuration data including 

317 station ID, operator information, company name, and notes. 

318 

319 Raises 

320 ------ 

321 AttributeError 

322 If no configuration is loaded or required fields are missing. 

323 

324 Notes 

325 ----- 

326 The method extracts the following information from config.layout: 

327 - Station_Name -> station.id 

328 - Operator -> station.acquired_by.name 

329 - Company_Name -> station.acquired_by.organization 

330 - Notes -> station.comments 

331 

332 Examples 

333 -------- 

334 >>> config = PhoenixConfig("config.json") 

335 >>> config.read() 

336 >>> station = config.station_metadata() 

337 >>> print(f"Station: {station.id}") 

338 """ 

339 s = Station() # type: ignore 

340 

341 s.id = self.config.layout.Station_Name # type: ignore 

342 s.acquired_by.name = self.config.layout.Operator # type: ignore 

343 s.acquired_by.organization = self.config.layout.Company_Name # type: ignore 

344 s.comments = self.config.layout.Notes # type: ignore 

345 

346 return s