Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mth5 \ mth5 \ clients \ make_mth5.py: 92%
98 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-27 20:09 -0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-27 20:09 -0800
1# -*- coding: utf-8 -*-
2"""
3Make MTH5
4============
6This module provides helper functions to make MTH5 file from various clients
8Supported Clients include:
10 * FDSN (through Obspy)
11 * Science Base (TODO)
12 * NCI - Australia (TODO)
13 * Phoenix MTU-5C
14 * Zen
15 * LEMI 424
18Updated on Wed Aug 25 19:57:00 2021
20@author: jpeacock + tronan
21"""
22# =============================================================================
23# Imports
24# =============================================================================
25from pathlib import Path
27import pandas as pd
29from . import (
30 FDSN,
31 LEMI424Client,
32 MetronixClient,
33 NIMSClient,
34 PhoenixClient,
35 USGSGeomag,
36 ZenClient,
37)
40# =============================================================================
43class MakeMTH5:
44 """
45 Factory class for creating MTH5 files from various data sources.
47 This class provides class methods to create MTH5 files from different
48 magnetotelluric data acquisition systems and data repositories.
50 Parameters
51 ----------
52 mth5_version : str, default "0.2.0"
53 MTH5 file format version
54 interact : bool, default False
55 If True, keep file open for interactive use. If False, close file after creation.
56 save_path : str or Path, optional
57 Directory path to save MTH5 file. If None, uses current working directory.
58 **kwargs : dict
59 Additional keyword arguments for HDF5 file parameters. Any parameter
60 starting with 'h5' will be used for HDF5 configuration.
62 Attributes
63 ----------
64 h5_compression : str, default "gzip"
65 HDF5 compression algorithm
66 h5_compression_opts : int, default 4
67 Compression level (0-9 for gzip)
68 h5_shuffle : bool, default True
69 Enable byte shuffle filter for better compression
70 h5_fletcher32 : bool, default True
71 Enable Fletcher32 checksum for data integrity
72 h5_data_level : int, default 1
73 Data processing level indicator
75 Examples
76 --------
77 Create a basic MakeMTH5 instance:
79 >>> from mth5.clients import MakeMTH5
80 >>> maker = MakeMTH5(save_path="/path/to/save")
81 >>> print(maker)
82 MakeMTH5 Attibutes:
83 mth5_version: 0.2.0
84 h5_compression: gzip
85 ...
87 Create with custom compression:
89 >>> maker = MakeMTH5(
90 ... save_path="/data/mt",
91 ... h5_compression="lzf",
92 ... h5_shuffle=False
93 ... )
95 See Also
96 --------
97 mth5.mth5.MTH5 : Main MTH5 file interface
98 """
100 def __init__(
101 self,
102 mth5_version: str = "0.2.0",
103 interact: bool = False,
104 save_path: str | Path | None = None,
105 **kwargs,
106 ):
107 self.mth5_version = mth5_version
108 self.interact = interact
109 self.save_path = save_path
110 self.h5_compression = "gzip"
111 self.h5_compression_opts = 4
112 self.h5_shuffle = True
113 self.h5_fletcher32 = True
114 self.h5_data_level = 1
115 self.mth5_file_mode = "w"
116 self.mth5_filename = "make_mth5.h5"
118 for key, value in kwargs.items():
119 setattr(self, key, value)
121 if self.save_path is None:
122 self.save_path = Path().cwd()
124 def __str__(self):
125 lines = ["MakeMTH5 Attibutes:"]
126 for key, value in self.get_h5_kwargs().items():
127 lines.append(f"\t{key}: {value}")
129 return "\n".join(lines)
131 def __repr__(self):
132 return self.__str__()
134 @property
135 def save_path(self) -> Path:
136 """Get the save path as a Path object."""
137 return Path(self._save_path)
139 @save_path.setter
140 def save_path(self, value: str | Path | None):
141 """Set the save path, converting to Path if necessary."""
142 if value is None:
143 self._save_path = Path().cwd()
144 else:
145 self._save_path = Path(value)
146 if "." in self._save_path.name:
147 self.mth5_filename = self._save_path.name
148 self._save_path = self._save_path.parent
149 else:
150 if not self._save_path.exists():
151 self._save_path.mkdir(parents=True, exist_ok=True)
153 def get_h5_kwargs(self) -> dict:
154 """
155 Extract HDF5-related keyword arguments from instance attributes.
157 Returns
158 -------
159 dict
160 Dictionary of HDF5 configuration parameters including version,
161 compression settings, shuffle, fletcher32, and data level.
163 Examples
164 --------
165 >>> maker = MakeMTH5(h5_compression="lzf", h5_data_level=2)
166 >>> kwargs = maker.get_h5_kwargs()
167 >>> print(kwargs["h5_compression"])
168 lzf
169 """
170 h5_params = dict(
171 mth5_version=self.mth5_version,
172 h5_compression=self.h5_compression,
173 h5_compression_opts=self.h5_compression_opts,
174 h5_shuffle=self.h5_shuffle,
175 h5_fletcher32=self.h5_fletcher32,
176 h5_data_level=self.h5_data_level,
177 mth5_file_mode=self.mth5_file_mode,
178 )
180 for key, value in self.__dict__.items():
181 if key.startswith("h5"):
182 h5_params[key] = value
184 return h5_params
186 @classmethod
187 def from_fdsn_client(cls, request_df: pd.DataFrame, client: str = "IRIS", **kwargs):
188 """
189 Create MTH5 file from FDSN data service.
191 Pull data from an FDSN archive like IRIS using ObsPy clients.
192 The request DataFrame specifies which data to download.
194 Parameters
195 ----------
196 request_df : pd.DataFrame
197 DataFrame with columns:
199 - 'network' : str
200 FDSN Network code (e.g., 'IU', 'TA')
201 - 'station' : str
202 FDSN Station code (e.g., 'ANMO', 'CAS04')
203 - 'location' : str
204 FDSN Location code (e.g., '00', '')
205 - 'channel' : str
206 FDSN Channel code (e.g., 'LFE', 'BHZ')
207 - 'start' : str
208 Start time in format 'YYYY-MM-DDThh:mm:ss'
209 - 'end' : str
210 End time in format 'YYYY-MM-DDThh:mm:ss'
212 client : str, default "IRIS"
213 FDSN client name (e.g., 'IRIS', 'USGS', 'NCEDC')
214 **kwargs : dict
215 Additional keyword arguments. HDF5 parameters should be prefixed
216 with 'h5_' (e.g., h5_compression='gzip', h5_compression_opts=4).
218 Returns
219 -------
220 mth5.mth5.MTH5 or Path
221 MTH5 object if interact=True, otherwise Path to created file
223 Raises
224 ------
225 AttributeError
226 If the input DataFrame is not properly formatted
227 ValueError
228 If the DataFrame column values are invalid
230 Notes
231 -----
232 If any column value is blank, any matching value will be searched.
233 For example, leaving 'station' blank will return all stations within
234 the specified time range.
236 Examples
237 --------
238 Create a request DataFrame and download data:
240 >>> import pandas as pd
241 >>> from mth5.clients import MakeMTH5
242 >>>
243 >>> # Define request
244 >>> request_df = pd.DataFrame({
245 ... 'network': ['IU'],
246 ... 'station': ['ANMO'],
247 ... 'location': ['00'],
248 ... 'channel': ['LF*'],
249 ... 'start': ['2020-01-01T00:00:00'],
250 ... 'end': ['2020-01-02T00:00:00']
251 ... })
252 >>>
253 >>> # Create MTH5 with custom compression
254 >>> mth5_obj = MakeMTH5.from_fdsn_client(
255 ... request_df,
256 ... client='IRIS',
257 ... h5_compression_opts=1
258 ... )
260 See Also
261 --------
262 from_fdsn_miniseed_and_stationxml : Create from existing files
263 obspy.clients.fdsn : ObsPy FDSN client documentation
264 """
265 maker = cls(**kwargs)
266 kw_dict = maker.get_h5_kwargs()
267 kw_dict["mth5_filename"] = maker.mth5_filename
269 fdsn_client = FDSN(client=client, **kw_dict)
271 mth5_object = fdsn_client.make_mth5_from_fdsn_client(
272 request_df, path=maker.save_path, interact=maker.interact
273 )
275 return mth5_object
277 @classmethod
278 def from_fdsn_miniseed_and_stationxml(
279 cls,
280 station_xml_path: str | Path,
281 miniseed_files: str | Path | list[str | Path],
282 save_path: str | Path | None = None,
283 **kwargs,
284 ):
285 """
286 Create MTH5 from existing StationXML and miniSEED files.
288 Use this method when you already have StationXML and miniSEED files
289 downloaded from an FDSN client or created locally.
291 Parameters
292 ----------
293 station_xml_path : str, Path, or obspy.Inventory
294 Full path to StationXML file or an ObsPy Inventory object
295 miniseed_files : str, Path, list, or obspy.Stream
296 List of miniSEED file paths or ObsPy Stream objects. Can also
297 be a single file path or Stream object.
298 save_path : str or Path, optional
299 Directory to save new MTH5 file. If None, saves to current
300 working directory.
301 **kwargs : dict
302 Additional keyword arguments. HDF5 parameters should be prefixed
303 with 'h5_' (e.g., h5_compression='gzip').
305 Returns
306 -------
307 Path
308 Path to created MTH5 file. Filename format is
309 {network}_{station}.h5 based on unique network and station codes.
311 Raises
312 ------
313 TypeError
314 If inputs are not of correct type
316 Examples
317 --------
318 Create MTH5 from existing files:
320 >>> from mth5.clients import MakeMTH5
321 >>> from pathlib import Path
322 >>>
323 >>> # Define file paths
324 >>> station_xml = Path("data/station.xml")
325 >>> miniseed = [
326 ... Path("data/IU.ANMO.00.LFE.mseed"),
327 ... Path("data/IU.ANMO.00.LFN.mseed")
328 ... ]
329 >>>
330 >>> # Create MTH5
331 >>> mth5_path = MakeMTH5.from_fdsn_miniseed_and_stationxml(
332 ... station_xml,
333 ... miniseed,
334 ... save_path="output",
335 ... h5_compression="lzf"
336 ... )
337 >>> print(mth5_path)
338 output/IU_ANMO.h5
340 Using ObsPy objects directly:
342 >>> from obspy import read, read_inventory
343 >>>
344 >>> inventory = read_inventory("station.xml")
345 >>> stream = read("data/*.mseed")
346 >>>
347 >>> mth5_path = MakeMTH5.from_fdsn_miniseed_and_stationxml(
348 ... inventory,
349 ... stream,
350 ... save_path="output"
351 ... )
353 See Also
354 --------
355 from_fdsn_client : Download and create in one step
356 """
357 maker = cls(**kwargs)
358 kw_dict = maker.get_h5_kwargs()
359 kw_dict["mth5_filename"] = maker.mth5_filename
361 fdsn_client = FDSN(**kw_dict)
363 return fdsn_client.make_mth5_from_inventory_and_streams(
364 station_xml_path, miniseed_files, save_path=save_path
365 )
367 @classmethod
368 def from_usgs_geomag(cls, request_df: pd.DataFrame | str | Path, **kwargs):
369 """
370 Create MTH5 from USGS geomagnetic observatory data.
372 Downloads geomagnetic observatory data from USGS webservices into an
373 MTH5 file using a request DataFrame or CSV file.
375 Parameters
376 ----------
377 request_df : pd.DataFrame, str, or Path
378 Request definition as DataFrame or path to CSV file. Required columns:
380 * **observatory** : str - Observatory code (e.g., 'BOU', 'FRN')
381 * **type** : str - Data type: 'variation', 'adjusted',
382 'quasi-definitive', or 'definitive'
383 * **elements** : str - Geomagnetic elements to retrieve:
384 D, DIST, DST, E, E-E, E-N, F, G, H, SQ, SV, UK1, UK2, UK3, UK4,
385 X, Y, Z
386 * **sampling_period** : int - Sample period in seconds: 1, 60, or 3600
387 * **start** : str - Start time in YYYY-MM-DDThh:mm:ss format (UTC)
388 * **end** : str - End time in YYYY-MM-DDThh:mm:ss format (UTC)
390 **kwargs : dict
391 Additional keyword arguments. HDF5 parameters should be prefixed
392 with 'h5_' (e.g., h5_compression='gzip', h5_compression_opts=1).
394 Returns
395 -------
396 Path or MTH5
397 If interact=False (default), returns Path to created MTH5 file.
398 If interact=True, returns MTH5 object with file open.
400 Notes
401 -----
402 See USGS Geomagnetism Data web service for more information:
403 https://www.usgs.gov/tools/web-service-geomagnetism-data
405 Examples
406 --------
407 Create MTH5 from USGS Boulder observatory using DataFrame:
409 >>> import pandas as pd
410 >>> from mth5.clients import MakeMTH5
411 >>>
412 >>> request = pd.DataFrame([{
413 ... 'observatory': 'BOU',
414 ... 'type': 'variation',
415 ... 'elements': 'XYZF',
416 ... 'sampling_period': 1,
417 ... 'start': '2020-01-01T00:00:00',
418 ... 'end': '2020-01-02T00:00:00'
419 ... }])
420 >>>
421 >>> mth5_path = MakeMTH5.from_usgs_geomag(
422 ... request,
423 ... h5_compression='gzip',
424 ... h5_compression_opts=1
425 ... )
427 Using CSV file:
429 >>> mth5_path = MakeMTH5.from_usgs_geomag('requests.csv')
431 Multiple observatories and periods:
433 >>> request = pd.DataFrame([
434 ... {'observatory': 'BOU', 'type': 'variation',
435 ... 'elements': 'XYZF', 'sampling_period': 1,
436 ... 'start': '2020-01-01T00:00:00', 'end': '2020-01-02T00:00:00'},
437 ... {'observatory': 'FRN', 'type': 'variation',
438 ... 'elements': 'XYZF', 'sampling_period': 60,
439 ... 'start': '2020-01-01T00:00:00', 'end': '2020-01-02T00:00:00'}
440 ... ])
441 >>> mth5_path = MakeMTH5.from_usgs_geomag(request)
443 See Also
444 --------
445 mth5.io.usgs_geomag.USGSGeomag : USGS geomagnetic data client
446 """
447 maker = cls(**kwargs)
448 kw_dict = maker.get_h5_kwargs()
450 geomag_client = USGSGeomag(
451 save_path=maker.save_path,
452 interact=maker.interact,
453 **kw_dict,
454 )
456 return geomag_client.make_mth5_from_geomag(request_df)
458 @classmethod
459 def from_zen(
460 cls,
461 data_path: str | Path,
462 sample_rates: list[int] = [4096, 1024, 256],
463 calibration_path: str | Path | None = None,
464 survey_id: str | None = None,
465 combine: bool = True,
466 **kwargs,
467 ):
468 """
469 Create MTH5 from Zonge ZEN data files.
471 Processes ZEN data files from a directory structure and creates an
472 MTH5 file with organized time series data.
474 Parameters
475 ----------
476 data_path : str or Path
477 Directory where ZEN data files are stored
478 sample_rates : list of int, default [4096, 1024, 256]
479 Sample rates to include in Hz
480 calibration_path : str or Path, optional
481 Path to calibration file (amtant.cal). If None, looks for
482 calibration file in data_path.
483 survey_id : str, optional
484 Survey ID to apply to all stations found under data_path. If None,
485 attempts to extract from directory structure.
486 combine : bool, default True
487 If True, combine multiple runs into single run sampled at 1s
488 **kwargs : dict
489 Additional keyword arguments. HDF5 parameters should be prefixed
490 with 'h5_' (e.g., h5_compression='gzip', h5_compression_opts=1).
491 Use save_path to specify output directory.
493 Returns
494 -------
495 Path
496 Path to created MTH5 file
498 Notes
499 -----
500 ZEN data is typically organized with multiple .Z3D files per station.
501 The reader processes these files and organizes them into runs based on
502 sampling rate and timing.
504 When combine=True, all runs are merged into a single continuous run
505 sampled at 1 second intervals, which is useful for long-term datasets.
507 Examples
508 --------
509 Create MTH5 from ZEN data directory:
511 >>> from mth5.clients import MakeMTH5
512 >>> from pathlib import Path
513 >>>
514 >>> data_dir = Path("data/zen_survey")
515 >>> mth5_path = MakeMTH5.from_zen(
516 ... data_dir,
517 ... sample_rates=[4096, 256],
518 ... survey_id="MT001",
519 ... save_path="output"
520 ... )
522 With calibration file and HDF5 compression:
524 >>> mth5_path = MakeMTH5.from_zen(
525 ... "data/zen_survey",
526 ... calibration_path="data/amtant.cal",
527 ... survey_id="MT001",
528 ... combine=False,
529 ... h5_compression="gzip",
530 ... h5_compression_opts=4
531 ... )
533 Process all sample rates without combining:
535 >>> mth5_path = MakeMTH5.from_zen(
536 ... "data/zen_survey",
537 ... sample_rates=[4096, 1024, 256, 64, 4],
538 ... combine=False
539 ... )
541 See Also
542 --------
543 mth5.io.zen.ZenCollection : ZEN data reader
544 """
546 maker = cls(**kwargs)
547 kw_dict = maker.get_h5_kwargs()
549 zc = ZenClient(
550 data_path,
551 sample_rates=sample_rates,
552 save_path=maker.save_path,
553 calibration_path=calibration_path,
554 **kw_dict,
555 )
557 return zc.make_mth5_from_zen(survey_id=survey_id, combine=combine, **kwargs)
559 @classmethod
560 def from_phoenix(
561 cls,
562 data_path: str | Path,
563 mth5_filename: str | None = None,
564 save_path: str | Path | None = None,
565 sample_rates: list[int] = [150, 24000],
566 receiver_calibration_dict: str | Path | dict | None = None,
567 sensor_calibration_dict: str | Path | dict | None = None,
568 **kwargs,
569 ):
570 """
571 Create MTH5 from Phoenix MTU-5C data files.
573 Builds an MTH5 file from Phoenix MTU-5C data with calibration support.
574 Requires receiver and sensor calibration files exported from EMPower
575 software.
577 Parameters
578 ----------
579 data_path : str or Path
580 Directory where Phoenix data files are stored. Can be single station
581 or multiple stations.
582 mth5_filename : str, optional
583 Filename for the MTH5 file. If None, defaults to 'from_phoenix.h5'
584 save_path : str or Path, optional
585 Directory to save MTH5 file. If None, saves to data_path.
586 sample_rates : list of int, default [150, 24000]
587 Sample rates to include in Hz
588 receiver_calibration_dict : str, Path, or dict, optional
589 Receiver calibration specification:
591 * str/Path: Directory containing rxcal.json files
592 * dict: Keys are receiver IDs, values are paths to rxcal.json files
594 sensor_calibration_dict : str, Path, or dict, optional
595 Sensor calibration specification:
597 * str/Path: Directory containing scal.json files
598 * dict: Keys are sensor IDs, values are PhoenixCalibration objects
599 or paths to scal.json files
601 **kwargs : dict
602 Additional keyword arguments. HDF5 parameters should be prefixed
603 with 'h5_' (e.g., h5_compression='gzip').
605 Returns
606 -------
607 Path
608 Path to created MTH5 file
610 Notes
611 -----
612 Phoenix data requires calibration files exported from EMPower software:
614 1. Export rxcal files (receiver calibration) to JSON
615 2. Export scal files (sensor calibration) to JSON
616 3. Place files in accessible directory
617 4. Provide directory path or dict mapping to from_phoenix()
619 The method automatically matches calibration files with data based on
620 receiver and sensor IDs.
622 Examples
623 --------
624 Basic usage with calibration directories:
626 >>> from mth5.clients import MakeMTH5
627 >>> from pathlib import Path
628 >>>
629 >>> data_dir = Path("data/phoenix_survey")
630 >>> cal_dir = Path("calibrations")
631 >>>
632 >>> mth5_path = MakeMTH5.from_phoenix(
633 ... data_dir,
634 ... receiver_calibration_dict=cal_dir / "receivers",
635 ... sensor_calibration_dict=cal_dir / "sensors",
636 ... save_path="output"
637 ... )
639 With explicit filename and HDF5 compression:
641 >>> mth5_path = MakeMTH5.from_phoenix(
642 ... "data/phoenix_survey",
643 ... mth5_filename="MT_survey_2020.h5",
644 ... sample_rates=[150, 24000],
645 ... receiver_calibration_dict="calibrations/receivers",
646 ... sensor_calibration_dict="calibrations/sensors",
647 ... save_path="output",
648 ... h5_compression="gzip",
649 ... h5_compression_opts=4
650 ... )
652 Using explicit calibration dictionaries:
654 >>> receiver_cal = {
655 ... 'RX001': Path('cal/rx001_cal.json'),
656 ... 'RX002': Path('cal/rx002_cal.json')
657 ... }
658 >>> sensor_cal = {
659 ... 'SN123': phoenix_cal_obj_1,
660 ... 'SN124': phoenix_cal_obj_2
661 ... }
662 >>> mth5_path = MakeMTH5.from_phoenix(
663 ... "data/phoenix_survey",
664 ... receiver_calibration_dict=receiver_cal,
665 ... sensor_calibration_dict=sensor_cal
666 ... )
668 See Also
669 --------
670 mth5.io.phoenix.PhoenixClient : Phoenix data reader
671 mth5.io.phoenix.PhoenixCalibration : Calibration file handler
672 """
674 maker = cls(**kwargs)
675 kw_dict = maker.get_h5_kwargs()
677 phx_client = PhoenixClient(
678 data_path,
679 mth5_filename=mth5_filename,
680 sample_rates=sample_rates,
681 receiver_calibration_dict=receiver_calibration_dict,
682 sensor_calibration_dict=sensor_calibration_dict,
683 save_path=save_path,
684 **kw_dict,
685 )
687 return phx_client.make_mth5_from_phoenix()
689 @classmethod
690 def from_lemi424(
691 cls,
692 data_path: str | Path,
693 survey_id: str,
694 station_id: str,
695 mth5_filename: str = "from_lemi424.h5",
696 save_path: str | Path = Path().cwd(),
697 **kwargs,
698 ):
699 """
700 Create MTH5 from LEMI-424 long period data.
702 Builds an MTH5 file from LEMI-424 instrument data on a station-by-station
703 basis. LEMI data has limited metadata, so survey and station IDs must
704 be provided.
706 Parameters
707 ----------
708 data_path : str or Path
709 Directory where LEMI-424 data files are stored. Can be single
710 station or full directory.
711 survey_id : str
712 Survey ID to apply to all stations
713 station_id : str
714 Station ID for this station's data
715 mth5_filename : str, default 'from_lemi424.h5'
716 Filename for the MTH5 output file
717 save_path : str or Path, default current directory
718 Directory to save MTH5 file
719 **kwargs : dict
720 Additional keyword arguments. HDF5 parameters should be prefixed
721 with 'h5_' (e.g., h5_compression='gzip').
723 Returns
724 -------
725 Path
726 Path to created MTH5 file
728 Notes
729 -----
730 LEMI-424 is a long-period magnetotelluric instrument. Data files have
731 limited embedded metadata, requiring manual specification of survey
732 and station information.
734 Process each station individually due to minimal automatic metadata
735 extraction capabilities.
737 Examples
738 --------
739 Create MTH5 from LEMI-424 data:
741 >>> from mth5.clients import MakeMTH5
742 >>> from pathlib import Path
743 >>>
744 >>> data_dir = Path("data/lemi_mt01")
745 >>> mth5_path = MakeMTH5.from_lemi424(
746 ... data_dir,
747 ... survey_id='MT2020',
748 ... station_id='MT01',
749 ... save_path="output"
750 ... )
752 With HDF5 compression:
754 >>> mth5_path = MakeMTH5.from_lemi424(
755 ... "data/lemi_mt01",
756 ... survey_id='MT2020',
757 ... station_id='MT01',
758 ... mth5_filename='MT2020_MT01.h5',
759 ... h5_compression='gzip',
760 ... h5_compression_opts=1
761 ... )
763 Multiple stations (process individually):
765 >>> for station in ['MT01', 'MT02', 'MT03']:
766 ... data_dir = Path(f"data/lemi_{station.lower()}")
767 ... mth5_path = MakeMTH5.from_lemi424(
768 ... data_dir,
769 ... survey_id='MT2020',
770 ... station_id=station,
771 ... mth5_filename=f'MT2020_{station}.h5',
772 ... save_path="output"
773 ... )
775 See Also
776 --------
777 mth5.io.lemi424.LEMI424Client : LEMI-424 data reader
778 """
779 maker = cls(**kwargs)
780 kw_dict = maker.get_h5_kwargs()
781 kw_dict.pop("mth5_filename", None)
782 kw_dict.pop("save_path", None)
784 lemi_client = LEMI424Client(
785 data_path,
786 save_path=save_path,
787 mth5_filename=mth5_filename,
788 **kw_dict,
789 )
791 return lemi_client.make_mth5_from_lemi424(survey_id, station_id)
793 @classmethod
794 def from_metronix(
795 cls,
796 data_path: str | Path,
797 sample_rates: list[float] = [128],
798 mth5_filename: str | None = None,
799 save_path: str | Path | None = None,
800 run_name_zeros: int = 0,
801 **kwargs,
802 ):
803 """
804 Create MTH5 from Metronix Geophysics ATSS + JSON files.
806 Builds an MTH5 file from Metronix data in their new folder structure
807 format with ATSS time series and JSON metadata files.
809 Parameters
810 ----------
811 data_path : str or Path
812 Highest level directory to archive data from, usually the survey
813 level. For single station, use station folder path.
814 sample_rates : list of float, default [128]
815 Sample rates to archive in samples/second
816 mth5_filename : str, optional
817 Filename for the MTH5 file. If None, automatically generated from
818 survey/station information.
819 save_path : str or Path, optional
820 Directory to save MTH5 file. If None, saves to current working
821 directory.
822 run_name_zeros : int, default 0
823 Number of zeros for zero-padding in run names. Run names formatted
824 as 'sr{sample_rate}_{run_id:0{run_name_zeros}}'. If 0, uses
825 original run names (e.g., 'run_0001').
826 **kwargs : dict
827 Additional keyword arguments. HDF5 parameters should be prefixed
828 with 'h5_' (e.g., h5_compression='gzip').
830 Returns
831 -------
832 Path
833 Path to created MTH5 file
835 Notes
836 -----
837 Metronix Geophysics uses a specific folder structure with ATSS binary
838 files and JSON metadata. The reader processes this structure and
839 organizes data by survey, station, and run.
841 Run naming can be customized with run_name_zeros:
842 - run_name_zeros=0: Keep original names like 'run_0001'
843 - run_name_zeros=4: Format as 'sr128_0001'
844 - run_name_zeros=2: Format as 'sr128_01'
846 Examples
847 --------
848 Create MTH5 from Metronix survey data:
850 >>> from mth5.clients import MakeMTH5
851 >>> from pathlib import Path
852 >>>
853 >>> data_dir = Path("data/metronix_survey")
854 >>> mth5_path = MakeMTH5.from_metronix(
855 ... data_dir,
856 ... sample_rates=[128, 4096],
857 ... save_path="output"
858 ... )
860 With custom run naming and compression:
862 >>> mth5_path = MakeMTH5.from_metronix(
863 ... "data/metronix_survey",
864 ... sample_rates=[128],
865 ... mth5_filename="survey_2020.h5",
866 ... run_name_zeros=4,
867 ... h5_compression="gzip",
868 ... h5_compression_opts=4
869 ... )
871 Single station with original run names:
873 >>> mth5_path = MakeMTH5.from_metronix(
874 ... "data/metronix_survey/Station_001",
875 ... sample_rates=[128, 512],
876 ... run_name_zeros=0,
877 ... save_path="output"
878 ... )
880 Multiple sample rates with formatted names:
882 >>> mth5_path = MakeMTH5.from_metronix(
883 ... "data/metronix_survey",
884 ... sample_rates=[32, 128, 512, 4096],
885 ... run_name_zeros=3,
886 ... mth5_filename="mt_data.h5"
887 ... )
889 See Also
890 --------
891 mth5.io.metronix.MetronixClient : Metronix data reader
892 """
893 maker = cls(**kwargs)
894 kw_dict = maker.get_h5_kwargs()
896 metronix_client = MetronixClient(
897 data_path,
898 sample_rates=sample_rates,
899 save_path=save_path,
900 mth5_filename=mth5_filename,
901 **kw_dict,
902 )
904 return metronix_client.make_mth5_from_metronix(run_name_zeros=run_name_zeros)
906 @classmethod
907 def from_nims(
908 cls,
909 data_path,
910 sample_rates=[4096, 1024, 256],
911 save_path=None,
912 calibration_path=None,
913 survey_id=None,
914 combine=True,
915 **kwargs,
916 ):
917 """
918 Create an MTH5 from nims data.
920 Any H5 file parameters like compression, shuffle, etc need to have a
921 prefix of 'h5'. For example h5_compression='gzip'.
923 >>> MakeMTH5.from_nims(
924 data_path, **{'h5_compression_opts': 1}
925 )
927 :param data_path: directory to where data are stored
928 :type data_path: Path, str
929 :param sample_rates: sample rates to include,
930 defaults to [4096, 1024, 256]
931 :type sample_rates: list, optional
932 :param save_path: path to save H5 file to, defaults to None which will
933 place the file in `data_path`
934 :type save_path: str or Path, optional
935 :param calibration_path: path to calibration file amtant.cal,
936 defaults to None
937 :type calibration_path: str or Path, optional
938 :param survey_id: survey ID to apply to all station found under
939 `data_path`, defaults to None
940 :type survey_id: string
941 :param combine: if True combine the runs into a single run sampled at 1s,
942 defaults to True
943 :type combine: bool
944 :return: MTH5 file name
945 :rtype: Path
947 """
949 maker = cls(**kwargs)
950 kw_dict = maker.get_h5_kwargs()
952 nc = NIMSClient(
953 data_path,
954 sample_rates=sample_rates,
955 save_path=save_path,
956 calibration_path=calibration_path,
957 **kw_dict,
958 )
960 return nc.make_mth5_from_nims(survey_id=survey_id, combine=combine, **kwargs)