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 06:59 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 06:59 +0000
1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6'''
7Implementation of :app:`squirrel template`.
8'''
10import re
11import logging
13from pyrocko.guts import load_string, dump
15from pyrocko.squirrel.error import ToolError
16from ..common import dq, ldq
18logger = logging.getLogger('psq.cli.template')
20headline = 'Print configuration snippets.'
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()
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))
38 kwargs['qargs'] = '\n' + '\n'.join(lqargs) if lqargs else '{}'
39 return '''
40--- !squirrel.Dataset
42{path_prefix}
44# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...)
45sources:
46- !squirrel.FDSNSource
48 # URL or alias of FDSN site.
49 site: {site}
51 # Uncomment to let metadata expire in 10 days:
52 #expires: 10d
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
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()
68templates = {
69 'local.dataset': {
70 'description':
71 'A typical collection of local files.',
72 'yaml': '''
73--- !squirrel.Dataset
75{path_prefix}
77# Data sources to be added (LocalData, FDSNSource, CatalogSource, ...)
78sources:
79- !squirrel.LocalData # This data source is for local files.
81 # These paths are scanned for waveforms, stations, events.
82 paths:
83 - 'catalogs/events.txt'
84 - 'meta/stations.xml'
85 - 'data/waveforms'
87 # Select file format or 'detect' for autodetection.
88 format: 'detect'
89'''.format(path_prefix=path_prefix).strip()},
91 'geofon.dataset': {
92 'description':
93 'Everything available through GEOFON.',
94 'yaml': _template_online_dataset(
95 site='geofon',
96 ),
97 },
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 },
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 },
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 },
126 'gcmt-m7.dataset': {
127 'description': 'Global-CMT events with Mw >= 7.0.',
128 'yaml': '''
129--- !squirrel.Dataset
131{path_prefix}
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}
143names = sorted(templates.keys())
145template_listing = '\n'.join(
146 '%-30s %s' % (
147 '%s:' % name,
148 templates[name]['description']) for name in templates)
151def make_subparser(subparsers):
152 return subparsers.add_parser(
153 'template',
154 help=headline,
155 description=headline + '''
157Available SNIPPETs
159{}
160'''.format('\n'.join(' ' + line for line in template_listing.splitlines())))
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.')
171 format_default = 'commented'
172 format_choices = ['commented', 'normal', 'brief']
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)))
182 parser.add_argument(
183 '--write', '-w',
184 action='store_true',
185 help='Write to file.')
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)
195 return '\n'.join(out)
198def brief(s):
199 return dump(load_string(s))
202def run(parser, args):
204 if not args.name:
205 print(template_listing)
207 else:
208 func = {
209 'brief': brief,
210 'commented': lambda s: s,
211 'normal': decomment}[args.format]
213 s = func(templates[args.name]['yaml'])
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')
222 logger.info('File written: %s' % path)
224 except FileExistsError:
225 raise ToolError('File exists: %s' % path)
226 else:
227 print(s)