Source code for obspy.taup.helper_classes

# -*- coding: utf-8 -*-
"""
Holds various helper classes to keep the file number manageable.
"""
from collections import namedtuple

import numpy as np


[docs]class SlownessModelError(Exception): pass
[docs]class TauModelError(Exception): pass
#: The SlownessLayer dtype stores a single layer. SlownessLayer = np.dtype([ ('top_p', np.float_), ('top_depth', np.float_), ('bot_p', np.float_), ('bot_depth', np.float_), ]) #: Holds the ray parameter, time and distance increments, and optionally a #: depth, for a ray passing through some layer. TimeDist = np.dtype([ ('p', np.float_), ('time', np.float_), ('dist', np.float_), ('depth', np.float_), ]) #: Holds the ray parameter, time and distance increments, and optionally a #: depth, latitude and longitude for a ray passing through some layer. TimeDistGeo = np.dtype([ ('p', np.float_), ('time', np.float_), ('dist', np.float_), ('depth', np.float_), ('lat', np.float_), ('lon', np.float_) ]) #: Tracks critical points (discontinuities or reversals in slowness gradient) #: within slowness and velocity models. CriticalDepth = np.dtype([ ('depth', np.float_), ('vel_layer_num', np.int_), ('p_layer_num', np.int_), ('s_layer_num', np.int_), ])
[docs]class DepthRange: """ Convenience class for storing a depth range. It has a top and a bottom and can have an associated ray parameter. """
[docs] def __init__(self, top_depth=None, bot_depth=None, ray_param=-1): self.top_depth = top_depth self.bot_depth = bot_depth self.ray_param = ray_param
[docs] def _to_array(self): """ Store all attributes for serialization in a structured array. """ arr = np.empty(3, dtype=np.float_) arr[0] = self.top_depth arr[1] = self.bot_depth arr[2] = self.ray_param return arr
[docs] @staticmethod def _from_array(arr): """ Create instance object from a structured array used in serialization. """ depth_range = DepthRange() depth_range.top_depth = arr[0] depth_range.bot_depth = arr[1] depth_range.ray_param = arr[2] return depth_range
SplitLayerInfo = namedtuple( 'SplitLayerInfo', ['s_mod', 'needed_split', 'moved_sample', 'ray_param'] )
[docs]class Arrival(object): """ Convenience class for storing parameters associated with a phase arrival. :ivar phase: Phase that generated this arrival :vartype phase: :class:`~obspy.taup.seismic_phase.SeismicPhase` :ivar distance: Actual distance in degrees :vartype distance: float :ivar time: Travel time in seconds :vartype time: float :ivar purist_dist: Purist angular distance (great circle) in radians :vartype purist_dist: float :ivar ray_param: Ray parameter in seconds per radians :vartype ray_param: float :ivar name: Phase name :vartype name: str :ivar purist_name: Phase name changed for true depths :vartype purist_name: str :ivar source_depth: Source depth in kilometers :vartype source_depth: float :ivar incident_angle: Angle (in degrees) at which the ray arrives at the receiver :vartype incident_angle: float :ivar takeoff_angle: Angle (in degrees) at which the ray leaves the source :vartype takeoff_angle: float :ivar pierce: Points pierced by ray :vartype pierce: :class:`~numpy.ndarray` (dtype = :class:`~obspy.taup.helper_classes.TimeDist`) :ivar path: Path taken by ray :vartype path: :class:`~numpy.ndarray` (dtype = :class:`~obspy.taup.helper_classes.TimeDist`) """
[docs] def __init__(self, phase, distance, time, purist_dist, ray_param, ray_param_index, name, purist_name, source_depth, receiver_depth, takeoff_angle=None, incident_angle=None): if np.isnan(time): raise ValueError('Time cannot be NaN') if ray_param_index < 0: raise ValueError( 'ray_param_index cannot be negative: %d' % (ray_param_index, )) self.phase = phase self.distance = distance self.time = time self.purist_dist = purist_dist self.ray_param = ray_param self.ray_param_index = ray_param_index self.name = name self.purist_name = purist_name self.source_depth = source_depth self.receiver_depth = receiver_depth if takeoff_angle is None: self.takeoff_angle = phase.calc_takeoff_angle(ray_param) else: self.takeoff_angle = takeoff_angle if incident_angle is None: self.incident_angle = phase.calc_incident_angle(ray_param) else: self.incident_angle = incident_angle self.pierce = None self.path = None
[docs] def __str__(self): return "%s phase arrival at %.3f seconds" % (self.phase.name, self.time)
@property def ray_param_sec_degree(self): """ Return the ray parameter in seconds per degree. """ return self.ray_param * np.pi / 180.0 @property def purist_distance(self): """ Return the purist distance in degrees. """ return self.purist_dist * 180.0 / np.pi