Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

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

 

from StringIO import StringIO 

from obspy.xseed.blockette import Blockette 

from obspy.xseed.fields import Integer, VariableString, FixedString, Float, \ 

    Loop 

from obspy.xseed.utils import formatRESP, LookupCode 

 

 

class Blockette041(Blockette): 

    """ 

    Blockette 041: FIR Dictionary Blockette. 

 

    The FIR blockette is used to specify FIR (Finite Impulse Response) 

    digital filter coefficients. It is an alternative to blockette [44] when 

    specifying FIR filters. The blockette recognizes the various forms of 

    filter symmetry and can exploit them to reduce the number of factors 

    specified in the blockette. See Response (Coefficients) Blockette [54] 

    for more information. 

    """ 

 

    id = 41 

    name = "FIR Dictionary" 

    fields = [ 

        Integer(3, "Response Lookup Key", 4), 

        VariableString(4, "Response Name", 1, 25, 'UN_'), 

        FixedString(5, "Symmetry Code", 1, 'U'), 

        Integer(6, "Signal In Units", 3, xpath=34), 

        Integer(7, "Signal Out Units", 3, xpath=34), 

        Integer(8, "Number of Factors", 4), 

        #REPEAT field 9 for the Number of Factors 

        Loop("FIR Coefficient", "Number of Factors", [ 

            Float(9, "FIR Coefficient", 14, mask='%+1.7e')], flat=True), 

    ] 

 

    def parseSEED(self, data, expected_length=0): 

        """ 

        If number of FIR coefficients are larger than maximal blockette size of 

        9999 chars a follow up blockette with the same blockette id and 

        response lookup key is expected - this is checked here. 

        """ 

        # convert to stream for test issues 

        if isinstance(data, basestring): 

            expected_length = len(data) 

            data = StringIO(data) 

        # get current lookup key 

        pos = data.tell() 

        data.read(7) 

        global_lookup_key = int(data.read(4)) 

        data.seek(pos) 

        # read first blockette 

        temp = StringIO() 

        temp.write(data.read(expected_length)) 

        # check next blockettes 

        while True: 

            # save position 

            pos = data.tell() 

            try: 

                blockette_id = int(data.read(3)) 

            except ValueError: 

                break 

            if blockette_id != 41: 

                # different blockette id -> break 

                break 

            blockette_length = int(data.read(4)) 

            lookup_key = int(data.read(4)) 

            if lookup_key != global_lookup_key: 

                # different lookup key -> break 

                break 

            # ok follow up blockette found - skip some unneeded fields 

            self.fields[1].read(data) 

            self.fields[2].read(data) 

            self.fields[3].read(data) 

            self.fields[4].read(data) 

            self.fields[5].read(data) 

            # remaining length in current blockette 

            length = pos - data.tell() + blockette_length 

            # read follow up blockette and append it to temporary blockette 

            temp.write(data.read(length)) 

        # reposition file pointer 

        data.seek(pos) 

        # parse new combined temporary blockette 

        temp.seek(0) 

        Blockette.parseSEED(self, temp, expected_length=temp.len) 

 

    def parseXML(self, xml_doc, *args, **kwargs): 

        if self.xseed_version == '1.0': 

            xml_doc.find('fir_coefficient').tag = 'FIR_coefficient' 

        Blockette.parseXML(self, xml_doc, *args, **kwargs) 

 

    def getXML(self, *args, **kwargs): 

        xml = Blockette.getXML(self, *args, **kwargs) 

        if self.xseed_version == '1.0': 

            xml.find('FIR_coefficient').tag = 'fir_coefficient' 

        return xml 

 

    def getRESP(self, station, channel, abbreviations): 

        """ 

        Returns RESP string. 

        """ 

        string = \ 

        '#\t\t+                     +--------------------------------+' + \ 

        '                      +\n' + \ 

        '#\t\t+                     |   FIR response,' + \ 

        '%6s ch %s   |                      +\n' % (station, channel) + \ 

        '#\t\t+                     +--------------------------------+' + \ 

        '                      +\n' + \ 

        '#\t\t\n' + \ 

        'B041F05     Symmetry type:                         %s\n' \ 

                % self.symmetry_code + \ 

        'B041F06     Response in units lookup:              %s - %s\n'\ 

            % (LookupCode(abbreviations, 34, 'unit_name', 'unit_lookup_code', 

                         self.signal_in_units), 

              LookupCode(abbreviations, 34, 'unit_description', 

                    'unit_lookup_code', self.signal_in_units)) + \ 

        'B041F07     Response out units lookup:             %s - %s\n'\ 

            % (LookupCode(abbreviations, 34, 'unit_name', 'unit_lookup_code', 

                         self.signal_out_units), 

              LookupCode(abbreviations, 34, 'unit_description', 

                    'unit_lookup_code', self.signal_out_units)) + \ 

        'B041F08     Number of numerators:                  %s\n' \ 

                % self.number_of_factors 

        if self.number_of_factors > 1: 

            string += '#\t\tNumerator coefficients:\n' + \ 

                       '#\t\t  i, coefficient\n' 

            for _i in xrange(self.number_of_factors): 

                string += 'B041F09    %4s %13s\n' \ 

                            % (_i, formatRESP(self.FIR_coefficient[_i], 6)) 

        elif self.number_of_factors == 1: 

            string += '#\t\tNumerator coefficients:\n' + \ 

                       '#\t\t  i, coefficient\n' 

            string += 'B041F09    %4s %13s\n' \ 

                            % (0, formatRESP(self.FIR_coefficient, 6)) 

        string += '#\t\t\n' 

        return string