Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mt_metadata \ mt_metadata \ timeseries \ filters \ coefficient_filter.py: 90%

21 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 

6import numpy as np 

7from pydantic import Field, PrivateAttr 

8 

9from mt_metadata.timeseries.filters import FilterBase 

10 

11 

12try: 

13 from obspy.core import inventory 

14except ImportError: 

15 inventory = None 

16 

17from mt_metadata.base.helpers import requires 

18 

19 

20# ===================================================== 

21class CoefficientFilter(FilterBase): 

22 _filter_type: str = PrivateAttr("coefficient") 

23 type: Annotated[ 

24 str, 

25 Field( 

26 default="coefficient", 

27 description="Type of filter. Must be 'coefficient'", 

28 alias=None, 

29 json_schema_extra={ 

30 "units": None, 

31 "required": True, 

32 "examples": ["coefficient"], 

33 }, 

34 ), 

35 ] 

36 gain: Annotated[ 

37 float, 

38 Field( 

39 default=1.0, 

40 description="Scale factor for a simple coefficient filter.", 

41 alias=None, 

42 # gt=0.0, 

43 json_schema_extra={ 

44 "units": None, 

45 "required": True, 

46 "examples": ["100"], 

47 }, 

48 ), 

49 ] 

50 

51 @requires(obspy=inventory) 

52 def to_obspy( 

53 self, 

54 stage_number=1, 

55 cf_type="DIGITAL", 

56 sample_rate=1, 

57 normalization_frequency=0, 

58 ): 

59 """ 

60 stage_sequence_number, 

61 stage_gain, 

62 stage_gain_frequency, 

63 input_units, 

64 output_units, 

65 cf_transfer_function_type, 

66 resource_id=None, 

67 resource_id2=None, 

68 name=None, 

69 numerator=None, 

70 denominator=None, 

71 input_units_description=None, 

72 output_units_description=None, 

73 description=None, 

74 decimation_input_sample_rate=None, 

75 decimation_factor=None, 

76 decimation_offset=None, 

77 decimation_delay=None, 

78 decimation_correction=None 

79 

80 :param stage_number: DESCRIPTION, defaults to 1 

81 :type stage_number: TYPE, optional 

82 :param cf_type: DESCRIPTION, defaults to "DIGITAL" 

83 :type cf_type: TYPE, optional 

84 :param sample_rate: DESCRIPTION, defaults to 1 

85 :type sample_rate: TYPE, optional 

86 :return: DESCRIPTION 

87 :rtype: TYPE 

88 

89 """ 

90 

91 stage = inventory.CoefficientsTypeResponseStage( 

92 stage_number, 

93 self.gain, 

94 normalization_frequency, 

95 self.units_in_object.symbol, 

96 self.units_out_object.symbol, 

97 cf_type, 

98 name=self.name, 

99 decimation_input_sample_rate=sample_rate, 

100 decimation_factor=1, 

101 decimation_offset=0, 

102 decimation_delay=0, 

103 decimation_correction=0, 

104 numerator=[1], 

105 denominator=[], 

106 description=self.get_filter_description(), 

107 input_units_description=self.units_in_object.name, 

108 output_units_description=self.units_out_object.name, 

109 ) 

110 

111 return stage 

112 

113 def complex_response(self, frequencies, **kwargs): 

114 """ 

115 

116 Parameters 

117 ---------- 

118 frequencies: numpy array of frequencies, expected in Hz 

119 

120 Returns 

121 ------- 

122 h : numpy array of (possibly complex-valued) frequency response at the input frequencies 

123 

124 """ 

125 if isinstance(frequencies, (float, int)): 

126 frequencies = np.array([frequencies]) 

127 return self.gain * np.ones(len(frequencies), dtype=complex)