1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6import time 

7 

8from pyrocko import util 

9from pyrocko.plot import terminal 

10from pyrocko.get_terminal_size import get_terminal_size 

11from pyrocko.squirrel.error import ToolError 

12 

13from ..common import ldq 

14 

15 

16headline = 'Report time spans covered.' 

17 

18 

19def make_subparser(subparsers): 

20 return subparsers.add_parser( 

21 'coverage', 

22 help=headline, 

23 description=headline + ''' 

24 

25Time spans covered by the given data selection are listed or plotted. 

26''') 

27 

28 

29def setup(parser): 

30 parser.add_squirrel_selection_arguments() 

31 parser.add_squirrel_query_arguments(without=['time']) 

32 

33 style_choices = ['visual', 'summary', 'yaml'] 

34 

35 parser.add_argument( 

36 '--style', 

37 dest='style', 

38 choices=style_choices, 

39 default='visual', 

40 help='Set style of presentation. Choices: %s' % ldq(style_choices)) 

41 

42 

43def run(parser, args): 

44 from pyrocko import squirrel as sq 

45 

46 squirrel = args.make_squirrel() 

47 kwargs = args.squirrel_query 

48 kinds = kwargs.pop('kind', sq.supported_content_kinds()) 

49 

50 tmin_g, tmax_g = squirrel.get_time_span(kinds) 

51 

52 sx, _ = get_terminal_size() 

53 

54 now = time.time() 

55 if tmax_g is None or tmax_g > now: 

56 tmax_g = now 

57 

58 codes = kwargs.pop('codes', None) 

59 tmin = kwargs.pop('tmin', tmin_g) 

60 tmax = kwargs.pop('tmax', tmax_g) 

61 if tmin is not None and tmax is not None: 

62 if not tmin < tmax: 

63 raise ToolError( 

64 'Invalid time span: %s - %s' % ( 

65 util.time_to_str(tmin), util.time_to_str(tmax))) 

66 

67 for kind in kinds: 

68 coverage = squirrel.get_coverage( 

69 kind, 

70 codes=codes if (codes is not None) else None, 

71 tmin=tmin, 

72 tmax=tmax, 

73 **kwargs) 

74 

75 if coverage: 

76 

77 if args.style == 'yaml': 

78 for entry in coverage: 

79 print(entry) 

80 elif args.style == 'summary': 

81 for entry in coverage: 

82 print(entry.summary) 

83 elif args.style == 'visual': 

84 slabels = [entry.labels for entry in coverage] 

85 

86 scs = [ 

87 max(len(s) for s in entries) 

88 for entries in zip(*slabels)] 

89 

90 label = 'kind: %s' % kind 

91 sc = max(18, len(label), sum(scs)) + 1 

92 si = (sx-sc) - 2 

93 sl = si // 2 

94 sr = si - sl 

95 print(''.join(( 

96 label.ljust(sc), 

97 terminal.ansi_dim, 

98 terminal.bar_right, 

99 util.time_to_str(tmin).ljust(sl), 

100 util.time_to_str(tmax).rjust(sr), 

101 terminal.bar_left, 

102 terminal.ansi_dim_reset))) 

103 

104 for (scodes, srate), entry in zip(slabels, coverage): 

105 line = \ 

106 (scodes.ljust(scs[0]) 

107 + ' ' + srate.rjust(scs[1])).ljust(sc) \ 

108 + terminal.bar( 

109 tmin, tmax, entry.changes, 

110 entry.tmin, entry.tmax, 

111 sx-sc) 

112 

113 print(line) 

114 

115 for line in terminal.time_axis(tmin, tmax, sx-sc): 

116 print(''.join(( 

117 ' '*sc, 

118 terminal.ansi_dim, 

119 line, 

120 terminal.ansi_dim_reset)))