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
@@ -0,0 +1,138 @@
|
|
1
|
+
"""
|
2
|
+
Utility tool for computing the second possible strike, rake, and dip in a focal mechanism,
|
3
|
+
given the strike, rake, and dip of the first focal plane.
|
4
|
+
Inspiration from Vince Cronin's website.
|
5
|
+
"""
|
6
|
+
|
7
|
+
# Internal information:
|
8
|
+
# Variable "a" is the reference strike azimuth.
|
9
|
+
# Variable "b" is the unit vector toward the reference strike azimuth in
|
10
|
+
# a coordinate system in which the +Y axis is north, the +X axis is east, and the +Z axis is up.
|
11
|
+
# Variable "c" is the unit dip vector.
|
12
|
+
# Variable "d" is the vector normal to the input nodal plane, and is the slip vector for the auxilary plane.
|
13
|
+
# Vector "d" points up if the input rake is a positive number, and down if the input rake is a negative number.
|
14
|
+
# Variable "f" is the basis vector for the X axis of the geographic coordinate system, which points east.
|
15
|
+
# Variable "g" is the basis vector for the Y axis of the geographic coordinate system, which points north.
|
16
|
+
# Variable "h" is the basis vector for the Z axis of the geographic coordinate system, which points up.
|
17
|
+
# Variable "i" is the basis vector for the X axis of the nodal plane coordinate system.
|
18
|
+
# If the rake is a negative number, the strike vector is the X axis and the dip vector is the Y axis.
|
19
|
+
# If the rake is a positive vector, the dip vector is the X axis and the strike vector is the Y axis.
|
20
|
+
# Variable "j" is the basis vec tor for the Y axis of the nodal plane coordinate system.
|
21
|
+
# Variable "d" is the basis vector of the Z axis of the nodal plane coordinate system.
|
22
|
+
# Variable "k" is the unit vector in the nodal plane coordinate system that is coincident with the slip vector
|
23
|
+
# on the (input) nodal plane.
|
24
|
+
# Variable "m" is the transformation matrix from the nodal plane coordinate system to the geographic coordinate system.
|
25
|
+
# Variable "rakeVector" is the unit location vector along the slip direction on the nodal plane, expressed in the
|
26
|
+
# geographic coordinate system.
|
27
|
+
# Variable "n" is the dip vector of the auxilary plane, expressed in radian measure.
|
28
|
+
# Variable "s" is the unit vector projection of the rake vector onto the X - Y (horizontal) plane of the
|
29
|
+
# geographic coordinate system.
|
30
|
+
# Explanation of the result.
|
31
|
+
# The first element is the trend of the dip vector of the auxillary plane, in degrees.
|
32
|
+
# The second element is the dip angle of the auxillary plane, in degrees.
|
33
|
+
# The third element is the trend of the slip vector of the auxillary plane, in degrees.
|
34
|
+
|
35
|
+
|
36
|
+
import numpy as np
|
37
|
+
|
38
|
+
|
39
|
+
def vector_norm(v):
|
40
|
+
"""Computes norm of vector."""
|
41
|
+
norm = np.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
|
42
|
+
return norm
|
43
|
+
|
44
|
+
|
45
|
+
def unit_vector(v):
|
46
|
+
"""Computes unit vector associated with 3-component vector."""
|
47
|
+
norm = vector_norm(v)
|
48
|
+
unit_vector = [v[0]/norm, v[1]/norm, v[2]/norm]
|
49
|
+
return unit_vector
|
50
|
+
|
51
|
+
|
52
|
+
def vector_angle(v1, v2):
|
53
|
+
"""Returns angle between two vectors, in radians."""
|
54
|
+
vectorAngle = np.arccos(np.dot(v1, v2)/(vector_norm(v1)*vector_norm(v2))) # Returns in radians
|
55
|
+
return vectorAngle
|
56
|
+
|
57
|
+
|
58
|
+
def find_aux_plane(strike, dip, rake):
|
59
|
+
"""
|
60
|
+
Find the second auxiliary plane in a double couple focal mechanism from the given slip plane/vector.
|
61
|
+
|
62
|
+
:param strike: strike of first focal plane, in degrees
|
63
|
+
:type strike: float
|
64
|
+
:param dip: dip of first focal plane, in degrees
|
65
|
+
:type dip: float
|
66
|
+
:param rake: rake of slip vector on first focal plane, in degrees
|
67
|
+
:type rake: float
|
68
|
+
:returns: [strike, dip, rake] of second focal plane
|
69
|
+
:rtype: list of 3 floats
|
70
|
+
"""
|
71
|
+
a = strike # degrees
|
72
|
+
dipaz = strike + 90 # degrees
|
73
|
+
b = np.array([np.sin(np.deg2rad(a)), np.cos(np.deg2rad(a)), 0])
|
74
|
+
c = np.array([np.sin(np.deg2rad(dipaz))*np.cos(np.deg2rad(dip)),
|
75
|
+
np.cos(np.deg2rad(dipaz))*np.cos(np.deg2rad(dip)),
|
76
|
+
-np.sin(np.deg2rad(dip))])
|
77
|
+
|
78
|
+
if rake < 0:
|
79
|
+
d = np.cross(b, c)
|
80
|
+
else:
|
81
|
+
d = np.cross(c, b)
|
82
|
+
|
83
|
+
f = np.array([1, 0, 0])
|
84
|
+
g = np.array([0, 1, 0])
|
85
|
+
h = np.array([0, 0, 1])
|
86
|
+
|
87
|
+
if rake < 0:
|
88
|
+
i = b
|
89
|
+
j = c
|
90
|
+
k = np.array([np.cos(np.deg2rad(rake)), -np.sin(np.deg2rad(rake)), 0])
|
91
|
+
else:
|
92
|
+
i = c
|
93
|
+
j = b
|
94
|
+
k = np.array([-np.sin(np.deg2rad(rake)), np.cos(np.deg2rad(rake)), 0])
|
95
|
+
|
96
|
+
m = np.array([[np.dot(f, i), np.dot(f, j), np.dot(f, d)],
|
97
|
+
[np.dot(g, i), np.dot(g, j), np.dot(g, d)],
|
98
|
+
[np.dot(h, i), np.dot(h, j), np.dot(h, d)]])
|
99
|
+
|
100
|
+
rakeVector = np.dot(m, k)
|
101
|
+
n = np.arccos(abs(rakeVector[2])) # auxDipAngle, radians
|
102
|
+
|
103
|
+
s = unit_vector([rakeVector[0], rakeVector[1], 0])
|
104
|
+
|
105
|
+
if rakeVector[0] < 0:
|
106
|
+
rakeTrend = 360-vector_angle(s, g)*(180/np.pi)
|
107
|
+
else:
|
108
|
+
rakeTrend = vector_angle(s, g)*(180/np.pi)
|
109
|
+
|
110
|
+
if rake < 0:
|
111
|
+
if rakeTrend > 270:
|
112
|
+
auxStrike = rakeTrend-270
|
113
|
+
else:
|
114
|
+
auxStrike = rakeTrend+90
|
115
|
+
else:
|
116
|
+
if rakeTrend < 90:
|
117
|
+
auxStrike = rakeTrend+270
|
118
|
+
else:
|
119
|
+
auxStrike = rakeTrend-90
|
120
|
+
auxStrikeRad = auxStrike*(np.pi/180)
|
121
|
+
auxStrikeVector = [np.sin(auxStrikeRad), np.cos(auxStrikeRad), 0]
|
122
|
+
|
123
|
+
if auxStrike > 270:
|
124
|
+
auxDipAz = (auxStrike-270)
|
125
|
+
else:
|
126
|
+
auxDipAz = auxStrike+90
|
127
|
+
auxDipAngle = n*180/np.pi
|
128
|
+
|
129
|
+
if rake < 0:
|
130
|
+
auxRake = -1*vector_angle(auxStrikeVector, d)*180/np.pi
|
131
|
+
else:
|
132
|
+
auxRake = vector_angle(auxStrikeVector, d)*180/np.pi
|
133
|
+
|
134
|
+
auxStrikeAz = auxDipAz-90
|
135
|
+
if auxStrikeAz < 0:
|
136
|
+
auxStrikeAz = auxStrikeAz+360
|
137
|
+
|
138
|
+
return [auxStrikeAz, auxDipAngle, auxRake]
|
Binary file
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import unittest
|
2
|
+
from .. import wells_and_coppersmith as wc
|
3
|
+
|
4
|
+
|
5
|
+
class Tests(unittest.TestCase):
|
6
|
+
|
7
|
+
def test_simple_focal_plane(self):
|
8
|
+
print("Testing WC")
|
9
|
+
mag = 6.8
|
10
|
+
RLD = wc.RLD_from_M(mag, "N")
|
11
|
+
RW = wc.RW_from_M(mag, "N")
|
12
|
+
expected_RLD = 33.11311214825911 # km
|
13
|
+
expected_RW = 17.378008287493753 # km
|
14
|
+
self.assertEqual(RLD, expected_RLD, 'Wells and Coppersmith wrong')
|
15
|
+
self.assertEqual(RW, expected_RW, 'Wells and Coppersmith wrong')
|
16
|
+
|
17
|
+
|
18
|
+
if __name__ == '__main__':
|
19
|
+
unittest.main()
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import unittest
|
2
|
+
from .. import second_focal_plane
|
3
|
+
|
4
|
+
|
5
|
+
class Tests(unittest.TestCase):
|
6
|
+
|
7
|
+
def test_simple_focal_plane(self):
|
8
|
+
print("Testing second focal plane.")
|
9
|
+
np1 = [38, 51, 44]
|
10
|
+
expected_outcome = [276.71179351444425, 57.32650724684216, 131.61502732561564]
|
11
|
+
np2 = second_focal_plane.find_aux_plane(np1[0], np1[1], np1[2])
|
12
|
+
self.assertEqual(np2, expected_outcome, 'Wrong focal plane')
|
13
|
+
|
14
|
+
|
15
|
+
if __name__ == '__main__':
|
16
|
+
unittest.main()
|
@@ -0,0 +1,167 @@
|
|
1
|
+
"""
|
2
|
+
Set of functions that calculate important scaling relationships between earthquake magnitude and other parameters.
|
3
|
+
From Wells and Coppersmith, 1994.
|
4
|
+
|
5
|
+
* FAULT_TYPE = SS, R, N, All
|
6
|
+
* a, b = parameters in equation
|
7
|
+
* sa, sb = parameter uncertainties
|
8
|
+
* s = estimate uncertainty
|
9
|
+
* r = R correlation coefficient
|
10
|
+
|
11
|
+
Average displacements, Max displacements, and inverse relationships not included.
|
12
|
+
"""
|
13
|
+
|
14
|
+
import numpy as np
|
15
|
+
import sys
|
16
|
+
from . import moment_calculations
|
17
|
+
|
18
|
+
|
19
|
+
def check_fault_types(fault_type):
|
20
|
+
"""Ensure that provided fault type is within ["SS", "N", "R", "ALL"]"""
|
21
|
+
if fault_type == "SS" or fault_type == "N" or fault_type == "R" or fault_type == "ALL":
|
22
|
+
return
|
23
|
+
else:
|
24
|
+
sys.exit("Error! Fault Type should be SS, N, R, or ALL! Exiting...")
|
25
|
+
|
26
|
+
|
27
|
+
def rectangular_slip(length, width, magnitude, mu=30*1e9):
|
28
|
+
"""Magnitude to slip on rectangular patch
|
29
|
+
|
30
|
+
:param length: fault length, in m
|
31
|
+
:type length: float
|
32
|
+
:param width: fault width, in m
|
33
|
+
:type width: float
|
34
|
+
:param magnitude: magnitude
|
35
|
+
:type magnitude: float
|
36
|
+
:param mu: shear modulus, in Pa, defaults to 30 GPa
|
37
|
+
:type mu: float, optional
|
38
|
+
:returns: slip, in m
|
39
|
+
:rtype: float
|
40
|
+
"""
|
41
|
+
area = length * width # meters^2
|
42
|
+
moment_nm = moment_calculations.moment_from_mw(magnitude)
|
43
|
+
slip = moment_nm / (area * mu) # Moment = Area * slip * mu.
|
44
|
+
return slip
|
45
|
+
|
46
|
+
|
47
|
+
def get_magnitude_from_rectangle(length, width, slip, mu=30*1e9):
|
48
|
+
"""
|
49
|
+
:param length: fault length, in m
|
50
|
+
:type length: float
|
51
|
+
:param width: fault width, in m
|
52
|
+
:type width: float
|
53
|
+
:param slip: fault slip, in m
|
54
|
+
:type slip: float
|
55
|
+
:param mu: shear modulus, in Pa, defaults to 30 GPa
|
56
|
+
:type mu: float, optional
|
57
|
+
:returns: magnitude
|
58
|
+
:rtype: float
|
59
|
+
"""
|
60
|
+
area = length * width # meters^2
|
61
|
+
moment_nm = moment_calculations.moment_from_muad(mu, area, slip) # newton-meters
|
62
|
+
magnitude = moment_calculations.mw_from_moment(moment_nm)
|
63
|
+
return magnitude
|
64
|
+
|
65
|
+
|
66
|
+
def SLR_from_M(M, fault_type):
|
67
|
+
"""
|
68
|
+
Surface rupture width from Magnitude, computed using log(SLR)=a + b*M
|
69
|
+
|
70
|
+
:param M: magnitude
|
71
|
+
:type M: float
|
72
|
+
:param fault_type: fault_type ["SS", "N", "R", "ALL"]
|
73
|
+
:type fault_type: string
|
74
|
+
:returns: surface rupture length, in km
|
75
|
+
:rtype: float
|
76
|
+
"""
|
77
|
+
# row has the form [a, sa, b, sb, s, r, mmin, mmax]
|
78
|
+
check_fault_types(fault_type)
|
79
|
+
if fault_type == "SS":
|
80
|
+
[a, _, b, _, _, _, mmin, mmax] = [-3.55, 0.37, 0.74, 0.05, 0.23, 0.91, 5.6, 8.1]
|
81
|
+
elif fault_type == "R":
|
82
|
+
[a, _, b, _, _, _, mmin, mmax] = [-2.86, 0.55, 0.63, 0.08, 0.20, 0.88, 5.4, 7.4]
|
83
|
+
elif fault_type == "N":
|
84
|
+
[a, _, b, _, _, _, mmin, mmax] = [-2.01, 0.65, 0.50, 0.10, 0.21, 0.81, 5.2, 7.3]
|
85
|
+
else:
|
86
|
+
[a, _, b, _, _, _, mmin, mmax] = [-3.22, 0.27, 0.69, 0.04, 0.22, 0.89, 5.2, 8.1]
|
87
|
+
assert(mmin <= M <= mmax), ValueError("M"+str(M)+" outside valid bounds for Wells and Coppersmith.")
|
88
|
+
SLR = np.power(10, (a + b * M))
|
89
|
+
return SLR
|
90
|
+
|
91
|
+
|
92
|
+
def RW_from_M(M, fault_type):
|
93
|
+
"""
|
94
|
+
Downdip rupture width from Magnitude, computed using log(RW)=a + b*M
|
95
|
+
|
96
|
+
:param M: magnitude
|
97
|
+
:type M: float
|
98
|
+
:param fault_type: fault_type ["SS", "N", "R", "ALL"]
|
99
|
+
:type fault_type: string
|
100
|
+
:returns: downdip rupture width, in km
|
101
|
+
:rtype: float
|
102
|
+
"""
|
103
|
+
# row has the form [a, sa, b, sb, s, r, mmin, mmax]
|
104
|
+
check_fault_types(fault_type)
|
105
|
+
if fault_type == "SS":
|
106
|
+
[a, _, b, _, _, _, mmin, mmax] = [-0.76, 0.12, 0.27, 0.02, 0.14, 0.84, 4.8, 8.1]
|
107
|
+
elif fault_type == "R":
|
108
|
+
[a, _, b, _, _, _, mmin, mmax] = [-1.61, 0.20, 0.41, 0.03, 0.15, 0.90, 4.8, 7.6]
|
109
|
+
elif fault_type == "N":
|
110
|
+
[a, _, b, _, _, _, mmin, mmax] = [-1.14, 0.28, 0.35, 0.05, 0.12, 0.86, 5.2, 7.3]
|
111
|
+
else:
|
112
|
+
[a, _, b, _, _, _, mmin, mmax] = [-1.01, 0.10, 0.32, 0.02, 0.15, 0.84, 4.8, 8.1]
|
113
|
+
assert(mmin <= M <= mmax), ValueError("M"+str(M)+" outside valid bounds for Wells and Coppersmith.")
|
114
|
+
RW = np.power(10, (a + b * M))
|
115
|
+
return RW
|
116
|
+
|
117
|
+
|
118
|
+
def RLD_from_M(M, fault_type):
|
119
|
+
"""
|
120
|
+
Subsurface rupture length from Magnitude, computed using log(RLD)=a + b*M
|
121
|
+
|
122
|
+
:param M: magnitude
|
123
|
+
:type M: float
|
124
|
+
:param fault_type: fault_type ["SS", "N", "R", "ALL"]
|
125
|
+
:type fault_type: string
|
126
|
+
:returns: subsurface rupture length, in km
|
127
|
+
:rtype: float
|
128
|
+
"""
|
129
|
+
# row has the form [a, sa, b, sb, s, r, mmin, mmax]
|
130
|
+
check_fault_types(fault_type)
|
131
|
+
if fault_type == "SS":
|
132
|
+
[a, _, b, _, _, _, mmin, mmax] = [-2.57, 0.12, 0.62, 0.02, 0.15, 0.96, 4.8, 8.1]
|
133
|
+
elif fault_type == "R":
|
134
|
+
[a, _, b, _, _, _, mmin, mmax] = [-2.42, 0.21, 0.58, 0.03, 0.16, 0.93, 4.8, 7.6]
|
135
|
+
elif fault_type == "N":
|
136
|
+
[a, _, b, _, _, _, mmin, mmax] = [-1.88, 0.37, 0.50, 0.06, 0.17, 0.88, 5.2, 7.3]
|
137
|
+
else:
|
138
|
+
[a, _, b, _, _, _, mmin, mmax] = [-2.44, 0.11, 0.59, 0.02, 0.16, 0.94, 4.8, 8.1]
|
139
|
+
assert(mmin <= M <= mmax), ValueError("M"+str(M)+" outside valid bounds for Wells and Coppersmith.")
|
140
|
+
RLD = np.power(10, (a + b * M))
|
141
|
+
return RLD
|
142
|
+
|
143
|
+
|
144
|
+
def RA_from_M(M, fault_type):
|
145
|
+
"""
|
146
|
+
Rupture Area from Magnitude, computed using log(RA)=a + b*M
|
147
|
+
|
148
|
+
:param M: magnitude
|
149
|
+
:type M: float
|
150
|
+
:param fault_type: fault_type ["SS", "N", "R", "ALL"]
|
151
|
+
:type fault_type: string
|
152
|
+
:returns: rupture area, in km^2
|
153
|
+
:rtype: float
|
154
|
+
"""
|
155
|
+
# row has the form [a, sa, b, sb, s, r, mmin, mmax]
|
156
|
+
check_fault_types(fault_type)
|
157
|
+
if fault_type == "SS":
|
158
|
+
[a, _, b, _, _, _, mmin, mmax] = [-3.42, 0.18, 0.90, 0.03, 0.22, 0.96, 4.8, 7.9]
|
159
|
+
elif fault_type == "R":
|
160
|
+
[a, _, b, _, _, _, mmin, mmax] = [-3.99, 0.36, 0.98, 0.06, 0.26, 0.94, 4.8, 7.6]
|
161
|
+
elif fault_type == "N":
|
162
|
+
[a, _, b, _, _, _, mmin, mmax] = [-2.87, 0.50, 0.82, 0.08, 0.22, 0.92, 5.2, 7.3]
|
163
|
+
else: # ALL
|
164
|
+
[a, _, b, _, _, _, mmin, mmax] = [-3.49, 0.16, 0.91, 0.03, 0.24, 0.95, 4.8, 7.9]
|
165
|
+
assert(mmin <= M <= mmax), ValueError("M"+str(M)+" outside valid bounds for Wells and Coppersmith.")
|
166
|
+
RA = np.power(10, (a + b * M))
|
167
|
+
return RA
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Kathryn Materna
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,82 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: tectonic-utils
|
3
|
+
Version: 0.1.2
|
4
|
+
Summary: A small package of useful geophysics utilities
|
5
|
+
Home-page: https://github.com/kmaterna/Tectonic_Utils
|
6
|
+
License: MIT
|
7
|
+
Author: Kathryn Materna
|
8
|
+
Author-email: kmaterna@berkeley.edu
|
9
|
+
Requires-Python: >=3.7
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
11
|
+
Classifier: Operating System :: OS Independent
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
13
|
+
Classifier: Programming Language :: Python :: 3.7
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
19
|
+
Requires-Dist: netCDF4
|
20
|
+
Requires-Dist: numpy (>=1.20,<2.0)
|
21
|
+
Requires-Dist: scipy
|
22
|
+
Project-URL: Repository, https://github.com/kmaterna/Tectonic_Utils
|
23
|
+
Description-Content-Type: text/markdown
|
24
|
+
|
25
|
+
# Tectonic Utils
|
26
|
+
|
27
|
+
A simple library with utility functions for "everyday use" in active tectonics research.
|
28
|
+
There are geodesy and seismology utility functions in Python,
|
29
|
+
some originally from libraries in Matlab or other languages.
|
30
|
+
There are read-write functions to access commonly used formats.
|
31
|
+
Please explore and let me know if you'd like to contribute!
|
32
|
+
|
33
|
+
Functions in this library that I use regularly:
|
34
|
+
* Haversine formula
|
35
|
+
* Euler Pole rotations
|
36
|
+
* Geographic to XYZ Earth-centered coordinates
|
37
|
+
* InSAR look vectors (Fialko et al., 2001)
|
38
|
+
* Fault vector operations (Aki and Richards, 1980)
|
39
|
+
* Moment magnitude conversions (Hanks and Kanamori, 1979)
|
40
|
+
* Earthquake magnitude scaling (Wells and Coppersmith, 1994)
|
41
|
+
* Reading GMT multi-segment files into Python
|
42
|
+
|
43
|
+

|
44
|
+
|
45
|
+
## Dependencies
|
46
|
+
* Python 3
|
47
|
+
* numpy
|
48
|
+
* scipy
|
49
|
+
* netCDF4 (pip install netCDF4)
|
50
|
+
|
51
|
+
|
52
|
+
## Installation
|
53
|
+
On Unix (other systems not tested yet), install from PyPI using:
|
54
|
+
|
55
|
+
```pip install Tectonic-Utils```
|
56
|
+
|
57
|
+
To test that it works, import a utility in Python. I use an import structure like:
|
58
|
+
```
|
59
|
+
$ python
|
60
|
+
>>> from Tectonic_Utils.geodesy import haversine
|
61
|
+
```
|
62
|
+
|
63
|
+
## Documentation
|
64
|
+
The preliminary sphinx html docs can be found here: https://kmaterna.github.io/Tectonic_Utils/index.html
|
65
|
+
|
66
|
+
## Additional Thoughts
|
67
|
+
I wrote this library for my own research because (**in theory**)
|
68
|
+
putting all my Python utility functions
|
69
|
+
into one unit-tested repository reduces bugs, increases code reproducibility, and allows for faster experimentation.
|
70
|
+
The library is open source and available on Pip in case it would help others too.
|
71
|
+
|
72
|
+
Disclaimer: Completely bug-free code can never be guaranteed. As things come up, I occasionally fix and update the package on Pip/PyPI.
|
73
|
+
|
74
|
+
If you're using this package and you'd like to contribute or you find bugs, please let me know!
|
75
|
+
|
76
|
+
## References
|
77
|
+
|
78
|
+
* Aki, K., and P. G. Richards (1980), Quantitative Seismology: Theory and Methods, W. H. Freeman, New York.
|
79
|
+
* Fialko, Y., Simons, M., & Agnew, D. (2001). The complete (3-D) surface displacement field in the epicentral area of the 1999 Mw7.1 Hector Mine earthquake, California, from space geodetic observations. Geophysical Research Letters, 28(16), 3063–3066.
|
80
|
+
* Hanks, T., & Kanamori, H. (1979). A moment magnitude scale. Journal of Geophysical Research, 84(B5), 2348–2350.
|
81
|
+
* Wells, D. L., & Coppersmith, K. J. (1994). New Empirical Relationships among Magnitude, Rupture Length, Rupture Width, Rupture Area, and Surface Displacement. Bulletin of the Seismological Society of America, 84(4), 974–1002.
|
82
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
tectonic_utils/.DS_Store,sha256=kRqKlYZrl1RGaoPXapBlMI2wNLE1cqcvn4IknBT8D2Q,6148
|
2
|
+
tectonic_utils/__init__.py,sha256=KhFOyyd1QUbOdza1-ovPLepPkHPoNBYLX0axjvz2Aw4,68
|
3
|
+
tectonic_utils/cover_picture.png,sha256=SioKXhjLRmjUBbVKY-4saEEO3yUVDB06P50Hv8XpLJ8,1733968
|
4
|
+
tectonic_utils/geodesy/.DS_Store,sha256=oELC_Tpc4DH6jDWVlImUeFSN8EDmW2TsXrWR0300T5Y,6148
|
5
|
+
tectonic_utils/geodesy/.ruff_cache/.gitignore,sha256=aEiIwOuxfzdCmLZe4oB1JsBmCUxwG8x-u-HBCV9JT8E,1
|
6
|
+
tectonic_utils/geodesy/.ruff_cache/0.1.5/15663111236935520357,sha256=iRigcC_uE9RzPVJMM_H2-2XRweGq7TPZmatXT-J4Yhk,1014
|
7
|
+
tectonic_utils/geodesy/.ruff_cache/CACHEDIR.TAG,sha256=WVMVbX4MVkpCclExbq8m-IcOZIOuIZf5FrYw5Pk-Ma4,43
|
8
|
+
tectonic_utils/geodesy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
tectonic_utils/geodesy/datums.py,sha256=z_IAhNFMSz7avDt2WhxZnU5Y2SMjMrVdszO0BwYEbsM,11000
|
10
|
+
tectonic_utils/geodesy/euler_pole.py,sha256=0KNBnmHegL0ARA6uSySEZBtmzC3hfMUYjBoNrHAjGpk,6418
|
11
|
+
tectonic_utils/geodesy/fault_vector_functions.py,sha256=vAdIX2evtitrheyK4LWNIEx3BNskp3J0jvyYDgl40rM,12823
|
12
|
+
tectonic_utils/geodesy/haversine.py,sha256=aRoeztLfe8zFiNKupWN33AA9VrS5uU-ZAzQVQf5Oqao,6945
|
13
|
+
tectonic_utils/geodesy/insar_vector_functions.py,sha256=1MLy5J2W3jHjMbtyeuLL74HPLF8CW1ztIxHFaLXsWhc,11446
|
14
|
+
tectonic_utils/geodesy/linear_elastic.py,sha256=wdTB4m_nDbUCUPNlUxjTScfAjCxGIUqhN4wRhYNeqng,6476
|
15
|
+
tectonic_utils/geodesy/test/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
16
|
+
tectonic_utils/geodesy/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
tectonic_utils/geodesy/test/test_conversion_functions.py,sha256=TVrs3LCMQWPxRUMmvzKAB1f3-Oc40jZk9F4E7uZq28U,3709
|
18
|
+
tectonic_utils/geodesy/test/test_euler_poles.py,sha256=P4rNRnalbfnkCuXnyiuzHjMoqguA1k-2pMEyfch9hvE,1375
|
19
|
+
tectonic_utils/geodesy/test/test_insar_vector_functions.py,sha256=ChHB3dwC-cHpFuSBCxOII1KcoPVNVSIRCEY2ifWsK1o,1561
|
20
|
+
tectonic_utils/geodesy/utilities.py,sha256=538vb-4BCYVUWkwl9V5tKS9DnjJ3KQFjRMPtrKiDjbo,1163
|
21
|
+
tectonic_utils/geodesy/xyz2llh.py,sha256=oPDS7nWl7gJe6WD7DQqvKlrffV69avdpiy0epUwcjzE,8083
|
22
|
+
tectonic_utils/read_write/.DS_Store,sha256=SkDIyIgu4JN5DmqhlYPZoyLgbY4WmKMc6hw6usKijGk,6148
|
23
|
+
tectonic_utils/read_write/.ruff_cache/.gitignore,sha256=aEiIwOuxfzdCmLZe4oB1JsBmCUxwG8x-u-HBCV9JT8E,1
|
24
|
+
tectonic_utils/read_write/.ruff_cache/0.1.5/680373307893520726,sha256=M_jn9qQ1oFwhM09Msm3b_JM7m-TQnsoZ-hR3a17VfVU,177
|
25
|
+
tectonic_utils/read_write/.ruff_cache/CACHEDIR.TAG,sha256=WVMVbX4MVkpCclExbq8m-IcOZIOuIZf5FrYw5Pk-Ma4,43
|
26
|
+
tectonic_utils/read_write/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
+
tectonic_utils/read_write/general_io.py,sha256=HfXgGqePenAqLQ0WQJEmgxygKORy_9DR5TLlSak9Ezs,2036
|
28
|
+
tectonic_utils/read_write/netcdf_read_write.py,sha256=hFlyDNJFOPaQwihzi0heyW6XNUyLqTQK3MUKwx_MS-Q,14753
|
29
|
+
tectonic_utils/read_write/read_kml.py,sha256=G1wzrCPRljnvRja1dV6-Na6BHqjRLciST2Oh1jgqHK0,2300
|
30
|
+
tectonic_utils/read_write/test/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
31
|
+
tectonic_utils/read_write/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
|
+
tectonic_utils/read_write/test/example_grd.grd,sha256=tJD_Q6IqDMdi2SuN9f0Z70yKyLpUumgDtIqUM42G-48,60395
|
33
|
+
tectonic_utils/read_write/test/test_conversion_functions.py,sha256=4Li_lFOiXDFAQ0AvN7OsfuRbJS2V_jd_eNqyKh0B7ck,1512
|
34
|
+
tectonic_utils/read_write/test/written_example.grd,sha256=9Ium7MjpxFOvNnr00iYb78jN0n50aiGF26ynnVMrC9M,58986
|
35
|
+
tectonic_utils/seismo/.DS_Store,sha256=l3pS6MjdhXRwqDQMYSmLH9GgZ90rVhOAgOySNGfW8Nk,6148
|
36
|
+
tectonic_utils/seismo/.ruff_cache/.gitignore,sha256=aEiIwOuxfzdCmLZe4oB1JsBmCUxwG8x-u-HBCV9JT8E,1
|
37
|
+
tectonic_utils/seismo/.ruff_cache/0.1.5/12911000862714636977,sha256=y0tMlRMFpMQ44MESW-KBEqvl9vPYdp2UEvfBKMXvyW4,173
|
38
|
+
tectonic_utils/seismo/.ruff_cache/CACHEDIR.TAG,sha256=WVMVbX4MVkpCclExbq8m-IcOZIOuIZf5FrYw5Pk-Ma4,43
|
39
|
+
tectonic_utils/seismo/MT_calculations.py,sha256=ccd-DOVr4Vhj21WfWeicetmICOVOrST8rS0ow_GSt5w,4146
|
40
|
+
tectonic_utils/seismo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
|
+
tectonic_utils/seismo/moment_calculations.py,sha256=ihrBYwhvAPhfT-QZ6oM-lSktjZrnto6TC5N9plSQ9po,1146
|
42
|
+
tectonic_utils/seismo/second_focal_plane.py,sha256=8GTSkeBg6owHk5-KsE6LM0b1NhoPjtQyLXwLu1sDCJo,5436
|
43
|
+
tectonic_utils/seismo/test/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
44
|
+
tectonic_utils/seismo/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
|
+
tectonic_utils/seismo/test/test_WC.py,sha256=d7qNTPAPDKPu2bRlpS5f5pNwRfrN7ZbxKhBGuIu-ZuQ,544
|
46
|
+
tectonic_utils/seismo/test/test_second_focal_plane.py,sha256=bb5-wMkeLgZPXW5qpqXo4BMNIjKQdVP8ZlAnI_uw3QA,473
|
47
|
+
tectonic_utils/seismo/wells_and_coppersmith.py,sha256=NXbUVXDgifqTro-DeOXdFe6_eOQ82sVg6_rWvg0p-g0,6003
|
48
|
+
tectonic_utils-0.1.2.dist-info/LICENSE.md,sha256=BoWwOxP7snl4zEufDQFfftDiyZgYqGr09E7brqIs8M4,1072
|
49
|
+
tectonic_utils-0.1.2.dist-info/METADATA,sha256=j-vlc-aRZKbDMMTOfefURKVn4gUPTAINe52eDRLFTaQ,3524
|
50
|
+
tectonic_utils-0.1.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
51
|
+
tectonic_utils-0.1.2.dist-info/RECORD,,
|