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
« 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
7from pyrocko import gf, util
8from pyrocko.guts import String, Float, Dict
10from grond.meta import Forbidden, expand_template, Parameter, \
11 has_get_plot_classes
13from ..base import Problem, ProblemConfig
15guts_prefix = 'grond'
16logger = logging.getLogger('grond.problems.locate.problem')
17km = 1e3
18as_km = dict(scale_factor=km, scale_unit='km')
21class LocateProblemConfig(ProblemConfig):
23 ranges = Dict.T(String.T(), gf.Range.T())
24 distance_min = Float.T(default=0.0)
26 def get_problem(self, event, target_groups, targets):
27 self.check_deprecations()
29 if event.depth is None:
30 event.depth = 0.
32 base_source = gf.Source.from_pyrocko_event(event)
34 subs = dict(
35 event_name=event.name,
36 event_time=util.time_to_str(event.time))
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)
47 return problem
50@has_get_plot_classes
51class LocateProblem(Problem):
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)]
59 dependants = []
61 distance_min = Float.T(default=0.0)
63 def __init__(self, **kwargs):
64 Problem.__init__(self, **kwargs)
66 def get_source(self, x):
67 d = self.get_parameter_dict(x)
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]))
75 return self.base_source.clone(**p)
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])
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()
90 return x
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
100__all__ = '''
101 LocateProblem
102 LocateProblemConfig
103'''.split()