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
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-10 00:01 -0800
1# -*- coding: utf-8 -*-
2"""
4Created on Fri Jun 10 07:52:03 2022
6:author: Jared Peacock
8:license: MIT
10"""
12# =============================================================================
13# Imports
14# =============================================================================
15from __future__ import annotations
17from pathlib import Path
18from typing import Any, TYPE_CHECKING
20from loguru import logger
21from mt_metadata.timeseries import Station
23from .helpers import read_json_to_object
26if TYPE_CHECKING:
27 from loguru import Logger
30# =============================================================================
33class PhoenixConfig:
34 """
35 Phoenix Geophysics configuration file reader and metadata container.
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.
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).
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.
59 Examples
60 --------
61 >>> config = PhoenixConfig("config.json")
62 >>> config.read()
63 >>> station = config.station_metadata()
64 >>> print(f"Station ID: {station.id}")
65 """
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
73 @property
74 def fn(self) -> Path | None:
75 """
76 Path to the Phoenix configuration file.
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
85 @fn.setter
86 def fn(self, fn: str | Path | None) -> None:
87 """
88 Set the configuration file path with validation.
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.
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}")
110 def read(self, fn: str | Path | None = None) -> None:
111 """
112 Read and parse a Phoenix configuration file.
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.
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.
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.
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)
140 def has_obj(self) -> bool:
141 """
142 Check if configuration data has been loaded.
144 Returns
145 -------
146 bool
147 True if configuration data is loaded, False otherwise.
148 """
149 return self.obj is not None
151 @property
152 def auto_power_enabled(self) -> Any | None:
153 """
154 Auto power enabled setting from configuration.
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
165 @property
166 def config(self) -> Any | None:
167 """
168 Main configuration section from the configuration file.
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
180 @property
181 def empower_version(self) -> Any | None:
182 """
183 EMPower software version from configuration.
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
194 @property
195 def mtc150_reset(self) -> Any | None:
196 """
197 MTC150 reset setting from configuration.
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
208 @property
209 def network(self) -> Any | None:
210 """
211 Network configuration from configuration file.
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
222 @property
223 def receiver(self) -> Any | None:
224 """
225 Receiver configuration from configuration file.
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
236 @property
237 def schedule(self) -> Any | None:
238 """
239 Recording schedule from configuration file.
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
250 @property
251 def surveyTechnique(self) -> Any | None:
252 """
253 Survey technique setting from configuration file.
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
264 @property
265 def timezone(self) -> Any | None:
266 """
267 Timezone setting from configuration file.
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
278 @property
279 def timezone_offset(self) -> Any | None:
280 """
281 Timezone offset from configuration file.
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
292 @property
293 def version(self) -> Any | None:
294 """
295 Configuration file version from configuration file.
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
306 def station_metadata(self) -> Station:
307 """
308 Create a Station metadata object from configuration data.
310 Extracts station information from the loaded configuration and creates
311 a standardized Station metadata object with basic station parameters.
313 Returns
314 -------
315 Station
316 A Station metadata object populated with configuration data including
317 station ID, operator information, company name, and notes.
319 Raises
320 ------
321 AttributeError
322 If no configuration is loaded or required fields are missing.
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
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
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
346 return s