1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6from pyrocko import plot 

7 

8 

9ansi_reverse = u'\033[7m' 

10ansi_reverse_reset = u'\033[27m' 

11ansi_dim = u'\033[2m' 

12ansi_dim_reset = u'\033[22m' 

13 

14blocks = u'\u2588\u2589\u258a\u258b\u258c\u258d\u258e\u258f ' 

15bar_right = '\u2595' 

16bar_left = '\u258f' 

17 

18tri_left = '<' # '\u25c0' 

19tri_right = '>' # '\u25b6' 

20hmulti = 'X' 

21vmulti = '%s%%s%s' % (ansi_reverse, ansi_reverse_reset) 

22 

23 

24def time_axis(view_tmin, view_tmax, sx): 

25 

26 lines = [] 

27 for napprox in range(10, 0, -1): 

28 tinc, tunit = plot.nice_time_tick_inc( 

29 (view_tmax - view_tmin) / napprox) 

30 

31 times, labels = plot.time_tick_labels( 

32 view_tmin, view_tmax, tinc, tunit) 

33 

34 if not labels: 

35 # show only ticks? 

36 continue 

37 

38 delta = (view_tmax - view_tmin) / (sx-2) 

39 

40 itimes = [int(round((t - view_tmin) / delta)) for t in times] 

41 nlines = len(labels[0].split('\n')) 

42 lines = ([bar_right] if itimes[0] != 0 else ['']) * nlines 

43 overfull = False 

44 for it, lab in zip(itimes, labels): 

45 for iline, word in enumerate(lab.split('\n')): 

46 if len(lines[iline]) > it and word: 

47 overfull = True 

48 break 

49 

50 if it > sx-1: 

51 break 

52 

53 lines[iline] += ' ' * (it - len(lines[iline])) 

54 if len(lines[iline]) < sx-1 and (it - len(lines[iline])) >= 0: 

55 lines[iline] += bar_right 

56 if len(word) > 0 and len(lines[iline]) + len(word) + 1 < sx-1: 

57 lines[iline] += word + ' ' 

58 

59 if overfull: 

60 break 

61 

62 for iline in range(nlines): 

63 lines[iline] += ' ' * ((sx-1) - len(lines[iline])) + bar_left 

64 

65 if overfull: 

66 continue 

67 

68 break 

69 

70 return lines 

71 

72 

73def bar(view_tmin, view_tmax, changes, tmin, tmax, sx): 

74 

75 delta = (view_tmax - view_tmin) / (sx-2) 

76 out = [ansi_dim] 

77 ic = 0 

78 while ic < len(changes) and changes[ic][0] < view_tmin: 

79 ic += 1 

80 

81 if 0 < ic and ic < len(changes): 

82 count = changes[ic-1][1] 

83 else: 

84 count = 0 

85 

86 out.append(bar_right if (ic == 0 and view_tmin <= tmin) else tri_left) 

87 

88 for i in range(sx-2): 

89 block_tmin = view_tmin + i * delta 

90 block_tmax = view_tmin + (i+1) * delta 

91 ic_start = ic 

92 if i < sx-3: 

93 while ic < len(changes) and changes[ic][0] < block_tmax: 

94 ic += 1 

95 else: 

96 while ic < len(changes) and changes[ic][0] <= block_tmax: 

97 ic += 1 

98 

99 nc_block = ic - ic_start 

100 if nc_block == 0: 

101 if count == 0: 

102 out.append(blocks[-1]) 

103 elif count == 1: 

104 out.append(blocks[0]) 

105 else: 

106 out.append(vmulti % ('%i' % count if count <= 9 else 'N')) 

107 

108 elif nc_block == 1: 

109 t, new_count = changes[ic_start] 

110 ib = int(round((t - block_tmin) / delta * (len(blocks) - 1))) 

111 if new_count == 1 and count == 0: 

112 out.append( 

113 '%s%s%s' % ( 

114 ansi_reverse, blocks[-ib-1], ansi_reverse_reset)) 

115 elif new_count == 0 and count == 1: 

116 out.append(blocks[-ib-1]) 

117 elif new_count > count: 

118 out.append( 

119 '%s%s%s' % ( 

120 ansi_reverse, '+', ansi_reverse_reset)) 

121 elif new_count < count: 

122 out.append( 

123 '%s%s%s' % ( 

124 ansi_reverse, '-', ansi_reverse_reset)) 

125 elif count == 0 and count == new_count: 

126 out.append(blocks[-1]) 

127 

128 elif count == 1 and count == new_count: 

129 out.append(blocks[0]) 

130 else: 

131 out.append('N') 

132 

133 count = new_count 

134 

135 elif nc_block > 1: 

136 _, count = changes[ic_start + nc_block - 1] 

137 out.append(hmulti) 

138 else: 

139 assert False 

140 

141 out.append( 

142 bar_left if (ic == len(changes) and tmax <= view_tmax) else tri_right) 

143 out.append(ansi_dim_reset) 

144 

145 return ''.join(out) 

146 

147 

148if __name__ == '__main__': 

149 from ..get_terminal_size import get_terminal_size 

150 sx, _ = get_terminal_size() 

151 

152 view_tmin = 0. 

153 view_tmax = 100. 

154 

155 import numpy as num 

156 

157 n = 20 

158 phis = num.linspace(-0.1, 1., n) 

159 

160 for phi in phis: 

161 tmin = view_tmin + 0.2 * phi * (view_tmax - view_tmin) 

162 tmin2 = view_tmin + 0.3 * phi * (view_tmax - view_tmin) 

163 tmax2 = view_tmax - 0.3 * phi * (view_tmax - view_tmin) 

164 tmax = view_tmax - 0.2 * phi * (view_tmax - view_tmin) 

165 print(bar( 

166 view_tmin, view_tmax, 

167 [[tmin, 1], [tmin2, 2], [tmax2, 1], [tmax, 0]], 

168 view_tmin, view_tmax, sx)) 

169 

170 import time 

171 import numpy as num 

172 t0 = time.time() 

173 exps = num.linspace(-4., 11., 100) 

174 

175 for exp in exps: 

176 

177 for line in time_axis(t0, t0+10**exp, sx): 

178 print(line) 

179 print() 

180 

181 from pyrocko import util 

182 tmin = util.stt('2011-04-15 10:05:14') 

183 tmax = util.stt('2012-09-20 14:41:00') 

184 for line in time_axis(tmin, tmax, sx): 

185 print(line) 

186 print() 

187 

188 tmin = util.stt('2011-11-27 00:00:00') 

189 tmax = util.stt('2011-11-28 00:00:00') 

190 for line in time_axis(tmin, tmax, sx): 

191 print(line) 

192 print()