1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
5from __future__ import absolute_import
7import os
8import sys
9from optparse import OptionParser, OptionGroup
10from collections import OrderedDict
12from .report_main import GreensFunctionTest as gftest
13from .report_main import FilterFrequencyError as gft_ffe
14from .report_main import FomostoReportError
16spstr = '\n' + ' '*20
17subcmds_desc = OrderedDict([
18 ('single', 'create pdf of a single store'),
19 ('double', 'create pdf of two stores'),
20 ('sstandard', 'create a single store pdf with standard setup'),
21 ('dstandard', 'create a double store pdf with standard setup'),
22 ('slow', 'create a single store pdf, filtering the' +
23 spstr + 'traces with a low frequency'),
24 ('dlow', 'create a double store pdf, filtering the' +
25 spstr + 'traces with a low frequency'),
26 ('shigh', 'create a single store pdf, filtering the' +
27 spstr + 'traces with a low frequency'),
28 ('dhigh', 'create a single store pdf, filtering the' +
29 spstr + 'traces with a low frequency'),
30 ('slowband', 'create a single store pdf with a low' +
31 spstr + 'frequency band filter'),
32 ('dlowband', 'create a double store pdf with a low' +
33 spstr + 'frequency band filter'),
34 ('shighband', 'create a single store pdf with a high' +
35 spstr + 'frequency band filter'),
36 ('dhighband', 'create a double store pdf with a high' +
37 spstr + 'frequency band filter'),
38 ('snone', 'create a single store pdf with unfiltered'
39 ' traces'),
40 ('dnone', 'create a double store pdf with unfiltered'
41 ' traces')])
43subcmds_uses = {
44 'single': 'single <input config file> [options]',
45 'double': 'double <input config file> [options]',
46 'sstandard': 'sstandard <store dir> [options]',
47 'dstandard': 'dstandard <store dir1> <store dir2>'
48 ' <sensor distance minimum>'
49 ' <sensor distance maximum> [options]',
50 'slow': 'slow <store dir> [options]',
51 'dlow': 'dlow <store dir1> <store dir2>'
52 ' <sensor distance minimum>'
53 ' <sensor distance maximum> [options]',
54 'slowband': 'slowband <store dir> [options]',
55 'dlowband': 'dlowband <store dir1> <store dir2>'
56 ' <sensor distance minimum>'
57 ' <sensor distance maximum> [options]',
58 'shighband': 'shighband <store dir> [options]',
59 'dhighband': 'dhighband <store dir1> <store dir2>'
60 ' <sensor distance minimum>'
61 ' <sensor distance maximum> [options]',
62 'shigh': 'shigh <store dir> [options]',
63 'dhigh': 'dhigh <store dir1> <store dir2>'
64 ' <sensor distance minimum>'
65 ' <sensor distance maximum> [options]',
66 'snone': 'snone <store dir> [options]',
67 'dnone': 'dnone <store dir1> <store dir2>'
68 ' <sensor distance minimum>'
69 ' <sensor distance maximum> [options]'}
72def dict_to_string(dic):
73 st = 4
74 st2 = 20
75 s = ''
76 for k, v in dic.items():
77 s += '\n{0}{1}{2}{3}'.format(' '*st, k, ' '*(st2 - st - len(k)), v)
78 return s
81def add_common_options(parser):
82 parser.add_option('--show_defaults', '-d', action='store_false',
83 help='Show the default values of command options.'
84 ' Must be typed before help option.')
85 parser.add_option('--plot_velocity', '-v', action='store_true',
86 help='Plot the velocity traces also.', default=False)
87 parser.add_option('--output-format',
88 help='The format of the report: pdf or html',
89 choices=['pdf', 'html'], default='pdf')
90 parser.add_option('--pdf_dir', '-p',
91 help='The directory where the pdf/html will be saved to.'
92 ' Default is the HOME directory.',
93 default=None)
94 parser.add_option('--output', '-o',
95 help='The full path and name to save the'
96 ' resulting configuration file.',
97 default=None)
98 parser.add_option('--report_only', '-r', dest='plot_everything',
99 action='store_false', default=True,
100 help='Do not plot the trace graphs')
103def add_sensor_options(parser):
104 grp = OptionGroup(parser, 'Seismic sensor distance options')
105 grp.add_option('--distance_min', '-n', type=float, default=None,
106 help="The minimum distance to place sensors. Value of"
107 " 'None' will use store minimum.")
108 grp.add_option('--distance_max', '-x', type=float, default=None,
109 help="The maximum distance to place sensors. Value of"
110 " 'None' will use store maximum.")
111 grp.add_option('--sensor_count', '-c', type=int, default=50,
112 help="The number of sensors to use.")
113 parser.add_option_group(grp)
116def add_source_options(parser):
117 grp = OptionGroup(parser, 'Seismic source options')
118 grp.add_option('--depth',
119 dest='source_depth',
120 type=float,
121 help="The depth of the source. Value of 'None' will place"
122 " source at middle depth of allowed values.",
123 default=None)
124 parser.add_option_group(grp)
127def add_filter_options(parser):
128 grp = OptionGroup(parser, 'Trace frequency filter options')
129 grp.add_option('--lowpass',
130 dest='lowpass_frequency',
131 type=float,
132 help='The value of the lowpass filter applied to traces.',
133 default=None)
134 grp.add_option('--lowpass_rel',
135 dest='rel_lowpass_frequency',
136 type=float,
137 help='''The percentage of the store's sampling rate'''
138 ' to be used as the lowpass filter.',
139 default=None)
140 grp.add_option('--highpass',
141 dest='highpass_frequency',
142 type=float,
143 help='The value of the highpass filter applied to traces.',
144 default=None)
145 grp.add_option('--highpass_rel',
146 dest='rel_highpass_frequency',
147 type=float,
148 help='''The percentage of the store's samping rate'''
149 ' to be used as the lowpass filter.',
150 default=None)
151 parser.add_option_group(grp)
154def add_double_options(parser):
155 grp = OptionGroup(parser, 'Double store plotting options')
156 grp.add_option('--together', '-t', dest='together',
157 action='store_true', default=True,
158 help='Plot both stores on same axes.')
159 grp.add_option('--separate', '-s', dest='together',
160 action='store_false',
161 help='Plot stores next to each other.')
162 parser.add_option_group(grp)
165def cl_parse(command, args, setup=None):
166 usage = '{0} {1}'.format(program_name, subcmds_uses[command])
167 desc = ' '.join(subcmds_desc[command].split())
168 parser = OptionParser(usage=usage, description=desc)
169 add_common_options(parser)
170 if setup:
171 setup(parser)
173 if args and args[0] in ('-d', '--show_defaults'):
174 for opt in parser.option_list:
175 if opt.default == ('NO', 'DEFAULT'):
176 continue
177 opt.help += (' ' if opt.help else '') + '[default: %default]'
178 for grp in parser.option_groups:
179 for opt in grp.option_list:
180 if opt.default == ('NO', 'DEFAULT'):
181 continue
182 opt.help += (' ' if opt.help else '') + '[default: %default]'
183 opts, args = parser.parse_args(args)
184 opts = vars(opts)
185 if 'show_defaults' in opts:
186 del opts['show_defaults']
187 return parser, opts, args
190def verify_arguements(command, allowed, args):
191 if len(args) != allowed:
192 raise TypeError('{0}() takes {1} arguements ({2} given)'.format(
193 command, allowed, len(args)))
195 dir1 = args.pop(0)
196 if not os.path.exists(dir1):
197 raise OSError('Path does not exist: {0}'.format(dir1))
199 if allowed == 1:
200 return dir1
202 dir2 = args.pop(0)
203 if not os.path.exists(dir2):
204 raise OSError('Path does not exist: {0}'.format(dir1))
206 if args:
207 sen_min = float(args.pop(0))
208 sen_max = float(args.pop(0))
209 return dir1, dir2, sen_min, sen_max
210 else:
211 return dir1, dir2
214def verify_options(command, **opts):
215 lpf = None
216 hpf = None
217 rlpf = None
218 rhpf = None
220 tstr = 'lowpass_frequency'
221 if tstr in opts:
222 lpf = opts[tstr]
223 tstr = 'highpass_frequency'
224 if tstr in opts:
225 hpf = opts[tstr]
226 tstr = 'rel_lowpass_frequency'
227 if tstr in opts:
228 rlpf = opts[tstr]
229 tstr = 'rel_highpass_frequency'
230 if tstr in opts:
231 rhpf = opts[tstr]
233 if lpf and rlpf:
234 raise gft_ffe('lowpass')
235 if hpf and rhpf:
236 raise gft_ffe('highpass')
239def command_single(command, args):
240 def setup(parser):
241 parser.set_defaults(plot_velocity=None)
242 parser.set_defaults(plot_everything=None)
244 parser, opts, args = cl_parse(command, args, setup)
245 filename = verify_arguements('single', 1, args)
246 out_filename = opts.pop('output')
247 gft = gftest.createDocumentFromFile(filename, **opts)
248 if out_filename is not None:
249 return gft, out_filename
252def command_sstandard(command, args):
253 def setup(parser):
254 add_source_options(parser)
255 add_sensor_options(parser)
257 parser, opts, args = cl_parse(command, args, setup)
258 st_dir = verify_arguements('sstandard', 1, args)
259 out_filename = opts.pop('output')
260 gft = gftest.runStandardCheck(st_dir, **opts)
261 if out_filename is not None:
262 return gft, out_filename
265def command_slow(command, args):
266 def setup(parser):
267 add_source_options(parser)
268 add_sensor_options(parser)
269 add_filter_options(parser)
270 parser.remove_option('--highpass')
271 parser.remove_option('--highpass_rel')
272 parser.set_defaults(rel_lowpass_frequency=0.25)
274 parser, opts, args = cl_parse(command, args, setup=setup)
275 if opts['lowpass_frequency'] is not None:
276 opts['rel_lowpass_frequency'] = None
277 st_dir = verify_arguements('slow', 1, args)
278 out_filename = opts.pop('output')
279 gft = gftest.runStandardCheck(st_dir, **opts)
280 if out_filename is not None:
281 return gft, out_filename
284def command_shigh(command, args):
285 def setup(parser):
286 add_source_options(parser)
287 add_sensor_options(parser)
288 add_filter_options(parser)
289 parser.remove_option('--lowpass')
290 parser.remove_option('--lowpass_rel')
291 parser.set_defaults(rel_highpass_frequency=0.25)
293 parser, opts, args = cl_parse(command, args, setup=setup)
294 if opts['highpass_frequency'] is not None:
295 opts['rel_highpass_frequency'] = None
296 st_dir = verify_arguements('shigh', 1, args)
297 out_filename = opts.pop('output')
298 gft = gftest.runStandardCheck(st_dir, **opts)
299 if out_filename is not None:
300 return gft, out_filename
303def command_slowband(command, args):
304 def setup(parser):
305 add_source_options(parser)
306 add_sensor_options(parser)
307 add_filter_options(parser)
308 parser.set_defaults(lowpass_frequency=0.0018)
309 parser.set_defaults(highpass_frequency=0.004)
311 parser, opts, args = cl_parse(command, args, setup=setup)
312 st_dir = verify_arguements('slowband', 1, args)
313 verify_options('slowband', **opts)
314 out_filename = opts.pop('output')
315 gft = gftest.runStandardCheck(st_dir, **opts)
316 if out_filename is not None:
317 return gft, out_filename
320def command_shighband(command, args):
321 def setup(parser):
322 add_source_options(parser)
323 add_sensor_options(parser)
324 add_filter_options(parser)
325 parser.set_defaults(rel_lowpass_frequency=0.125)
326 parser.set_defaults(rel_highpass_frequency=0.25)
328 parser, opts, args = cl_parse(command, args, setup=setup)
329 st_dir = verify_arguements('shighband', 1, args)
330 verify_options('shighband', **opts)
331 out_filename = opts.pop('output')
332 gft = gftest.runStandardCheck(st_dir, **opts)
333 if out_filename is not None:
334 return gft, out_filename
337def command_snone(command, args):
338 def setup(parser):
339 add_source_options(parser)
340 add_sensor_options(parser)
342 parser, opts, args = cl_parse(command, args, setup=setup)
343 st_dir = verify_arguements('snone', 1, args)
344 opts['rel_lowpass_frequency'] = None
345 opts['rel_highpass_frequency'] = None
346 out_filename = opts.pop('output')
347 gft = gftest.runStandardCheck(st_dir, **opts)
348 if out_filename is not None:
349 return gft, out_filename
352def command_double(command, args):
353 def setup(parser):
354 add_double_options(parser)
355 parser.set_defaults(plot_velocity=None)
356 parser.set_defaults(plot_everything=None)
358 parser, opts, args = cl_parse(command, args, setup=setup)
359 filename = verify_arguements('double', 1, args)
360 verify_options('double', **opts)
361 out_filename = opts.pop('output')
362 gfts = gftest.createDocumentFromFile(filename, 2, **opts)
363 if out_filename is not None:
364 return gfts, out_filename
367def command_dstandard(command, args):
368 def setup(parser):
369 add_source_options(parser)
370 add_double_options(parser)
372 parser, opts, args = cl_parse(command, args, setup=setup)
373 dir1, dir2, smin, smax = verify_arguements('dstandard', 4, args)
374 out_filename = opts.pop('output')
375 gfts = gftest.runComparissonStandardCheck(dir1, dir2, smin, smax, **opts)
376 if out_filename is not None:
377 return gfts, out_filename
380def command_dlow(command, args):
381 def setup(parser):
382 add_source_options(parser)
383 add_double_options(parser)
384 add_filter_options(parser)
385 parser.remove_option('--highpass')
386 parser.remove_option('--highpass_rel')
387 parser.set_defaults(rel_lowpass_frequency=0.25)
389 parser, opts, args = cl_parse(command, args, setup=setup)
390 if opts['lowpass_frequency'] is not None:
391 opts['rel_lowpass_frequency'] = None
392 dir1, dir2, smin, smax = verify_arguements('dlow', 4, args)
393 opts['rel_highpass_frequency'] = None
394 out_filename = opts.pop('output')
395 gfts = gftest.runComparissonStandardCheck(dir1, dir2, smin, smax, **opts)
396 if out_filename is not None:
397 return gfts, out_filename
400def command_dhigh(command, args):
401 def setup(parser):
402 add_source_options(parser)
403 add_double_options(parser)
404 add_filter_options(parser)
405 parser.remove_option('--lowpass')
406 parser.remove_option('--lowpass_rel')
407 parser.set_defaults(rel_highpass_frequency=0.25)
409 parser, opts, args = cl_parse(command, args, setup=setup)
410 if opts['highpass_frequency'] is not None:
411 opts['rel_highpass_frequency'] = None
412 dir1, dir2, smin, smax = verify_arguements('dhigh', 4, args)
413 opts['rel_lowpass_frequency'] = None
414 out_filename = opts.pop('output')
415 gfts = gftest.runComparissonStandardCheck(dir1, dir2, smin, smax, **opts)
416 if out_filename is not None:
417 return gfts, out_filename
420def command_dlowband(command, args):
421 def setup(parser):
422 add_source_options(parser)
423 add_double_options(parser)
424 add_filter_options(parser)
425 parser.set_defaults(lowpass_frequency=0.0018)
426 parser.set_defaults(highpass_frequency=0.004)
428 parser, opts, args = cl_parse(command, args, setup=setup)
429 dir1, dir2, smin, smax = verify_arguements('dlowband', 4, args)
430 verify_options('dlowband', **opts)
431 out_filename = opts.pop('output')
432 gfts = gftest.runComparissonStandardCheck(dir1, dir2, smin, smax, **opts)
433 if out_filename is not None:
434 return gfts, out_filename
437def command_dhighband(command, args):
438 def setup(parser):
439 add_source_options(parser)
440 add_double_options(parser)
441 add_filter_options(parser)
442 parser.set_defaults(rel_lowpass_frequency=0.125)
443 parser.set_defaults(rel_highpass_frequency=0.25)
445 parser, opts, args = cl_parse(command, args, setup=setup)
446 dir1, dir2, smin, smax = verify_arguements('dhighband', 4, args)
447 verify_options('dhighband', **opts)
448 out_filename = opts.pop('output')
449 gfts = gftest.runComparissonStandardCheck(dir1, dir2, smin, smax, **opts)
450 if out_filename is not None:
451 return gfts, out_filename
454def command_dnone(command, args):
455 def setup(parser):
456 add_source_options(parser)
457 add_double_options(parser)
459 parser, opts, args = cl_parse(command, args, setup=setup)
460 dir1, dir2, smin, smax = verify_arguements('dnone', 4, args)
461 opts['rel_lowpass_frequency'] = None
462 opts['rel_highpass_frequency'] = None
463 out_filename = opts.pop('output')
464 gfts = gftest.runComparissonStandardCheck(dir1, dir2, smin, smax, **opts)
465 if out_filename is not None:
466 return gfts, out_filename
469program_name = 'fomosto report'
470usage = 'Create a pdf of displacment and velocity traces, max. amplitude of' \
471 ' traces and' \
472 ' displacment spectra for Green\'s Function stores.\n\n' \
473 'Usage: {0} <subcommand> <arguments> ... [options]\n\nSubcommands:\n' \
474 '{1}\n\nTo get further help and a list of available options for any' \
475 ' subcommand run:\n\n{2}{0} <subcommand> --help\n\n'. \
476 format(program_name, dict_to_string(subcmds_desc), ' '*4)
479def run_program(args):
480 if len(args) < 1:
481 sys.exit(usage)
483 command = args.pop(0)
484 if command in ('--help', '-h', 'help'):
485 sys.exit(usage)
487 if command in ('--multiple', '-m'):
488 glbs = globals()
489 cmds = []
490 while args and args[0] in subcmds_desc:
491 cmds.append(args.pop(0))
492 for command in cmds:
493 glbs['command_' + command](args)
494 sys.exit()
496 if command not in subcmds_desc:
497 sys.exit('{0}: error: no such subcommand: {1}'.
498 format(program_name, command))
500 if len(args) == 0 or (len(args) == 1 and
501 args[0] in ('-d', '--show_defaults')):
502 args.append('--help')
504 try:
505 lst = globals()['command_' + command](command, args)
506 if lst is not None:
507 gfts = lst[0]
508 with open(lst[-1], 'w') as f:
509 if isinstance(gfts, gftest):
510 f.write(gfts.dump())
511 else:
512 for i in lst[0]:
513 f.write(i.dump())
515 except FomostoReportError as e:
516 sys.exit(str(e))
519if __name__ == '__main__':
520 run_program(sys.argv)