-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtriangular.py
More file actions
176 lines (102 loc) · 5.13 KB
/
triangular.py
File metadata and controls
176 lines (102 loc) · 5.13 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import sklearn.preprocessing as preprocessing
from scipy.signal import correlate
import numpy as np
import matplotlib.pyplot as plt
def find_pattern(signal, pattern, depth):
'''
Finds the index of a pattern in a given discrete signal
middle state is defined as elements in pattern[1:-1]
Parameters:
pattern (np.array): pattern to be found
signal (np.array): signal discrete signal
depth (int): number containing the maximum repetition of the middle state on the pattern
Returns:
index_dict (dict): each element contains a list of np.arrays of indexes.
each list is on the following format
[indexes(pattern), indexes(reversed(pattern))]
'''
encoder = preprocessing.OneHotEncoder(handle_unknown='ignore')
encoder.fit(signal[:, None])
index_dict = dict()
for current_depth in range(1, depth + 1):
h = np.append( pattern[0], np.append(np.repeat(pattern[1:-1], current_depth), pattern[-1]))
#middle state is expanded every iteration
x_ = encoder.transform(signal[:, None]).toarray()
h_ = encoder.transform(h[:, None]).toarray()
y_ = correlate(x_.T, h_.T, mode = 'valid')[0]
y_r = correlate(x_.T, h_[::-1].T, mode = 'valid')[0]
index_dict[current_depth] = [np.where(y_ == len(h_))[0], np.where(y_r == len(h_))[0]]
return index_dict
def get_window(indexes, signal, win_size = 5):
'''
Will take a signal, from a given index will take the [index-win_size:index+win_size+1] elements
Parameters:
indexes (np.array- 1D or list) : list of indexes
signal (np.array): signal to be windowed
win_size (int): size of window
Returns:
window (2D-array)
'''
indexes = indexes[np.where( (indexes>win_size) & (indexes < (len(signal) -win_size) ) )[0]]
if len(indexes) == 0:
return np.array([]).reshape(0, 2*win_size + 1)
window = np.array([signal[index-win_size:index+win_size+1] for index in indexes])
return window
def stack_windows(index_dict, target_signal, win_size = 5):
'''
Gets all the windows of size 2*win_size +1
For a given index
Parameters:
index_dict (dict): dictionary that has the depth as an index.
target_signal (np.array): array containing signal to be processed
win_size (int): size of windows
Returns:
windows_dict (dict): each value contains a list
each list is of the format
[windows(indexes(patterns)), windows(indexes(reversed(pattern)))]
'''
windows_dict = dict()
for key, val in index_dict.items():
windows_dict[key] = [get_window(val[0] + (key + 1)//2, target_signal, win_size = win_size),
get_window(val[1] + int(np.ceil((key + 1)/2)), target_signal, win_size = win_size)]
return windows_dict
def create_triangle(windows_dict, average = False):
'''
Creates the triangular numpy array from windows_dict
'''
triangle = list()
for i in range(1, len(windows_dict) + 1):
combined = np.concatenate( ( windows_dict[i][0], windows_dict[i][1][:, ::-1]))
if average and combined.size:
combined = combined.mean(axis = 0, keepdims = True)
triangle.append(combined)
return np.vstack(triangle)
def get_triangle(index_dict, signal, win_size = 10, average = True, fold = False):
'''
Creates triangle from index_dict
Returns:
Numpy array triangle
'''
windows_dict = stack_windows(index_dict,signal, win_size)
triangle = create_triangle(windows_dict, average)
if fold:
mask = triangle > np.percentile(triangle, 25)
median = np.median(triangle[mask])
enrich = np.clip(triangle/median, 0, 2)
return enrich
return triangle
# def fake_triangle(index_dict):
# for key, val in index_dict.items():
def plot_triangle(index_dict, signal, figsize = (10, 8), win_size = 10, average = True, fold = False, title = None):
triangle = get_triangle(index_dict, signal, win_size, average, fold)
fig = plt.figure( figsize=figsize)
if fold:
plt.imshow(triangle, cmap = 'bwr', vmin = 0, vmax = 2, extent = [ -(triangle.shape[1]-1)*100/2, (triangle.shape[1]-1)*100/2, triangle.shape[0], 0 ], aspect = 'auto' )
else:
plt.imshow(triangle, cmap = 'bwr', vmin = -1, vmax = 1, extent = [ -(triangle.shape[1]-1)*100/2, (triangle.shape[1]-1)*100/2, triangle.shape[0], 0 ], aspect = 'auto' )
if title:
plt.title(title)
plt.colorbar()
plt.xlabel("Kb");
plt.close(fig)
return fig