1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
5from __future__ import absolute_import, division, print_function
7import os.path as op
9from pyrocko import moment_tensor
10from pyrocko.guts import Timestamp, Float, Int, Bool
12from ..base import LocationGenerator
13from ..error import ScenarioError
15km = 1e3
16guts_prefix = 'pf.scenario'
19class SourceGenerator(LocationGenerator):
21 nevents = Int.T(default=2)
22 avoid_water = Bool.T(
23 default=False,
24 help='Avoid sources offshore under the ocean / lakes.')
26 time_min = Timestamp.T(default=Timestamp.D('2017-01-01 00:00:00'))
27 time_max = Timestamp.T(default=Timestamp.D('2017-01-03 00:00:00'))
29 magnitude_min = Float.T(
30 default=4.0,
31 help='minimum moment magnitude')
32 magnitude_max = Float.T(
33 optional=True,
34 help='if set, maximum moment magnitude for a uniform distribution. '
35 'If set to ``None``, magnitudes are drawn using a '
36 'Gutenberg-Richter distribution, see :gattr:`b_value`.')
37 b_value = Float.T(
38 optional=True,
39 help='b-value for Gutenberg-Richter magnitude distribution. If unset, '
40 'a value of 1 is assumed.')
42 def __init__(self, *args, **kwargs):
43 super(SourceGenerator, self).__init__(*args, **kwargs)
44 if self.b_value is not None and self.magnitude_max is not None:
45 raise ScenarioError(
46 '%s: b_value and magnitude_max are mutually exclusive.'
47 % self.__class__.__name__)
49 def draw_magnitude(self, rstate):
50 if self.b_value is None and self.magnitude_max is None:
51 b_value = 1.0
52 else:
53 b_value = self.b_value
55 if b_value is None:
56 return rstate.uniform(self.magnitude_min, self.magnitude_max)
57 else:
58 return moment_tensor.rand_to_gutenberg_richter(
59 rstate.rand(), b_value, magnitude_min=self.magnitude_min)
61 def get_sources(self):
62 sources = []
63 for ievent in range(self.nevents):
64 src = self.get_source(ievent)
65 src.name = 'scenario_ev%03d' % (ievent + 1)
66 sources.append(src)
68 return sources
70 def ensure_data(self, path):
71 fn_sources = op.join(path, 'sources.yml')
72 if not op.exists(fn_sources):
73 with open(fn_sources, 'w') as f:
74 for src in self.get_sources():
75 f.write(src.dump())
77 fn_events = op.join(path, 'events.txt')
78 if not op.exists(fn_events):
79 with open(fn_events, 'w') as f:
80 for isrc, src in enumerate(self.get_sources()):
81 f.write(src.pyrocko_event().dump())
83 def add_map_artists(self, automap):
84 pass