apsg 1.3.5__tar.gz → 1.3.7__tar.gz
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-1.3.5/src/apsg.egg-info → apsg-1.3.7}/PKG-INFO +2 -8
- {apsg-1.3.5 → apsg-1.3.7}/pyproject.toml +1 -10
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/__init__.py +1 -1
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/config.py +0 -1
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/database/_sdbread.py +1 -1
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/_container.py +39 -1
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_roseplot.py +36 -35
- {apsg-1.3.5 → apsg-1.3.7/src/apsg.egg-info}/PKG-INFO +2 -8
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg.egg-info/requires.txt +1 -7
- {apsg-1.3.5 → apsg-1.3.7}/LICENSE +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/README.md +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/setup.cfg +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/database/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/database/_alchemy.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/decorator/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/decorator/_decorator.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/_geodata.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/_paleomag.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/_statistics.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/_tensor2.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/feature/_tensor3.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/helpers/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/helpers/_helper.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/helpers/_math.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/helpers/_notation.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/math/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/math/_matrix.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/math/_vector.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/pandas/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/pandas/_pandas_api.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/__init__.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_fabricplot.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_paleomagplots.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_plot_artists.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_projection.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_stereogrid.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/plotting/_stereonet.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg/shell.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg.egg-info/SOURCES.txt +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg.egg-info/dependency_links.txt +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg.egg-info/entry_points.txt +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/src/apsg.egg-info/top_level.txt +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/tests/test_apsg.py +0 -0
- {apsg-1.3.5 → apsg-1.3.7}/tests/test_tensors.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apsg
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.7
|
|
4
4
|
Summary: APSG - The package for structural geologists
|
|
5
5
|
Author-email: Ondrej Lexa <lexa.ondrej@gmail.com>
|
|
6
6
|
Maintainer-email: Ondrej Lexa <lexa.ondrej@gmail.com>
|
|
@@ -59,14 +59,8 @@ Requires-Dist: ipykernel; extra == "docs"
|
|
|
59
59
|
Requires-Dist: nbsphinx; extra == "docs"
|
|
60
60
|
Requires-Dist: autodocsumm; extra == "docs"
|
|
61
61
|
Provides-Extra: dev
|
|
62
|
-
Requires-Dist:
|
|
62
|
+
Requires-Dist: apsg[docs,extra,tests]; extra == "dev"
|
|
63
63
|
Requires-Dist: black; extra == "dev"
|
|
64
|
-
Requires-Dist: sphinx; extra == "dev"
|
|
65
|
-
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
|
66
|
-
Requires-Dist: readthedocs-sphinx-search; extra == "dev"
|
|
67
|
-
Requires-Dist: ipykernel; extra == "dev"
|
|
68
|
-
Requires-Dist: nbsphinx; extra == "dev"
|
|
69
|
-
Requires-Dist: autodocsumm; extra == "dev"
|
|
70
64
|
Dynamic: license-file
|
|
71
65
|
|
|
72
66
|
<img src="https://ondrolexa.github.io/apsg/apsg_banner.svg" alt="APSG logo" width="300px"/>
|
|
@@ -28,16 +28,7 @@ docs = [
|
|
|
28
28
|
"nbsphinx",
|
|
29
29
|
"autodocsumm",
|
|
30
30
|
]
|
|
31
|
-
dev = [
|
|
32
|
-
"pytest",
|
|
33
|
-
"black",
|
|
34
|
-
"sphinx",
|
|
35
|
-
"sphinx_rtd_theme",
|
|
36
|
-
"readthedocs-sphinx-search",
|
|
37
|
-
"ipykernel",
|
|
38
|
-
"nbsphinx",
|
|
39
|
-
"autodocsumm",
|
|
40
|
-
]
|
|
31
|
+
dev = ["apsg[extra,tests,docs]", "black"]
|
|
41
32
|
|
|
42
33
|
[project.urls]
|
|
43
34
|
Homepage = "https://github.com/ondrolexa/apsg"
|
|
@@ -142,6 +142,14 @@ class Vector2Set(FeatureSet):
|
|
|
142
142
|
"""Return array of direction angles"""
|
|
143
143
|
return np.asarray([e.direction for e in self]).T
|
|
144
144
|
|
|
145
|
+
def to_vec2(self):
|
|
146
|
+
"""Return ``Vector2Set`` object with all data converted to ``Vector2``."""
|
|
147
|
+
return Vector2Set([Vector2(e) for e in self], name=self.name)
|
|
148
|
+
|
|
149
|
+
def to_dir2(self):
|
|
150
|
+
"""Return ``Direction2Set`` object with all data converted to ``Direction``."""
|
|
151
|
+
return Direction2Set([Direction(e) for e in self], name=self.name)
|
|
152
|
+
|
|
145
153
|
def proj(self, vec):
|
|
146
154
|
"""Return projections of all features in ``Vector2Set`` onto vector."""
|
|
147
155
|
return type(self)([e.project() for e in self], name=self.name)
|
|
@@ -1376,6 +1384,9 @@ class EllipseSet(FeatureSet):
|
|
|
1376
1384
|
|
|
1377
1385
|
__feature_class__ = Ellipse
|
|
1378
1386
|
|
|
1387
|
+
def __repr__(self):
|
|
1388
|
+
return f"E2({len(self)}) {self.name}"
|
|
1389
|
+
|
|
1379
1390
|
@property
|
|
1380
1391
|
def S1(self) -> np.ndarray:
|
|
1381
1392
|
"""
|
|
@@ -1425,6 +1436,15 @@ class EllipseSet(FeatureSet):
|
|
|
1425
1436
|
"""
|
|
1426
1437
|
return np.array([e.e12 for e in self])
|
|
1427
1438
|
|
|
1439
|
+
def transform(self, F):
|
|
1440
|
+
"""Return transformation of all features ``EllipseSet`` by matrix 'F'.
|
|
1441
|
+
|
|
1442
|
+
Args:
|
|
1443
|
+
F: Transformation matrix. Array-like value e.g. ``DeformationGradient3``
|
|
1444
|
+
|
|
1445
|
+
"""
|
|
1446
|
+
return type(self)([e.transform(F) for e in self], name=self.name)
|
|
1447
|
+
|
|
1428
1448
|
|
|
1429
1449
|
class OrientationTensor2Set(EllipseSet):
|
|
1430
1450
|
"""
|
|
@@ -1433,6 +1453,9 @@ class OrientationTensor2Set(EllipseSet):
|
|
|
1433
1453
|
|
|
1434
1454
|
__feature_class__ = OrientationTensor2
|
|
1435
1455
|
|
|
1456
|
+
def __repr__(self):
|
|
1457
|
+
return f"M2({len(self)}) {self.name}"
|
|
1458
|
+
|
|
1436
1459
|
|
|
1437
1460
|
class EllipsoidSet(FeatureSet):
|
|
1438
1461
|
"""
|
|
@@ -1441,6 +1464,9 @@ class EllipsoidSet(FeatureSet):
|
|
|
1441
1464
|
|
|
1442
1465
|
__feature_class__ = Ellipsoid
|
|
1443
1466
|
|
|
1467
|
+
def __repr__(self):
|
|
1468
|
+
return f"E({len(self)}) {self.name}"
|
|
1469
|
+
|
|
1444
1470
|
@property
|
|
1445
1471
|
def strength(self) -> np.ndarray:
|
|
1446
1472
|
"""
|
|
@@ -1667,6 +1693,15 @@ class EllipsoidSet(FeatureSet):
|
|
|
1667
1693
|
"""
|
|
1668
1694
|
return np.array([e.MAD for e in self])
|
|
1669
1695
|
|
|
1696
|
+
def transform(self, F):
|
|
1697
|
+
"""Return transformation of all features ``EllipsoidSet`` by matrix 'F'.
|
|
1698
|
+
|
|
1699
|
+
Args:
|
|
1700
|
+
F: Transformation matrix. Array-like value e.g. ``DeformationGradient3``
|
|
1701
|
+
|
|
1702
|
+
"""
|
|
1703
|
+
return type(self)([e.transform(F) for e in self], name=self.name)
|
|
1704
|
+
|
|
1670
1705
|
|
|
1671
1706
|
class OrientationTensor3Set(EllipsoidSet):
|
|
1672
1707
|
"""
|
|
@@ -1675,6 +1710,9 @@ class OrientationTensor3Set(EllipsoidSet):
|
|
|
1675
1710
|
|
|
1676
1711
|
__feature_class__ = OrientationTensor3
|
|
1677
1712
|
|
|
1713
|
+
def __repr__(self):
|
|
1714
|
+
return f"M({len(self)}) {self.name}"
|
|
1715
|
+
|
|
1678
1716
|
|
|
1679
1717
|
class ClusterSet(object):
|
|
1680
1718
|
"""
|
|
@@ -1752,7 +1790,7 @@ class ClusterSet(object):
|
|
|
1752
1790
|
"""
|
|
1753
1791
|
|
|
1754
1792
|
self.method = kwargs.get("method", self.method)
|
|
1755
|
-
if issubclass(self.__feature_class__, (Axial2, Axial3)):
|
|
1793
|
+
if issubclass(self.data.__feature_class__, (Axial2, Axial3)):
|
|
1756
1794
|
self.Z = linkage(self.pdist, method=self.method, metric=angle_metric_axial)
|
|
1757
1795
|
else:
|
|
1758
1796
|
self.Z = linkage(self.pdist, method=self.method, metric=angle_metric)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import pickle
|
|
2
2
|
|
|
3
|
-
import numpy as np
|
|
4
3
|
import matplotlib.pyplot as plt
|
|
5
|
-
|
|
4
|
+
import numpy as np
|
|
5
|
+
from scipy.stats import circmean, vonmises
|
|
6
6
|
|
|
7
7
|
from apsg.config import apsg_conf
|
|
8
|
-
from apsg.plotting._plot_artists import RosePlotArtistFactory
|
|
9
8
|
from apsg.feature import feature_from_json
|
|
9
|
+
from apsg.math._vector import Axial2, Axial3
|
|
10
|
+
from apsg.plotting._plot_artists import RosePlotArtistFactory
|
|
10
11
|
|
|
11
12
|
__all__ = ["RosePlot"]
|
|
12
13
|
|
|
@@ -20,7 +21,6 @@ class RosePlot(object):
|
|
|
20
21
|
title_kws (dict): dictionary of keyword arguments passed to matplotlib suptitle
|
|
21
22
|
method.
|
|
22
23
|
bins (int): Number of bins. Default 36
|
|
23
|
-
axial (bool): Directional data are axial. Defaut True
|
|
24
24
|
density (bool): Use density instead of counts. Default False
|
|
25
25
|
pdf (bool): Plot Von Mises density function instead histogram. Default False
|
|
26
26
|
pdf_res (int): Resolution of pdf. Default 901
|
|
@@ -245,7 +245,7 @@ class RosePlot(object):
|
|
|
245
245
|
width = 2 * np.pi / self._kwargs["bins"]
|
|
246
246
|
legend = kwargs.pop("legend")
|
|
247
247
|
for arg in args:
|
|
248
|
-
if
|
|
248
|
+
if issubclass(arg.__feature_class__, (Axial2, Axial3)):
|
|
249
249
|
ang = np.concatenate((arg.direction % 360, (arg.direction + 180) % 360))
|
|
250
250
|
weights = np.concatenate((abs(arg), abs(arg)))
|
|
251
251
|
else:
|
|
@@ -279,7 +279,7 @@ class RosePlot(object):
|
|
|
279
279
|
ang = arg.direction % 360
|
|
280
280
|
# weights = abs(arg)
|
|
281
281
|
radii = np.zeros_like(theta)
|
|
282
|
-
if
|
|
282
|
+
if issubclass(arg.__feature_class__, (Axial2, Axial3)):
|
|
283
283
|
for a in ang:
|
|
284
284
|
radii += (
|
|
285
285
|
vonmises.pdf(theta, self._kwargs["kappa"], loc=np.radians(a))
|
|
@@ -308,32 +308,21 @@ class RosePlot(object):
|
|
|
308
308
|
bottom = bottom + radii
|
|
309
309
|
|
|
310
310
|
def _muci(self, *args, **kwargs):
|
|
311
|
-
ang = np.radians(np.concatenate([arg.direction for arg in args]))
|
|
312
311
|
conflevel = kwargs.pop("confidence_level")
|
|
313
312
|
n_resamples = kwargs.pop("n_resamples")
|
|
314
|
-
# calculate mean and CI
|
|
315
|
-
if self._kwargs["axial"]:
|
|
316
|
-
mu = circmean(2 * ang) / 2
|
|
317
|
-
ang_shift = ang + np.pi / 2 - mu
|
|
318
|
-
bsmu = [
|
|
319
|
-
circmean(np.random.choice(2 * ang_shift, size=len(ang_shift)))
|
|
320
|
-
for i in range(n_resamples)
|
|
321
|
-
]
|
|
322
|
-
low = np.percentile(bsmu, 100 - conflevel) / 2 + mu - np.pi / 2
|
|
323
|
-
high = np.percentile(bsmu, conflevel) / 2 + mu - np.pi / 2
|
|
324
|
-
else:
|
|
325
|
-
mu = circmean(ang)
|
|
326
|
-
ang_shift = ang + np.pi - mu
|
|
327
|
-
bsmu = [
|
|
328
|
-
circmean(np.random.choice(ang_shift, size=len(ang_shift)))
|
|
329
|
-
for i in range(n_resamples)
|
|
330
|
-
]
|
|
331
|
-
low = np.percentile(bsmu, (100 - conflevel) / 2) + mu - np.pi
|
|
332
|
-
high = np.percentile(bsmu, 100 - (100 - conflevel) / 2) + mu - np.pi
|
|
333
|
-
radii = []
|
|
334
313
|
for arg in args:
|
|
314
|
+
radii = []
|
|
335
315
|
p = 0
|
|
336
|
-
|
|
316
|
+
ang = np.radians(arg.direction)
|
|
317
|
+
if issubclass(arg.__feature_class__, (Axial2, Axial3)):
|
|
318
|
+
mu = circmean(2 * ang) / 2
|
|
319
|
+
ang_shift = ang + np.pi / 2 - mu
|
|
320
|
+
bsmu = [
|
|
321
|
+
circmean(np.random.choice(2 * ang_shift, size=len(ang_shift)))
|
|
322
|
+
for i in range(n_resamples)
|
|
323
|
+
]
|
|
324
|
+
low = np.percentile(bsmu, 100 - conflevel) / 2 + mu - np.pi / 2
|
|
325
|
+
high = np.percentile(bsmu, conflevel) / 2 + mu - np.pi / 2
|
|
337
326
|
for a in arg.direction:
|
|
338
327
|
p += vonmises.pdf(mu, self._kwargs["kappa"], loc=np.radians(a)) / 2
|
|
339
328
|
p += (
|
|
@@ -341,16 +330,28 @@ class RosePlot(object):
|
|
|
341
330
|
/ 2
|
|
342
331
|
)
|
|
343
332
|
else:
|
|
333
|
+
mu = circmean(ang)
|
|
334
|
+
ang_shift = ang + np.pi - mu
|
|
335
|
+
bsmu = [
|
|
336
|
+
circmean(np.random.choice(ang_shift, size=len(ang_shift)))
|
|
337
|
+
for i in range(n_resamples)
|
|
338
|
+
]
|
|
339
|
+
low = np.percentile(bsmu, (100 - conflevel) / 2) + mu - np.pi
|
|
340
|
+
high = np.percentile(bsmu, 100 - (100 - conflevel) / 2) + mu - np.pi
|
|
344
341
|
for a in arg.direction:
|
|
345
342
|
p += vonmises.pdf(mu, self._kwargs["kappa"], loc=np.radians(a))
|
|
346
343
|
radii.append(p / len(arg))
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
344
|
+
if self._kwargs["scaled"]:
|
|
345
|
+
radii = np.sqrt(radii)
|
|
346
|
+
mur = 1.1 * sum(radii)
|
|
347
|
+
ci_angles = np.linspace(low, high, int(5 * np.degrees(high - low)))
|
|
348
|
+
if issubclass(arg.__feature_class__, (Axial2, Axial3)):
|
|
349
|
+
self.ax.plot([mu, mu + np.pi], [mur, mur], **kwargs)
|
|
350
|
+
self.ax.plot(ci_angles, mur * np.ones_like(ci_angles), **kwargs)
|
|
351
|
+
self.ax.plot(ci_angles + np.pi, mur * np.ones_like(ci_angles), **kwargs)
|
|
352
|
+
else:
|
|
353
|
+
self.ax.plot([0, mu], [0, mur], **kwargs)
|
|
354
|
+
self.ax.plot(ci_angles, mur * np.ones_like(ci_angles), **kwargs)
|
|
354
355
|
|
|
355
356
|
|
|
356
357
|
def roseartist_from_json(obj_json):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apsg
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.7
|
|
4
4
|
Summary: APSG - The package for structural geologists
|
|
5
5
|
Author-email: Ondrej Lexa <lexa.ondrej@gmail.com>
|
|
6
6
|
Maintainer-email: Ondrej Lexa <lexa.ondrej@gmail.com>
|
|
@@ -59,14 +59,8 @@ Requires-Dist: ipykernel; extra == "docs"
|
|
|
59
59
|
Requires-Dist: nbsphinx; extra == "docs"
|
|
60
60
|
Requires-Dist: autodocsumm; extra == "docs"
|
|
61
61
|
Provides-Extra: dev
|
|
62
|
-
Requires-Dist:
|
|
62
|
+
Requires-Dist: apsg[docs,extra,tests]; extra == "dev"
|
|
63
63
|
Requires-Dist: black; extra == "dev"
|
|
64
|
-
Requires-Dist: sphinx; extra == "dev"
|
|
65
|
-
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
|
66
|
-
Requires-Dist: readthedocs-sphinx-search; extra == "dev"
|
|
67
|
-
Requires-Dist: ipykernel; extra == "dev"
|
|
68
|
-
Requires-Dist: nbsphinx; extra == "dev"
|
|
69
|
-
Requires-Dist: autodocsumm; extra == "dev"
|
|
70
64
|
Dynamic: license-file
|
|
71
65
|
|
|
72
66
|
<img src="https://ondrolexa.github.io/apsg/apsg_banner.svg" alt="APSG logo" width="300px"/>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|