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

51 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-10-06 15:01 +0000

1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6''' 

7Implementation of :app:`squirrel template`. 

8''' 

9 

10import re 

11import logging 

12 

13from pyrocko.guts import load_string, dump 

14 

15from pyrocko.squirrel.error import ToolError 

16from ..common import dq, ldq 

17 

18logger = logging.getLogger('psq.cli.template') 

19 

20headline = 'Print configuration snippets.' 

21 

22path_prefix = ''' 

23# All file paths given below are treated relative to the location of this 

24# configuration file. Here we may give a common prefix. For example, if the 

25# configuration file is in the sub-directory 'PROJECT/config/', set it to '..' 

26# so that all paths are relative to 'PROJECT/'. 

27path_prefix: '.' 

28'''.strip() 

29 

30 

31def _template_online_dataset(**kwargs): 

32 lqargs = [] 

33 for k in ['network', 'station', 'channel']: 

34 if k in kwargs: 

35 v = kwargs.pop(k) 

36 lqargs.append(" %s: '%s'" % (k, v)) 

37 

38 kwargs['qargs'] = '\n' + '\n'.join(lqargs) if lqargs else '{}' 

39 return ''' 

40--- !squirrel.Dataset 

41 

42{path_prefix} 

43 

44# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...) 

45sources: 

46- !squirrel.FDSNSource 

47 

48 # URL or alias of FDSN site. 

49 site: {site} 

50 

51 # Uncomment to let metadata expire in 10 days: 

52 #expires: 10d 

53 

54 # Waveforms can be optionally shared with other FDSN client configurations, 

55 # so that data is not downloaded multiple times. The downside may be that in 

56 # some cases more data than expected is available (if data was previously 

57 # downloaded for a different application). 

58 #shared_waveforms: true 

59 

60 # FDSN query arguments to make metadata queries. 

61 # See http://www.fdsn.org/webservices/fdsnws-station-1.1.pdf 

62 # Time span arguments should not be added here, because they are handled 

63 # automatically by Squirrel. 

64 query_args: {qargs} 

65'''.format(path_prefix=path_prefix, **kwargs).strip() 

66 

67 

68templates = { 

69 'local.dataset': { 

70 'description': 

71 'A typical collection of local files.', 

72 'yaml': ''' 

73--- !squirrel.Dataset 

74 

75{path_prefix} 

76 

77# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...) 

78sources: 

79- !squirrel.LocalData # This data source is for local files. 

80 

81 # These paths are scanned for waveforms, stations, events. 

82 paths: 

83 - 'catalogs/events.txt' 

84 - 'meta/stations.xml' 

85 - 'data/waveforms' 

86 

87 # Select file format or 'detect' for autodetection. 

88 format: 'detect' 

89'''.format(path_prefix=path_prefix).strip()}, 

90 

91 'geofon.dataset': { 

92 'description': 

93 'Everything available through GEOFON.', 

94 'yaml': _template_online_dataset( 

95 site='geofon', 

96 ), 

97 }, 

98 

99 'iris-seis.dataset': { 

100 'description': 

101 'High- and low-gain seismometer channels from IRIS.', 

102 'yaml': _template_online_dataset( 

103 site='iris', 

104 channel='?H?,?L?', 

105 ), 

106 }, 

107 

108 'iris-seis-bb.dataset': { 

109 'description': 

110 'Broad-band high-gain seismometer channels from IRIS.', 

111 'yaml': _template_online_dataset( 

112 site='iris', 

113 channel='VH?,LH?,BH?,HH?', 

114 ), 

115 }, 

116 

117 'bgr-gr-lh.dataset': { 

118 'description': 'LH channels for network GR from BGR.', 

119 'yaml': _template_online_dataset( 

120 site='bgr', 

121 network='GR', 

122 channel='LH?', 

123 ), 

124 }, 

125 

126 'gcmt-m7.dataset': { 

127 'description': 'Global-CMT events with Mw >= 7.0.', 

128 'yaml': ''' 

129--- !squirrel.Dataset 

130 

131{path_prefix} 

132 

133# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...) 

134sources: 

135- !squirrel.CatalogSource 

136 catalog: gcmt 

137 query_args: 

138 magmin: '7.0' 

139'''.format(path_prefix=path_prefix).strip() 

140 }, 

141} 

142 

143names = sorted(templates.keys()) 

144 

145template_listing = '\n'.join( 

146 '%-30s %s' % ( 

147 '%s:' % name, 

148 templates[name]['description']) for name in templates) 

149 

150 

151def make_subparser(subparsers): 

152 return subparsers.add_parser( 

153 'template', 

154 help=headline, 

155 description=headline + ''' 

156 

157Available SNIPPETs 

158 

159{} 

160'''.format('\n'.join(' ' + line for line in template_listing.splitlines()))) 

161 

162 

163def setup(parser): 

164 parser.add_argument( 

165 'name', 

166 choices=names, 

167 nargs='?', 

168 metavar='SNIPPET', 

169 help='Name of template snippet to print.') 

170 

171 format_default = 'commented' 

172 format_choices = ['commented', 'normal', 'brief'] 

173 

174 parser.add_argument( 

175 '--format', '-f', 

176 choices=format_choices, 

177 default=format_default, 

178 metavar='FMT', 

179 help='Set verbosity level of output YAML. Choices: %s. ' 

180 'Default: %s.' % (ldq(format_choices), dq(format_default))) 

181 

182 parser.add_argument( 

183 '--write', '-w', 

184 action='store_true', 

185 help='Write to file.') 

186 

187 

188def decomment(s): 

189 out = [] 

190 for line in s.splitlines(): 

191 line = re.sub(r'#.+', '', line) 

192 if line.strip(): 

193 out.append(line) 

194 

195 return '\n'.join(out) 

196 

197 

198def brief(s): 

199 return dump(load_string(s)) 

200 

201 

202def run(parser, args): 

203 

204 if not args.name: 

205 print(template_listing) 

206 

207 else: 

208 func = { 

209 'brief': brief, 

210 'commented': lambda s: s, 

211 'normal': decomment}[args.format] 

212 

213 s = func(templates[args.name]['yaml']) 

214 

215 if args.write: 

216 path = args.name + '.yaml' 

217 try: 

218 with open(path, 'x') as f: 

219 f.write(s) 

220 f.write('\n') 

221 

222 logger.info('File written: %s' % path) 

223 

224 except FileExistsError: 

225 raise ToolError('File exists: %s' % path) 

226 else: 

227 print(s)