diff --git a/.bowerrc b/.bowerrc
new file mode 100644
index 0000000..afd1c95
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory" : "static/bower_components"
+}
diff --git a/eeg_test_thread.py b/eeg_test_thread.py
index d6e5e6f..1f4d415 100644
--- a/eeg_test_thread.py
+++ b/eeg_test_thread.py
@@ -63,7 +63,7 @@ class EEGTestThread(Thread):
self.question_files = []
self.question = []
- self.socketio.on_event('eeg_page_loaded', self.setPageLoaded, namespace='/main')
+ self.socketio.on_event('page_loaded', self.setPageLoaded, namespace='/main')
self.socketio.on_event('submit_eeg_response', self.submitTestResponse, namespace='/main')
self.socketio.on_event('finish_eeg_test', self.finishTestEarly, namespace='/main')
# Percent speech inteligibility (estimated using behavioural measure)
@@ -119,6 +119,15 @@ class EEGTestThread(Thread):
self.unsetPageLoaded()
self.socketio.emit('processing-complete', {'data': ''}, namespace='/main')
self.waitForPageLoad()
+ self.fillTable()
+
+ def fillTable(self):
+ '''
+ '''
+ symb = [[symb_dict[x], symb_dict[y]] for x, y in self.answers]
+ set_trace()
+ self.socketio.emit('eeg_test_fill_table', {'data': symb}, namespace='/main')
+
def setMatrix(self, questions):
'''
@@ -141,11 +150,8 @@ class EEGTestThread(Thread):
True: 10003,
False: 10007
}
- try:
- self.answers[self.trial_ind, self.q_ind] = self.answer in self.response
- symb = symb_dict[self.answers[self.trial_ind, self.q_ind]]
- except:
- set_trace()
+ self.answers[self.trial_ind, self.q_ind] = self.answer in self.response
+ symb = symb_dict[self.answers[self.trial_ind, self.q_ind]]
self.socketio.emit('eeg_test_resp', {'q_ind': self.q_ind, 'trial_ind': self.trial_ind, "ans": symb}, namespace='/main')
def finishTestEarly(self):
@@ -310,7 +316,7 @@ class EEGTestThread(Thread):
def saveState(self, out="eeg_test_state.pkl"):
toSave = ['marker_files', 'clinPageLoaded', 'wav_files', 'participant',
- 'response', 'pageLoaded', 'backupFilepath', 'noise_path',
+ 'response', 'backupFilepath', 'noise_path',
'question_files', 'partPageLoaded', 'si', 'question', 'answers']
saveDict = {k:self.__dict__[k] for k in toSave}
with open(out, 'wb') as f:
diff --git a/matrix_test/gen_noise.py b/matrix_test/gen_noise.py
index bfaa6c8..b6943ae 100755
--- a/matrix_test/gen_noise.py
+++ b/matrix_test/gen_noise.py
@@ -190,13 +190,17 @@ def calc_spectrum(files, silences, fs=44100, plot=False):
def gen_noise(OutDir, b, fs):
print("Generating noise...")
# Generate 10 minutes of white noise
- x = np.random.randn(int(fs*60.*20.))
+ x = np.random.randn(int(fs*60.*10.))
x /= x.max()
noiseDir = os.path.join(OutDir, 'wav')
+ noiseDir = os.path.join(OutDir, 'rms')
dir_must_exist(noiseDir)
noiseDir = os.path.join(noiseDir, 'noise')
dir_must_exist(noiseDir)
y = block_lfilter_wav(b, [1.0], x, os.path.join(noiseDir, 'noise.wav'), 65538, 44100)
+ noise_rms_path = os.path.join(noiseDir, 'noise_rms.npy')
+ rms = np.mean(np.sqrt(y**2))
+ np.save(noise_rms_path, rms)
return y
@@ -211,11 +215,11 @@ if __name__ == "__main__":
help='Matrix test speech data location')
parser.add_argument('--OutDir', type=PathType(exists=None, type='dir'),
default='./stimulus', help='Output directory')
- parser.add_argument('--SkipRMS', action='store_true')
+ parser.add_argument('--CalcRMS', action='store_true')
args = {k:v for k,v in vars(parser.parse_args()).items() if v is not None}
rmsDir = os.path.join(args['OutDir'], "rms")
- if not args['SkipRMS']:
+ if args['CalcRMS']:
indexes = gen_indexes()
wavFiles = gen_audio_stim(args['MatrixDir'], args['OutDir'], indexes)
rmsFiles = gen_rms(wavFiles, rmsDir)
diff --git a/matrix_test/generate_matrix_stimulus.py b/matrix_test/generate_matrix_stimulus.py
index d36f75d..f56a360 100755
--- a/matrix_test/generate_matrix_stimulus.py
+++ b/matrix_test/generate_matrix_stimulus.py
@@ -322,7 +322,7 @@ if __name__ == "__main__":
gen2(args['MatrixDir'], args['OutDir'], y)
generateAudioStimulus(**args)
- #generateNoiseFromSentences(args['OutDir'], noiseDir)
+ generateNoiseFromSentences(args['OutDir'], noiseDir)
#generateDecoderAudio(args['OutDir'], noiseDir, decoderDir)
diff --git a/matrix_test_thread.py b/matrix_test_thread.py
index 54961f0..e3f0092 100644
--- a/matrix_test_thread.py
+++ b/matrix_test_thread.py
@@ -10,7 +10,7 @@ from scipy.optimize import minimize
import csv
from shutil import copy2
-from pysndfile import sndio
+from pysndfile import sndio, PySndfile
from matrix_test.filesystem import globDir
import sounddevice as sd
import pdb
@@ -18,7 +18,7 @@ import pdb
from config import socketio
-def run_matrix_thread(listN=None, sessionFilepath=None, participant=None):
+def run_matrix_thread(listN=3, sessionFilepath=None, participant=None):
global matThread
if 'matThread' in globals():
if matThread.isAlive() and isinstance(matThread, MatTestThread):
@@ -59,8 +59,11 @@ class MatTestThread(Thread):
'''
Thread for running server side matrix test operations
'''
- def __init__(self, listN=3, sessionFilepath=None, noiseFilepath="./matrix_test/stimulus/wav/noise/noise.wav",
- listFolder="./matrix_test/stimulus/wav/sentence-lists/", socketio=None, participant=None):
+ def __init__(self, listN=3, sessionFilepath=None,
+ noiseFilepath="./matrix_test/stimulus/wav/noise/noise.wav",
+ noiseRMSFilepath="./matrix_test/stimulus/rms/noise/noise_rms.npy",
+ listFolder="./matrix_test/stimulus/wav/sentence-lists/",
+ socketio=None, participant=None):
super(MatTestThread, self).__init__()
self.participant=participant
self.newResp = False
@@ -72,14 +75,14 @@ class MatTestThread(Thread):
self.socketio = socketio
# Attach messages from gui to class methods
self.socketio.on_event('submit_mat_response', self.submitMatResponse, namespace='/main')
- self.socketio.on_event('mat_page_loaded', self.setPageLoaded, namespace='/main')
+ self.socketio.on_event('page_loaded', self.setPageLoaded, namespace='/main')
self.socketio.on_event('save_file_dialog_resp', self.manualSave, namespace='/main')
self.socketio.on_event('load_file_dialog_resp', self.loadStateSocketHandle, namespace='/main')
self.socketio.on_event('repeat_stimulus', self.playStimulusSocketHandle, namespace='/main')
self.socketio.on_event('finish_test', self.finishTestEarly, namespace='/main')
self.socketio.on_event('finalise_results', self.finaliseResults, namespace='/main')
- self.listN = listN
+ self.listN = int(listN)
self.loadedLists = []
self.lists = []
self.listsRMS = []
@@ -128,10 +131,11 @@ class MatTestThread(Thread):
# If loading session from file, load session variables from the file
if sessionFilepath:
self.loadState(sessionFilepath)
+ self.loadNoise(noiseFilepath, noiseRMSFilepath)
else:
# Preload audio at start of the test
self.loadStimulus(listFolder, n=self.listN)
- self.loadNoise(noiseFilepath)
+ self.loadNoise(noiseFilepath, noiseRMSFilepath)
def testLoop(self):
@@ -413,13 +417,12 @@ class MatTestThread(Thread):
random.shuffle(self.availableSentenceInds)
- def loadNoise(self, noiseFilepath):
+ def loadNoise(self, noiseFilepath, noiseRMSFilepath):
'''
Read noise samples and calculate the RMS of the signal
'''
- x, _, _ = sndio.read(noiseFilepath)
- self.noise = x
- self.noise_rms = np.sqrt(np.mean(self.noise**2))
+ self.noise = PySndfile(noiseFilepath, 'r')
+ self.noise_rms = np.load(noiseRMSFilepath)
def unsetPageLoaded(self):
@@ -445,13 +448,12 @@ class MatTestThread(Thread):
self.currentWords = self.listsString[0][currentSentenceInd]
# Get noise data
noiseLen = x.size + self.fs
- start = random.randint(0, self.noise.size-noiseLen)
+ start = random.randint(0, self.noise.frames()-noiseLen)
end = start + noiseLen
- x_noise = self.noise[start:end]
- # Calculate RMS of noise
- noise_rms = np.sqrt(np.mean(x_noise**2))
+ self.noise.seek(start)
+ x_noise = self.noise.read_frames(end-start)
# Scale noise to match the RMS of the speech
- x_noise = x_noise*(x_rms/noise_rms)
+ x_noise = x_noise*(x_rms/self.noise_rms)
y = x_noise
# Set speech to start 500ms after the noise, scaled to the desired SNR
sigStart = round(self.fs/2.)
@@ -470,9 +472,9 @@ class MatTestThread(Thread):
def saveState(self, out="mat_state.pkl"):
toSave = ['listsRMS', 'y', 'currentList', 'slope', 'snr', 'snrTrack',
'direction', 'noise_rms', 'i', 'currentWords', 'usedLists',
- 'availableSentenceInds', 'trialN', 'listsString', 'noise',
- 'fs', 'nCorrect', 'loadedLists', 'lists', 'listN',
- 'wordsCorrect', 'responses', 'presentedWords', 'srt_50', 's_50']
+ 'availableSentenceInds', 'trialN', 'listsString', 'fs',
+ 'nCorrect', 'loadedLists', 'lists', 'listN', 'wordsCorrect',
+ 'responses', 'presentedWords', 'srt_50', 's_50']
saveDict = {k:self.__dict__[k] for k in toSave}
with open(out, 'wb') as f:
dill.dump(saveDict, f)
@@ -493,7 +495,8 @@ class MatTestThread(Thread):
def loadState(self, filepath):
with open(filepath, 'rb') as f:
- self.__dict__.update(dill.load(f))
+ backup_dict = dill.load(f)
+ self.__dict__.update(backup_dict)
def run(self):
diff --git a/socket_handlers.py b/socket_handlers.py
index a880e43..0848748 100644
--- a/socket_handlers.py
+++ b/socket_handlers.py
@@ -30,6 +30,12 @@ from matrix_test_thread import run_matrix_thread
from eeg_test_thread import run_eeg_test_thread
from eeg_train_thread import run_eeg_train_thread
+thread_runners = {
+ "eeg_test": run_eeg_test_thread,
+ "eeg_train": run_eeg_train_thread,
+ "mat": run_matrix_thread
+}
+
'''
Generic socket handlers
'''
@@ -160,6 +166,21 @@ def start_saved_eeg_train(msg):
'''
EEG test socket handlers
'''
+
+@socketio.on('start_test', namespace='/main')
+def start_test(msg):
+ test_name = msg.pop('test_name')
+ part_key = msg.pop('part_key')
+ thread_runner = thread_runners[test_name]
+ socketio.emit('participant_start_{}'.format(test_name), namespace='/main')
+
+ if part_key != "--":
+ participant = participants[part_key]
+ else:
+ raise ValueError("Participant must be selected...")
+
+ thread_runner(participant=participant, **msg)
+
@socketio.on('start_eeg_test', namespace='/main')
def start_eeg_test(msg):
'''
diff --git a/templates/eeg_setup.html b/templates/eeg_setup.html
index dac37d8..72f7c8c 100644
--- a/templates/eeg_setup.html
+++ b/templates/eeg_setup.html
@@ -33,12 +33,12 @@
$('#load-backup').click(function(event) {
// Send message to call stimulus generation function in Python
- socket.emit('load_eeg_backup', {part_key: $("#participant").val()});
+ socket.emit('load_eeg_test_backup', {part_key: $("#participant").val()});
return false;
})
$('#load-saved').click(function(event) {
// Send message to call stimulus generation function in Python
- socket.emit('load_eeg_session', {part_key: $("#participant").val()});
+ socket.emit('load_eeg_test_session', {part_key: $("#participant").val()});
return false;
})
$('#start_eeg_train').click(function(event) {
diff --git a/templates/eeg_test_clinician_end.html b/templates/eeg_test_clinician_end.html
index a4fdb2d..4e77bc6 100644
--- a/templates/eeg_test_clinician_end.html
+++ b/templates/eeg_test_clinician_end.html
@@ -1,3 +1,73 @@
{% extends 'index.html' %}
{% block content %}
+
+
+
+
+
+ | Trial # |
+ 1 |
+ 2 |
+ 3 |
+ 4 |
+ 5 |
+ 6 |
+ 7 |
+
+
+
+
+ | Q1 |
+ - |
+ - |
+ - |
+ - |
+ - |
+ - |
+ - |
+
+
+ | Q2 |
+ - |
+ - |
+ - |
+ - |
+ - |
+ - |
+ - |
+
+
+
+
+
+
+
+
+
{% endblock %}
diff --git a/templates/eeg_test_clinician_view.html b/templates/eeg_test_clinician_view.html
index 8db1679..e52d663 100644
--- a/templates/eeg_test_clinician_view.html
+++ b/templates/eeg_test_clinician_view.html
@@ -63,10 +63,6 @@
waitingDialog.hide();
});
- socket.on('check-loaded', function(msg) {
- socket.emit('eeg_page_loaded', {data: "clinician"});
- });
-
$('#eeg_test_finish').click(function(event) {
socket.emit("finish_eeg_test")
});
diff --git a/templates/eeg_test_run.html b/templates/eeg_test_run.html
index aac5a98..ef7d5be 100644
--- a/templates/eeg_test_run.html
+++ b/templates/eeg_test_run.html
@@ -94,10 +94,6 @@
return false;
});
- socket.on('check-loaded', function(msg) {
- socket.emit('eeg_page_loaded', {data: "participant"});
- });
-
socket.on('eeg_stim_done', function(msg) {
$('.eeg_submit').find('input, textarea, button, select').removeAttr('disabled');
off()
diff --git a/templates/index.html b/templates/index.html
index 722afc7..a67ec01 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -108,6 +108,10 @@
socket.on('main-notification', function(msg) {
alert(msg.data)
});
+
+ socket.on('check-loaded', function(msg) {
+ socket.emit('page_loaded', {data: "clinician"});
+ });
});