tectonic-utils 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tectonic_utils/.DS_Store +0 -0
- tectonic_utils/__init__.py +3 -0
- tectonic_utils/cover_picture.png +0 -0
- tectonic_utils/geodesy/.DS_Store +0 -0
- tectonic_utils/geodesy/.ruff_cache/.gitignore +1 -0
- tectonic_utils/geodesy/.ruff_cache/0.1.5/15663111236935520357 +0 -0
- tectonic_utils/geodesy/.ruff_cache/CACHEDIR.TAG +1 -0
- tectonic_utils/geodesy/__init__.py +0 -0
- tectonic_utils/geodesy/datums.py +156 -0
- tectonic_utils/geodesy/euler_pole.py +170 -0
- tectonic_utils/geodesy/fault_vector_functions.py +383 -0
- tectonic_utils/geodesy/haversine.py +193 -0
- tectonic_utils/geodesy/insar_vector_functions.py +285 -0
- tectonic_utils/geodesy/linear_elastic.py +231 -0
- tectonic_utils/geodesy/test/.DS_Store +0 -0
- tectonic_utils/geodesy/test/__init__.py +0 -0
- tectonic_utils/geodesy/test/test_conversion_functions.py +74 -0
- tectonic_utils/geodesy/test/test_euler_poles.py +33 -0
- tectonic_utils/geodesy/test/test_insar_vector_functions.py +36 -0
- tectonic_utils/geodesy/utilities.py +47 -0
- tectonic_utils/geodesy/xyz2llh.py +220 -0
- tectonic_utils/read_write/.DS_Store +0 -0
- tectonic_utils/read_write/.ruff_cache/.gitignore +1 -0
- tectonic_utils/read_write/.ruff_cache/0.1.5/680373307893520726 +0 -0
- tectonic_utils/read_write/.ruff_cache/CACHEDIR.TAG +1 -0
- tectonic_utils/read_write/__init__.py +0 -0
- tectonic_utils/read_write/general_io.py +55 -0
- tectonic_utils/read_write/netcdf_read_write.py +382 -0
- tectonic_utils/read_write/read_kml.py +68 -0
- tectonic_utils/read_write/test/.DS_Store +0 -0
- tectonic_utils/read_write/test/__init__.py +0 -0
- tectonic_utils/read_write/test/example_grd.grd +0 -0
- tectonic_utils/read_write/test/test_conversion_functions.py +40 -0
- tectonic_utils/read_write/test/written_example.grd +0 -0
- tectonic_utils/seismo/.DS_Store +0 -0
- tectonic_utils/seismo/.ruff_cache/.gitignore +1 -0
- tectonic_utils/seismo/.ruff_cache/0.1.5/12911000862714636977 +0 -0
- tectonic_utils/seismo/.ruff_cache/CACHEDIR.TAG +1 -0
- tectonic_utils/seismo/MT_calculations.py +132 -0
- tectonic_utils/seismo/__init__.py +0 -0
- tectonic_utils/seismo/moment_calculations.py +44 -0
- tectonic_utils/seismo/second_focal_plane.py +138 -0
- tectonic_utils/seismo/test/.DS_Store +0 -0
- tectonic_utils/seismo/test/__init__.py +0 -0
- tectonic_utils/seismo/test/test_WC.py +19 -0
- tectonic_utils/seismo/test/test_second_focal_plane.py +16 -0
- tectonic_utils/seismo/wells_and_coppersmith.py +167 -0
- tectonic_utils-0.1.2.dist-info/LICENSE.md +21 -0
- tectonic_utils-0.1.2.dist-info/METADATA +82 -0
- tectonic_utils-0.1.2.dist-info/RECORD +51 -0
- tectonic_utils-0.1.2.dist-info/WHEEL +4 -0
tectonic_utils/.DS_Store
ADDED
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
*
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
Signature: 8a477f597d28d172789f06886806bc55
|
File without changes
|
@@ -0,0 +1,156 @@
|
|
1
|
+
"""
|
2
|
+
Convert between local enu, local llh, and global xyz coordinates
|
3
|
+
Translated from the Matlab toolkit of the Stanford lab.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import numpy as np
|
7
|
+
|
8
|
+
# Datum list --------------------------------------------------------------------
|
9
|
+
data = {
|
10
|
+
'ABINDAN ': [-1.121450e+002, -5.475071e-005, -162, -12, 206],
|
11
|
+
'AFGOOYE ': [-1.080000e+002, 4.807955e-007, -43, -163, 45],
|
12
|
+
'AIN EL ABD 1970 ': [-2.510000e+002, -1.419270e-005, -150, -251, -2],
|
13
|
+
'ANNA 1 ASTRO 1965 ': [-2.300000e+001, -8.120449e-008, -491, -22, 435],
|
14
|
+
'ARC 1950 ': [-1.121450e+002, -5.475071e-005, -143, -90, -294],
|
15
|
+
'ARC 1960 ': [-1.121450e+002, -5.475071e-005, -160, -8, -300],
|
16
|
+
'ASCENSION ISLAND 1958': [-2.510000e+002, -1.419270e-005, -207, 107, 52],
|
17
|
+
'ASTRO B4 SOROL ATOLL ': [-2.510000e+002, -1.419270e-005, 114, -116, -333],
|
18
|
+
'ASTRO BEACON "E" ': [-2.510000e+002, -1.419270e-005, 145, 75, -272],
|
19
|
+
'ASTRO DOS 71/4 ': [-2.510000e+002, -1.419270e-005, -320, 550, -494],
|
20
|
+
'ASTRONOMIC STN 1952 ': [-2.510000e+002, -1.419270e-005, 124, -234, -25],
|
21
|
+
'AUSTRALIAN GEOD 1966 ': [-2.300000e+001, -8.120449e-008, -133, -48, 148],
|
22
|
+
'AUSTRALIAN GEOD 1984 ': [-2.300000e+001, -8.120449e-008, -134, -48, 149],
|
23
|
+
'BD 72 ': [-2.510000e+002, -1.419270e-005, -126, 80, -101],
|
24
|
+
'BELLEVUE (IGN) ': [-2.510000e+002, -1.419270e-005, -127, -769, 472],
|
25
|
+
'BERMUDA 1957 ': [-6.940000e+001, -3.726464e-005, -73, 213, 296],
|
26
|
+
'BOGOTA OBSRVATRY ': [-2.510000e+002, -1.419270e-005, 307, 304, -318],
|
27
|
+
'CAMPO INCHAUSPE ': [-2.510000e+002, -1.419270e-005, -148, 136, 90],
|
28
|
+
'CANTON ASTRO 1966 ': [-2.510000e+002, -1.419270e-005, 298, -304, -375],
|
29
|
+
'CAPE ': [-1.121450e+002, -5.475071e-005, -136, -108, -292],
|
30
|
+
'CAPE CANAVERAL ': [-6.940000e+001, -3.726464e-005, -2, 150, 181],
|
31
|
+
'CARTHAGE ': [-1.121450e+002, -5.475071e-005, -263, 6, 431],
|
32
|
+
'CH-1903 ': [07.398450e+002, 1.003748e-005, 674, 15, 405],
|
33
|
+
'CHATHAM 1971 ': [-2.510000e+002, -1.419270e-005, 175, -38, 113],
|
34
|
+
'CHUA ASTRO ': [-2.510000e+002, -1.419270e-005, -134, 229, -29],
|
35
|
+
'CORREGO ALEGRE ': [-2.510000e+002, -1.419270e-005, -206, 172, -6],
|
36
|
+
'DJAKARTA (BATAVIA) ': [07.398450e+002, 1.003748e-005, -377, 681, -50],
|
37
|
+
'DOS 1968 ': [-2.510000e+002, -1.419270e-005, 230, -199, -752],
|
38
|
+
'EASTER ISLAND 1967 ': [-2.510000e+002, -1.419270e-005, 211, 147, 111],
|
39
|
+
'EUROPEAN 1950 ': [-2.510000e+002, -1.419270e-005, -87, -98, -121],
|
40
|
+
'EUROPEAN 1979 ': [-2.510000e+002, -1.419270e-005, -86, -98, -119],
|
41
|
+
'FINLAND HAYFORD ': [-2.510000e+002, -1.419270e-005, -78, -231, -97],
|
42
|
+
'GANDAJIKA BASE ': [-2.510000e+002, -1.419270e-005, -133, -321, 50],
|
43
|
+
'GEODETIC DATUM 1949 ': [-2.510000e+002, -1.419270e-005, 84, -22, 209],
|
44
|
+
'GUAM 1963 ': [-6.940000e+001, -3.726464e-005, -100, -248, 259],
|
45
|
+
'GUX 1 ASTRO ': [-2.510000e+002, -1.419270e-005, 252, -209, -751],
|
46
|
+
'HJORSEY 1955 ': [-2.510000e+002, -1.419270e-005, -73, 46, -86],
|
47
|
+
'HONG KONG 1963 ': [-2.510000e+002, -1.419270e-005, -156, -271, -189],
|
48
|
+
'HU-TZU-SHAN ': [-2.510000e+002, -1.419270e-005, -637, -549, -203],
|
49
|
+
'INDIAN BANGLADESH ': [08.606550e+002, 2.836137e-005, 289, 734, 257],
|
50
|
+
'INDIAN THAILAND ': [08.606550e+002, 2.836137e-005, 214, 836, 303],
|
51
|
+
'IRELAND 1965 ': [07.968110e+002, 1.196002e-005, 506, -122, 611],
|
52
|
+
'ISRAEL ': [-1.637890e+002, -5.473908e-005, -235, -85, 264],
|
53
|
+
'ISTS 073 ASTRO 1969 ': [-2.510000e+002, -1.419270e-005, 208, -435, -229],
|
54
|
+
'JOHNSTON ISLAND ': [-2.510000e+002, -1.419270e-005, 191, -77, -204],
|
55
|
+
'KANDAWALA ': [08.606550e+002, 2.836137e-005, -97, 787, 86],
|
56
|
+
'KERGUELEN ISLAND ': [-2.510000e+002, -1.419270e-005, 145, -187, 103],
|
57
|
+
'KERTAU 1948 ': [08.329370e+002, 2.836137e-005, -11, 851, 5],
|
58
|
+
'L.C. 5 ASTRO ': [-6.940000e+001, -3.726464e-005, 42, 124, 147],
|
59
|
+
'LIBERIA 1964 ': [-1.121450e+002, -5.475071e-005, -90, 40, 88],
|
60
|
+
'LUZON MINDANAO ': [-6.940000e+001, -3.726464e-005, -133, -79, -72],
|
61
|
+
'LUZON PHILIPPINES ': [-6.940000e+001, -3.726464e-005, -133, -77, -51],
|
62
|
+
'MAHE 1971 ': [-1.121450e+002, -5.475071e-005, 41, -220, -134],
|
63
|
+
'MARCO ASTRO ': [-2.510000e+002, -1.419270e-005, -289, -124, 60],
|
64
|
+
'MASSAWA ': [07.398450e+002, 1.003748e-005, 639, 405, 60],
|
65
|
+
'MERCHICH ': [-1.121450e+002, -5.475071e-005, 31, 146, 47],
|
66
|
+
'MICHELIN ': [01.614000e+003, 1.127918e-004, 1118, 23, 66],
|
67
|
+
'MIDWAY ASTRO 1961 ': [-2.510000e+002, -1.419270e-005, 912, -58, 1227],
|
68
|
+
'MINNA ': [-1.121450e+002, -5.475071e-005, -92, -93, 122],
|
69
|
+
'NAD27 ALASKA ': [-6.940000e+001, -3.726464e-005, -5, 135, 172],
|
70
|
+
'NAD27 BAHAMAS ': [-6.940000e+001, -3.726464e-005, -4, 154, 178],
|
71
|
+
'NAD27 CANADA ': [-6.940000e+001, -3.726464e-005, -10, 158, 187],
|
72
|
+
'NAD27 CANAL ZONE ': [-6.940000e+001, -3.726464e-005, 0, 125, 201],
|
73
|
+
'NAD27 CARIBBEAN ': [-6.940000e+001, -3.726464e-005, -7, 152, 178],
|
74
|
+
'NAD27 CENTRAL ': [-6.940000e+001, -3.726464e-005, 0, 125, 194],
|
75
|
+
'NAD27 CONUS ': [-6.940000e+001, -3.726464e-005, -8, 160, 176],
|
76
|
+
'NAD27 CUBA ': [-6.940000e+001, -3.726464e-005, -9, 152, 178],
|
77
|
+
'NAD27 GREENLAND ': [-6.940000e+001, -3.726464e-005, 11, 114, 195],
|
78
|
+
'NAD27 MEXICO ': [-6.940000e+001, -3.726464e-005, -12, 130, 190],
|
79
|
+
'NAD27 SAN SALVADOR ': [-6.940000e+001, -3.726464e-005, 1, 140, 165],
|
80
|
+
'NAD83 ': [00.000000e+000, -1.643484e-011, 0, 0, 0],
|
81
|
+
'NAHRWN MASIRAH ILND ': [-1.121450e+002, -5.475071e-005, -247, -148, 369],
|
82
|
+
'NAHRWN SAUDI ARABIA ': [-1.121450e+002, -5.575071e-005, -231, -196, 482],
|
83
|
+
'NAHRWN UNITED ARAB ': [-1.121450e+002, -5.475071e-005, -249, -156, 381],
|
84
|
+
'NAPARIMA BWI ': [-2.510000e+002, -1.419270e-005, -2, 374, 172],
|
85
|
+
'NETHERLANDS ': [07.400000e+002, 1.003748e-005, 593, 26, 478],
|
86
|
+
'OBSERVATORIO 1966 ': [-2.510000e+002, -1.419270e-005, -425, -169, 81],
|
87
|
+
'OLD EGYPTIAN ': [-6.300000e+001, 4.807955e-007, -130, 110, -13],
|
88
|
+
'OLD HAWAIIAN ': [-6.940000e+001, -3.726464e-005, 61, -285, -181],
|
89
|
+
'OMAN ': [-1.121450e+002, -5.475071e-005, -346, -1, 224],
|
90
|
+
'ORD SRVY GRT BRITN ': [05.736040e+002, 1.196002e-005, 375, -111, 431],
|
91
|
+
'PICO DE LAS NIEVES ': [-2.510000e+002, -1.419270e-005, -307, -92, 127],
|
92
|
+
'PITCAIRN ASTRO 1967 ': [-2.510000e+002, -1.419270e-005, 185, 165, 42],
|
93
|
+
'POTSDAM ': [07.398000e+002, 1.003748e-005, 587, 16, 393],
|
94
|
+
'PROV SO AMRICN 1956 ': [-2.510000e+002, -1.419270e-005, -288, 175, -376],
|
95
|
+
'PROV SO CHILEAN 1963 ': [-2.510000e+002, -1.419270e-005, 16, 196, 93],
|
96
|
+
'PUERTO RICO ': [-6.940000e+001, -3.726464e-005, 11, 72, -101],
|
97
|
+
'QATAR NATIONAL ': [-2.510000e+002, -1.419270e-005, -128, -283, 22],
|
98
|
+
'QORNOQ ': [-2.510000e+002, -1.419270e-005, 164, 138, -189],
|
99
|
+
'REUNION ': [-2.510000e+002, -1.419270e-005, 94, -948, -1262],
|
100
|
+
'ROME 1940 ': [-2.510000e+002, -1.419270e-005, -225, -65, 9],
|
101
|
+
'RT 90 ': [07.398450e+002, 1.003748e-005, 498, -36, 568],
|
102
|
+
'S-42 ': [-1.080000e+002, 4.807600e-007, 23, -124, -84],
|
103
|
+
'SANTO (DOS) ': [-2.510000e+002, -1.419270e-005, 170, 42, 84],
|
104
|
+
'SAO BRAZ ': [-2.510000e+002, -1.419270e-005, -203, 141, 53],
|
105
|
+
'SAPPER HILL 1943 ': [-2.510000e+002, -1.419270e-005, -355, 16, 74],
|
106
|
+
'SCHWARZECK ': [06.531350e+002, 1.003748e-005, 616, 97, -251],
|
107
|
+
'SOUTH AMERICAN 1969 ': [-2.300000e+001, -8.120449e-008, -57, 1, -41],
|
108
|
+
'SOUTH ASIA ': [-1.800000e+001, 4.807955e-007, 7, -10, -26],
|
109
|
+
'SOUTHEAST BASE ': [-2.510000e+002, -1.419270e-005, -499, -249, 314],
|
110
|
+
'SOUTHWEST BASE ': [-2.510000e+002, -1.419270e-005, -104, 167, -38],
|
111
|
+
'TIMBALAI 1948 ': [08.606550e+002, 2.836137e-005, -689, 691, -46],
|
112
|
+
'TOKYO ': [07.398450e+002, 1.003748e-005, -128, 481, 664],
|
113
|
+
'TRISTAN ASTRO 1968 ': [-2.510000e+002, -1.419270e-005, -632, 438, -609],
|
114
|
+
'VITI LEVU 1916 ': [-1.121450e+002, -5.475071e-005, 51, 391, -36],
|
115
|
+
'WAKE-ENIWETOK 1960 ': [-1.330000e+002, -1.419270e-005, 101, 52, -39],
|
116
|
+
'WGS 72 ': [02.000000e+000, 3.121058e-008, 0, 0, 5],
|
117
|
+
'WGS 84 ': [00.000000e+000, 0.000000e+000, 0, 0, 0],
|
118
|
+
'ZANDERIJ ': [-2.510000e+002, -1.419270e-005, -265, 120, -358]
|
119
|
+
}
|
120
|
+
|
121
|
+
|
122
|
+
def get_datums(names=None):
|
123
|
+
"""
|
124
|
+
Returns da, df, dX, dY, dZ given a specific datum.
|
125
|
+
DATUMVALUE=data(DATUMNAMES) returns the datum parameters for datum specified by string array DATUMNAMES.
|
126
|
+
These parameters are defined as differences to the WGS-84 ellipsoid:
|
127
|
+
* da = WGS-84 equatorial radius minus the specified datum equatorial radius (meters)
|
128
|
+
* df = WGS-84 flattening minus the specified datum flattening
|
129
|
+
* dX = X-coordinate of WGS-84 geocenter minus the specified datum X-coordinate (meters)
|
130
|
+
* dY = Y-coordinate of WGS-84 geocenter minus the specified datum Y-coordinate (meters)
|
131
|
+
* dZ = Z-coordinate of WGS-84 geocenter minus the specified datum Z-coordinate (meters)
|
132
|
+
|
133
|
+
For reference:
|
134
|
+
* WGS-84 Equatorial Radius (a) = 6378137.0
|
135
|
+
* WGS-84 Flattening (f) = 1/298.257223563
|
136
|
+
|
137
|
+
Calling the function without input arguments returns a list of available datums.
|
138
|
+
Unmatched datums return NaNs.
|
139
|
+
|
140
|
+
:param names: string
|
141
|
+
:type names: string
|
142
|
+
:returns: 5 floats representing the chosen datum relative to WGS-84
|
143
|
+
:rtype: array
|
144
|
+
"""
|
145
|
+
|
146
|
+
if not names: # Return list of available datums if called with no input arguments.
|
147
|
+
return data.keys()
|
148
|
+
# Read the database. Match requested datums with those available.
|
149
|
+
all_keys = data.keys() # collect keys
|
150
|
+
value = np.zeros((1, 5)) # initialize return vaule
|
151
|
+
modified_name = "{:<21}".format(names.upper())
|
152
|
+
if modified_name in all_keys:
|
153
|
+
value[0, :] = data[modified_name]
|
154
|
+
else:
|
155
|
+
value[0, :] = [np.nan, np.nan, np.nan, np.nan, np.nan]
|
156
|
+
return value
|
@@ -0,0 +1,170 @@
|
|
1
|
+
"""
|
2
|
+
Functions to rotate a point by a known Euler pole.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
from . import fault_vector_functions, utilities
|
7
|
+
|
8
|
+
|
9
|
+
def point_rotation_by_Euler_Pole(Point, Euler_Pole):
|
10
|
+
"""
|
11
|
+
Compute the velocity of rotation of a point about an Euler pole on a spherical earth.
|
12
|
+
This function is useful for computing the velocity of a stationary point in one reference frame
|
13
|
+
with respect to another reference frame.
|
14
|
+
The resulting velocity is assumed to be horizontal.
|
15
|
+
|
16
|
+
:param Point: [longitude, latitude] of observation point, in degrees
|
17
|
+
:type Point: array_like
|
18
|
+
:param Euler_Pole: [longitude, latitude, omega] of Euler Pole, in degrees and degrees/Ma
|
19
|
+
:type Euler_Pole: array_like
|
20
|
+
:returns: [e_velocity, n_velocity, u_velocity] of point in rotated reference frame, in mm/yr
|
21
|
+
:rtype: [float, float, float]
|
22
|
+
"""
|
23
|
+
R_point = get_r(Point[0], Point[1])
|
24
|
+
R_ep = get_r(Euler_Pole[0], Euler_Pole[1])
|
25
|
+
unit_ep = fault_vector_functions.get_unit_vector(R_ep)
|
26
|
+
omega_raw = degma2radyr(Euler_Pole[2])
|
27
|
+
omega = omega_raw * unit_ep # in radians per year
|
28
|
+
|
29
|
+
velocity_of_transformation = np.cross(omega, R_point) # velocity at the station from the euler pole rotation
|
30
|
+
velocity_of_transformation = velocity_of_transformation * 1000 # mm/yr in x, y, z
|
31
|
+
|
32
|
+
xvel = velocity_of_transformation[0]
|
33
|
+
yvel = velocity_of_transformation[1]
|
34
|
+
zvel = velocity_of_transformation[2]
|
35
|
+
[east_transform, north_transform] = xyz2en(xvel, yvel, zvel, Point[0])
|
36
|
+
up_transform = 0 # by definition the velocity will be horizontal
|
37
|
+
|
38
|
+
return [east_transform, north_transform, up_transform]
|
39
|
+
|
40
|
+
|
41
|
+
def degma2radyr(omega):
|
42
|
+
"""
|
43
|
+
Convert omega from degrees/Ma to radians/yr.
|
44
|
+
|
45
|
+
:param omega: rotation rate in degrees per million years
|
46
|
+
:type omega: float
|
47
|
+
:returns: rotation rate in radians per year
|
48
|
+
:rtype: float
|
49
|
+
"""
|
50
|
+
radyr = omega * (np.pi / 180) * 1e-6
|
51
|
+
return radyr
|
52
|
+
|
53
|
+
|
54
|
+
def get_r(lon, lat):
|
55
|
+
"""
|
56
|
+
Vector from center of earth to the point in question assuming a spherical earth.
|
57
|
+
The XYZ coordinate system has x=0 at longitude=0 and z=0 at the equator with positive to the north.
|
58
|
+
|
59
|
+
:param lon: Longitude of initial point, in degrees
|
60
|
+
:type lon: float
|
61
|
+
:param lat: Latitude of initial point, in degrees
|
62
|
+
:type lat: float
|
63
|
+
:returns: [X, Y, Z] coordinates in meters.
|
64
|
+
:rtype: [float, float, float]
|
65
|
+
"""
|
66
|
+
R_fixed = 6378000 # In meters
|
67
|
+
R_equatorial_disk = R_fixed * np.cos(np.deg2rad(lat))
|
68
|
+
T_equatorial_disk = np.deg2rad(lon)
|
69
|
+
X = R_equatorial_disk * np.cos(T_equatorial_disk)
|
70
|
+
Y = R_equatorial_disk * np.sin(T_equatorial_disk)
|
71
|
+
Z = np.sqrt(R_fixed * R_fixed - X * X - Y * Y)
|
72
|
+
if lat < 0:
|
73
|
+
Z = Z * -1
|
74
|
+
return [X, Y, Z]
|
75
|
+
|
76
|
+
|
77
|
+
def euler_vector_to_euler_pole(euler_vector):
|
78
|
+
"""
|
79
|
+
Convert a three-component vector representing an Euler Pole into a lon/lat/rate representation of the Euler Pole.
|
80
|
+
|
81
|
+
:param euler_vector: [ev_x, ev_y, ev_z] in deg/ma, where longitude 0 is along the positive east axis
|
82
|
+
:type euler_vector: array_like
|
83
|
+
:returns: lon, lat, rate
|
84
|
+
:rtype: float, float, float
|
85
|
+
"""
|
86
|
+
lon = np.rad2deg(np.arctan2(euler_vector[1], euler_vector[0]))
|
87
|
+
horiz_mag = fault_vector_functions.get_vector_magnitude([euler_vector[0], euler_vector[1], 0])
|
88
|
+
lat = np.rad2deg(np.arctan(np.abs(euler_vector[2])/horiz_mag))
|
89
|
+
if euler_vector[2] < 0: # if negative z-coordinate, it should be in the southern hemisphere.
|
90
|
+
lat = -lat
|
91
|
+
magnitude = fault_vector_functions.get_vector_magnitude(euler_vector)
|
92
|
+
return lon, lat, magnitude
|
93
|
+
|
94
|
+
|
95
|
+
def euler_pole_to_euler_vector(euler_pole):
|
96
|
+
"""
|
97
|
+
Convert a lon/lat/rate representing an Euler Pole into a vector representation of the Euler Pole.
|
98
|
+
|
99
|
+
:param euler_pole: [lon, lat, rate]
|
100
|
+
:type euler_pole: array_like
|
101
|
+
:returns: ev_x, ev_y, ev_z in same units as `rate`, where longitude 0 is along the positive east axis.
|
102
|
+
:rtype: float, float, float
|
103
|
+
"""
|
104
|
+
direction_vector = get_r(euler_pole[0], euler_pole[1])
|
105
|
+
unit_vector = fault_vector_functions.get_unit_vector(direction_vector)
|
106
|
+
scaled_vector = np.multiply(unit_vector, euler_pole[2])
|
107
|
+
return scaled_vector[0], scaled_vector[1], scaled_vector[2]
|
108
|
+
|
109
|
+
|
110
|
+
def get_opposite_ep(euler_pole):
|
111
|
+
"""
|
112
|
+
Get opposite pole on other side of the Earth.
|
113
|
+
|
114
|
+
:param euler_pole: [lon, lat, rate]
|
115
|
+
:type euler_pole: array_like
|
116
|
+
:returns: opposite euler pole, -180 <= lon <= 180
|
117
|
+
:rtype: [float, float, float]
|
118
|
+
"""
|
119
|
+
return [utilities.wrap_lon(euler_pole[0]+180), -euler_pole[1], -euler_pole[2]]
|
120
|
+
|
121
|
+
|
122
|
+
def get_unit_east(lon):
|
123
|
+
"""
|
124
|
+
Unit east vector from a point on earth's surface in XYZ coordinates.
|
125
|
+
The XYZ coordinate system has x=0 at longitude=0 and z=0 at the equator with positive to the north.
|
126
|
+
The return value of Z is zero for eastward motion.
|
127
|
+
|
128
|
+
:param lon: Longitude of initial point, in degrees
|
129
|
+
:type lon: float
|
130
|
+
:returns: [X, Y, Z] components
|
131
|
+
:rtype: [float, float, float]
|
132
|
+
"""
|
133
|
+
T_equatorial_disk = np.deg2rad(lon)
|
134
|
+
x = -np.sin(T_equatorial_disk)
|
135
|
+
y = np.cos(T_equatorial_disk)
|
136
|
+
return [x, y, 0]
|
137
|
+
|
138
|
+
|
139
|
+
def xyz2en(x, y, z, lon):
|
140
|
+
"""
|
141
|
+
Convert velocities from xyz to horizontal east and north, assuming spherical earth and no vertical motion.
|
142
|
+
We take the dot product of the velocity with the unit east vector and the north component is the remainder.
|
143
|
+
A more complex function xyz2enu(X, Y, Z, lon, lat) could be written later.
|
144
|
+
|
145
|
+
:param x: x velocity at observation point
|
146
|
+
:type x: float
|
147
|
+
:param y: y velocity at observation point
|
148
|
+
:type y: float
|
149
|
+
:param z: z velocity at observation point
|
150
|
+
:type z: float
|
151
|
+
:param lon: Longitude of observation point, in degrees
|
152
|
+
:type lon: float
|
153
|
+
:returns: [east_vel, north_vel]
|
154
|
+
:rtype: [float, float]
|
155
|
+
"""
|
156
|
+
vel_vector = [x, y, z]
|
157
|
+
unit_east = get_unit_east(lon)
|
158
|
+
e = np.dot(vel_vector, unit_east)
|
159
|
+
n = np.sqrt(x * x + y * y + z * z - e * e)
|
160
|
+
if z < 0:
|
161
|
+
n = n * -1
|
162
|
+
return [e, n]
|
163
|
+
|
164
|
+
|
165
|
+
if __name__ == "__main__":
|
166
|
+
Euler_Pole = [69.9, -12.3, 0.55] # Lon, Lat, Deg/Ma
|
167
|
+
Point = [-124, 40.5] # Lon, Lat
|
168
|
+
[east_transform, north_transform, up_transform] = point_rotation_by_Euler_Pole(Point, Euler_Pole)
|
169
|
+
total = np.sqrt(east_transform * east_transform + north_transform * north_transform)
|
170
|
+
print("%.2f east, %.2f north, %.2f up, %.2f mm/yr total" % (east_transform, north_transform, up_transform, total))
|