The fatiando package has been deprecated. Please check out the new tools in the Fatiando a Terra website: www.fatiando.org

Source code for fatiando.seismic.epic2d

"""
Epicenter determination in 2D, i.e., assuming a flat Earth.

There are solvers for the following approximations.

**Homogeneous Earth**

Estimates the (x, y) cartesian coordinates of the epicenter based on
travel-time residuals between S and P waves, assuming a homogeneous velocity
distribution.

* :func:`~fatiando.seismic.epic2d.Homogeneous`

----

"""
from __future__ import division
from future.builtins import super
import numpy as np

from ..inversion import Misfit


[docs]class Homogeneous(Misfit): r""" Estimate the epicenter assuming a homogeneous Earth. Parameters: * ttres : array Travel-time residuals between S and P waves * recs : list of lists List with the (x, y) coordinates of the receivers * vp : float Assumed velocity of P waves * vs : float Assumed velocity of S waves .. note:: The recommended solver for this inverse problem is the Levemberg-Marquardt method. Since this is a non-linear problem, set the desired method and initial solution using the :meth:`~fatiando.inversion.base.OptimizerMixin.config` method. See the example bellow. Examples: Using synthetic data. >>> from fatiando.mesher import Square >>> from fatiando.seismic import ttime2d >>> # Generate synthetic travel-time residuals >>> area = (0, 10, 0, 10) >>> vp = 2 >>> vs = 1 >>> model = [Square(area, props={'vp':vp, 'vs':vs})] >>> # The true source (epicenter) >>> src = (5, 5) >>> recs = [(5, 0), (5, 10), (10, 0)] >>> srcs = [src, src, src] >>> #The travel-time residual between P and S waves >>> ptime = ttime2d.straight(model, 'vp', srcs, recs) >>> stime = ttime2d.straight(model, 'vs', srcs, recs) >>> ttres = stime - ptime >>> # Pass the data to the solver class >>> solver = Homogeneous(ttres, recs, vp, vs).config('levmarq', ... initial=[1, 1]) >>> # Estimate the epicenter >>> x, y = solver.fit().estimate_ >>> print "(%.4f, %.4f)" % (x, y) (5.0000, 5.0000) Notes: The travel-time residual measured by the ith receiver is a function of the (x, y) coordinates of the epicenter: .. math:: t_{S_i} - t_{P_i} = \Delta t_i (x, y) = \left(\frac{1}{V_S} - \frac{1}{V_P} \right) \sqrt{(x_i - x)^2 + (y_i - y)^2} The elements :math:`G_{i1}` and :math:`G_{i2}` of the Jacobian matrix for this data type are .. math:: G_{i1}(x, y) = -\left(\frac{1}{V_S} - \frac{1}{V_P} \right) \frac{x_i - x}{\sqrt{(x_i - x)^2 + (y_i - y)^2}} .. math:: G_{i2}(x, y) = -\left(\frac{1}{V_S} - \frac{1}{V_P} \right) \frac{y_i - y}{\sqrt{(x_i - x)^2 + (y_i - y)^2}} The Hessian matrix is approximated by :math:`2\bar{\bar{G}}^T\bar{\bar{G}}` (Gauss-Newton method). """ def __init__(self, ttres, recs, vp, vs): super().__init__(data=ttres, nparams=2, islinear=False) self.recs = np.array(recs) self.vp = vp self.vs = vs
[docs] def predicted(self, p): "Calculate the predicted travel time data given a parameter vector." x, y = p alpha = 1/self.vs - 1/self.vp pred = alpha*np.sqrt((self.recs[:, 0] - x)**2 + (self.recs[:, 1] - y)**2) return pred
[docs] def jacobian(self, p): "Calculate the Jacobian matrix for the inversion." x, y = p alpha = 1/self.vs - 1/self.vp sqrt = np.sqrt((self.recs[:, 0] - x)**2 + (self.recs[:, 1] - y)**2) jac = np.empty((self.ndata, self.nparams)) jac[:, 0] = -alpha*(self.recs[:, 0] - x)/sqrt jac[:, 1] = -alpha*(self.recs[:, 1] - y)/sqrt return jac