forked from agilescientific/seisplot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
patterns.py
112 lines (89 loc) · 2.38 KB
/
patterns.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# -*- coding: utf-8 -*-
"""
Patterns for finding info in seismic headers heuristically.
:copyright: 2016-22 Agile Scientific
:license: Apache 2.0
"""
import numpy as np
def flat(arr):
"""
Finds flat things (could be zeros)
___________________________
"""
arr = np.array(arr)
if arr.size == 0:
return False
mean = np.repeat(np.mean(arr), arr.size)
nonzero_residuals = np.nonzero(arr - mean)[0]
return nonzero_residuals.size < arr.size/100
def zero(arr):
"""
Finds flat things (flat and almost all zeros)
___________________________
"""
arr = np.array(arr)
nonzero_residuals = np.nonzero(np.zeros_like(arr) - arr)[0]
return nonzero_residuals.size < arr.size/100
def monotonic(arr):
""" /
Finds /
/
/
/
/
"""
arr = np.array(arr)
if flat(arr):
return False
# Second derivative is zero
return zero(np.diff(np.diff(arr)))
def count_spikes(arr):
"""
Counts the spikes in
____/\____/\____/\____/\____/\____/\
"""
arr = np.array(arr)
if (arr.size == 0) or flat(arr) or monotonic(arr):
return 0
return len(np.where(np.abs(arr) > arr.mean())[0])
def normalize(arr):
mi, ma = np.amin(arr), np.amax(arr)
return (arr - mi) / (ma - mi)
def spikes(arr):
"""
True if array is a sequence of regularly-spaced spikes.
____/\____/\____/\____/\____/\____/\
"""
arr = np.array(arr)
if (arr.size == 0) or flat(arr) or monotonic(arr):
return False
arr = normalize(arr)
spikes = np.where(arr > arr.mean())[0]
rest = np.ones_like(arr, dtype=bool)
rest[spikes] = False
return flat(arr[rest]) and flat(np.diff(arr[spikes]))
def sawtooth(arr):
"""
Finds /| /| /| /| /|
/ | / | / | / | / |
/ |/ |/ |/ |/ |
"""
arr = np.array(arr)
if monotonic(arr):
return False
if count_spikes(np.diff(arr)) < arr.size/100:
return False
return (arr[0] != arr[1]) and spikes(np.diff(arr))
def stairstep(arr):
""" _____
Finds _____|
_____|
_____|
_____|
"""
arr = np.array(arr)
if monotonic(arr):
return False
if count_spikes(np.diff(arr)) < arr.size/100:
return False
return (arr[0] == arr[1]) and spikes(np.diff(arr))