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.
Files changed (51) hide show
  1. tectonic_utils/.DS_Store +0 -0
  2. tectonic_utils/__init__.py +3 -0
  3. tectonic_utils/cover_picture.png +0 -0
  4. tectonic_utils/geodesy/.DS_Store +0 -0
  5. tectonic_utils/geodesy/.ruff_cache/.gitignore +1 -0
  6. tectonic_utils/geodesy/.ruff_cache/0.1.5/15663111236935520357 +0 -0
  7. tectonic_utils/geodesy/.ruff_cache/CACHEDIR.TAG +1 -0
  8. tectonic_utils/geodesy/__init__.py +0 -0
  9. tectonic_utils/geodesy/datums.py +156 -0
  10. tectonic_utils/geodesy/euler_pole.py +170 -0
  11. tectonic_utils/geodesy/fault_vector_functions.py +383 -0
  12. tectonic_utils/geodesy/haversine.py +193 -0
  13. tectonic_utils/geodesy/insar_vector_functions.py +285 -0
  14. tectonic_utils/geodesy/linear_elastic.py +231 -0
  15. tectonic_utils/geodesy/test/.DS_Store +0 -0
  16. tectonic_utils/geodesy/test/__init__.py +0 -0
  17. tectonic_utils/geodesy/test/test_conversion_functions.py +74 -0
  18. tectonic_utils/geodesy/test/test_euler_poles.py +33 -0
  19. tectonic_utils/geodesy/test/test_insar_vector_functions.py +36 -0
  20. tectonic_utils/geodesy/utilities.py +47 -0
  21. tectonic_utils/geodesy/xyz2llh.py +220 -0
  22. tectonic_utils/read_write/.DS_Store +0 -0
  23. tectonic_utils/read_write/.ruff_cache/.gitignore +1 -0
  24. tectonic_utils/read_write/.ruff_cache/0.1.5/680373307893520726 +0 -0
  25. tectonic_utils/read_write/.ruff_cache/CACHEDIR.TAG +1 -0
  26. tectonic_utils/read_write/__init__.py +0 -0
  27. tectonic_utils/read_write/general_io.py +55 -0
  28. tectonic_utils/read_write/netcdf_read_write.py +382 -0
  29. tectonic_utils/read_write/read_kml.py +68 -0
  30. tectonic_utils/read_write/test/.DS_Store +0 -0
  31. tectonic_utils/read_write/test/__init__.py +0 -0
  32. tectonic_utils/read_write/test/example_grd.grd +0 -0
  33. tectonic_utils/read_write/test/test_conversion_functions.py +40 -0
  34. tectonic_utils/read_write/test/written_example.grd +0 -0
  35. tectonic_utils/seismo/.DS_Store +0 -0
  36. tectonic_utils/seismo/.ruff_cache/.gitignore +1 -0
  37. tectonic_utils/seismo/.ruff_cache/0.1.5/12911000862714636977 +0 -0
  38. tectonic_utils/seismo/.ruff_cache/CACHEDIR.TAG +1 -0
  39. tectonic_utils/seismo/MT_calculations.py +132 -0
  40. tectonic_utils/seismo/__init__.py +0 -0
  41. tectonic_utils/seismo/moment_calculations.py +44 -0
  42. tectonic_utils/seismo/second_focal_plane.py +138 -0
  43. tectonic_utils/seismo/test/.DS_Store +0 -0
  44. tectonic_utils/seismo/test/__init__.py +0 -0
  45. tectonic_utils/seismo/test/test_WC.py +19 -0
  46. tectonic_utils/seismo/test/test_second_focal_plane.py +16 -0
  47. tectonic_utils/seismo/wells_and_coppersmith.py +167 -0
  48. tectonic_utils-0.1.2.dist-info/LICENSE.md +21 -0
  49. tectonic_utils-0.1.2.dist-info/METADATA +82 -0
  50. tectonic_utils-0.1.2.dist-info/RECORD +51 -0
  51. 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
+ ![cover](https://github.com/kmaterna/Tectonic_Utils/blob/master/Tectonic_Utils/cover_picture.png)
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,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.8.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any