apsg 1.3.4__py3-none-any.whl → 1.3.5__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.
- apsg/__init__.py +91 -31
- apsg/feature/__init__.py +24 -20
- apsg/feature/_container.py +148 -101
- apsg/feature/_geodata.py +65 -11
- apsg/feature/_tensor3.py +24 -0
- apsg/math/_matrix.py +1 -5
- {apsg-1.3.4.dist-info → apsg-1.3.5.dist-info}/METADATA +1 -1
- {apsg-1.3.4.dist-info → apsg-1.3.5.dist-info}/RECORD +12 -12
- {apsg-1.3.4.dist-info → apsg-1.3.5.dist-info}/WHEEL +0 -0
- {apsg-1.3.4.dist-info → apsg-1.3.5.dist-info}/entry_points.txt +0 -0
- {apsg-1.3.4.dist-info → apsg-1.3.5.dist-info}/licenses/LICENSE +0 -0
- {apsg-1.3.4.dist-info → apsg-1.3.5.dist-info}/top_level.txt +0 -0
apsg/__init__.py
CHANGED
|
@@ -1,56 +1,114 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
from apsg.math import (
|
|
4
|
-
Vector3 as vec,
|
|
5
|
-
Vector2 as vec2,
|
|
6
|
-
Matrix2 as matrix2,
|
|
7
|
-
Matrix3 as matrix,
|
|
8
|
-
)
|
|
9
3
|
from apsg.config import apsg_conf
|
|
10
4
|
from apsg.feature import (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Fault as fault,
|
|
5
|
+
ClusterSet as cluster,
|
|
6
|
+
)
|
|
7
|
+
from apsg.feature import (
|
|
15
8
|
Cone as cone,
|
|
16
9
|
)
|
|
17
10
|
from apsg.feature import (
|
|
18
|
-
Vector3Set as vecset,
|
|
19
|
-
Vector2Set as vec2set,
|
|
20
|
-
LineationSet as linset,
|
|
21
|
-
FoliationSet as folset,
|
|
22
|
-
PairSet as pairset,
|
|
23
|
-
FaultSet as faultset,
|
|
24
11
|
ConeSet as coneset,
|
|
12
|
+
)
|
|
13
|
+
from apsg.feature import (
|
|
14
|
+
DeformationGradient2 as defgrad2,
|
|
15
|
+
)
|
|
16
|
+
from apsg.feature import (
|
|
17
|
+
DeformationGradient3 as defgrad,
|
|
18
|
+
)
|
|
19
|
+
from apsg.feature import (
|
|
20
|
+
Direction as dir2,
|
|
21
|
+
)
|
|
22
|
+
from apsg.feature import (
|
|
23
|
+
Direction2Set as dir2set,
|
|
24
|
+
)
|
|
25
|
+
from apsg.feature import (
|
|
26
|
+
Ellipse as ellipse,
|
|
27
|
+
)
|
|
28
|
+
from apsg.feature import (
|
|
25
29
|
EllipseSet as ellipseset,
|
|
30
|
+
)
|
|
31
|
+
from apsg.feature import (
|
|
32
|
+
Ellipsoid as ellipsoid,
|
|
33
|
+
)
|
|
34
|
+
from apsg.feature import (
|
|
26
35
|
EllipsoidSet as ellipsoidset,
|
|
36
|
+
)
|
|
37
|
+
from apsg.feature import (
|
|
38
|
+
Fault as fault,
|
|
39
|
+
)
|
|
40
|
+
from apsg.feature import (
|
|
41
|
+
FaultSet as faultset,
|
|
42
|
+
)
|
|
43
|
+
from apsg.feature import (
|
|
44
|
+
Foliation as fol,
|
|
45
|
+
)
|
|
46
|
+
from apsg.feature import (
|
|
47
|
+
FoliationSet as folset,
|
|
48
|
+
)
|
|
49
|
+
from apsg.feature import G
|
|
50
|
+
from apsg.feature import (
|
|
51
|
+
Lineation as lin,
|
|
52
|
+
)
|
|
53
|
+
from apsg.feature import (
|
|
54
|
+
LineationSet as linset,
|
|
55
|
+
)
|
|
56
|
+
from apsg.feature import (
|
|
57
|
+
OrientationTensor2 as ortensor2,
|
|
58
|
+
)
|
|
59
|
+
from apsg.feature import (
|
|
27
60
|
OrientationTensor2Set as ortensor2set,
|
|
61
|
+
)
|
|
62
|
+
from apsg.feature import (
|
|
63
|
+
OrientationTensor3 as ortensor,
|
|
64
|
+
)
|
|
65
|
+
from apsg.feature import (
|
|
28
66
|
OrientationTensor3Set as ortensorset,
|
|
29
|
-
ClusterSet as cluster,
|
|
30
67
|
)
|
|
31
68
|
from apsg.feature import (
|
|
32
|
-
|
|
33
|
-
|
|
69
|
+
Pair as pair,
|
|
70
|
+
)
|
|
71
|
+
from apsg.feature import (
|
|
72
|
+
PairSet as pairset,
|
|
73
|
+
)
|
|
74
|
+
from apsg.feature import (
|
|
75
|
+
Stress2 as stress2,
|
|
76
|
+
)
|
|
77
|
+
from apsg.feature import (
|
|
34
78
|
Stress3 as stress,
|
|
35
|
-
Ellipsoid as ellipsoid,
|
|
36
|
-
OrientationTensor3 as ortensor,
|
|
37
79
|
)
|
|
38
80
|
from apsg.feature import (
|
|
39
|
-
|
|
81
|
+
Vector2Set as vec2set,
|
|
82
|
+
)
|
|
83
|
+
from apsg.feature import (
|
|
84
|
+
Vector3Set as vecset,
|
|
85
|
+
)
|
|
86
|
+
from apsg.feature import (
|
|
40
87
|
VelocityGradient2 as velgrad2,
|
|
41
|
-
Stress2 as stress2,
|
|
42
|
-
Ellipse as ellipse,
|
|
43
|
-
OrientationTensor2 as ortensor2,
|
|
44
88
|
)
|
|
45
|
-
from apsg.feature import
|
|
89
|
+
from apsg.feature import (
|
|
90
|
+
VelocityGradient3 as velgrad,
|
|
91
|
+
)
|
|
92
|
+
from apsg.math import (
|
|
93
|
+
Matrix2 as matrix2,
|
|
94
|
+
)
|
|
95
|
+
from apsg.math import (
|
|
96
|
+
Matrix3 as matrix,
|
|
97
|
+
)
|
|
98
|
+
from apsg.math import (
|
|
99
|
+
Vector2 as vec2,
|
|
100
|
+
)
|
|
101
|
+
from apsg.math import (
|
|
102
|
+
Vector3 as vec,
|
|
103
|
+
)
|
|
46
104
|
from apsg.plotting import (
|
|
105
|
+
FlinnPlot,
|
|
106
|
+
HsuPlot,
|
|
107
|
+
RamsayPlot,
|
|
108
|
+
RosePlot,
|
|
47
109
|
StereoGrid,
|
|
48
110
|
StereoNet,
|
|
49
|
-
RosePlot,
|
|
50
111
|
VollmerPlot,
|
|
51
|
-
RamsayPlot,
|
|
52
|
-
FlinnPlot,
|
|
53
|
-
HsuPlot,
|
|
54
112
|
quicknet,
|
|
55
113
|
)
|
|
56
114
|
|
|
@@ -60,6 +118,7 @@ __all__ = (
|
|
|
60
118
|
"vec2",
|
|
61
119
|
"matrix",
|
|
62
120
|
"matrix2",
|
|
121
|
+
"dir2",
|
|
63
122
|
"lin",
|
|
64
123
|
"fol",
|
|
65
124
|
"pair",
|
|
@@ -67,6 +126,7 @@ __all__ = (
|
|
|
67
126
|
"cone",
|
|
68
127
|
"vecset",
|
|
69
128
|
"vec2set",
|
|
129
|
+
"dir2set",
|
|
70
130
|
"linset",
|
|
71
131
|
"folset",
|
|
72
132
|
"pairset",
|
|
@@ -98,6 +158,6 @@ __all__ = (
|
|
|
98
158
|
"quicknet",
|
|
99
159
|
)
|
|
100
160
|
|
|
101
|
-
__version__ = "1.3.
|
|
161
|
+
__version__ = "1.3.5"
|
|
102
162
|
__author__ = "Ondrej Lexa"
|
|
103
163
|
__email__ = "lexa.ondrej@gmail.com"
|
apsg/feature/__init__.py
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import sys
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
from apsg.feature._container import (
|
|
5
|
-
|
|
6
|
-
Vector2Set,
|
|
7
|
-
Vector3Set,
|
|
8
|
-
LineationSet,
|
|
9
|
-
FoliationSet,
|
|
10
|
-
PairSet,
|
|
11
|
-
FaultSet,
|
|
5
|
+
ClusterSet,
|
|
12
6
|
ConeSet,
|
|
7
|
+
Direction2Set,
|
|
13
8
|
EllipseSet,
|
|
14
9
|
EllipsoidSet,
|
|
10
|
+
FaultSet,
|
|
11
|
+
FeatureSet,
|
|
12
|
+
FoliationSet,
|
|
13
|
+
G,
|
|
14
|
+
LineationSet,
|
|
15
15
|
OrientationTensor2Set,
|
|
16
16
|
OrientationTensor3Set,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
from apsg.feature._tensor3 import (
|
|
21
|
-
DeformationGradient3,
|
|
22
|
-
VelocityGradient3,
|
|
23
|
-
Stress3,
|
|
24
|
-
Ellipsoid,
|
|
25
|
-
OrientationTensor3,
|
|
17
|
+
PairSet,
|
|
18
|
+
Vector2Set,
|
|
19
|
+
Vector3Set,
|
|
26
20
|
)
|
|
21
|
+
from apsg.feature._geodata import Cone, Direction, Fault, Foliation, Lineation, Pair
|
|
22
|
+
from apsg.feature._paleomag import Core
|
|
27
23
|
from apsg.feature._tensor2 import (
|
|
28
24
|
DeformationGradient2,
|
|
29
|
-
VelocityGradient2,
|
|
30
|
-
Stress2,
|
|
31
25
|
Ellipse,
|
|
32
26
|
OrientationTensor2,
|
|
27
|
+
Stress2,
|
|
28
|
+
VelocityGradient2,
|
|
29
|
+
)
|
|
30
|
+
from apsg.feature._tensor3 import (
|
|
31
|
+
DeformationGradient3,
|
|
32
|
+
Ellipsoid,
|
|
33
|
+
OrientationTensor3,
|
|
34
|
+
Stress3,
|
|
35
|
+
VelocityGradient3,
|
|
33
36
|
)
|
|
34
|
-
from apsg.feature._paleomag import Core
|
|
35
37
|
|
|
36
38
|
__all__ = (
|
|
39
|
+
"Direction",
|
|
37
40
|
"Lineation",
|
|
38
41
|
"Foliation",
|
|
39
42
|
"Pair",
|
|
@@ -50,6 +53,7 @@ __all__ = (
|
|
|
50
53
|
"Ellipse",
|
|
51
54
|
"OrientationTensor2",
|
|
52
55
|
"Vector2Set",
|
|
56
|
+
"Direction2Set",
|
|
53
57
|
"FeatureSet",
|
|
54
58
|
"Vector3Set",
|
|
55
59
|
"LineationSet",
|
apsg/feature/_container.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import csv
|
|
2
2
|
from itertools import combinations
|
|
3
|
-
|
|
3
|
+
from os.path import basename
|
|
4
|
+
|
|
4
5
|
import matplotlib.pyplot as plt
|
|
6
|
+
import numpy as np
|
|
7
|
+
from scipy.cluster.hierarchy import dendrogram, fcluster, linkage
|
|
5
8
|
from scipy.stats import vonmises
|
|
6
|
-
from scipy.cluster.hierarchy import linkage, fcluster, dendrogram
|
|
7
9
|
|
|
8
10
|
from apsg.config import apsg_conf
|
|
9
|
-
from apsg.
|
|
10
|
-
from apsg.helpers._math import acosd
|
|
11
|
-
from apsg.feature._geodata import Lineation, Foliation, Pair, Fault, Cone
|
|
12
|
-
from apsg.feature._tensor3 import OrientationTensor3, Ellipsoid, DeformationGradient3
|
|
13
|
-
from apsg.feature._tensor2 import OrientationTensor2, Ellipse
|
|
11
|
+
from apsg.feature._geodata import Cone, Direction, Fault, Foliation, Lineation, Pair
|
|
14
12
|
from apsg.feature._statistics import KentDistribution, vonMisesFisher
|
|
13
|
+
from apsg.feature._tensor2 import Ellipse, OrientationTensor2
|
|
14
|
+
from apsg.feature._tensor3 import DeformationGradient3, Ellipsoid, OrientationTensor3
|
|
15
|
+
from apsg.helpers._math import acosd
|
|
16
|
+
from apsg.math._vector import Axial2, Axial3, Vector2, Vector3
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class FeatureSet:
|
|
@@ -22,12 +24,11 @@ class FeatureSet:
|
|
|
22
24
|
__slots__ = ("data", "name")
|
|
23
25
|
|
|
24
26
|
def __init__(self, data, name="Default"):
|
|
25
|
-
dtype_cls = getattr(sys.modules[__name__], type(self).__feature_type__)
|
|
26
27
|
assert all(
|
|
27
|
-
[isinstance(obj,
|
|
28
|
-
), f"Data must be instances of {
|
|
28
|
+
[isinstance(obj, self.__feature_class__) for obj in data]
|
|
29
|
+
), f"Data must be instances of {self.__feature_class__.__name__}"
|
|
29
30
|
# cast to correct instances
|
|
30
|
-
self.data = tuple([
|
|
31
|
+
self.data = tuple([self.__feature_class__(d) for d in data])
|
|
31
32
|
self.name = name
|
|
32
33
|
self._cache = {}
|
|
33
34
|
|
|
@@ -117,7 +118,7 @@ class Vector2Set(FeatureSet):
|
|
|
117
118
|
Class to store set of ``Vector2`` features
|
|
118
119
|
"""
|
|
119
120
|
|
|
120
|
-
|
|
121
|
+
__feature_class__ = Vector2
|
|
121
122
|
|
|
122
123
|
def __repr__(self):
|
|
123
124
|
return f"V2({len(self)}) {self.name}"
|
|
@@ -283,7 +284,6 @@ class Vector2Set(FeatureSet):
|
|
|
283
284
|
resultant.
|
|
284
285
|
|
|
285
286
|
"""
|
|
286
|
-
dtype_cls = getattr(sys.modules[__name__], type(self).__feature_type__)
|
|
287
287
|
v = Vector3Set(self)
|
|
288
288
|
v_data = list(v)
|
|
289
289
|
alldone = np.all(v.angle(v.R()) <= 90)
|
|
@@ -294,10 +294,10 @@ class Vector2Set(FeatureSet):
|
|
|
294
294
|
v_data[ix] = -v_data[ix]
|
|
295
295
|
v = Vector3Set(v_data)
|
|
296
296
|
alldone = np.all(v.angle(v.R()) <= 90)
|
|
297
|
-
return type(self)([
|
|
297
|
+
return type(self)([self.__feature_class__(vec) for vec in v], name=self.name)
|
|
298
298
|
|
|
299
299
|
@classmethod
|
|
300
|
-
def
|
|
300
|
+
def from_directions(cls, angles, name="Default"):
|
|
301
301
|
"""Create ``Vector2Set`` object from arrays of direction angles
|
|
302
302
|
|
|
303
303
|
Args:
|
|
@@ -309,8 +309,7 @@ class Vector2Set(FeatureSet):
|
|
|
309
309
|
Example:
|
|
310
310
|
>>> f = vec2set.from_angles([120,130,140,125, 132. 131])
|
|
311
311
|
"""
|
|
312
|
-
|
|
313
|
-
return cls([dtype_cls(a) for a in angles], name=name)
|
|
312
|
+
return cls([cls.__feature_class__(a) for a in angles], name=name)
|
|
314
313
|
|
|
315
314
|
@classmethod
|
|
316
315
|
def from_xy(cls, x, y, name="Default"):
|
|
@@ -327,8 +326,7 @@ class Vector2Set(FeatureSet):
|
|
|
327
326
|
>>> v = vec2set.from_xy([-0.4330127, -0.4330127, -0.66793414],
|
|
328
327
|
[0.75, 0.25, 0.60141061])
|
|
329
328
|
"""
|
|
330
|
-
|
|
331
|
-
return cls([dtype_cls(xx, yy) for xx, yy in zip(x, y)], name=name)
|
|
329
|
+
return cls([cls.__feature_class__(xx, yy) for xx, yy in zip(x, y)], name=name)
|
|
332
330
|
|
|
333
331
|
@classmethod
|
|
334
332
|
def random(cls, n=100, name="Default"):
|
|
@@ -344,8 +342,7 @@ class Vector2Set(FeatureSet):
|
|
|
344
342
|
>>> l = vec2set.random(100)
|
|
345
343
|
|
|
346
344
|
"""
|
|
347
|
-
|
|
348
|
-
return cls([dtype_cls.random() for i in range(n)], name=name)
|
|
345
|
+
return cls([cls.__feature_class__.random() for i in range(n)], name=name)
|
|
349
346
|
|
|
350
347
|
@classmethod
|
|
351
348
|
def random_vonmises(cls, n=100, position=0, kappa=5, name="Default"):
|
|
@@ -361,9 +358,19 @@ class Vector2Set(FeatureSet):
|
|
|
361
358
|
Example:
|
|
362
359
|
>>> l = linset.random_fisher(position=lin(120,50))
|
|
363
360
|
"""
|
|
364
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
365
361
|
angles = np.degrees(vonmises.rvs(kappa, loc=np.radians(position), size=n))
|
|
366
|
-
return cls([
|
|
362
|
+
return cls([cls.__feature_class__(a) for a in angles], name=name)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class Direction2Set(Vector2Set):
|
|
366
|
+
"""
|
|
367
|
+
Class to store set of ``Direction`` features
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
__feature_class__ = Direction
|
|
371
|
+
|
|
372
|
+
def __repr__(self):
|
|
373
|
+
return f"D2({len(self)}) {self.name}"
|
|
367
374
|
|
|
368
375
|
|
|
369
376
|
class Vector3Set(FeatureSet):
|
|
@@ -371,7 +378,7 @@ class Vector3Set(FeatureSet):
|
|
|
371
378
|
Class to store set of ``Vector3`` features
|
|
372
379
|
"""
|
|
373
380
|
|
|
374
|
-
|
|
381
|
+
__feature_class__ = Vector3
|
|
375
382
|
|
|
376
383
|
def __repr__(self):
|
|
377
384
|
return f"V3({len(self)}) {self.name}"
|
|
@@ -597,7 +604,6 @@ class Vector3Set(FeatureSet):
|
|
|
597
604
|
resultant.
|
|
598
605
|
|
|
599
606
|
"""
|
|
600
|
-
dtype_cls = getattr(sys.modules[__name__], type(self).__feature_type__)
|
|
601
607
|
v = Vector3Set(self)
|
|
602
608
|
v_data = list(v)
|
|
603
609
|
alldone = np.all(v.angle(v.R()) <= 90)
|
|
@@ -608,7 +614,7 @@ class Vector3Set(FeatureSet):
|
|
|
608
614
|
v_data[ix] = -v_data[ix]
|
|
609
615
|
v = Vector3Set(v_data)
|
|
610
616
|
alldone = np.all(v.angle(v.R()) <= 90)
|
|
611
|
-
return type(self)([
|
|
617
|
+
return type(self)([self.__feature_class__(vec) for vec in v], name=self.name)
|
|
612
618
|
|
|
613
619
|
@classmethod
|
|
614
620
|
def from_csv(cls, filename, acol=0, icol=1):
|
|
@@ -627,9 +633,6 @@ class Vector3Set(FeatureSet):
|
|
|
627
633
|
>>> gl = linset.from_csv('file2.csv', acol=1, icol=2) #doctest: +SKIP
|
|
628
634
|
|
|
629
635
|
"""
|
|
630
|
-
from os.path import basename
|
|
631
|
-
import csv
|
|
632
|
-
|
|
633
636
|
with open(filename) as csvfile:
|
|
634
637
|
has_header = csv.Sniffer().has_header(csvfile.read(1024))
|
|
635
638
|
csvfile.seek(0)
|
|
@@ -665,7 +668,6 @@ class Vector3Set(FeatureSet):
|
|
|
665
668
|
Note: Written values are rounded according to `ndigits` settings in apsg_conf
|
|
666
669
|
|
|
667
670
|
"""
|
|
668
|
-
import csv
|
|
669
671
|
|
|
670
672
|
n = apsg_conf["ndigits"]
|
|
671
673
|
|
|
@@ -692,8 +694,9 @@ class Vector3Set(FeatureSet):
|
|
|
692
694
|
>>> f = folset.from_array([120,130,140], [10,20,30])
|
|
693
695
|
>>> l = linset.from_array([120,130,140], [10,20,30])
|
|
694
696
|
"""
|
|
695
|
-
|
|
696
|
-
|
|
697
|
+
return cls(
|
|
698
|
+
[cls.__feature_class__(azi, inc) for azi, inc in zip(azis, incs)], name=name
|
|
699
|
+
)
|
|
697
700
|
|
|
698
701
|
@classmethod
|
|
699
702
|
def from_xyz(cls, x, y, z, name="Default"):
|
|
@@ -712,8 +715,10 @@ class Vector3Set(FeatureSet):
|
|
|
712
715
|
[0.75, 0.25, 0.60141061],
|
|
713
716
|
[0.5, 0.8660254, 0.43837115])
|
|
714
717
|
"""
|
|
715
|
-
|
|
716
|
-
|
|
718
|
+
return cls(
|
|
719
|
+
[cls.__feature_class__(xx, yy, zz) for xx, yy, zz in zip(x, y, z)],
|
|
720
|
+
name=name,
|
|
721
|
+
)
|
|
717
722
|
|
|
718
723
|
@classmethod
|
|
719
724
|
def random_normal(cls, n=100, position=Vector3(0, 0, 1), sigma=20, name="Default"):
|
|
@@ -733,7 +738,6 @@ class Vector3Set(FeatureSet):
|
|
|
733
738
|
|
|
734
739
|
"""
|
|
735
740
|
data = []
|
|
736
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
737
741
|
orig = Vector3(0, 0, 1)
|
|
738
742
|
ax = orig.cross(position)
|
|
739
743
|
ang = orig.angle(position)
|
|
@@ -742,7 +746,7 @@ class Vector3Set(FeatureSet):
|
|
|
742
746
|
np.random.normal(loc=0, scale=sigma, size=n),
|
|
743
747
|
):
|
|
744
748
|
v = orig.rotate(Vector3(s, 0), r).rotate(ax, ang)
|
|
745
|
-
data.append(
|
|
749
|
+
data.append(cls.__feature_class__(v))
|
|
746
750
|
return cls(data, name=name)
|
|
747
751
|
|
|
748
752
|
@classmethod
|
|
@@ -759,9 +763,8 @@ class Vector3Set(FeatureSet):
|
|
|
759
763
|
Example:
|
|
760
764
|
>>> l = linset.random_fisher(position=lin(120,50))
|
|
761
765
|
"""
|
|
762
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
763
766
|
dc = vonMisesFisher(position, kappa, n)
|
|
764
|
-
return cls([
|
|
767
|
+
return cls([cls.__feature_class__(d) for d in dc], name=name)
|
|
765
768
|
|
|
766
769
|
@classmethod
|
|
767
770
|
def random_fisher2(cls, n=100, position=Vector3(0, 0, 1), kappa=20, name="Default"):
|
|
@@ -807,11 +810,10 @@ class Vector3Set(FeatureSet):
|
|
|
807
810
|
>>> l = linset.random_kent(p, n=300, kappa=30)
|
|
808
811
|
"""
|
|
809
812
|
assert issubclass(type(p), Pair), "Argument must be Pair object."
|
|
810
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
811
813
|
if beta is None:
|
|
812
814
|
beta = kappa / 2
|
|
813
815
|
kd = KentDistribution(p.lvec, p.fvec.cross(p.lvec), p.fvec, kappa, beta)
|
|
814
|
-
return cls([
|
|
816
|
+
return cls([cls.__feature_class__(d) for d in kd.rvs(n)], name=name)
|
|
815
817
|
|
|
816
818
|
@classmethod
|
|
817
819
|
def uniform_sfs(cls, n=100, name="Default"):
|
|
@@ -830,14 +832,13 @@ class Vector3Set(FeatureSet):
|
|
|
830
832
|
>>> v.ortensor().eigenvalues()
|
|
831
833
|
(0.3334645347163635, 0.33333474915201167, 0.33320071613162483)
|
|
832
834
|
"""
|
|
833
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
834
835
|
phi = (1 + np.sqrt(5)) / 2
|
|
835
836
|
i2 = 2 * np.arange(n) - n + 1
|
|
836
837
|
theta = 2 * np.pi * i2 / phi
|
|
837
838
|
sp = i2 / n
|
|
838
839
|
cp = np.sqrt((n + i2) * (n - i2)) / n
|
|
839
840
|
dc = np.array([cp * np.sin(theta), cp * np.cos(theta), sp]).T
|
|
840
|
-
return cls([
|
|
841
|
+
return cls([cls.__feature_class__(d) for d in dc], name=name)
|
|
841
842
|
|
|
842
843
|
@classmethod
|
|
843
844
|
def uniform_gss(cls, n=100, name="Default"):
|
|
@@ -855,7 +856,6 @@ class Vector3Set(FeatureSet):
|
|
|
855
856
|
>>> v.ortensor().eigenvalues()
|
|
856
857
|
(0.33335688569571587, 0.33332315115436933, 0.33331996314991513)
|
|
857
858
|
"""
|
|
858
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
859
859
|
inc = np.pi * (3 - np.sqrt(5))
|
|
860
860
|
off = 2 / n
|
|
861
861
|
k = np.arange(n)
|
|
@@ -863,7 +863,7 @@ class Vector3Set(FeatureSet):
|
|
|
863
863
|
r = np.sqrt(1 - y * y)
|
|
864
864
|
phi = k * inc
|
|
865
865
|
dc = np.array([np.cos(phi) * r, y, np.sin(phi) * r]).T
|
|
866
|
-
return cls([
|
|
866
|
+
return cls([cls.__feature_class__(d) for d in dc], name=name)
|
|
867
867
|
|
|
868
868
|
|
|
869
869
|
class LineationSet(Vector3Set):
|
|
@@ -871,7 +871,7 @@ class LineationSet(Vector3Set):
|
|
|
871
871
|
Class to store set of ``Lineation`` features
|
|
872
872
|
"""
|
|
873
873
|
|
|
874
|
-
|
|
874
|
+
__feature_class__ = Lineation
|
|
875
875
|
|
|
876
876
|
def __repr__(self):
|
|
877
877
|
return f"L({len(self)}) {self.name}"
|
|
@@ -882,7 +882,7 @@ class FoliationSet(Vector3Set):
|
|
|
882
882
|
Class to store set of ``Foliation`` features
|
|
883
883
|
"""
|
|
884
884
|
|
|
885
|
-
|
|
885
|
+
__feature_class__ = Foliation
|
|
886
886
|
|
|
887
887
|
def __repr__(self):
|
|
888
888
|
return f"S({len(self)}) {self.name}"
|
|
@@ -897,7 +897,7 @@ class PairSet(FeatureSet):
|
|
|
897
897
|
Class to store set of ``Pair`` features
|
|
898
898
|
"""
|
|
899
899
|
|
|
900
|
-
|
|
900
|
+
__feature_class__ = Pair
|
|
901
901
|
|
|
902
902
|
def __repr__(self):
|
|
903
903
|
return f"P({len(self)}) {self.name}"
|
|
@@ -995,9 +995,6 @@ class PairSet(FeatureSet):
|
|
|
995
995
|
def from_csv(cls, filename, delimiter=",", facol=0, ficol=1, lacol=2, licol=3):
|
|
996
996
|
"""Read ``PairSet`` from csv file"""
|
|
997
997
|
|
|
998
|
-
from os.path import basename
|
|
999
|
-
import csv
|
|
1000
|
-
|
|
1001
998
|
with open(filename) as csvfile:
|
|
1002
999
|
has_header = csv.Sniffer().has_header(csvfile.read(1024))
|
|
1003
1000
|
csvfile.seek(0)
|
|
@@ -1063,7 +1060,6 @@ class PairSet(FeatureSet):
|
|
|
1063
1060
|
Note: Written values are rounded according to `ndigits` settings in apsg_conf
|
|
1064
1061
|
|
|
1065
1062
|
"""
|
|
1066
|
-
import csv
|
|
1067
1063
|
|
|
1068
1064
|
n = apsg_conf["ndigits"]
|
|
1069
1065
|
|
|
@@ -1095,10 +1091,9 @@ class PairSet(FeatureSet):
|
|
|
1095
1091
|
name: name of ``PairSet`` object. Default is 'Default'
|
|
1096
1092
|
"""
|
|
1097
1093
|
|
|
1098
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
1099
1094
|
return cls(
|
|
1100
1095
|
[
|
|
1101
|
-
|
|
1096
|
+
cls.__feature_class__(fazi, finc, lazi, linc)
|
|
1102
1097
|
for fazi, finc, lazi, linc in zip(fazis, fincs, lazis, lincs)
|
|
1103
1098
|
],
|
|
1104
1099
|
name=name,
|
|
@@ -1110,7 +1105,7 @@ class FaultSet(PairSet):
|
|
|
1110
1105
|
Class to store set of ``Fault`` features
|
|
1111
1106
|
"""
|
|
1112
1107
|
|
|
1113
|
-
|
|
1108
|
+
__feature_class__ = Fault
|
|
1114
1109
|
|
|
1115
1110
|
def __repr__(self):
|
|
1116
1111
|
return f"F({len(self)}) {self.name}"
|
|
@@ -1120,6 +1115,11 @@ class FaultSet(PairSet):
|
|
|
1120
1115
|
"""Return array of sense values"""
|
|
1121
1116
|
return np.array([f.sense for f in self])
|
|
1122
1117
|
|
|
1118
|
+
@property
|
|
1119
|
+
def sense_str(self):
|
|
1120
|
+
"""Return array of sense characters"""
|
|
1121
|
+
return np.array([f.sense_str for f in self])
|
|
1122
|
+
|
|
1123
1123
|
@property
|
|
1124
1124
|
def p_vector(self, ptangle=90):
|
|
1125
1125
|
"""Return p-axes of FaultSet as Vector3Set"""
|
|
@@ -1196,13 +1196,18 @@ class FaultSet(PairSet):
|
|
|
1196
1196
|
|
|
1197
1197
|
@classmethod
|
|
1198
1198
|
def from_csv(
|
|
1199
|
-
cls,
|
|
1199
|
+
cls,
|
|
1200
|
+
filename,
|
|
1201
|
+
delimiter=",",
|
|
1202
|
+
sense_str=False,
|
|
1203
|
+
facol=0,
|
|
1204
|
+
ficol=1,
|
|
1205
|
+
lacol=2,
|
|
1206
|
+
licol=3,
|
|
1207
|
+
scol=4,
|
|
1200
1208
|
):
|
|
1201
1209
|
"""Read ``FaultSet`` from csv file"""
|
|
1202
1210
|
|
|
1203
|
-
from os.path import basename
|
|
1204
|
-
import csv
|
|
1205
|
-
|
|
1206
1211
|
with open(filename) as csvfile:
|
|
1207
1212
|
has_header = csv.Sniffer().has_header(csvfile.read(1024))
|
|
1208
1213
|
csvfile.seek(0)
|
|
@@ -1220,48 +1225,73 @@ class FaultSet(PairSet):
|
|
|
1220
1225
|
faname, finame = reader.fieldnames[facol], reader.fieldnames[ficol]
|
|
1221
1226
|
laname, liname = reader.fieldnames[lacol], reader.fieldnames[licol]
|
|
1222
1227
|
sname = reader.fieldnames[scol]
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1228
|
+
if sense_str:
|
|
1229
|
+
r = [
|
|
1230
|
+
(
|
|
1231
|
+
float(row[faname]),
|
|
1232
|
+
float(row[finame]),
|
|
1233
|
+
float(row[laname]),
|
|
1234
|
+
float(row[liname]),
|
|
1235
|
+
row[sname],
|
|
1236
|
+
)
|
|
1237
|
+
for row in reader
|
|
1238
|
+
]
|
|
1239
|
+
else:
|
|
1240
|
+
r = [
|
|
1241
|
+
(
|
|
1242
|
+
float(row[faname]),
|
|
1243
|
+
float(row[finame]),
|
|
1244
|
+
float(row[laname]),
|
|
1245
|
+
float(row[liname]),
|
|
1246
|
+
int(row[sname]),
|
|
1247
|
+
)
|
|
1248
|
+
for row in reader
|
|
1249
|
+
]
|
|
1233
1250
|
else:
|
|
1234
1251
|
reader = csv.reader(csvfile, dialect=dialect)
|
|
1252
|
+
|
|
1235
1253
|
r = [
|
|
1236
1254
|
(
|
|
1237
1255
|
float(row[facol]),
|
|
1238
1256
|
float(row[ficol]),
|
|
1239
1257
|
float(row[lacol]),
|
|
1240
1258
|
float(row[licol]),
|
|
1241
|
-
|
|
1259
|
+
row[scol],
|
|
1242
1260
|
)
|
|
1243
1261
|
for row in reader
|
|
1244
1262
|
]
|
|
1245
1263
|
else:
|
|
1246
1264
|
if has_header:
|
|
1247
1265
|
reader = csv.DictReader(csvfile, dialect=dialect)
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1266
|
+
if sense_str:
|
|
1267
|
+
r = [
|
|
1268
|
+
(
|
|
1269
|
+
float(row[facol]),
|
|
1270
|
+
float(row[ficol]),
|
|
1271
|
+
float(row[lacol]),
|
|
1272
|
+
float(row[licol]),
|
|
1273
|
+
row[scol],
|
|
1274
|
+
)
|
|
1275
|
+
for row in reader
|
|
1276
|
+
]
|
|
1277
|
+
else:
|
|
1278
|
+
r = [
|
|
1279
|
+
(
|
|
1280
|
+
float(row[facol]),
|
|
1281
|
+
float(row[ficol]),
|
|
1282
|
+
float(row[lacol]),
|
|
1283
|
+
float(row[licol]),
|
|
1284
|
+
int(row[scol]),
|
|
1285
|
+
)
|
|
1286
|
+
for row in reader
|
|
1287
|
+
]
|
|
1258
1288
|
else:
|
|
1259
1289
|
raise ValueError("No header line in CSV file...")
|
|
1260
1290
|
|
|
1261
1291
|
fazi, finc, lazi, linc, sense = zip(*r)
|
|
1262
1292
|
return cls.from_array(fazi, finc, lazi, linc, sense, name=basename(filename))
|
|
1263
1293
|
|
|
1264
|
-
def to_csv(self, filename, delimiter=","):
|
|
1294
|
+
def to_csv(self, filename, delimiter=",", sense_str=False):
|
|
1265
1295
|
"""Save ``FaultSet`` object to csv file
|
|
1266
1296
|
|
|
1267
1297
|
Args:
|
|
@@ -1269,11 +1299,11 @@ class FaultSet(PairSet):
|
|
|
1269
1299
|
|
|
1270
1300
|
Keyword Args:
|
|
1271
1301
|
delimiter (str): values delimiter. Default ','
|
|
1302
|
+
sense_str (bool): save sense as N, R, S or D. Default False
|
|
1272
1303
|
|
|
1273
1304
|
Note: Written values are rounded according to `ndigits` settings in apsg_conf
|
|
1274
1305
|
|
|
1275
1306
|
"""
|
|
1276
|
-
import csv
|
|
1277
1307
|
|
|
1278
1308
|
n = apsg_conf["ndigits"]
|
|
1279
1309
|
|
|
@@ -1284,19 +1314,30 @@ class FaultSet(PairSet):
|
|
|
1284
1314
|
for dt in self:
|
|
1285
1315
|
fazi, finc = dt.fol.geo
|
|
1286
1316
|
lazi, linc = dt.lin.geo
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1317
|
+
if sense_str:
|
|
1318
|
+
writer.writerow(
|
|
1319
|
+
{
|
|
1320
|
+
"fazi": round(fazi, n),
|
|
1321
|
+
"finc": round(finc, n),
|
|
1322
|
+
"lazi": round(lazi, n),
|
|
1323
|
+
"linc": round(linc, n),
|
|
1324
|
+
"sense": dt.sense_str,
|
|
1325
|
+
}
|
|
1326
|
+
)
|
|
1327
|
+
else:
|
|
1328
|
+
writer.writerow(
|
|
1329
|
+
{
|
|
1330
|
+
"fazi": round(fazi, n),
|
|
1331
|
+
"finc": round(finc, n),
|
|
1332
|
+
"lazi": round(lazi, n),
|
|
1333
|
+
"linc": round(linc, n),
|
|
1334
|
+
"sense": dt.sense,
|
|
1335
|
+
}
|
|
1336
|
+
)
|
|
1296
1337
|
|
|
1297
1338
|
@classmethod
|
|
1298
1339
|
def from_array(cls, fazis, fincs, lazis, lincs, senses, name="Default"):
|
|
1299
|
-
"""Create ``
|
|
1340
|
+
"""Create ``FaultSet`` from arrays of azimuths, inclinations and senses
|
|
1300
1341
|
|
|
1301
1342
|
Args:
|
|
1302
1343
|
azis: list or array of azimuths
|
|
@@ -1306,10 +1347,9 @@ class FaultSet(PairSet):
|
|
|
1306
1347
|
name: name of ``PairSet`` object. Default is 'Default'
|
|
1307
1348
|
"""
|
|
1308
1349
|
|
|
1309
|
-
dtype_cls = getattr(sys.modules[__name__], cls.__feature_type__)
|
|
1310
1350
|
return cls(
|
|
1311
1351
|
[
|
|
1312
|
-
|
|
1352
|
+
cls.__feature_class__(fazi, finc, lazi, linc, sense)
|
|
1313
1353
|
for fazi, finc, lazi, linc, sense in zip(
|
|
1314
1354
|
fazis, fincs, lazis, lincs, senses
|
|
1315
1355
|
)
|
|
@@ -1323,7 +1363,7 @@ class ConeSet(FeatureSet):
|
|
|
1323
1363
|
Class to store set of ``Cone`` features
|
|
1324
1364
|
"""
|
|
1325
1365
|
|
|
1326
|
-
|
|
1366
|
+
__feature_class__ = Cone
|
|
1327
1367
|
|
|
1328
1368
|
def __repr__(self):
|
|
1329
1369
|
return f"C({len(self)}) {self.name}"
|
|
@@ -1334,7 +1374,7 @@ class EllipseSet(FeatureSet):
|
|
|
1334
1374
|
Class to store set of ``Ellipse`` features
|
|
1335
1375
|
"""
|
|
1336
1376
|
|
|
1337
|
-
|
|
1377
|
+
__feature_class__ = Ellipse
|
|
1338
1378
|
|
|
1339
1379
|
@property
|
|
1340
1380
|
def S1(self) -> np.ndarray:
|
|
@@ -1391,7 +1431,7 @@ class OrientationTensor2Set(EllipseSet):
|
|
|
1391
1431
|
Class to store set of ``OrientationTensor2`` features
|
|
1392
1432
|
"""
|
|
1393
1433
|
|
|
1394
|
-
|
|
1434
|
+
__feature_class__ = OrientationTensor2
|
|
1395
1435
|
|
|
1396
1436
|
|
|
1397
1437
|
class EllipsoidSet(FeatureSet):
|
|
@@ -1399,7 +1439,7 @@ class EllipsoidSet(FeatureSet):
|
|
|
1399
1439
|
Class to store set of ``Ellipsoid`` features
|
|
1400
1440
|
"""
|
|
1401
1441
|
|
|
1402
|
-
|
|
1442
|
+
__feature_class__ = Ellipsoid
|
|
1403
1443
|
|
|
1404
1444
|
@property
|
|
1405
1445
|
def strength(self) -> np.ndarray:
|
|
@@ -1633,7 +1673,7 @@ class OrientationTensor3Set(EllipsoidSet):
|
|
|
1633
1673
|
Class to store set of ``OrientationTensor3`` features
|
|
1634
1674
|
"""
|
|
1635
1675
|
|
|
1636
|
-
|
|
1676
|
+
__feature_class__ = OrientationTensor3
|
|
1637
1677
|
|
|
1638
1678
|
|
|
1639
1679
|
class ClusterSet(object):
|
|
@@ -1660,7 +1700,7 @@ class ClusterSet(object):
|
|
|
1660
1700
|
isinstance(d, Vector2Set)
|
|
1661
1701
|
or isinstance(d, Vector3Set)
|
|
1662
1702
|
or isinstance(d, PairSet)
|
|
1663
|
-
), "Only vec2set
|
|
1703
|
+
), "Only vec2set, vecset and pairset could be clustered"
|
|
1664
1704
|
self.data = d.copy()
|
|
1665
1705
|
self.maxclust = kwargs.get("maxclust", 2)
|
|
1666
1706
|
self.angle = kwargs.get("angle", None)
|
|
@@ -1712,7 +1752,10 @@ class ClusterSet(object):
|
|
|
1712
1752
|
"""
|
|
1713
1753
|
|
|
1714
1754
|
self.method = kwargs.get("method", self.method)
|
|
1715
|
-
|
|
1755
|
+
if issubclass(self.__feature_class__, (Axial2, Axial3)):
|
|
1756
|
+
self.Z = linkage(self.pdist, method=self.method, metric=angle_metric_axial)
|
|
1757
|
+
else:
|
|
1758
|
+
self.Z = linkage(self.pdist, method=self.method, metric=angle_metric)
|
|
1716
1759
|
|
|
1717
1760
|
def dendrogram(self, **kwargs):
|
|
1718
1761
|
"""Show dendrogram
|
|
@@ -1805,4 +1848,8 @@ def G(lst, name="Default"):
|
|
|
1805
1848
|
|
|
1806
1849
|
|
|
1807
1850
|
def angle_metric(u, v):
|
|
1851
|
+
return np.degrees(np.arccos(np.dot(u, v)))
|
|
1852
|
+
|
|
1853
|
+
|
|
1854
|
+
def angle_metric_axial(u, v):
|
|
1808
1855
|
return np.degrees(np.arccos(np.abs(np.dot(u, v))))
|
apsg/feature/_geodata.py
CHANGED
|
@@ -1,15 +1,50 @@
|
|
|
1
1
|
import warnings
|
|
2
|
+
|
|
2
3
|
import numpy as np
|
|
3
4
|
|
|
5
|
+
from apsg.decorator._decorator import ensure_arguments, ensure_first_arg_same
|
|
4
6
|
from apsg.helpers._notation import (
|
|
5
7
|
geo2vec_planar,
|
|
6
|
-
vec2geo_planar,
|
|
7
|
-
vec2geo_planar_signed,
|
|
8
8
|
vec2geo_linear,
|
|
9
9
|
vec2geo_linear_signed,
|
|
10
|
+
vec2geo_planar,
|
|
11
|
+
vec2geo_planar_signed,
|
|
10
12
|
)
|
|
11
|
-
from apsg.
|
|
12
|
-
|
|
13
|
+
from apsg.math._vector import Axial2, Axial3, Vector3
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Direction(Axial2):
|
|
17
|
+
"""
|
|
18
|
+
A class to represent axial (non-oriented) 2D linear feature (direction).
|
|
19
|
+
|
|
20
|
+
There are different way to create ``Direction`` object:
|
|
21
|
+
|
|
22
|
+
- without arguments create default ``Direction`` D:0
|
|
23
|
+
- with single argument `d`, where:
|
|
24
|
+
|
|
25
|
+
- `d` could be Vector2-like object
|
|
26
|
+
- `d` could be string 'x' or 'y' - principal axes of coordinate system
|
|
27
|
+
- `d` could be tuple of (x, y) - vector components
|
|
28
|
+
- with 1 argument direction
|
|
29
|
+
- with 2 numerical arguments defining vector components
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
direction (float): plunge direction of linear feature in degrees
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
>>> dir2()
|
|
36
|
+
>>> dir2('y')
|
|
37
|
+
>>> dir2(45)
|
|
38
|
+
>>> d = dir2(1, -1)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __repr__(self):
|
|
42
|
+
return f"D:{self.direction:.0f}"
|
|
43
|
+
|
|
44
|
+
def to_json(self):
|
|
45
|
+
"""Return as JSON dict"""
|
|
46
|
+
azi, inc = vec2geo_linear_signed(self)
|
|
47
|
+
return {"datatype": type(self).__name__, "args": (azi, inc)}
|
|
13
48
|
|
|
14
49
|
|
|
15
50
|
class Lineation(Axial3):
|
|
@@ -446,15 +481,15 @@ class Fault(Pair):
|
|
|
446
481
|
elif isinstance(sense, str):
|
|
447
482
|
p = Pair(fvec, lvec)
|
|
448
483
|
if sense.lower() == "s":
|
|
449
|
-
if p.rax
|
|
450
|
-
res = -1
|
|
451
|
-
else:
|
|
452
|
-
res = 1
|
|
453
|
-
elif sense.lower() == "d":
|
|
454
|
-
if p.rax == p.rax.lower():
|
|
484
|
+
if p.rax.is_upper():
|
|
455
485
|
res = 1
|
|
456
486
|
else:
|
|
457
487
|
res = -1
|
|
488
|
+
elif sense.lower() == "d":
|
|
489
|
+
if p.rax.is_upper():
|
|
490
|
+
res = -1
|
|
491
|
+
else:
|
|
492
|
+
res = 1
|
|
458
493
|
elif sense.lower() == "n":
|
|
459
494
|
res = 1
|
|
460
495
|
elif sense.lower() == "r":
|
|
@@ -464,7 +499,8 @@ class Fault(Pair):
|
|
|
464
499
|
def __repr__(self):
|
|
465
500
|
fazi, finc = self.fol.geo
|
|
466
501
|
lazi, linc = self.lin.geo
|
|
467
|
-
schar =
|
|
502
|
+
schar = self.sense_str
|
|
503
|
+
# schar = [" ", "+", "-"][self.sense]
|
|
468
504
|
return f"F:{fazi:.0f}/{finc:.0f}-{lazi:.0f}/{linc:.0f} {schar}"
|
|
469
505
|
|
|
470
506
|
@ensure_first_arg_same
|
|
@@ -519,6 +555,24 @@ class Fault(Pair):
|
|
|
519
555
|
else:
|
|
520
556
|
return -1
|
|
521
557
|
|
|
558
|
+
@property
|
|
559
|
+
def sense_str(self):
|
|
560
|
+
if abs(self.rax.geo[1]) > 75:
|
|
561
|
+
if self.rax.z > 0:
|
|
562
|
+
schar = "D"
|
|
563
|
+
elif self.rax.z < 0:
|
|
564
|
+
schar = "S"
|
|
565
|
+
else:
|
|
566
|
+
schar = " "
|
|
567
|
+
else:
|
|
568
|
+
if self.sense < 0:
|
|
569
|
+
schar = "R"
|
|
570
|
+
elif self.sense > 0:
|
|
571
|
+
schar = "N"
|
|
572
|
+
else:
|
|
573
|
+
schar = " "
|
|
574
|
+
return schar
|
|
575
|
+
|
|
522
576
|
def p_vector(self, ptangle=90):
|
|
523
577
|
"""Return P axis as ``Vector3``"""
|
|
524
578
|
return self.fvec.rotate(self.lvec.cross(self.fvec), -ptangle / 2)
|
apsg/feature/_tensor3.py
CHANGED
|
@@ -440,6 +440,30 @@ class Stress3(Tensor3):
|
|
|
440
440
|
|
|
441
441
|
return cls([[xx, xy, xz], [xy, yy, yz], [xz, yz, zz]])
|
|
442
442
|
|
|
443
|
+
@classmethod
|
|
444
|
+
def from_ratio(cls, r=0.5, mag=1):
|
|
445
|
+
"""
|
|
446
|
+
Return ``Stress`` tensor with given shape ration.
|
|
447
|
+
|
|
448
|
+
Keyword Args:
|
|
449
|
+
r (float): shape ratio between 0 and 1. Default 0.5
|
|
450
|
+
mag (float): magnitude of differential stress. Default 1.
|
|
451
|
+
|
|
452
|
+
Example:
|
|
453
|
+
>>> S = stress.from_ratio(r=0.25, mag=10)
|
|
454
|
+
>>> S
|
|
455
|
+
Stress3
|
|
456
|
+
[[-5. 0. 0. ]
|
|
457
|
+
[ 0. -2.5 0. ]
|
|
458
|
+
[ 0. 0. 5. ]]
|
|
459
|
+
|
|
460
|
+
"""
|
|
461
|
+
|
|
462
|
+
xx = -mag / 2
|
|
463
|
+
yy = xx + r * mag
|
|
464
|
+
zz = mag / 2
|
|
465
|
+
return cls([[xx, 0, 0], [0, yy, 0], [0, 0, zz]])
|
|
466
|
+
|
|
443
467
|
@property
|
|
444
468
|
def mean_stress(self):
|
|
445
469
|
"""
|
apsg/math/_matrix.py
CHANGED
|
@@ -4,10 +4,6 @@ from apsg.config import apsg_conf
|
|
|
4
4
|
from apsg.decorator._decorator import ensure_first_arg_same
|
|
5
5
|
from apsg.math._vector import Vector3, Vector2
|
|
6
6
|
|
|
7
|
-
"""
|
|
8
|
-
TO BE ADDED
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
7
|
|
|
12
8
|
class Matrix:
|
|
13
9
|
"""Base class for Matrix2 and Matrix3"""
|
|
@@ -128,7 +124,7 @@ class Matrix:
|
|
|
128
124
|
return self._coefs[1][1]
|
|
129
125
|
|
|
130
126
|
@property
|
|
131
|
-
def I(self):
|
|
127
|
+
def I(self): # noqa: E743
|
|
132
128
|
return type(self)(np.linalg.inv(self))
|
|
133
129
|
|
|
134
130
|
@property
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
apsg/__init__.py,sha256
|
|
1
|
+
apsg/__init__.py,sha256=4i4ax3NRSxmyaPTssR_c_6j17kFU7CAbEfW02aeXjwc,2849
|
|
2
2
|
apsg/config.py,sha256=X3_yXT96xXlVxFA94EfYFKJbrcGIHT0PvB9s8EKmYOg,4569
|
|
3
3
|
apsg/shell.py,sha256=1D0PeB7qXzlpiOf2QYGo6OJlEVN1KJPYld1GEREBiFg,707
|
|
4
4
|
apsg/database/__init__.py,sha256=7Rvcf1KBBBNhoM28ZlvQ01CkScQTroFkoS4d1kD55Ws,315
|
|
@@ -6,19 +6,19 @@ apsg/database/_alchemy.py,sha256=geV3Q6ZLdGvjzxry7GTHHIQq6t_ccsUxZvuv13CLYFQ,194
|
|
|
6
6
|
apsg/database/_sdbread.py,sha256=EP0hSp6_4-DZZptkMNDgKnQ3GD58mpr_SAgFohKu6xQ,11017
|
|
7
7
|
apsg/decorator/__init__.py,sha256=fZ-dxpldQIk6-2JhVnCj-Tsl8bz2nvoGOyG7uXKvBfg,160
|
|
8
8
|
apsg/decorator/_decorator.py,sha256=8TMSrcVvhU5UCbNMrnyrW3-65qo20_6N2ShtXd3bP-k,1194
|
|
9
|
-
apsg/feature/__init__.py,sha256=
|
|
10
|
-
apsg/feature/_container.py,sha256=
|
|
11
|
-
apsg/feature/_geodata.py,sha256=
|
|
9
|
+
apsg/feature/__init__.py,sha256=XkyS-X8lUaXCVaXgoK0GETmTCCGqB1BmSwZRZG3blZQ,1733
|
|
10
|
+
apsg/feature/_container.py,sha256=Rx7rEO1DQB-dUDXIbJJlig-Ly0ler25eYLRK5uKd3aY,60443
|
|
11
|
+
apsg/feature/_geodata.py,sha256=tjgPSKXyEOXiAN3iPeHpm8kpj__jI4ahtTpDuWhQNBE,24008
|
|
12
12
|
apsg/feature/_paleomag.py,sha256=WIICUOEJGGFHbCDF0gbW7lMt10jI0el0UVhkbMH7XAs,14911
|
|
13
13
|
apsg/feature/_statistics.py,sha256=WwBU2D7SyIHMpWnO7WFqbIpSkz6KUCT9xkG8oVzgskQ,13916
|
|
14
14
|
apsg/feature/_tensor2.py,sha256=XzGuSU46RkeVHQu3pqKzgzf0cYZCgbs9eP_yfYa82SU,13451
|
|
15
|
-
apsg/feature/_tensor3.py,sha256=
|
|
15
|
+
apsg/feature/_tensor3.py,sha256=uRC-Vi3HFNwOM33wg5r5N8JUwOeKC64PyRV5J9QbSTk,30329
|
|
16
16
|
apsg/helpers/__init__.py,sha256=6SF_Srq6fS-uomvpwdW0JSQs-tmWnzUoTk4a1K_J1aE,532
|
|
17
17
|
apsg/helpers/_helper.py,sha256=1Xf1yiNYIEoUJqXH4C0390osGWk6AERr_LrCSTnsRVw,146
|
|
18
18
|
apsg/helpers/_math.py,sha256=NLHw9UGiSlNggwZB-o0ORpG2sY00qIcbMbDJftRWFE8,896
|
|
19
19
|
apsg/helpers/_notation.py,sha256=oSxvZdv06eJ5GotS2IwbAJ-8UTZ49z8slqdhUDQJ9e8,2486
|
|
20
20
|
apsg/math/__init__.py,sha256=qJa4JP79nXn-6Xb7aaZUPWmz0qadmC4F0tGORTOZDVI,211
|
|
21
|
-
apsg/math/_matrix.py,sha256=
|
|
21
|
+
apsg/math/_matrix.py,sha256=4LcafIEdpnJ0yoeoD1bypfeyyVPeDDzSbQKKlF5nerg,10411
|
|
22
22
|
apsg/math/_vector.py,sha256=mD8kYggfGys-XWtnE90X2ZcTGBtDN49wEAUXQYXj3dI,16587
|
|
23
23
|
apsg/pandas/__init__.py,sha256=jmlsulHmH9IbErJgSWlJx1J33-v--O5zxSE4kdt6fUI,456
|
|
24
24
|
apsg/pandas/_pandas_api.py,sha256=MKV7MIhPIeSMH8ryjC858F3MjyB47cA_bAKtlKbFlNc,13576
|
|
@@ -30,9 +30,9 @@ apsg/plotting/_projection.py,sha256=ix67PwOU2WGjryEcsHlVIMpcVC9yxy45ycOV9k5x_Q8,
|
|
|
30
30
|
apsg/plotting/_roseplot.py,sha256=jbaUXSb3DIcXs0pWAQUTZfdlA2XcbquT0yHLYDjLirQ,12808
|
|
31
31
|
apsg/plotting/_stereogrid.py,sha256=awh7MwN1WgszhOlr6UgR20wHQJ8u778-Tf_w1uflrV4,11869
|
|
32
32
|
apsg/plotting/_stereonet.py,sha256=uHJXluFMkeaI4yzD9pGc4DIlgjZA01INySLKtUHLAlU,36624
|
|
33
|
-
apsg-1.3.
|
|
34
|
-
apsg-1.3.
|
|
35
|
-
apsg-1.3.
|
|
36
|
-
apsg-1.3.
|
|
37
|
-
apsg-1.3.
|
|
38
|
-
apsg-1.3.
|
|
33
|
+
apsg-1.3.5.dist-info/licenses/LICENSE,sha256=lY0kfpVRrzcgVZq7pI6rLK5WYiUMWe0bdKpDelN6hk8,1120
|
|
34
|
+
apsg-1.3.5.dist-info/METADATA,sha256=9Y4Y2Ixu8KOY_UgxJ_3l4m4sL726P8eRRjlmMbW7PoE,8298
|
|
35
|
+
apsg-1.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
36
|
+
apsg-1.3.5.dist-info/entry_points.txt,sha256=SowP7_uRI0NJuzznKBXyM9BJcSwBxbXo6Iz5LUo9mEQ,42
|
|
37
|
+
apsg-1.3.5.dist-info/top_level.txt,sha256=xWxwi0nqqOyKdmpsszfR-bmqnNpgVbhnLRuIKGJnaUM,5
|
|
38
|
+
apsg-1.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|