APSG tutorial - Part 1
APSG defines several new python classes to easily manage, analyze and visualize orientation structural geology data. There are several classes to work with orientation data, namely Vector3
for vectorial data and Lineation
, Foliation
for axial data
Basic usage
APSG module could be imported either into own name space or into active one for easier interactive work.
[1]:
from apsg import *
Basic operations with vectors in 2D and 3D
Instance of vector object Vector3
could be created by passing 3 arguments correspondig to 3 components to function vec
:
[2]:
u = vec(1, -2, 3)
v = vec(-2, 1, 1)
Alternative ways to create vector is to pass single iterable object as list, tuple or array, or to provide geological orientation according to APSG notation (default is direction of dip and dip angle for planar and trend and plunge for linear features)
[3]:
coords = (-2, 2, 3)
a = vec(coords)
b = vec(120, 60)
print(a, b)
Vector3(-2, 2, 3) Vector3(-0.25, 0.433, 0.866)
The instance of 2D vector Vector2
could be created passing 2 arguments correspondig to 2 components or single iterable with components to function vec2
:
[4]:
k = vec2(1, 1)
coords = (-1, 2)
l = vec2(coords)
print(k, l)
Vector2(1, 1) Vector2(-1, 2)
Alternatively, single argument is interpreted as direction in degrees (0-top, 90-right, 180-down, 270-left)
[5]:
m = 5 * vec2(120)
m
[5]:
Vector2(-2.5, 4.33)
For common vector operation we can use standard mathematical operators or special methods using dot notation
[6]:
u + v
[6]:
Vector3(-1, -1, 4)
[7]:
u - v
[7]:
Vector3(3, -3, 2)
[8]:
3*u - 2*v
[8]:
Vector3(7, -8, 7)
Its magnitude or length is most commonly defined as its Euclidean norm and could be calculated using abs
[9]:
abs(v)
[9]:
2.449489742783178
[10]:
abs(u + v)
[10]:
4.242640687119285
For dot product we can use dot
method or operator @
[11]:
u.dot(v)
[11]:
-1
[12]:
u @ v
[12]:
-1.0
For cross product we can method cross
[13]:
u.cross(v)
[13]:
Vector3(-5, -7, -3)
To project vector u
onto vector v
we can use method proj
[14]:
u.proj(v)
[14]:
Vector3(0.333, -0.167, -0.167)
To find angle (in degrees) between to vectors we use method angle
[15]:
u.angle(v)
[15]:
96.26395271992722
Method rotate
provide possibility to rotate vector around another vector. For example, to rotate vector u
around vector v
for 45°
[16]:
u.rotate(v, 45)
[16]:
Vector3(2.248, 0.558, 2.939)
Classes Lineation and Foliation
To work with orientation data in structural geology, APSG provide two classes, Foliation
class to represent planar features and Lineation
class to represent linear features. Both classes support all Vector3
methods and operators, but it should be noted, that dot
and angle
respect their axial nature, i.e. angle between two lineations cant’t be bigger than 90 degrees.
To create instance of Lineation
or Foliation
, we can use functions lin
and fol
. Arguments have similar syntax to vec3
.
[17]:
lin(120, 60), fol(216, 62)
[17]:
(L:120/60, S:216/62)
We can also cast Vector3
instance to Foliation
or Lineation
[18]:
lin(u), fol(u)
[18]:
(L:297/53, S:117/37)
Vector methods for Lineation and Foliation
To find angle between two linear or planar features we can use method angle
[19]:
l1 = lin(110, 40)
l2 = lin(160, 30)
l1.angle(l2)
[19]:
41.59741268003547
[20]:
p1 = fol(330, 50)
p2 = fol(250, 40)
p1.angle(p2)
[20]:
54.69639932197533
We can use cross product to construct planar feature defined by two linear features
[21]:
l1.cross(l2)
[21]:
S:113/40
or to construct linear feature defined by intersection of two planar features
[22]:
p1.cross(p2)
[22]:
L:278/36
Cross product of planar and linear features could be used to construct plane defined by linear feature and normal of planar feature
[23]:
l2.cross(p2)
[23]:
S:96/53
or to find perpendicular linear feature on given plane
[24]:
p2.cross(l2)
[24]:
L:276/37
To rotate structural features we can use method rotate
[25]:
p2.rotate(l2, 45)
[25]:
S:269/78
Classes Pair and Fault
To work with paired orientation data like foliations and lineations or fault data in structural geology, APSG provide two base Pair
class and derived Fault
class. Both classes are instantiated providing dip direction and dip of planar and linear measurements, which are automatically orthogonalized. If misfit is too high, warning is raised. The Fault
class expects one more argument providing sense of movement information, either 1 or -1 for normal/reverse movement.
To create instance of Pair
, we have to pass two arguments for planar and two argumets for linear features following geological notation to function pair
:
[26]:
p = pair(120, 40, 162, 28)
p
[26]:
P:118/39-163/30
[27]:
p.misfit
[27]:
3.5623168411508175
Planar and linear features are accessible using fol
and lin
properties
[28]:
p.fol, p.lin
[28]:
(S:118/39, L:163/30)
To rotate Pair
instance we can use rotate
method
[29]:
p.rotate(lin(45, 10), 60)
[29]:
P:314/83-237/61
Instantiation of Fault
class is similar, we just have to provide argument to define sense of movement
[30]:
f = fault(120, 60, 110, 58, 1) # 1 for normal fault
f
[30]:
F:120/59-110/59 +
Note the change in sense of movement after Fault
rotation
[31]:
f.rotate(lin(45, 10), 60)
[31]:
F:312/62-340/59 -
For simple fault analyses Fault
class also provide p
, t
, m
and d
properties to get PT-axes, kinematic plane and dihedra separation plane
[32]:
f.p, f.t, f.m, f.d
[32]:
(L:315/75, L:116/14, S:27/85, S:290/31)
Class Cone
General feature type to store small or great circles as cone. It could be defined by axis
, secant
and revolving angle
or by axis
and apical angle
The revolving angle is by default 360° defining full cone. For segments of small circles, the revolving angle
could be different.
[33]:
c = cone(lin(140, 50), lin(140, 75))
c
[33]:
C:140/50 [25]
To create small circle segment, you can provide revolving angle
[34]:
c = cone(lin(90, 70), lin(45,30), 115)
The tips of small circle segments could be obtained from cone property secant
and rotated_secant
[35]:
lin(c.secant), lin(c.rotated_secant)
[35]:
(L:45/30, L:137/30)
To define cone using apical angle
, use axis
amd number arguments. Note, that revolving angle
is 360 by default
[36]:
c = cone(lin(140, 50), 25)
c
[36]:
C:140/50 [25]
[37]:
c.revangle
[37]:
360.0
Feature sets
APSG provide several classes to process, analyze and visualize the sets of data. There are e.g. vecset
, linset
and folset
classes to store group of vec
, lin
and fol
objects. All these feature sets are created from homogeneous list of data with optional name
atribute.
[38]:
v = vecset([vec(120,60), vec(116,50), vec(132,45), vec(90,60), vec(84,52)], name='Vectors')
v
[38]:
V3(5) Vectors
[39]:
l = linset([lin(120,60), lin(116,50), lin(132,45), lin(90,60), lin(84,52)], name='Lineations')
l
[39]:
L(5) Lineations
[40]:
f = folset([fol(120,60), fol(116,50), fol(132,45), fol(90,60), fol(84,52)], name='Foliations')
f
[40]:
S(5) Foliations
To simplify interactive group creation, you can use function G
[41]:
g = G([lin(120,60), lin(116,50), lin(132,45), lin(90,60), lin(84,52)], name='L1')
g
[41]:
L(5) L1
Method len
returns number of features in group
[42]:
len(v)
[42]:
5
Most of the vec
, lin
and fol
methods could be used for feature sets as well. For example, to measure angles between all features in group and another feature, we can use method angle
:
[43]:
l.angle(lin(110,50))
[43]:
array([11.49989817, 3.85569115, 15.61367789, 15.11039885, 16.3947936 ])
To rotate all features in group around another feature, we can use method rotate
[44]:
lr = l.rotate(lin(150, 30), 45)
To show data in list you can use data
property
[45]:
l.data
[45]:
(L:120/60, L:116/50, L:132/45, L:90/60, L:84/52)
[46]:
lr.data
[46]:
(L:107/35, L:113/26, L:126/30, L:93/26, L:94/18)
Function R
returns resultant of all features in set. Note that Lineation
and Foliation
are axial in nature, so resultant vector is not reliable. Check the orientation tensor anlysis below.
[47]:
v.R()
[47]:
Vector3(-0.941, 2.649, 3.993)
[48]:
lin(v.R())
[48]:
L:110/55
There is several methods to infer spherical statistics as spherical variance, Fisher’s statistics, confidence cones on data etc.
[49]:
l.var()
[49]:
0.02337168447438498
[50]:
v.fisher_statistics()
[50]:
{'k': 34.22945405911087, 'a95': 13.26402990511733, 'csd': 13.844747281750971}
[51]:
v.fisher_cone_a95()
[51]:
C:110/55 [13.264]
[52]:
v.fisher_cone_csd()
[52]:
C:110/55 [13.8447]
[53]:
v.delta()
[53]:
12.411724720740516
[54]:
v.rdegree()
[54]:
95.32566310512297
To calculate orientation tensor of all features in group, we can use ortensor
method.
[55]:
v.ortensor()
[55]:
OrientationTensor3
[[ 0.074 -0.096 -0.143]
[-0.096 0.284 0.421]
[-0.143 0.421 0.642]]
(S1:0.977, S2:0.201, S3:0.0758)
[ ]: