Source code for kite.sources.pyrocko_gf

import numpy as num
from pyrocko.guts import String, Float, Int
from pyrocko import gf

from .base import SandboxSourceRectangular, SandboxSource, SourceProcessor

d2r = num.pi / 180.
r2d = 180. / num.pi
km = 1e3
km3 = 1e9


[docs]class PyrockoSource(object): def parametersUpdated(self): self.updatePyrockoSource() SandboxSource.parametersUpdated(self) def updatePyrockoSource(self): for arg, value in self._src_args.items(): self.pyrocko_source.__setattr__(arg, value)
[docs]class PyrockoRectangularSource(SandboxSourceRectangular, PyrockoSource): '''Classical Haskell source model modified for bilateral rupture. See :class:`pyrocko.gf.seismosizer.RectangularSource`. ''' __implements__ = 'pyrocko' decimation_factor = Int.T( optional=True, default=10, help='Sub-source decimation factor.') store_dir = String.T( help='Pyrocko GF Store path') parametersUpdated = PyrockoSource.parametersUpdated def __init__(self, *args, **kwargs): SandboxSourceRectangular.__init__(self, *args, **kwargs) self.pyrocko_source = gf.RectangularSource(**self._src_args) @property def _src_args(self): return { 'lat': 0., 'lon': 0., 'north_shift': self.northing, 'east_shift': self.easting, 'depth': self.depth, 'length': self.length, 'width': self.width, 'strike': self.strike, 'dip': self.dip, 'rake': self.rake, 'slip': self.slip, 'decimation_factor': self.decimation_factor, 'anchor': 'top', }
[docs]class PyrockoMomentTensor(SandboxSource, PyrockoSource): '''A moment tensor point source. See :class:`pyrocko.gf.seismosizer.MomentTensor`. ''' __implements__ = 'pyrocko' store_dir = String.T( help='Pyrocko GF Store path') mnn = Float.T( default=1., help='north-north component of moment tensor in [Nm]') mee = Float.T( default=1., help='east-east component of moment tensor in [Nm]') mdd = Float.T( default=1., help='down-down component of moment tensor in [Nm]') mne = Float.T( default=0., help='north-east component of moment tensor in [Nm]') mnd = Float.T( default=0., help='north-down component of moment tensor in [Nm]') med = Float.T( default=0., help='east-down component of moment tensor in [Nm]') parametersUpdated = PyrockoSource.parametersUpdated def __init__(self, *args, **kwargs): SandboxSource.__init__(self, *args, **kwargs) self.pyrocko_source = gf.MTSource(**self._src_args) @property def _src_args(self): return { 'lat': 0., 'lon': 0., 'north_shift': self.northing, 'east_shift': self.easting, 'depth': self.depth, 'mnn': self.mnn, 'mee': self.mee, 'mdd': self.mdd, 'mne': self.mne, 'mnd': self.mnd, 'med': self.med, }
[docs]class PyrockoDoubleCouple(SandboxSource, PyrockoSource): '''A double-couple point source. See :class:`pyrocko.gf.seismosizer.DCSource`. ''' __implements__ = 'pyrocko' strike = Float.T( default=0.0, help='strike direction in [deg], measured clockwise from north') magnitude = Float.T( default=6.0, help='moment magnitude Mw as in [Hanks and Kanamori, 1979]') dip = Float.T( default=90.0, help='dip angle in [deg], measured downward from horizontal') rake = Float.T( default=0.0, help='rake angle in [deg], ' 'measured counter-clockwise from right-horizontal ' 'in on-plane view') store_dir = String.T( help='Pyrocko GF Store path') parametersUpdated = PyrockoSource.parametersUpdated def __init__(self, *args, **kwargs): SandboxSource.__init__(self, *args, **kwargs) self.pyrocko_source = gf.DCSource(**self._src_args) @property def moment(self): return self.pyrocko_source.moment @property def _src_args(self): return { 'lat': 0., 'lon': 0., 'north_shift': self.northing, 'east_shift': self.easting, 'depth': self.depth, 'magnitude': self.magnitude, 'strike': self.strike, 'dip': self.dip, 'rake': self.rake }
[docs]class PyrockoRingfaultSource(SandboxSource, PyrockoSource): '''A ring fault with vertical doublecouples. See :class:`pyrocko.gf.seismosizer.RingfaultSource`. ''' __implements__ = 'pyrocko' store_dir = String.T( help='Pyrocko GF Store path') diameter = Float.T( default=1.0, help='diameter of the ring in [m]') sign = Float.T( default=1.0, help='inside of the ring moves up (+1) or down (-1)') strike = Float.T( default=0.0, help='strike direction of the ring plane, clockwise from north,' ' in [deg]') dip = Float.T( default=0.0, help='dip angle of the ring plane from horizontal in [deg]') npointsources = Int.T( default=8, help='number of point sources to use') magnitude = Float.T( default=6.0, help='moment magnitude Mw as in [Hanks and Kanamori, 1979]') parametersUpdated = PyrockoSource.parametersUpdated def __init__(self, *args, **kwargs): SandboxSource.__init__(self, *args, **kwargs) PyrockoSource.__init__(self) self.pyrocko_source = gf.RingfaultSource(**self._src_args) @property def _src_args(self): return { 'lat': 0., 'lon': 0., 'north_shift': self.northing, 'east_shift': self.easting, 'depth': self.depth, 'diameter': self.diameter, 'strike': self.strike, 'dip': self.dip, 'magnitude': self.magnitude, 'npointsources': self.npointsources, }
class PyrockoVLVDSource(SandboxSource, PyrockoSource): '''A ring fault with vertical doublecouples. See :class:`pyrocko.gf.seismosizer.VLVDSource`. ''' __implements__ = 'pyrocko' store_dir = String.T( help='Pyrocko GF Store path') volume_change = Float.T( default=.25, help='Volume change in [km^3]') azimuth = Float.T( default=0.0, help='azimuth direction of CLVD, clockwise from north,' ' in [deg]') dip = Float.T( default=90.0, help='dip angle of the CLVD from horizontal in [deg]') clvd_moment = Float.T( default=3e18, help='Moment in [Nm] of the CLVD contribution') parametersUpdated = PyrockoSource.parametersUpdated def __init__(self, *args, **kwargs): SandboxSource.__init__(self, *args, **kwargs) PyrockoSource.__init__(self) self.pyrocko_source = gf.VLVDSource(**self._src_args) @property def _src_args(self): return { 'lat': 0., 'lon': 0., 'north_shift': self.northing, 'east_shift': self.easting, 'depth': self.depth, 'volume_change': self.volume_change * km3, 'azimuth': self.azimuth, 'dip': self.dip, 'clvd_moment': self.clvd_moment } class PyrockoProcessor(SourceProcessor): __implements__ = 'pyrocko' def __init__(self, *args): SourceProcessor.__init__(self, *args) self.engine = gf.LocalEngine() def process(self, sources, sandbox, nthreads=0): result = { 'processor_profile': dict(), 'displacement.n': num.zeros(sandbox.frame.npixel), 'displacement.e': num.zeros(sandbox.frame.npixel), 'displacement.d': num.zeros(sandbox.frame.npixel) } coords = sandbox.frame.coordinatesMeter target = gf.StaticTarget( lats=num.full(sandbox.frame.npixel, sandbox.frame.llLat), lons=num.full(sandbox.frame.npixel, sandbox.frame.llLon), east_shifts=coords[:, 0], north_shifts=coords[:, 1], interpolation='nearest_neighbor') store_dirs = set([src.store_dir for src in sources]) for store_dir in store_dirs: self.engine.store_dirs = [store_dir] talpa_sources = [src for src in sources if src.store_dir == store_dir] pyr_sources = [src.pyrocko_source for src in talpa_sources] for src in sources: src.regularize() try: res = self.engine.process( pyr_sources, [target], nthreads=nthreads) except Exception as e: self._log.error( 'Could not execute pyrocko.gf.LocalEngine.process! \n' 'LocalEngine Exception: %s' % e) continue for ires, static_res in enumerate(res.static_results()): result['displacement.n'] += static_res.result['displacement.n'] result['displacement.e'] += static_res.result['displacement.e'] result['displacement.d'] += static_res.result['displacement.d'] talpa_sources[ires]._cached_result = static_res.result for src in sources: if src._cached_result is None: continue self._log.debug('Using cached displacement for %s' % src.__class__.__name__) result['displacement.n'] += src._cached_result['displacement.n'] result['displacement.e'] += src._cached_result['displacement.e'] result['displacement.d'] += src._cached_result['displacement.d'] return result