1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5from __future__ import absolute_import 

6 

7from .qt_compat import qc, qw 

8 

9from .util import make_QPolygonF, LinValControl 

10from .pile_viewer import Projection 

11 

12from pyrocko import beachball, moment_tensor as mtm 

13from pyrocko import plot 

14 

15 

16class BeachballView(qw.QWidget): 

17 

18 def __init__(self, *args): 

19 qw.QWidget.__init__(self, *args) 

20 mt = mtm.MomentTensor(m=mtm.symmat6(1., -1., 2., 0., -2., 1.)) 

21 self._mt = mt 

22 self.set_moment_tensor(mt) 

23 

24 def set_moment_tensor(self, mt): 

25 self._mt = mt 

26 self.update() 

27 

28 def paintEvent(self, paint_ev): 

29 ''' 

30 Called by QT whenever widget needs to be painted. 

31 ''' 

32 

33 painter = qw.QPainter(self) 

34 painter.setRenderHint(qw.QPainter.Antialiasing) 

35 self.drawit(painter) 

36 

37 def drawit(self, p): 

38 ''' 

39 Draw beachball into painter. 

40 ''' 

41 

42 h = self.height() 

43 w = self.width() 

44 

45 s = min(h, w)*0.9 

46 

47 xproj = Projection() 

48 xproj.set_in_range(-1., 1.) 

49 xproj.set_out_range((w-s)/2., w-(w-s)/2.) 

50 

51 yproj = Projection() 

52 yproj.set_in_range(-1., 1.) 

53 yproj.set_out_range(h-(h-s)/2., (h-s)/2.) 

54 

55 # m = mtm.symmat6(*(num.random.random(6)*2.-1.)) 

56 # mtm.MomentTensor(m=m) 

57 

58 mt = self._mt 

59 

60 mt_devi = mt.deviatoric() 

61 eig = mt_devi.eigensystem() 

62 

63 group_to_color = { 

64 'P': plot.graph_colors[0], 

65 'T': plot.graph_colors[1]} 

66 

67 for (group, patches, patches_lower, patches_upper, 

68 lines, lines_lower, lines_upper) in beachball.eig2gx(eig): 

69 

70 color = group_to_color[group] 

71 brush = qw.QBrush(qw.QColor(*color)) 

72 p.setBrush(brush) 

73 

74 pen = qw.QPen(qw.QColor(*color)) 

75 pen.setWidth(1) 

76 p.setPen(pen) 

77 

78 for poly in patches_lower: 

79 px, py, pz = poly.T 

80 points = make_QPolygonF(xproj(px), yproj(py)) 

81 p.drawPolygon(points) 

82 

83 color = (0, 0, 0) 

84 pen = qw.QPen(qw.QColor(*color)) 

85 pen.setWidth(2) 

86 p.setPen(pen) 

87 

88 for poly in lines_lower: 

89 px, py, pz = poly.T 

90 points = make_QPolygonF(xproj(px), yproj(py)) 

91 p.drawPolyline(points) 

92 

93 

94class MomentTensorEditor(qw.QFrame): 

95 

96 moment_tensor_changed = qc.pyqtSignal(object) 

97 

98 def __init__(self, *args): 

99 qw.QFrame.__init__(self, *args) 

100 

101 self._mt = mtm.MomentTensor(m=mtm.symmat6(1., -1., 2., 0., -2., 1.)) 

102 

103 setupdata = [ 

104 (LinValControl, 'Strike 1', 0., 360., 0., 0), 

105 (LinValControl, 'Dip 1', 0., 90., 0., 1), 

106 (LinValControl, 'Slip-Rake 1', -180., 180., 0., 2), 

107 (LinValControl, 'Strike 2', 0., 360., 0., 3), 

108 (LinValControl, 'Dip 2', 0., 90., 0., 4), 

109 (LinValControl, 'Slip-Rake 2', -180., 180., 0., 5)] 

110 

111 layout = qw.QGridLayout() 

112 self.setLayout(layout) 

113 

114 val_controls = [] 

115 for irow, (typ, name, vmin, vmax, vcur, ind) in enumerate(setupdata): 

116 val_control = typ() 

117 val_control.setup(name, vmin, vmax, vcur, ind) 

118 val_controls.append(val_control) 

119 for icol, widget in enumerate(val_control.widgets()): 

120 layout.addWidget(widget, irow, icol) 

121 val_control.valchanged.connect( 

122 self.valchange) 

123 

124 self.val_controls = val_controls 

125 self.adjust_values() 

126 

127 def adjust_values(self): 

128 

129 ((strike1, dip1, rake1), 

130 (strike2, dip2, rake2)) = self._mt.both_strike_dip_rake() 

131 

132 for val_control, value in zip( 

133 self.val_controls, [ 

134 strike1, dip1, rake1, strike2, dip2, rake2]): 

135 val_control.set_value(value) 

136 

137 def valchange(self, val, ind): 

138 strike, dip, rake = [ 

139 val_control.get_value() for val_control in self.val_controls[:3]] 

140 

141 self._mt = mtm.MomentTensor( 

142 strike=strike, dip=dip, rake=rake) 

143 

144 self.adjust_values() 

145 

146 self.moment_tensor_changed.emit( 

147 self._mt)