Coverage for /usr/local/lib/python3.13/dist-packages/pyrocko/squirrel/tool/commands/summon.py: 15%
62 statements
« prev ^ index » next coverage.py v7.6.0, created at 2025-12-04 10:41 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2025-12-04 10:41 +0000
1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6'''
7Implementation of :app:`squirrel summon`.
8'''
10import math
11import logging
13from pyrocko.squirrel.error import SquirrelError
14from pyrocko import progress, guts, util
16logger = logging.getLogger('psq.cli.summon')
18headline = 'Fill local cache.'
21def make_subparser(subparsers):
22 return subparsers.add_parser(
23 'summon',
24 help=headline,
25 description=headline)
28def setup(parser):
29 parser.add_squirrel_selection_arguments()
30 parser.add_squirrel_query_arguments()
31 parser.add_argument(
32 '--channel-priorities',
33 dest='channel_priorities',
34 metavar='CHA',
35 help='''
36List of 2-character band/instrument code combinations to try. For example,
37giving ```HH,BH``` would first try to get ```HH?``` channels and then fallback
38to ```BH?``` if these are not available. The first matching waveforms are
39returned. Use in combination with ``--sample-rate-min`` and
40``--sample-rate-max`` to constrain the sample rate.
41'''.strip())
43 parser.add_argument(
44 '--sample-rate-min',
45 dest='sample_rate_min',
46 metavar='FLOAT',
47 type=float,
48 help='Minimum sample rate [Hz] to consider.')
50 parser.add_argument(
51 '--sample-rate-max',
52 dest='sample_rate_max',
53 metavar='FLOAT',
54 type=float,
55 help='Maximum sample rate [Hz] to consider.')
57 parser.add_argument(
58 '--get-events',
59 dest='get_events',
60 action='store_true',
61 help='Get only time spans with events.')
63 parser.add_argument(
64 '--event-time-span',
65 dest='event_time_span',
66 metavar='DURATION,DURATION',
67 help='Set time span to be completed for events, e.g. `-30m,2h`.')
69 parser.add_argument(
70 '--tinc',
71 dest='tinc',
72 type=float,
73 default=3600.,
74 metavar='SECONDS',
75 help='Download loop time window length [s].')
78def run(parser, args):
79 d = args.squirrel_query
80 squirrel = args.make_squirrel()
82 if not squirrel.has(['waveform_promise']):
83 logger.warning(
84 'No waveform promises available. It may be necessary to run '
85 '`squirrel update --promises ...`.')
87 if args.get_events:
88 events = squirrel.get_events(
89 tmin=d.get('tmin', None),
90 tmax=d.get('tmax', None))
92 if not args.event_time_span:
93 raise SquirrelError(
94 'Time span setting need. Currently --event-time-span')
96 try:
97 span_tmin, span_tmax = [
98 guts.parse_duration(s)
99 for s in args.event_time_span.split(',')]
101 except Exception:
102 raise SquirrelError(
103 'Invalid argument to --event-time-span: %s'
104 % args.event_time_span)
106 groups = [
107 (event.time + span_tmin, event.time + span_tmax, event.name)
108 for event in events]
109 else:
110 p_tmin, p_tmax = squirrel.get_time_span(
111 kinds=['waveform_promise'],
112 dummy_limits=False)
114 if d.get('tmin') is None and p_tmin is not None:
115 d['tmin'] = p_tmin
117 if d.get('tmax') is None and p_tmax is not None:
118 d['tmax'] = p_tmax
120 if 'tmin' not in d or 'tmax' not in d:
121 raise SquirrelError('Time span required.')
123 groups = [(d['tmin'], d['tmax'], '')]
125 d.pop('tmin', None)
126 d.pop('tmax', None)
128 tinc = args.tinc
130 channel_priorities = None
131 if args.channel_priorities:
132 channel_priorities = [
133 cha.strip() for cha in args.channel_priorities.split(',')]
135 with progress.view():
136 task_group = progress.task('Group', len(groups))
138 for igroup, (group_tmin, group_tmax, group_name) in enumerate(groups):
139 group_label = '%s - %s%s' % (
140 util.time_to_str(group_tmin, '%Y-%m-%d %H:%M:%S'),
141 util.time_to_str(group_tmax, '%Y-%m-%d %H:%M:%S'),
142 '(%s)' % group_name if group_name else '')
144 task_group.update(igroup, group_label)
146 if group_name:
147 logger.info('Summoning group: %s' % group_label)
149 tmin = math.floor(group_tmin / tinc) * tinc
150 tmax = math.ceil(group_tmax / tinc) * tinc
151 nwindows = int(round((tmax - tmin) / tinc))
152 task = progress.task('Summoning', nwindows)
153 iwindow = 0
154 try:
155 for batch in squirrel.chopper_waveforms(
156 tinc=tinc,
157 load_data=False,
158 channel_priorities=channel_priorities,
159 sample_rate_min=args.sample_rate_min,
160 sample_rate_max=args.sample_rate_max,
161 tmin=tmin,
162 tmax=tmax,
163 **d):
165 iwindow += 1
166 task.update(iwindow, '%s - %s' % (
167 util.time_to_str(batch.tmin, '%Y-%m-%d %H:%M:%S'),
168 util.time_to_str(batch.tmax, '%Y-%m-%d %H:%M:%S')))
170 finally:
171 task.done()
173 stats = str(squirrel)
174 stats = '\n'.join(' ' + s for s in stats.splitlines())
176 logger.info('Squirrel stats:\n%s' % stats)