Coverage for /usr/local/lib/python3.11/dist-packages/grond/problems/rectangular/problem.py: 86%

50 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2025-04-03 09:31 +0000

1# https://pyrocko.org/grond - GPLv3 

2# 

3# The Grond Developers, 21st Century 

4import logging 

5 

6from pyrocko import gf, util 

7from pyrocko.guts import String, Dict, Int, Float 

8 

9from grond.meta import expand_template, Parameter, has_get_plot_classes 

10 

11from ..base import Problem, ProblemConfig 

12 

13guts_prefix = 'grond' 

14logger = logging.getLogger('grond.problems.rectangular.problem') 

15km = 1e3 

16as_km = dict(scale_factor=km, scale_unit='km') 

17 

18 

19class RectangularProblemConfig(ProblemConfig): 

20 

21 ranges = Dict.T(String.T(), gf.Range.T()) 

22 decimation_factor = Int.T(default=1) 

23 distance_min = Float.T(default=0.0) 

24 

25 def get_problem(self, event, target_groups, targets): 

26 self.check_deprecations() 

27 

28 if self.decimation_factor != 1: 

29 logger.warning( 

30 'Decimation factor for rectangular source set to %i. Results ' 

31 'may be inaccurate.' % self.decimation_factor) 

32 

33 base_source = gf.RectangularSource.from_pyrocko_event( 

34 event, 

35 anchor='top', 

36 decimation_factor=self.decimation_factor) 

37 

38 subs = dict( 

39 event_name=event.name, 

40 event_time=util.time_to_str(event.time)) 

41 

42 problem = RectangularProblem( 

43 name=expand_template(self.name_template, subs), 

44 base_source=base_source, 

45 target_groups=target_groups, 

46 targets=targets, 

47 ranges=self.ranges, 

48 norm_exponent=self.norm_exponent, 

49 distance_min=self.distance_min) 

50 

51 return problem 

52 

53 

54@has_get_plot_classes 

55class RectangularProblem(Problem): 

56 distance_min = Float.T(default=0.0) 

57 

58 problem_parameters = [ 

59 Parameter('east_shift', 'm', label='Easting', **as_km), 

60 Parameter('north_shift', 'm', label='Northing', **as_km), 

61 Parameter('depth', 'm', label='Depth', **as_km), 

62 Parameter('length', 'm', label='Length', optional=False, **as_km), 

63 Parameter('width', 'm', label='Width', optional=False, **as_km), 

64 Parameter('slip', 'm', label='Slip', optional=False), 

65 Parameter('strike', 'deg', label='Strike'), 

66 Parameter('dip', 'deg', label='Dip'), 

67 Parameter('rake', 'deg', label='Rake') 

68 ] 

69 

70 problem_waveform_parameters = [ 

71 Parameter('nucleation_x', 'offset', label='Nucleation X'), 

72 Parameter('nucleation_y', 'offset', label='Nucleation Y'), 

73 Parameter('time', 's', label='Time'), 

74 Parameter('velocity', 'm/s', label='Rupture Velocity') 

75 ] 

76 

77 dependants = [] 

78 

79 def pack(self, source): 

80 arr = self.get_parameter_array(source) 

81 for ip, p in enumerate(self.parameters): 

82 if p.name == 'time': 

83 arr[ip] -= self.base_source.time 

84 return arr 

85 

86 def get_source(self, x): 

87 d = self.get_parameter_dict(x) 

88 p = {} 

89 for k in self.base_source.keys(): 

90 if k in d: 

91 p[k] = float( 

92 self.ranges[k].make_relative(self.base_source[k], d[k])) 

93 

94 source = self.base_source.clone(**p) 

95 

96 return source 

97 

98 def preconstrain(self, x): 

99 if self.distance_min != 0.0: 

100 raise ValueError( 

101 'RectangularProblem currently cannot handle ' 

102 'distance_min != 0.0.') 

103 return x 

104 

105 @classmethod 

106 def get_plot_classes(cls): 

107 plots = super(RectangularProblem, cls).get_plot_classes() 

108 return plots 

109 

110 

111__all__ = ''' 

112 RectangularProblem 

113 RectangularProblemConfig 

114'''.split()