Skip to content

Commit 70a1a6b

Browse files
committed
Remove useless code.
1 parent f93fa3f commit 70a1a6b

File tree

1 file changed

+0
-363
lines changed

1 file changed

+0
-363
lines changed

wfdb/processing/peaks.py

Lines changed: 0 additions & 363 deletions
Original file line numberDiff line numberDiff line change
@@ -37,366 +37,3 @@ def find_peaks(x):
3737
i += 1
3838
soft_peaks = numpy.asarray(soft_peaks)+1
3939
return hard_peaks, soft_peaks
40-
41-
42-
class GQRS(object):
43-
def putann(self, annotation):
44-
self.annotations.append(copy.deepcopy(annotation))
45-
46-
def detect(self, x, freq, adczero, threshold=1.0):
47-
self.c = Conf(ADC_units=1.0, freq=freq)
48-
self.annotations = []
49-
self.sample_valid = False
50-
51-
if freq < 50:
52-
print("Sampling frequency is too low!")
53-
return
54-
55-
if len(x) < 1:
56-
return []
57-
58-
self.x = x
59-
self.freq = freq
60-
self.adczero = adczero
61-
62-
self.qfv = numpy.zeros((self.c._BUFLN))
63-
self.smv = numpy.zeros((self.c._BUFLN))
64-
self.v1 = 0
65-
66-
t0 = 0
67-
tf = len(x)-1
68-
self.t = 0 - self.c.dt4
69-
70-
self.annot = Annotation(0, "NOTE", 0, 0)
71-
self.putann(self.annot)
72-
73-
# Cicular buffer of Peaks
74-
first_peak = Peak(0,0,0)
75-
tmp = first_peak
76-
for _ in range(1, self.c._NPEAKS):
77-
tmp.next_peak = Peak(0,0,0)
78-
tmp.next_peak.prev_peak = tmp
79-
tmp = tmp.next_peak
80-
tmp.next_peak = first_peak
81-
first_peak.prev_peak = tmp
82-
self.current_peak = first_peak
83-
84-
if self.c.spm > self.c._BUFLN:
85-
if tf - t0 > self.c._BUFLN:
86-
tf_learn = t0 + self.c._BUFLN - self.c.dt4
87-
else:
88-
tf_learn = tf - self.c.dt4
89-
else:
90-
if tf - t0 > self.c.spm:
91-
tf_learn = t0 + self.c.spm - self.c.dt4
92-
else:
93-
tf_learn = tf - self.c.dt4
94-
95-
self.state = "LEARNING"
96-
self.gqrs(t0, tf_learn)
97-
98-
self.rewind_gqrs()
99-
100-
self.state = "RUNNING"
101-
t = t0 - self.c.dt4
102-
self.gqrs(t0, tf)
103-
104-
def rewind_gqrs(self):
105-
self.countdown = -1
106-
self.annot.time = 0
107-
self.annot.type = "NORMAL"
108-
self.annot.subtype = 0
109-
self.annot.num = 0
110-
p = self.current_peak
111-
for _ in range(self.c._NPEAKS):
112-
p.time = 0
113-
p.type = 0
114-
p.amp = 0
115-
p = p.next_peak
116-
117-
def at(self, t):
118-
if t < 0:
119-
self.sample_valid = False
120-
return None
121-
if t > len(self.x)-1:
122-
self.sample_valid = False
123-
return None
124-
return self.x[t]
125-
126-
127-
def smv_at(self, t):
128-
return self.smv[t&(self.c._BUFLN-1)]
129-
130-
def smv_put(self, t, v):
131-
self.smv[t&(self.c._BUFLN-1)] = v
132-
133-
def qfv_at(self, t):
134-
return self.qfv[t&(self.c._BUFLN-1)]
135-
136-
def qfv_put(self, t, v):
137-
self.qfv[t&(self.c._BUFLN-1)] = v
138-
139-
def sm(self, t): # CHECKED!
140-
# implements a trapezoidal low pass (smoothing) filter
141-
# (with a gain of 4*smdt) applied to input signal sig
142-
# before the QRS matched filter qf().
143-
# Before attempting to 'rewind' by more than BUFLN-smdt
144-
# samples, reset smt and smt0.
145-
smt = self.c.smt
146-
smdt = self.c.smdt
147-
148-
while self.t > smt:
149-
smt += 1
150-
if smt > smt0:
151-
self.smv_put(smt, self.smv_at(smt-1) +\
152-
self.at(smt+smdt) + self.at(smt+smdt-1) -\
153-
self.at(smt-smdt) + self.at(smt-smdt-1))
154-
else:
155-
for j in range(1, smdt):
156-
v = self.at(smt) + self.at(smt+j) + self.at(smt-j)
157-
self.smv_put(smt, (v << 1) + self.at(smt+j) + self.at(smt-j) -\
158-
self.adczero * (smdt << 2))
159-
self.c.smt = smt
160-
161-
return self.smv_at(t)
162-
163-
def qf(self, t): # CHECKED!
164-
# evaluate the QRS detector filter for the next sample
165-
166-
bufln = self.c._BUFLN - 1
167-
168-
# do this first, to ensure that all of the other smoothed values needed below are in the buffer
169-
dv2 = self.sm(t + self.c.dt4) - self.smv_at(t-self.c.dt4)
170-
dv1 = self.smv_at(t+self.c.dt) - self.smv_at(t-self.c.dt)
171-
dv = dv1 << 1
172-
dv -= self.smv_at(t+self.c.dt2) - self.smv_at(t-self.c.dt2)
173-
dv = dv << 1
174-
dv += dv1
175-
dv -= self.smv_at(t+self.c.dt3) - self.smv_at(t-self.c.dt3)
176-
177-
dv -= self.smv_at(t+self.c.dt3) - self.smv_at(t-self.c.dt3)
178-
dv = dv << 1
179-
dv += dv2
180-
self.v1 += dv
181-
v0 = self.v1 / self.c.v1norm
182-
self.qfv_put(t, v0*v0)
183-
184-
def gqrs(self, from_sample, to_sample):
185-
self.countdown = -1
186-
187-
c = None
188-
i = None
189-
qamp = None
190-
q0 = None
191-
q1 = 0
192-
q2 = 0
193-
rr = None
194-
rrd = None
195-
rt = None
196-
rtd = None
197-
rtdmin = None
198-
199-
p = None # (Peak)
200-
q = None # (Peak)
201-
r = None # (Peak)
202-
tw = None # (Peak)
203-
204-
last_peak = from_sample
205-
last_qrs = from_sample
206-
207-
def add_peak(peak_time, peak_amp, type):
208-
p = self.current_peak.next_peak
209-
p.time = peak_time
210-
p.amp = peak_amp
211-
p.type = type
212-
self.current_peak = p
213-
p.next_peak.amp = 0
214-
215-
def peaktype(p):
216-
# peaktype() returns 1 if p is the most prominent peak in its neighborhood, 2
217-
# otherwise. The neighborhood consists of all other peaks within rrmin.
218-
# Normally, "most prominent" is equivalent to "largest in amplitude", but this
219-
# is not always true. For example, consider three consecutive peaks a, b, c
220-
# such that a and b share a neighborhood, b and c share a neighborhood, but a
221-
# and c do not; and suppose that amp(a) > amp(b) > amp(c). In this case, if
222-
# there are no other peaks, a is the most prominent peak in the (a, b)
223-
# neighborhood. Since b is thus identified as a non-prominent peak, c becomes
224-
# the most prominent peak in the (b, c) neighborhood. This is necessary to
225-
# permit detection of low-amplitude beats that closely precede or follow beats
226-
# with large secondary peaks (as, for example, in R-on-T PVCs).
227-
if p.type: # TODO: check that
228-
return p.type
229-
else:
230-
a = p.amp
231-
t0 = p.time - self.c.rrmin
232-
t1 = p.time + self.c.rrmin
233-
234-
if t0 < 0:
235-
t0 = 0
236-
237-
pp = p.prev_peak
238-
while t0 < pp.time and pp.time < pp.next_peak.time:
239-
if pp.amp == 0:
240-
break
241-
if a < pp.amp and peaktype(pp) == 1:
242-
p.type = 2
243-
return p.type
244-
# end:
245-
pp = pp.prev_peak
246-
247-
pp = p.next_peak
248-
while pp.time < t1 and pp.time > pp.prev_peak.time:
249-
if pp.amp == 0:
250-
break
251-
if a < pp.amp and peaktype(pp) == 1:
252-
p.type = 2
253-
return p.type
254-
# end:
255-
pp = pp.next_peak
256-
257-
p.type = 1
258-
return p.type
259-
260-
def find_missing(r, p):
261-
if r is None or p is None:
262-
return None
263-
264-
minrrerr = p.time - r.time
265-
266-
s = None
267-
q = r.next_peak
268-
while q.time < p.time:
269-
if peaktype(q) == 1:
270-
rrtmp = q.time - r.time
271-
rrerr = rrtmp - self.c.rrmean
272-
if rrerr < 0:
273-
rrerr = -rrerr
274-
if rrerr < minrrerr:
275-
minrrerr = rrerr
276-
s = q
277-
# end:
278-
q = q.next_peak
279-
280-
return s
281-
282-
r = None
283-
next_minute = 0
284-
minutes = 0
285-
while self.t <= to_sample + self.c.sps:
286-
if self.countdown < 0:
287-
if self.sample_valid:
288-
self.qf()
289-
else:
290-
self.countdown = time_to_sample_number(1, self.freq)
291-
self.state = "CLEANUP"
292-
else:
293-
self.countdown -= 1
294-
if self.countdown < 0:
295-
break
296-
297-
q0 = self.qfv_at(self.t)
298-
q1 = self.qfv_at(self.t-1)
299-
q2 = self.qfv_at(self.t-2)
300-
301-
if q1 > self.c.pthr and q2 < q1 and q1 >= q0 and t > self.c.dt4:
302-
add_peak(self.t-1, q1, 0)
303-
last_peak = self.t-1
304-
305-
p = self.current_peak.next
306-
while p.time < t-self.c.rtmax:
307-
if p.time >= self.annot.time + self.c.rrmin and peaktype(p) == 1:
308-
if p.amp > self.c.qthr:
309-
rr = p.time - self.annot.time
310-
q = find_missing(r, p)
311-
if rr > self.c.rrmean + 2 * self.c.rrdev and\
312-
rr > 2 * (self.c.rrmean - self.c.rrdev) and\
313-
q is not None:
314-
p = q
315-
rr = p.time - self.annot.time
316-
annot.subtype = 1
317-
rrd = rr - self.c.rrmean
318-
if rrd < 0:
319-
rrd = -rrd
320-
self.c.rrdev += (rrd - self.c.rrdev) >> 3
321-
if rrd > self.c.rrinc:
322-
rrd = self.c.rrinc
323-
if rr > self.c.rrmean:
324-
self.c.rrmean += rrd
325-
else:
326-
self.c.rrmean -= rrd
327-
if p.amp > self.c.qthr * 4:
328-
self.c.qthr += 1
329-
elif p.amp < self.c.qthr:
330-
self.c.qthr -= 1
331-
if self.c.qthr > self.c.pthr * 20:
332-
self.c.qthr = self.c.pthr * 20
333-
last_qrs = p.time
334-
335-
if state == "RUNNING":
336-
self.annot.time = p.time - self.c.dt2
337-
self.annot.type = "NORMAL"
338-
qsize = p.amp * 10.0 / self.c.qthr
339-
if qsize > 127:
340-
qsize = 127
341-
self.annot.num = qsize
342-
putann(self.annot)
343-
self.annot.time += self.c.dt2
344-
345-
# look for this beat's T-wave
346-
tw = None
347-
rtdmin = self.c.rtmean
348-
q = p.next
349-
while q.time > self.annot.time:
350-
rt = q.time - self.annot.time - self.c.dt2
351-
if rt < self.c.rtmin:
352-
continue
353-
if rt > self.c.rtmax:
354-
break
355-
rtd = rt - self.c.rtmean
356-
if rtd < 0:
357-
rtd = -rtd
358-
if rtd < rtdmin:
359-
rtdmin = rtd
360-
tw = q
361-
# end:
362-
q = q.next
363-
if tw is not None:
364-
tmp_time = tw.time - self.c.dt2
365-
tann = Annotation(tmp_time, "TWAVE", 1 if tmp_time > self.annot.time + self.c.rtmean else 0, rtdmin)
366-
if state == "RUNNING":
367-
putann(tann)
368-
rt = tann.time - self.annot.time
369-
self.c.rtmean += (rt - self.c.rtmean) >> 4
370-
if self.c.rtmean > self.c.rtmax:
371-
self.c.rtmean = self.c.rtmax
372-
elif self.c.rtmean < self.c.rtmin:
373-
self.c.rtmean = self.c.rrmin
374-
tw.type = 2 # mark T-wave as secondary
375-
r = p
376-
q = None
377-
qamp = 0
378-
self.annot.subtype = 0
379-
elif t - last_qrs > self.c.rrmax and self.c.qthr > self.c.qthmin:
380-
self.c.qthr -= (self.c.qthr >> 4)
381-
elif t - last_qrs > self.c.rrmax and self.c.pthr > self.c.pthmin:
382-
self.c.pthr -= (self.c.pthr >> 4)
383-
384-
t += 1
385-
if t >= next_minute:
386-
next_minute += self.c.spm
387-
minutes += 1
388-
if minutes >= 60:
389-
minutes = 0
390-
391-
if self.state == "LEANING":
392-
return
393-
394-
# Mark the last beat or two.
395-
p = self.current_peak.next_peak
396-
while p.time < p.next_peak.time:
397-
if p.time >= self.annot.time + self.c.rrmin and p.time < tf and peaktype(p) == 1:
398-
self.annot.type = "NORMAL"
399-
self.annot.time = p.time
400-
putann(self.annot)
401-
# end:
402-
p = p.next_peak

0 commit comments

Comments
 (0)