Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/scenario/sources/dcsource.py: 98%

43 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-03-07 11:54 +0000

1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

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

5 

6''' 

7Double-couple random source generator. 

8''' 

9 

10import numpy as num 

11 

12from pyrocko import util 

13from pyrocko.guts import Float 

14from pyrocko import moment_tensor, gf 

15 

16from .base import SourceGenerator 

17from ..error import ScenarioError 

18 

19km = 1e3 

20guts_prefix = 'pf.scenario' 

21 

22 

23class DCSourceGenerator(SourceGenerator): 

24 

25 depth_min = Float.T(default=0.0) 

26 depth_max = Float.T(default=30*km) 

27 

28 strike = Float.T(optional=True) 

29 dip = Float.T(optional=True) 

30 rake = Float.T(optional=True) 

31 perturbation_angle_std = Float.T(optional=True) 

32 

33 def get_source(self, ievent): 

34 rstate = self.get_rstate(ievent) 

35 time = self.time_min + rstate.uniform( 

36 0., float(self.time_max - self.time_min)) # hptime aware 

37 

38 lat, lon, north_shift, east_shift, depth = self.get_coordinates(ievent) 

39 depth = rstate.uniform(self.depth_min, self.depth_max) 

40 magnitude = self.draw_magnitude(rstate) 

41 

42 if self.strike is None and self.dip is None and self.rake is None: 

43 mt = moment_tensor.MomentTensor.random_dc(x=rstate.uniform(size=3)) 

44 else: 

45 if None in (self.strike, self.dip, self.rake): 

46 raise ScenarioError( 

47 'DCSourceGenerator: ' 

48 'strike, dip, and rake must be used in combination.') 

49 

50 mt = moment_tensor.MomentTensor( 

51 strike=self.strike, dip=self.dip, rake=self.rake) 

52 

53 if self.perturbation_angle_std is not None: 

54 mt = mt.random_rotated( 

55 self.perturbation_angle_std, 

56 rstate=rstate) 

57 

58 (s, d, r), (_, _, _) = mt.both_strike_dip_rake() 

59 

60 source = gf.DCSource( 

61 name='ev%04i' % ievent, 

62 time=util.to_time_float(time), 

63 lat=float(lat), 

64 lon=float(lon), 

65 north_shift=float(north_shift), 

66 east_shift=float(east_shift), 

67 depth=float(depth), 

68 magnitude=float(magnitude), 

69 strike=float(s), 

70 dip=float(d), 

71 rake=float(r)) 

72 

73 return source 

74 

75 def add_map_artists(self, automap): 

76 from pyrocko.plot import gmtpy 

77 

78 for source in self.get_sources(): 

79 event = source.pyrocko_event() 

80 mt = event.moment_tensor.m_up_south_east() 

81 

82 xx = num.trace(mt) / 3. 

83 mc = num.array([[xx, 0., 0.], [0., xx, 0.], [0., 0., xx]]) 

84 mc = mt - mc 

85 mc = mc / event.moment_tensor.scalar_moment() * \ 

86 moment_tensor.magnitude_to_moment(5.0) 

87 m6 = tuple(moment_tensor.to6(mc)) 

88 symbol_size = 20. 

89 automap.gmt.psmeca( 

90 S='%s%g' % ('d', symbol_size / gmtpy.cm), 

91 in_rows=[ 

92 (source.effective_lon, source.effective_lat, 10) 

93 + m6 

94 + (1, 0, 0)], 

95 M=True, 

96 *automap.jxyr)