Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/squirrel/tool/commands/response.py: 17%

58 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-10-23 12:35 +0000

1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6''' 

7Implementation of :app:`squirrel response`. 

8''' 

9 

10import logging 

11 

12from ..common import ldq 

13from pyrocko.squirrel.error import ToolError 

14 

15logger = logging.getLogger('psq.cli.response') 

16 

17headline = 'Print instrument response information.' 

18 

19 

20def indent(prefix, nfirst, n, message): 

21 return '\n'.join( 

22 prefix + ' ' * (nfirst if i == 0 else n) + line 

23 for i, line in enumerate(message.splitlines())) 

24 

25 

26def make_subparser(subparsers): 

27 return subparsers.add_parser( 

28 'response', 

29 help=headline, 

30 description=headline) 

31 

32 

33def setup(parser): 

34 parser.add_squirrel_selection_arguments() 

35 parser.add_squirrel_query_arguments(without=['kinds']) 

36 

37 level_choices = ['response', 'stages'] 

38 

39 parser.add_argument( 

40 '--level', 

41 choices=level_choices, 

42 dest='level', 

43 default='response', 

44 help='Set level of detail to be printed. Choices: %s' 

45 % ldq(level_choices)) 

46 

47 parser.add_argument( 

48 '--problems', 

49 action='store_true', 

50 dest='problems', 

51 default=False, 

52 help='Print attached warnings and error messages.') 

53 

54 parser.add_argument( 

55 '--plot', 

56 action='store_true', 

57 dest='plot', 

58 default=False, 

59 help='Create Bode plot showing the responses.') 

60 

61 parser.add_argument( 

62 '--fmin', 

63 dest='fmin', 

64 type=float, 

65 default=0.01, 

66 help='Minimum frequency [Hz], default: 0.01') 

67 

68 parser.add_argument( 

69 '--fmax', 

70 dest='fmax', 

71 type=float, 

72 default=100., 

73 help='Maximum frequency [Hz], default: 100') 

74 

75 parser.add_argument( 

76 '--normalize', 

77 dest='normalize', 

78 action='store_true', 

79 help='Normalize response to be 1 on flat part.') 

80 

81 parser.add_argument( 

82 '--save', 

83 dest='out_path', 

84 help='Save figure to file.') 

85 

86 parser.add_argument( 

87 '--dpi', 

88 dest='dpi', 

89 type=float, 

90 default=100., 

91 help='DPI setting for pixel image output, default: 100') 

92 

93 parser.add_argument( 

94 '--stages', 

95 dest='stages', 

96 metavar='START:STOP', 

97 help='Show response of selected stages. Indexing is Python style: ' 

98 'count starts at zero, negative values count from the end.') 

99 

100 input_quantity_choices = ['displacement', 'velocity', 'acceleration'] 

101 

102 parser.add_argument( 

103 '--input-quantity', 

104 dest='input_quantity', 

105 choices=input_quantity_choices, 

106 metavar='QUANTITY', 

107 help='Show converted response for given input quantity. choices: %s' 

108 % ldq(input_quantity_choices)) 

109 

110 parser.add_argument( 

111 '--show-breakpoints', 

112 dest='show_breakpoints', 

113 action='store_true', 

114 default=False, 

115 help='Show breakpoints of pole-zero responses.') 

116 

117 parser.add_argument( 

118 '--index-labels', 

119 dest='index_labels', 

120 action='store_true', 

121 default=False, 

122 help='Label graphs only by index and print details to terminal ' 

123 'to save space when many labels would be shown. Aggregate ' 

124 'identical responses under a common index.') 

125 

126 

127def run(parser, args): 

128 squirrel = args.make_squirrel() 

129 

130 stages = (None, None) 

131 if args.stages: 

132 words = args.stages.split(':') 

133 try: 

134 if len(words) == 1: 

135 stages = (int(words[0]), int(words[0])+1) 

136 elif len(words) == 2: 

137 stages = tuple(int(word) if word else None for word in words) 

138 else: 

139 raise ValueError() 

140 

141 except ValueError: 

142 raise ToolError('Invalid --stages argument.') 

143 

144 data = [] 

145 for response in squirrel.get_responses(**args.squirrel_query): 

146 print(response.summary) 

147 if args.problems: 

148 for level, message, _ in response.log: 

149 print('! %s: %s' % ( 

150 level.capitalize(), 

151 indent('!', 0, 5, message))) 

152 

153 if args.level == 'stages': 

154 for stage in response.stages[slice(*stages)]: 

155 print(' %s' % stage.summary) 

156 if args.problems: 

157 for level, message, _ in stage.log: 

158 print('! %s: %s' % ( 

159 level.capitalize(), 

160 indent('!', 0, 7, message))) 

161 

162 data.append(( 

163 ', '.join([ 

164 str(response.codes), 

165 response.str_time_span_short, 

166 response.summary_log, 

167 response.summary_quantities]), 

168 response.get_effective( 

169 input_quantity=args.input_quantity, 

170 stages=stages))) 

171 

172 if args.plot: 

173 if not data: 

174 logger.warning('No response objects found.') 

175 return 

176 

177 labels, resps = [list(x) for x in zip(*data)] 

178 

179 from pyrocko.plot.response import plot 

180 plot( 

181 resps, 

182 fmin=args.fmin, 

183 fmax=args.fmax, 

184 nf=200, 

185 normalize=args.normalize, 

186 labels=labels, 

187 filename=args.out_path, 

188 dpi=args.dpi, 

189 show_breakpoints=args.show_breakpoints, 

190 separate_combined_labels='print' if args.index_labels else None)