Commit bcc24f38 authored by Ed Rogers's avatar Ed Rogers
Browse files

Add redrawing of bars

parent 392d8c98
......@@ -2,17 +2,19 @@ import time
import numpy as np
import random
from SoundLibrary import SoundLibrary
from typing import List
# from HearingTestGUI import HearingMplCanvas
class SoundRecord:
def __init__(self, freq, volume, time):
self.freq = freq
self.volume = volume
self.heard = False
self.time = time
self.heard = None
class HearingTest:
upper_lim = 100
upper_lim = 1
lower_lim = 0
n_blocks = 20
max_response_time = 1 # in seconds
......@@ -21,22 +23,26 @@ class HearingTest:
def get_block_size():
return (HearingTest.upper_lim - HearingTest.lower_lim) / HearingTest.n_blocks
def __init__(self, library: SoundLibrary):
def __init__(self, library: SoundLibrary, canvas):
self.library = library
self.lower_bounds = np.full_like(self.bands, fill_value=self.lower_lim)
self.upper_bounds = np.full_like(self.bands, fill_value=self.upper_lim)
self.lower_bounds = np.full_like(self.bands, fill_value=self.lower_lim, dtype=float)
self.upper_bounds = np.full_like(self.bands, fill_value=self.upper_lim, dtype=float)
self.false_presses = 0
self.sounds = []
self.canvas = canvas
@property
def bands(self):
return self.library.freqs
def handle_key_press(self):
def handle_key_press(self, _time):
recent_sound = self.sounds[-1]
# if time.clock() - recent_sound.time_played < self.max_response_time:
# pass
# TODO finish me
if not recent_sound.heard and (_time - recent_sound.time <= self.max_response_time):
recent_sound.heard = True
self.set_lower_bound(recent_sound.freq, recent_sound.volume)
else:
self.false_presses += 1
self.check_for_not_heard(_time)
return
def play_next_sound(self):
......@@ -44,7 +50,7 @@ class HearingTest:
volume = random.random()
freq = random.choice(self.bands)
self.library.play(freq, volume)
played_time = time.clock()
played_time = time.time()
# TODO randomise time
next_sleep_time = 1
......@@ -52,4 +58,23 @@ class HearingTest:
self.sounds.append(SoundRecord(freq, volume, played_time))
test_finished = False
self.check_for_not_heard(played_time)
return test_finished, freq, volume, played_time, next_sleep_time
def check_for_not_heard(self, event_time):
for sound in reversed(self.sounds):
delay = event_time - sound.time
print(delay)
if sound.heard is not None:
break
elif delay > self.max_response_time:
sound.heard = False
self.set_upper_bound(sound.freq, sound.volume)
def set_lower_bound(self, band, volume):
self.lower_bounds[self.bands == band] = volume
self.canvas.update_result(self)
def set_upper_bound(self, band, volume):
self.upper_bounds[self.bands == band] = volume
self.canvas.update_result(self)
......@@ -28,10 +28,8 @@ from PyQt5.QtCore import QSize
import sys
from SoundLibrary import SoundLibrary
from HearingTest import HearingTest
import random
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
......@@ -40,6 +38,7 @@ class HearingMplCanvas(FigureCanvas):
"""Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.baseline = -0.1
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
......@@ -54,26 +53,26 @@ class HearingMplCanvas(FigureCanvas):
FigureCanvas.updateGeometry(self)
self.ul_bar = None
self.ll_bar = None
self.plot_result(HearingTest(parent.library))
self.plot_result(HearingTest(parent.library, self))
def plot_result(self, result: HearingTest):
inds = np.arange(0, result.bands.size)
baseline = -10
self.axes.set_facecolor('k')
self.ul_bar = self.axes.bar(inds, result.upper_bounds-baseline, color=(0, 0.5, 0), bottom=baseline)
self.ll_bar = self.axes.bar(inds, result.lower_bounds-baseline, color=(0, 1, 0), bottom=baseline)
self.ul_bar = self.axes.bar(inds, result.upper_bounds - self.baseline, color=(0, 0.5, 0), bottom=self.baseline)
self.ll_bar = self.axes.bar(inds, result.lower_bounds - self.baseline, color=(0, 1, 0), bottom=self.baseline)
xlim = self.axes.get_xlim()
for i in np.arange(result.lower_lim+baseline, result.upper_lim, result.get_block_size()):
for i in np.arange(result.lower_lim + self.baseline, result.upper_lim, result.get_block_size()):
self.axes.plot(self.axes.get_xlim(), np.ones(2)*i, color='k')
labels = [str(b) for b in result.bands]
labels.insert(0, '')
self.axes.set_xticklabels(labels)
self.axes.set_ylim(-10, 110)
self.axes.set_ylim(self.baseline, result.upper_lim - self.baseline)
self.axes.set_xlim(xlim)
def update_result(self, result: HearingTest) -> None:
self.set_bar_heights(self.ul_bar, result.upper_bounds)
self.set_bar_heights(self.ll_bar, result.lower_bounds)
self.set_bar_heights(self.ul_bar, result.upper_bounds-self.baseline)
self.set_bar_heights(self.ll_bar, result.lower_bounds-self.baseline)
self.draw()
@staticmethod
def set_bar_heights(bars: matplotlib.container.BarContainer, vals: np.ndarray):
......@@ -139,17 +138,18 @@ class TestWindow(QMainWindow):
self.test_running = True
self.run_test()
else:
self.result.handle_key_press()
self.record_key_press(event)
key_press_time = time.time()
self.result.handle_key_press(key_press_time)
self.record_key_press(event, key_press_time)
def record_key_press(self, event: QtGui.QKeyEvent):
self.log.append('Key {} pressed at {}'.format(event.key(), time.clock()))
def record_key_press(self, event: QtGui.QKeyEvent, _time):
self.log.append('Key {} pressed at {}'.format(event.key(), _time))
def run_test(self):
self.log.setText('')
self.title.setText('Test running')
self.log.append('Starting...')
self.result = HearingTest(self.library)
self.result = HearingTest(self.library, self.graph)
self.testing_thread = HearingTestThread(self.result)
self.testing_thread.played_sound.connect(self.sound_played)
self.testing_thread.finished.connect(self.test_finished)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment