We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Possible typo on the documentation page of `obspy.signal.rotate.rotate_ne_rt`
On its documentation page: https://docs.obspy.org/packages/autogen/obspy.signal.rotate.rotate_rt_ne.html
the inputs of the `obspy.signal.rotate_rt_ne()` are shown as the north and east components, which should be the radial and transverse components instead. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `obspy/signal/rotate.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # ------------------------------------------------------------------
4 # Filename: rotate.py
5 #  Purpose: Various Seismogram Rotation Functions
6 #   Author: Tobias Megies, Tom Richter, Lion Krischer
7 #    Email: tobias.megies@geophysik.uni-muenchen.de
8 #
9 # Copyright (C) 2009-2013 Tobias Megies, Tom Richter, Lion Krischer
10 # --------------------------------------------------------------------
11 """
12 Various Seismogram Rotation Functions
13 
14 :copyright:
15     The ObsPy Development Team (devs@obspy.org)
16 :license:
17     GNU Lesser General Public License, Version 3
18     (https://www.gnu.org/copyleft/lesser.html)
19 """
20 import warnings
21 from math import cos, sin, radians
22 
23 import numpy as np
24 
25 
26 def rotate_ne_rt(n, e, ba):
27     """
28     Rotates horizontal components of a seismogram.
29 
30     The North- and East-Component of a seismogram will be rotated in Radial
31     and Transversal Component. The angle is given as the back-azimuth, that is
32     defined as the angle measured between the vector pointing from the station
33     to the source and the vector pointing from the station to the North.
34 
35     :type n: :class:`~numpy.ndarray`
36     :param n: Data of the North component of the seismogram.
37     :type e: :class:`~numpy.ndarray`
38     :param e: Data of the East component of the seismogram.
39     :type ba: float
40     :param ba: The back azimuth from station to source in degrees.
41     :return: Radial and Transversal component of seismogram.
42     """
43     if len(n) != len(e):
44         raise TypeError("North and East component have different length.")
45     if ba < 0 or ba > 360:
46         raise ValueError("Back Azimuth should be between 0 and 360 degrees.")
47     ba = radians(ba)
48     r = - e * sin(ba) - n * cos(ba)
49     t = - e * cos(ba) + n * sin(ba)
50     return r, t
51 
52 
53 def rotate_rt_ne(n, e, ba):
54     """
55     Rotates horizontal components of a seismogram.
56 
57     Rotates from radial and transversal components to North and East
58     components.
59 
60     This is the inverse transformation of the transformation described
61     in :func:`rotate_ne_rt`.
62     """
63     ba = 360.0 - ba
64     return rotate_ne_rt(n, e, ba)
65 
66 
67 def rotate_zne_lqt(z, n, e, ba, inc):
68     """
69     Rotates all components of a seismogram.
70 
71     The components will be rotated from ZNE (Z, North, East, left-handed) to
72     LQT (e.g. ray coordinate system, right-handed). The rotation angles are
73     given as the back-azimuth and inclination.
74 
75     The transformation consists of 3 steps::
76 
77         1. mirroring of E-component at ZN plain: ZNE -> ZNW
78         2. negative rotation of coordinate system around Z-axis with angle ba:
79            ZNW -> ZRT
80         3. negative rotation of coordinate system around T-axis with angle inc:
81            ZRT -> LQT
82 
83     :type z: :class:`~numpy.ndarray`
84     :param z: Data of the Z component of the seismogram.
85     :type n: :class:`~numpy.ndarray`
86     :param n: Data of the North component of the seismogram.
87     :type e: :class:`~numpy.ndarray`
88     :param e: Data of the East component of the seismogram.
89     :type ba: float
90     :param ba: The back azimuth from station to source in degrees.
91     :type inc: float
92     :param inc: The inclination of the ray at the station in degrees.
93     :return: L-, Q- and T-component of seismogram.
94     """
95     if len(z) != len(n) or len(z) != len(e):
96         raise TypeError("Z, North and East component have different length!?!")
97     if ba < 0 or ba > 360:
98         raise ValueError("Back Azimuth should be between 0 and 360 degrees!")
99     if inc < 0 or inc > 360:
100         raise ValueError("Inclination should be between 0 and 360 degrees!")
101     ba = radians(ba)
102     inc = radians(inc)
103     l = z * cos(inc) - n * sin(inc) * cos(ba) - e * sin(inc) * sin(ba)  # NOQA
104     q = z * sin(inc) + n * cos(inc) * cos(ba) + e * cos(inc) * sin(ba)  # NOQA
105     t = n * sin(ba) - e * cos(ba)  # NOQA
106     return l, q, t
107 
108 
109 def rotate_lqt_zne(l, q, t, ba, inc):  # NOQA
110     """
111     Rotates all components of a seismogram.
112 
113     The components will be rotated from LQT to ZNE.
114     This is the inverse transformation of the transformation described
115     in :func:`rotate_zne_lqt`.
116     """
117     if len(l) != len(q) or len(l) != len(t):
118         raise TypeError("L, Q and T component have different length!?!")
119     if ba < 0 or ba > 360:
120         raise ValueError("Back Azimuth should be between 0 and 360 degrees!")
121     if inc < 0 or inc > 360:
122         raise ValueError("Inclination should be between 0 and 360 degrees!")
123     ba = radians(ba)
124     inc = radians(inc)
125     z = l * cos(inc) + q * sin(inc)
126     n = -l * sin(inc) * cos(ba) + q * cos(inc) * cos(ba) + t * sin(ba)
127     e = -l * sin(inc) * sin(ba) + q * cos(inc) * sin(ba) - t * cos(ba)
128     return z, n, e
129 
130 
131 def _dip_azimuth2zne_base_vector(dip, azimuth):
132     """
133     Helper function converting a vector described with azimuth and dip of unit
134     length to a vector in the ZNE (Vertical, North, East) base.
135 
136     The definition of azimuth and dip is according to the SEED reference
137     manual.
138     """
139     dip = np.deg2rad(dip)
140     azimuth = np.deg2rad(azimuth)
141 
142     return np.array([-np.sin(dip),
143                      np.cos(azimuth) * np.cos(dip),
144                      np.sin(azimuth) * np.cos(dip)])
145 
146 
147 def rotate2zne(data_1, azimuth_1, dip_1, data_2, azimuth_2, dip_2, data_3,
148                azimuth_3, dip_3, inverse=False):
149     """
150     Rotates an arbitrarily oriented three-component vector to ZNE.
151 
152     Each components orientation is described with a azimuth and a dip. The
153     azimuth is defined as the degrees from North, clockwise and the dip is the
154     defined as the number of degrees, down from horizontal. Both definitions
155     are according to the SEED standard.
156 
157     The three components need not be orthogonal to each other but the
158     components have to be linearly independent. The function performs a full
159     base change to orthogonal Vertical, North, and East orientations.
160 
161     :param data_1: Data component 1.
162     :param azimuth_1: The azimuth of component 1.
163     :param dip_1: The dip of component 1.
164     :param data_2: Data component 2.
165     :param azimuth_2: The azimuth of component 2.
166     :param dip_2: The dip of component 2.
167     :param data_3: Data component 3.
168     :param azimuth_3: The azimuth of component 3.
169     :param dip_3: The dip of component 3.
170     :param inverse: If `True`, the data arrays will be converted from ZNE to
171         whatever coordinate system the azimuths and dips specify. In that
172         case data_1, data_2, data_3 have to be data arrays for Z, N,
173         and E and the dips and azimuths specify where to transform to.
174     :type inverse: bool
175 
176     :rtype: tuple(:class:`numpy.ndarray`, :class:`numpy.ndarray`,
177         :class:`numpy.ndarray`)
178     :returns: The three rotated components, oriented in Z, N, and E if
179         `inverse` is `False`. Otherwise they will be oriented as specified
180         by the dips and azimuths.
181 
182     An input of ZNE yields an output of ZNE
183 
184     >>> rotate2zne(np.arange(3), 0, -90, np.arange(3) * 2, 0, 0, \
185             np.arange(3) * 3, 90, 0) # doctest: +NORMALIZE_WHITESPACE
186     (array([ 0., 1., 2.]), array([ 0., 2., 4.]), array([ 0., 3., 6.]))
187 
188     An input of ZSE yields an output of ZNE
189 
190     >>> rotate2zne(np.arange(3), 0, -90, np.arange(3) * 2, 180, 0, \
191             np.arange(3) * 3, 90, 0) # doctest: +NORMALIZE_WHITESPACE
192     (array([ 0., 1., 2.]), array([ 0., -2., -4.]), array([ 0., 3., 6.]))
193 
194     Mixed up components should get rotated to ZNE.
195 
196     >>> rotate2zne(np.arange(3), 0, 0, np.arange(3) * 2, 90, 0, \
197             np.arange(3) * 3, 0, -90) # doctest: +NORMALIZE_WHITESPACE
198     (array([ 0., 3., 6.]), array([ 0., 1., 2.]), array([ 0., 2., 4.]))
199     """
200     if len(set(len(i_) for i_ in (data_1, data_2, data_3))) != 1:
201         msg = "All three data arrays must be of same length."
202         raise ValueError(msg)
203 
204     # Define the base vectors of the old base in terms of the new base vectors.
205     base_vector_1 = _dip_azimuth2zne_base_vector(dip_1, azimuth_1)
206     base_vector_2 = _dip_azimuth2zne_base_vector(dip_2, azimuth_2)
207     base_vector_3 = _dip_azimuth2zne_base_vector(dip_3, azimuth_3)
208 
209     # Base change matrix.
210     m = np.array([base_vector_1,
211                   base_vector_2,
212                   base_vector_3])
213 
214     # Determinant gives the volume change of a unit cube going from one
215     # basis to the next. It should neither be too small nor to large. These
216     # here are arbitrary limits.
217     with warnings.catch_warnings():
218         warnings.filterwarnings('ignore',
219                                 '.*invalid value encountered in det.*')
220         det = np.linalg.det(m)
221     if not (1E-6 < abs(det) < 1E6):
222         raise ValueError("The given directions are not linearly independent, "
223                          "at least within numerical precision. Determinant "
224                          "of the base change matrix: %g" % det)
225 
226     if not inverse:
227         m = np.linalg.inv(m)
228 
229     z, n, e = np.dot(m, [data_1, data_2, data_3])
230 
231     # Replace all negative zeros. These might confuse some further
232     # processing programs.
233     z = np.array(z).ravel()
234     z[z == -0.0] = 0
235     n = np.array(n).ravel()
236     n[n == -0.0] = 0
237     e = np.array(e).ravel()
238     e[e == -0.0] = 0
239 
240     return z, n, e
241 
242 
243 if __name__ == '__main__':
244     import doctest
245     doctest.testmod(exclude_empty=True)
246
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/obspy/signal/rotate.py b/obspy/signal/rotate.py
--- a/obspy/signal/rotate.py
+++ b/obspy/signal/rotate.py
@@ -50,7 +50,7 @@
     return r, t
 
 
-def rotate_rt_ne(n, e, ba):
+def rotate_rt_ne(r, t, ba):
     """
     Rotates horizontal components of a seismogram.
 
@@ -59,9 +59,15 @@
 
     This is the inverse transformation of the transformation described
     in :func:`rotate_ne_rt`.
+
+    :type r: :class:`~numpy.ndarray`
+    :param r: Data of the Radial component of the seismogram.
+    :type t: :class:`~numpy.ndarray`
+    :param t: Data of the Transverse component of the seismogram.
+    :returns: North and East component of seismogram.
     """
     ba = 360.0 - ba
-    return rotate_ne_rt(n, e, ba)
+    return rotate_ne_rt(r, t, ba)
 
 
 def rotate_zne_lqt(z, n, e, ba, inc):

{"golden_diff": "diff --git a/obspy/signal/rotate.py b/obspy/signal/rotate.py\n--- a/obspy/signal/rotate.py\n+++ b/obspy/signal/rotate.py\n@@ -50,7 +50,7 @@\n     return r, t\n \n \n-def rotate_rt_ne(n, e, ba):\n+def rotate_rt_ne(r, t, ba):\n     \"\"\"\n     Rotates horizontal components of a seismogram.\n \n@@ -59,9 +59,15 @@\n \n     This is the inverse transformation of the transformation described\n     in :func:`rotate_ne_rt`.\n+\n+    :type r: :class:`~numpy.ndarray`\n+    :param r: Data of the Radial component of the seismogram.\n+    :type t: :class:`~numpy.ndarray`\n+    :param t: Data of the Transverse component of the seismogram.\n+    :returns: North and East component of seismogram.\n     \"\"\"\n     ba = 360.0 - ba\n-    return rotate_ne_rt(n, e, ba)\n+    return rotate_ne_rt(r, t, ba)\n \n \n def rotate_zne_lqt(z, n, e, ba, inc):\n", "issue": "Possible typo on the documentation page of `obspy.signal.rotate.rotate_ne_rt`\nOn its documentation page: https://docs.obspy.org/packages/autogen/obspy.signal.rotate.rotate_rt_ne.html\r\nthe inputs of the `obspy.signal.rotate_rt_ne()` are shown as the north and east components, which should be the radial and transverse components instead. \n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n# ------------------------------------------------------------------\n# Filename: rotate.py\n#  Purpose: Various Seismogram Rotation Functions\n#   Author: Tobias Megies, Tom Richter, Lion Krischer\n#    Email: tobias.megies@geophysik.uni-muenchen.de\n#\n# Copyright (C) 2009-2013 Tobias Megies, Tom Richter, Lion Krischer\n# --------------------------------------------------------------------\n\"\"\"\nVarious Seismogram Rotation Functions\n\n:copyright:\n    The ObsPy Development Team (devs@obspy.org)\n:license:\n    GNU Lesser General Public License, Version 3\n    (https://www.gnu.org/copyleft/lesser.html)\n\"\"\"\nimport warnings\nfrom math import cos, sin, radians\n\nimport numpy as np\n\n\ndef rotate_ne_rt(n, e, ba):\n    \"\"\"\n    Rotates horizontal components of a seismogram.\n\n    The North- and East-Component of a seismogram will be rotated in Radial\n    and Transversal Component. The angle is given as the back-azimuth, that is\n    defined as the angle measured between the vector pointing from the station\n    to the source and the vector pointing from the station to the North.\n\n    :type n: :class:`~numpy.ndarray`\n    :param n: Data of the North component of the seismogram.\n    :type e: :class:`~numpy.ndarray`\n    :param e: Data of the East component of the seismogram.\n    :type ba: float\n    :param ba: The back azimuth from station to source in degrees.\n    :return: Radial and Transversal component of seismogram.\n    \"\"\"\n    if len(n) != len(e):\n        raise TypeError(\"North and East component have different length.\")\n    if ba < 0 or ba > 360:\n        raise ValueError(\"Back Azimuth should be between 0 and 360 degrees.\")\n    ba = radians(ba)\n    r = - e * sin(ba) - n * cos(ba)\n    t = - e * cos(ba) + n * sin(ba)\n    return r, t\n\n\ndef rotate_rt_ne(n, e, ba):\n    \"\"\"\n    Rotates horizontal components of a seismogram.\n\n    Rotates from radial and transversal components to North and East\n    components.\n\n    This is the inverse transformation of the transformation described\n    in :func:`rotate_ne_rt`.\n    \"\"\"\n    ba = 360.0 - ba\n    return rotate_ne_rt(n, e, ba)\n\n\ndef rotate_zne_lqt(z, n, e, ba, inc):\n    \"\"\"\n    Rotates all components of a seismogram.\n\n    The components will be rotated from ZNE (Z, North, East, left-handed) to\n    LQT (e.g. ray coordinate system, right-handed). The rotation angles are\n    given as the back-azimuth and inclination.\n\n    The transformation consists of 3 steps::\n\n        1. mirroring of E-component at ZN plain: ZNE -> ZNW\n        2. negative rotation of coordinate system around Z-axis with angle ba:\n           ZNW -> ZRT\n        3. negative rotation of coordinate system around T-axis with angle inc:\n           ZRT -> LQT\n\n    :type z: :class:`~numpy.ndarray`\n    :param z: Data of the Z component of the seismogram.\n    :type n: :class:`~numpy.ndarray`\n    :param n: Data of the North component of the seismogram.\n    :type e: :class:`~numpy.ndarray`\n    :param e: Data of the East component of the seismogram.\n    :type ba: float\n    :param ba: The back azimuth from station to source in degrees.\n    :type inc: float\n    :param inc: The inclination of the ray at the station in degrees.\n    :return: L-, Q- and T-component of seismogram.\n    \"\"\"\n    if len(z) != len(n) or len(z) != len(e):\n        raise TypeError(\"Z, North and East component have different length!?!\")\n    if ba < 0 or ba > 360:\n        raise ValueError(\"Back Azimuth should be between 0 and 360 degrees!\")\n    if inc < 0 or inc > 360:\n        raise ValueError(\"Inclination should be between 0 and 360 degrees!\")\n    ba = radians(ba)\n    inc = radians(inc)\n    l = z * cos(inc) - n * sin(inc) * cos(ba) - e * sin(inc) * sin(ba)  # NOQA\n    q = z * sin(inc) + n * cos(inc) * cos(ba) + e * cos(inc) * sin(ba)  # NOQA\n    t = n * sin(ba) - e * cos(ba)  # NOQA\n    return l, q, t\n\n\ndef rotate_lqt_zne(l, q, t, ba, inc):  # NOQA\n    \"\"\"\n    Rotates all components of a seismogram.\n\n    The components will be rotated from LQT to ZNE.\n    This is the inverse transformation of the transformation described\n    in :func:`rotate_zne_lqt`.\n    \"\"\"\n    if len(l) != len(q) or len(l) != len(t):\n        raise TypeError(\"L, Q and T component have different length!?!\")\n    if ba < 0 or ba > 360:\n        raise ValueError(\"Back Azimuth should be between 0 and 360 degrees!\")\n    if inc < 0 or inc > 360:\n        raise ValueError(\"Inclination should be between 0 and 360 degrees!\")\n    ba = radians(ba)\n    inc = radians(inc)\n    z = l * cos(inc) + q * sin(inc)\n    n = -l * sin(inc) * cos(ba) + q * cos(inc) * cos(ba) + t * sin(ba)\n    e = -l * sin(inc) * sin(ba) + q * cos(inc) * sin(ba) - t * cos(ba)\n    return z, n, e\n\n\ndef _dip_azimuth2zne_base_vector(dip, azimuth):\n    \"\"\"\n    Helper function converting a vector described with azimuth and dip of unit\n    length to a vector in the ZNE (Vertical, North, East) base.\n\n    The definition of azimuth and dip is according to the SEED reference\n    manual.\n    \"\"\"\n    dip = np.deg2rad(dip)\n    azimuth = np.deg2rad(azimuth)\n\n    return np.array([-np.sin(dip),\n                     np.cos(azimuth) * np.cos(dip),\n                     np.sin(azimuth) * np.cos(dip)])\n\n\ndef rotate2zne(data_1, azimuth_1, dip_1, data_2, azimuth_2, dip_2, data_3,\n               azimuth_3, dip_3, inverse=False):\n    \"\"\"\n    Rotates an arbitrarily oriented three-component vector to ZNE.\n\n    Each components orientation is described with a azimuth and a dip. The\n    azimuth is defined as the degrees from North, clockwise and the dip is the\n    defined as the number of degrees, down from horizontal. Both definitions\n    are according to the SEED standard.\n\n    The three components need not be orthogonal to each other but the\n    components have to be linearly independent. The function performs a full\n    base change to orthogonal Vertical, North, and East orientations.\n\n    :param data_1: Data component 1.\n    :param azimuth_1: The azimuth of component 1.\n    :param dip_1: The dip of component 1.\n    :param data_2: Data component 2.\n    :param azimuth_2: The azimuth of component 2.\n    :param dip_2: The dip of component 2.\n    :param data_3: Data component 3.\n    :param azimuth_3: The azimuth of component 3.\n    :param dip_3: The dip of component 3.\n    :param inverse: If `True`, the data arrays will be converted from ZNE to\n        whatever coordinate system the azimuths and dips specify. In that\n        case data_1, data_2, data_3 have to be data arrays for Z, N,\n        and E and the dips and azimuths specify where to transform to.\n    :type inverse: bool\n\n    :rtype: tuple(:class:`numpy.ndarray`, :class:`numpy.ndarray`,\n        :class:`numpy.ndarray`)\n    :returns: The three rotated components, oriented in Z, N, and E if\n        `inverse` is `False`. Otherwise they will be oriented as specified\n        by the dips and azimuths.\n\n    An input of ZNE yields an output of ZNE\n\n    >>> rotate2zne(np.arange(3), 0, -90, np.arange(3) * 2, 0, 0, \\\n            np.arange(3) * 3, 90, 0) # doctest: +NORMALIZE_WHITESPACE\n    (array([ 0., 1., 2.]), array([ 0., 2., 4.]), array([ 0., 3., 6.]))\n\n    An input of ZSE yields an output of ZNE\n\n    >>> rotate2zne(np.arange(3), 0, -90, np.arange(3) * 2, 180, 0, \\\n            np.arange(3) * 3, 90, 0) # doctest: +NORMALIZE_WHITESPACE\n    (array([ 0., 1., 2.]), array([ 0., -2., -4.]), array([ 0., 3., 6.]))\n\n    Mixed up components should get rotated to ZNE.\n\n    >>> rotate2zne(np.arange(3), 0, 0, np.arange(3) * 2, 90, 0, \\\n            np.arange(3) * 3, 0, -90) # doctest: +NORMALIZE_WHITESPACE\n    (array([ 0., 3., 6.]), array([ 0., 1., 2.]), array([ 0., 2., 4.]))\n    \"\"\"\n    if len(set(len(i_) for i_ in (data_1, data_2, data_3))) != 1:\n        msg = \"All three data arrays must be of same length.\"\n        raise ValueError(msg)\n\n    # Define the base vectors of the old base in terms of the new base vectors.\n    base_vector_1 = _dip_azimuth2zne_base_vector(dip_1, azimuth_1)\n    base_vector_2 = _dip_azimuth2zne_base_vector(dip_2, azimuth_2)\n    base_vector_3 = _dip_azimuth2zne_base_vector(dip_3, azimuth_3)\n\n    # Base change matrix.\n    m = np.array([base_vector_1,\n                  base_vector_2,\n                  base_vector_3])\n\n    # Determinant gives the volume change of a unit cube going from one\n    # basis to the next. It should neither be too small nor to large. These\n    # here are arbitrary limits.\n    with warnings.catch_warnings():\n        warnings.filterwarnings('ignore',\n                                '.*invalid value encountered in det.*')\n        det = np.linalg.det(m)\n    if not (1E-6 < abs(det) < 1E6):\n        raise ValueError(\"The given directions are not linearly independent, \"\n                         \"at least within numerical precision. Determinant \"\n                         \"of the base change matrix: %g\" % det)\n\n    if not inverse:\n        m = np.linalg.inv(m)\n\n    z, n, e = np.dot(m, [data_1, data_2, data_3])\n\n    # Replace all negative zeros. These might confuse some further\n    # processing programs.\n    z = np.array(z).ravel()\n    z[z == -0.0] = 0\n    n = np.array(n).ravel()\n    n[n == -0.0] = 0\n    e = np.array(e).ravel()\n    e[e == -0.0] = 0\n\n    return z, n, e\n\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod(exclude_empty=True)\n", "path": "obspy/signal/rotate.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n# ------------------------------------------------------------------\n# Filename: rotate.py\n#  Purpose: Various Seismogram Rotation Functions\n#   Author: Tobias Megies, Tom Richter, Lion Krischer\n#    Email: tobias.megies@geophysik.uni-muenchen.de\n#\n# Copyright (C) 2009-2013 Tobias Megies, Tom Richter, Lion Krischer\n# --------------------------------------------------------------------\n\"\"\"\nVarious Seismogram Rotation Functions\n\n:copyright:\n    The ObsPy Development Team (devs@obspy.org)\n:license:\n    GNU Lesser General Public License, Version 3\n    (https://www.gnu.org/copyleft/lesser.html)\n\"\"\"\nimport warnings\nfrom math import cos, sin, radians\n\nimport numpy as np\n\n\ndef rotate_ne_rt(n, e, ba):\n    \"\"\"\n    Rotates horizontal components of a seismogram.\n\n    The North- and East-Component of a seismogram will be rotated in Radial\n    and Transversal Component. The angle is given as the back-azimuth, that is\n    defined as the angle measured between the vector pointing from the station\n    to the source and the vector pointing from the station to the North.\n\n    :type n: :class:`~numpy.ndarray`\n    :param n: Data of the North component of the seismogram.\n    :type e: :class:`~numpy.ndarray`\n    :param e: Data of the East component of the seismogram.\n    :type ba: float\n    :param ba: The back azimuth from station to source in degrees.\n    :return: Radial and Transversal component of seismogram.\n    \"\"\"\n    if len(n) != len(e):\n        raise TypeError(\"North and East component have different length.\")\n    if ba < 0 or ba > 360:\n        raise ValueError(\"Back Azimuth should be between 0 and 360 degrees.\")\n    ba = radians(ba)\n    r = - e * sin(ba) - n * cos(ba)\n    t = - e * cos(ba) + n * sin(ba)\n    return r, t\n\n\ndef rotate_rt_ne(r, t, ba):\n    \"\"\"\n    Rotates horizontal components of a seismogram.\n\n    Rotates from radial and transversal components to North and East\n    components.\n\n    This is the inverse transformation of the transformation described\n    in :func:`rotate_ne_rt`.\n\n    :type r: :class:`~numpy.ndarray`\n    :param r: Data of the Radial component of the seismogram.\n    :type t: :class:`~numpy.ndarray`\n    :param t: Data of the Transverse component of the seismogram.\n    :returns: North and East component of seismogram.\n    \"\"\"\n    ba = 360.0 - ba\n    return rotate_ne_rt(r, t, ba)\n\n\ndef rotate_zne_lqt(z, n, e, ba, inc):\n    \"\"\"\n    Rotates all components of a seismogram.\n\n    The components will be rotated from ZNE (Z, North, East, left-handed) to\n    LQT (e.g. ray coordinate system, right-handed). The rotation angles are\n    given as the back-azimuth and inclination.\n\n    The transformation consists of 3 steps::\n\n        1. mirroring of E-component at ZN plain: ZNE -> ZNW\n        2. negative rotation of coordinate system around Z-axis with angle ba:\n           ZNW -> ZRT\n        3. negative rotation of coordinate system around T-axis with angle inc:\n           ZRT -> LQT\n\n    :type z: :class:`~numpy.ndarray`\n    :param z: Data of the Z component of the seismogram.\n    :type n: :class:`~numpy.ndarray`\n    :param n: Data of the North component of the seismogram.\n    :type e: :class:`~numpy.ndarray`\n    :param e: Data of the East component of the seismogram.\n    :type ba: float\n    :param ba: The back azimuth from station to source in degrees.\n    :type inc: float\n    :param inc: The inclination of the ray at the station in degrees.\n    :return: L-, Q- and T-component of seismogram.\n    \"\"\"\n    if len(z) != len(n) or len(z) != len(e):\n        raise TypeError(\"Z, North and East component have different length!?!\")\n    if ba < 0 or ba > 360:\n        raise ValueError(\"Back Azimuth should be between 0 and 360 degrees!\")\n    if inc < 0 or inc > 360:\n        raise ValueError(\"Inclination should be between 0 and 360 degrees!\")\n    ba = radians(ba)\n    inc = radians(inc)\n    l = z * cos(inc) - n * sin(inc) * cos(ba) - e * sin(inc) * sin(ba)  # NOQA\n    q = z * sin(inc) + n * cos(inc) * cos(ba) + e * cos(inc) * sin(ba)  # NOQA\n    t = n * sin(ba) - e * cos(ba)  # NOQA\n    return l, q, t\n\n\ndef rotate_lqt_zne(l, q, t, ba, inc):  # NOQA\n    \"\"\"\n    Rotates all components of a seismogram.\n\n    The components will be rotated from LQT to ZNE.\n    This is the inverse transformation of the transformation described\n    in :func:`rotate_zne_lqt`.\n    \"\"\"\n    if len(l) != len(q) or len(l) != len(t):\n        raise TypeError(\"L, Q and T component have different length!?!\")\n    if ba < 0 or ba > 360:\n        raise ValueError(\"Back Azimuth should be between 0 and 360 degrees!\")\n    if inc < 0 or inc > 360:\n        raise ValueError(\"Inclination should be between 0 and 360 degrees!\")\n    ba = radians(ba)\n    inc = radians(inc)\n    z = l * cos(inc) + q * sin(inc)\n    n = -l * sin(inc) * cos(ba) + q * cos(inc) * cos(ba) + t * sin(ba)\n    e = -l * sin(inc) * sin(ba) + q * cos(inc) * sin(ba) - t * cos(ba)\n    return z, n, e\n\n\ndef _dip_azimuth2zne_base_vector(dip, azimuth):\n    \"\"\"\n    Helper function converting a vector described with azimuth and dip of unit\n    length to a vector in the ZNE (Vertical, North, East) base.\n\n    The definition of azimuth and dip is according to the SEED reference\n    manual.\n    \"\"\"\n    dip = np.deg2rad(dip)\n    azimuth = np.deg2rad(azimuth)\n\n    return np.array([-np.sin(dip),\n                     np.cos(azimuth) * np.cos(dip),\n                     np.sin(azimuth) * np.cos(dip)])\n\n\ndef rotate2zne(data_1, azimuth_1, dip_1, data_2, azimuth_2, dip_2, data_3,\n               azimuth_3, dip_3, inverse=False):\n    \"\"\"\n    Rotates an arbitrarily oriented three-component vector to ZNE.\n\n    Each components orientation is described with a azimuth and a dip. The\n    azimuth is defined as the degrees from North, clockwise and the dip is the\n    defined as the number of degrees, down from horizontal. Both definitions\n    are according to the SEED standard.\n\n    The three components need not be orthogonal to each other but the\n    components have to be linearly independent. The function performs a full\n    base change to orthogonal Vertical, North, and East orientations.\n\n    :param data_1: Data component 1.\n    :param azimuth_1: The azimuth of component 1.\n    :param dip_1: The dip of component 1.\n    :param data_2: Data component 2.\n    :param azimuth_2: The azimuth of component 2.\n    :param dip_2: The dip of component 2.\n    :param data_3: Data component 3.\n    :param azimuth_3: The azimuth of component 3.\n    :param dip_3: The dip of component 3.\n    :param inverse: If `True`, the data arrays will be converted from ZNE to\n        whatever coordinate system the azimuths and dips specify. In that\n        case data_1, data_2, data_3 have to be data arrays for Z, N,\n        and E and the dips and azimuths specify where to transform to.\n    :type inverse: bool\n\n    :rtype: tuple(:class:`numpy.ndarray`, :class:`numpy.ndarray`,\n        :class:`numpy.ndarray`)\n    :returns: The three rotated components, oriented in Z, N, and E if\n        `inverse` is `False`. Otherwise they will be oriented as specified\n        by the dips and azimuths.\n\n    An input of ZNE yields an output of ZNE\n\n    >>> rotate2zne(np.arange(3), 0, -90, np.arange(3) * 2, 0, 0, \\\n            np.arange(3) * 3, 90, 0) # doctest: +NORMALIZE_WHITESPACE\n    (array([ 0., 1., 2.]), array([ 0., 2., 4.]), array([ 0., 3., 6.]))\n\n    An input of ZSE yields an output of ZNE\n\n    >>> rotate2zne(np.arange(3), 0, -90, np.arange(3) * 2, 180, 0, \\\n            np.arange(3) * 3, 90, 0) # doctest: +NORMALIZE_WHITESPACE\n    (array([ 0., 1., 2.]), array([ 0., -2., -4.]), array([ 0., 3., 6.]))\n\n    Mixed up components should get rotated to ZNE.\n\n    >>> rotate2zne(np.arange(3), 0, 0, np.arange(3) * 2, 90, 0, \\\n            np.arange(3) * 3, 0, -90) # doctest: +NORMALIZE_WHITESPACE\n    (array([ 0., 3., 6.]), array([ 0., 1., 2.]), array([ 0., 2., 4.]))\n    \"\"\"\n    if len(set(len(i_) for i_ in (data_1, data_2, data_3))) != 1:\n        msg = \"All three data arrays must be of same length.\"\n        raise ValueError(msg)\n\n    # Define the base vectors of the old base in terms of the new base vectors.\n    base_vector_1 = _dip_azimuth2zne_base_vector(dip_1, azimuth_1)\n    base_vector_2 = _dip_azimuth2zne_base_vector(dip_2, azimuth_2)\n    base_vector_3 = _dip_azimuth2zne_base_vector(dip_3, azimuth_3)\n\n    # Base change matrix.\n    m = np.array([base_vector_1,\n                  base_vector_2,\n                  base_vector_3])\n\n    # Determinant gives the volume change of a unit cube going from one\n    # basis to the next. It should neither be too small nor to large. These\n    # here are arbitrary limits.\n    with warnings.catch_warnings():\n        warnings.filterwarnings('ignore',\n                                '.*invalid value encountered in det.*')\n        det = np.linalg.det(m)\n    if not (1E-6 < abs(det) < 1E6):\n        raise ValueError(\"The given directions are not linearly independent, \"\n                         \"at least within numerical precision. Determinant \"\n                         \"of the base change matrix: %g\" % det)\n\n    if not inverse:\n        m = np.linalg.inv(m)\n\n    z, n, e = np.dot(m, [data_1, data_2, data_3])\n\n    # Replace all negative zeros. These might confuse some further\n    # processing programs.\n    z = np.array(z).ravel()\n    z[z == -0.0] = 0\n    n = np.array(n).ravel()\n    n[n == -0.0] = 0\n    e = np.array(e).ravel()\n    e[e == -0.0] = 0\n\n    return z, n, e\n\n\nif __name__ == '__main__':\n    import doctest\n    doctest.testmod(exclude_empty=True)\n", "path": "obspy/signal/rotate.py"}]}