Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mth5 \ mth5 \ groups \ filter_groups \ fap_filter_group.py: 73%
60 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"""
3Created on Wed Jun 9 08:55:16 2021
5:copyright:
6 Jared Peacock (jpeacock@usgs.gov)
8:license: MIT
10"""
12# =============================================================================
13# Imports
14# =============================================================================
15import numpy as np
16from mt_metadata.timeseries.filters import FrequencyResponseTableFilter
18from mth5.groups.base import BaseGroup
21# =============================================================================
22# fap Group
23# =============================================================================
24class FAPGroup(BaseGroup):
25 """
26 Container for fap type filters
28 """
30 def __init__(self, group, **kwargs):
31 super().__init__(group, **kwargs)
33 @property
34 def filter_dict(self):
35 """
37 Dictionary of available fap filters
39 :return: DESCRIPTION
40 :rtype: TYPE
42 """
43 f_dict = {}
44 for key in self.hdf5_group.keys():
45 fap_group = self.hdf5_group[key]
46 f_dict[key] = {
47 "type": fap_group.attrs["type"],
48 "hdf5_ref": fap_group.ref,
49 }
51 return f_dict
53 def add_filter(self, name, frequency, amplitude, phase, fap_metadata):
54 """
56 create an HDF5 group/dataset from information given.
58 :param name: name of the filter
59 :type name: string
60 :param frequency: frequency array in samples per second
61 :type frequency: list, np.ndarray
62 :param amplitude: amplitude array in units of units out
63 :type amplitude: list, np.ndarray
64 :param phase: Phase in degrees
65 :type phase: list, np.ndarray
66 :param fap_metadata: other metadata for the filter see
67 :class:`mt_metadata.timeseries.filters.FrequencyResponseTableFilter` \
68 for details on entries
69 :type fap_metadata: dictionary
70 :return: DESCRIPTION
71 :rtype: TYPE
73 """
75 # create a group for the filter by the name
76 fap_filter_group = self.hdf5_group.create_group(name)
78 # create datasets for the poles and zeros
79 fap_ds = fap_filter_group.create_dataset(
80 "fap_table",
81 frequency.shape,
82 dtype=np.dtype(
83 [("frequency", float), ("amplitude", float), ("phase", float)]
84 ),
85 **self.dataset_options,
86 )
88 fap_ds[:] = [(f, a, p) for f, a, p in zip(frequency, amplitude, phase)]
90 # fill in the metadata
91 fap_filter_group.attrs.update(fap_metadata)
93 return fap_filter_group
95 def remove_filter(self):
96 pass
98 def get_filter(self, name):
99 """
100 Get a filter from the name
102 :param name: name of the filter
103 :type name: string
105 :return: HDF5 group of the fap filter
106 """
107 return self.hdf5_group[name]
109 def update_filter(self, fap_object):
110 """
111 update values from fap object
113 :param fap_object: DESCRIPTION
114 :type fap_object: TYPE
115 :return: DESCRIPTION
116 :rtype: TYPE
118 """
119 if fap_object.name in self.groups_list:
120 self.hdf5_group.pop(fap_object.name)
122 self.from_object(fap_object)
124 def from_object(self, fap_object):
125 """
126 make a filter from a :class:`mt_metadata.timeseries.filters.PoleZeroFilter`
128 :param fap_object: MT metadata PoleZeroFilter
129 :type fap_object: :class:`mt_metadata.timeseries.filters.PoleZeroFilter`
131 """
133 if not isinstance(fap_object, FrequencyResponseTableFilter):
134 msg = (
135 f"Filter must be a FrequencyResponseTableFilter not {type(fap_object)}"
136 )
137 self.logger.error(msg)
138 raise TypeError(msg)
140 input_dict = fap_object.to_dict(single=True, required=False)
141 input_dict.pop("frequencies")
142 input_dict.pop("amplitudes")
143 input_dict.pop("phases")
144 for k, v in input_dict.items():
145 if v is None:
146 input_dict[k] = str(v)
148 fap_group = self.add_filter(
149 fap_object.name,
150 fap_object.frequencies,
151 fap_object.amplitudes,
152 fap_object.phases,
153 input_dict,
154 )
155 return fap_group
157 def to_object(self, name):
158 """
159 make a :class:`mt_metadata.timeseries.filters.pole_zeros_filter` object
161 :return: DESCRIPTION
162 :rtype: TYPE
164 """
166 fap_group = self.get_filter(name)
168 fap_obj = FrequencyResponseTableFilter(**fap_group.attrs)
170 try:
171 fap_obj.frequencies = fap_group["fap_table"]["frequency"][:]
172 except TypeError:
173 self.logger.debug(f"fap filter {name} has no frequency")
174 fap_obj.frequencies = []
176 try:
177 fap_obj.amplitudes = fap_group["fap_table"]["amplitude"][:]
178 except TypeError:
179 self.logger.debug(f"fap filter {name} has no amplitudes")
180 fap_obj.amplitudes = []
182 try:
183 fap_obj.phases = fap_group["fap_table"]["phase"][:]
184 except TypeError:
185 self.logger.debug(f"fap filter {name} has no phases")
186 fap_obj.phases = []
188 return fap_obj