Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/scenario/sources/base.py: 85%
53 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 15:01 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 15:01 +0000
1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6'''
7Base class for source generators.
8'''
10import os.path as op
12from pyrocko import moment_tensor
13from pyrocko.guts import Timestamp, Float, Int, Bool, String, load_all
15from ..base import LocationGenerator
16from ..error import ScenarioError
18km = 1e3
19guts_prefix = 'pf.scenario'
22class SourceGenerator(LocationGenerator):
23 '''
24 Base class for source generators.
26 Provides the functionality to read sources from a file. Base class for
27 generators producing random sources.
28 '''
30 nevents = Int.T(default=2)
31 avoid_water = Bool.T(
32 default=False,
33 help='Avoid sources offshore under the ocean / lakes.')
35 time_min = Timestamp.T(default=Timestamp.D('2017-01-01 00:00:00'))
36 time_max = Timestamp.T(default=Timestamp.D('2017-01-03 00:00:00'))
38 magnitude_min = Float.T(
39 default=4.0,
40 help='minimum moment magnitude')
41 magnitude_max = Float.T(
42 optional=True,
43 help='if set, maximum moment magnitude for a uniform distribution. '
44 'If set to ``None``, magnitudes are drawn using a '
45 'Gutenberg-Richter distribution, see :gattr:`b_value`.')
46 b_value = Float.T(
47 optional=True,
48 help='b-value for Gutenberg-Richter magnitude distribution. If unset, '
49 'a value of 1 is assumed.')
51 source_file = String.T(
52 optional=True,
53 help='Path to source file. Sources are used as scenario events')
55 def __init__(self, *args, **kwargs):
56 super(SourceGenerator, self).__init__(*args, **kwargs)
57 if self.b_value is not None and self.magnitude_max is not None:
58 raise ScenarioError(
59 '%s: b_value and magnitude_max are mutually exclusive.'
60 % self.__class__.__name__)
62 def draw_magnitude(self, rstate):
63 if self.b_value is None and self.magnitude_max is None:
64 b_value = 1.0
65 else:
66 b_value = self.b_value
68 if b_value is None:
69 return rstate.uniform(self.magnitude_min, self.magnitude_max)
70 else:
71 return moment_tensor.rand_to_gutenberg_richter(
72 rstate.rand(), b_value, magnitude_min=self.magnitude_min)
74 def get_sources(self):
75 sources = []
77 if self.source_file is not None:
78 sources = load_all(filename=self.source_file)
79 self.nevents = len(sources)
81 for ievent in range(self.nevents):
82 sources[ievent].name = 'scenario_ev%03d' % (ievent + 1)
84 return sources
86 else:
87 for ievent in range(self.nevents):
88 src = self.get_source(ievent)
89 src.name = 'scenario_ev%03d' % (ievent + 1)
90 sources.append(src)
92 return sources
94 def ensure_data(self, path):
95 fn_sources = op.join(path, 'sources.yml')
96 if not op.exists(fn_sources):
97 with open(fn_sources, 'w') as f:
98 for src in self.get_sources():
99 f.write(src.dump())
101 fn_events = op.join(path, 'events.txt')
102 if not op.exists(fn_events):
103 with open(fn_events, 'w') as f:
104 for isrc, src in enumerate(self.get_sources()):
105 f.write(src.pyrocko_event().dump())
107 def add_map_artists(self, automap):
108 pass