forked from yetkinyilmaz/tracking
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Hough.py
192 lines (136 loc) · 5.24 KB
/
Hough.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
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
177
178
179
180
181
182
183
184
185
186
187
188
189
__author__ = 'mikhail91'
import numpy
coleventX = 4
class Hough(object):
def __init__(self, n_theta_bins=100, n_radius_bins=100, min_radius=1., min_hits=4):
"""
Track pattern recognition for one event based on Hough Transform.
Parameters
----------
n_theta_bins : int
Number of bins track theta parameter is divided into.
n_radius_bins : int
Number of bins track 1/r parameter is divided into.
min_radius : float
Minimum track radius which is taken into account.
min_hits : int
Minimum number of hits per on recognized track.
"""
self.n_theta_bins = n_theta_bins
self.n_radius_bins = n_radius_bins
self.min_radius = min_radius
self.min_hits = min_hits
def tranform(self, X):
"""
Hough Transformation and tracks pattern recognition.
Parameters
----------
X : array_like
Hit features.
Return
------
matrix_hough : ndarray
Hough Transform matrix of all hits of an event.
track_inds : ndarray
List of recognized tracks. Each track is a list of its hit indexes.
track_params : ndarray
List of track parameters.
"""
x, y = X[:, 2], X[:, 3]
# Transform cartesian coordinates to polar coordinates
hit_phis = numpy.arctan(y / x) * (x != 0) + numpy.pi * (x < 0) + 0.5 * numpy.pi * (x==0) * (y>0) + 1.5 * numpy.pi * (x==0) * (y<0)
hit_rs = numpy.sqrt(x**2 + y**2)
# Set ranges of a track theta and 1/r
track_thetas = numpy.linspace(0, 2 * numpy.pi, self.n_theta_bins)
track_invrs = numpy.linspace(0, 1. / self.min_radius, self.n_radius_bins)
# Init arrays for the results
matrix_hough = numpy.zeros((len(track_thetas)+1, len(track_invrs)+1))
track_inds = []
track_params = []
for num1, theta in enumerate(track_thetas):
# Hough Transform for one hit
invr = 2. * numpy.cos(hit_phis - theta) / hit_rs
# Hough Transform digitization
bin_inds = numpy.digitize(invr, track_invrs)
unique, counts = numpy.unique(bin_inds, return_counts=True)
# Count number of hits in each bin. Fill the results arrays.
for num2, one in enumerate(unique):
matrix_hough[num1, one] = counts[num2]
if counts[num2] >= self.min_hits and one != 0 and one < len(track_invrs) and num1 !=0 and num1 < len(track_thetas):
track_inds.append(numpy.arange(len(bin_inds))[bin_inds == one])
track_params.append([track_thetas[num1], track_invrs[one]])
track_inds = numpy.array(track_inds)
track_params = numpy.array(track_params)
return matrix_hough[:, 1:-1], track_inds, track_params
def get_hit_labels(self, track_inds, n_hits):
"""
Estimate hit labels based on the recognized tracks.
Parameters
----------
track_inds : ndarray
List of recognized tracks. Each track is a list of its hit indexes.
n_hits : int
Number of hits in the event.
Return
------
labels : array-like
Hit labels.
"""
labels = -1. * numpy.ones(n_hits)
used = numpy.zeros(n_hits)
track_id = 0
while 1:
track_lens = numpy.array([len(i[used[i] == 0]) for i in track_inds])
if len(track_lens) == 0:
break
max_len = track_lens.max()
if max_len < self.min_hits:
break
one_track_inds = track_inds[track_lens == track_lens.max()][0]
one_track_inds = one_track_inds[used[one_track_inds] == 0]
used[one_track_inds] = 1
labels[one_track_inds] = track_id
track_id += 1
return numpy.array(labels)
def fit(self, X, y):
pass
def predict_one_event(self, X):
"""
Hough Transformation and tracks pattern recognition for one event.
Parameters
----------
X : ndarray_like
Hit features.
Return
------
Labels : array-like
Track id labels for the each hit.
"""
matrix_hough, track_inds, track_params = self.tranform(X)
self.matrix_hough_ = matrix_hough
self.track_inds_ = track_inds
self.track_params_ = track_params
labels = self.get_hit_labels(track_inds, len(X))
return labels
def predict(self, X):
"""
Tracks pattern recognition for several events.
Parameters
----------
X : ndarray_like
Hit features.
Return
------
Labels : array-like
Track id labels for the each hit.
"""
event_ids = numpy.unique(X[:, coleventX])
y = numpy.zeros((len(X),2))
labels = []
for one_event_id in event_ids:
X_event = X[X[:, coleventX] == one_event_id]
labels_event = self.predict_one_event(X_event)
labels += list(labels_event)
y[:,0] = labels
y[:,1] = X[:, coleventX]
return y