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

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 numpy as num 

5import logging 

6 

7from pyrocko import gf, util 

8from pyrocko.guts import String, Float, Dict 

9 

10from grond.meta import Forbidden, expand_template, Parameter, \ 

11 has_get_plot_classes 

12 

13from ..base import Problem, ProblemConfig 

14 

15guts_prefix = 'grond' 

16logger = logging.getLogger('grond.problems.locate.problem') 

17km = 1e3 

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

19 

20 

21class LocateProblemConfig(ProblemConfig): 

22 

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

24 distance_min = Float.T(default=0.0) 

25 

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

27 self.check_deprecations() 

28 

29 if event.depth is None: 

30 event.depth = 0. 

31 

32 base_source = gf.Source.from_pyrocko_event(event) 

33 

34 subs = dict( 

35 event_name=event.name, 

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

37 

38 problem = LocateProblem( 

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

40 base_source=base_source, 

41 target_groups=target_groups, 

42 targets=targets, 

43 ranges=self.ranges, 

44 distance_min=self.distance_min, 

45 norm_exponent=self.norm_exponent) 

46 

47 return problem 

48 

49 

50@has_get_plot_classes 

51class LocateProblem(Problem): 

52 

53 problem_parameters = [ 

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

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

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

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

58 

59 dependants = [] 

60 

61 distance_min = Float.T(default=0.0) 

62 

63 def __init__(self, **kwargs): 

64 Problem.__init__(self, **kwargs) 

65 

66 def get_source(self, x): 

67 d = self.get_parameter_dict(x) 

68 

69 p = {} 

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

71 if k in d: 

72 p[k] = float( 

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

74 

75 return self.base_source.clone(**p) 

76 

77 def pack(self, source): 

78 return num.array([ 

79 source.time - self.base_source.time, 

80 source.north_shift, 

81 source.east_shift, 

82 source.depth]) 

83 

84 def preconstrain(self, x): 

85 source = self.get_source(x) 

86 for t in self.waveform_targets + self.phase_pick_targets: 

87 if (self.distance_min > num.asarray(t.distance_to(source))).any(): 

88 raise Forbidden() 

89 

90 return x 

91 

92 @classmethod 

93 def get_plot_classes(cls): 

94 from .. import plot 

95 plots = super(LocateProblem, cls).get_plot_classes() 

96 plots.extend([plot.LocationPlot]) 

97 return plots 

98 

99 

100__all__ = ''' 

101 LocateProblem 

102 LocateProblemConfig 

103'''.split()