Fixed backup bug in MT and continued implementing per participant testing
This commit is contained in:
+35
-13
@@ -4,8 +4,23 @@ from threading import Thread, Event
|
||||
import io
|
||||
import dill
|
||||
import base64
|
||||
import os
|
||||
import random
|
||||
from scipy.optimize import minimize
|
||||
import csv
|
||||
|
||||
from pysndfile import sndio
|
||||
from matrix_test.filesystem import globDir
|
||||
import sounddevice as sd
|
||||
import pdb
|
||||
|
||||
def set_trace():
|
||||
import logging
|
||||
log = logging.getLogger('werkzeug')
|
||||
log.setLevel(logging.ERROR)
|
||||
log = logging.getLogger('engineio')
|
||||
log.setLevel(logging.ERROR)
|
||||
pdb.set_trace()
|
||||
def find_nearest_idx(array, value):
|
||||
'''
|
||||
Adapted from: https://stackoverflow.com/questions/2566412/find-nearest-value-in-numpy-array
|
||||
@@ -28,8 +43,9 @@ 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):
|
||||
listFolder="./matrix_test/stimulus/wav/sentence-lists/", socketio=None, participant=None):
|
||||
super(MatTestThread, self).__init__()
|
||||
self.participant=participant
|
||||
self.newResp = False
|
||||
self.foundSRT = False
|
||||
self.pageLoaded = False
|
||||
@@ -80,6 +96,12 @@ class MatTestThread(Thread):
|
||||
|
||||
self._stopevent = Event()
|
||||
|
||||
if self.participant:
|
||||
folder = self.participant.data_paths['adaptive_matrix_data']
|
||||
self.backupFilepath=os.path.join(folder, 'mat_state.pik')
|
||||
else:
|
||||
self.backupFilepath='./mat_state.pik'
|
||||
|
||||
# If loading session from file, load session variables from the file
|
||||
if sessionFilepath:
|
||||
self.loadState(sessionFilepath)
|
||||
@@ -103,16 +125,14 @@ class MatTestThread(Thread):
|
||||
if self._stopevent.isSet():
|
||||
return
|
||||
self.calcSNR()
|
||||
self.saveState()
|
||||
|
||||
self.saveState(out=self.backupFilepath)
|
||||
self.saveState(out=self.backupFilepath)
|
||||
if not self._stopevent.isSet():
|
||||
self.unsetPageLoaded()
|
||||
self.socketio.emit('processing-complete', {'data': ''}, namespace='/main')
|
||||
self.waitForPageLoad()
|
||||
self.plotSNR()
|
||||
self.fitLogistic()
|
||||
self.saveState()
|
||||
#socketio.emit('update-progress', {'data': '{}%'.format(percent)}, namespace='/main')
|
||||
|
||||
|
||||
def finishTestEarly(self):
|
||||
@@ -297,12 +317,12 @@ class MatTestThread(Thread):
|
||||
|
||||
def playStimulus(self, replay=False):
|
||||
self.newResp = False
|
||||
socketio.emit("mat_stim_playing", namespace="/main")
|
||||
self.socketio.emit("mat_stim_playing", namespace="/main")
|
||||
if not replay:
|
||||
self.y = self.generateTrial(self.snr)
|
||||
# Play audio
|
||||
sd.play(self.y, self.fs, blocking=True)
|
||||
socketio.emit("mat_stim_done", namespace="/main")
|
||||
self.socketio.emit("mat_stim_done", namespace="/main")
|
||||
|
||||
|
||||
def loadStimulus(self, listDir, n=3, demo=False):
|
||||
@@ -399,14 +419,16 @@ class MatTestThread(Thread):
|
||||
|
||||
|
||||
def saveState(self, out="mat_state.pik"):
|
||||
toSave = ['listsRMS', 'y', 'currentList', 'foundSRT', 'slope', 'snr',
|
||||
'snrTrack', 'direction', 'noise_rms', 'i', 'currentWords',
|
||||
'usedLists', 'availableSentenceInds', 'trialN',
|
||||
'listsString', 'noise', 'fs', 'nCorrect', 'loadedLists',
|
||||
'lists', 'listN', 'wordsCorrect']
|
||||
toSave = ['listsRMS', 'y', 'currentList', 'slope', 'snr', 'snrTrack',
|
||||
'direction', 'noise_rms', 'i', 'currentWords', 'usedLists',
|
||||
'availableSentenceInds', 'trialN', 'listsString', 'noise',
|
||||
'fs', 'nCorrect', 'loadedLists', 'lists', 'listN',
|
||||
'wordsCorrect']
|
||||
saveDict = {k:self.__dict__[k] for k in toSave}
|
||||
with open(out, 'wb') as f:
|
||||
dill.dump(saveDict, f)
|
||||
if self.participant:
|
||||
self.participant['adaptive_matrix_data'].update(saveDict)
|
||||
|
||||
|
||||
def manualSave(self, msg):
|
||||
@@ -431,4 +453,4 @@ class MatTestThread(Thread):
|
||||
'''
|
||||
This function is called when the thread starts
|
||||
'''
|
||||
self.testLoop()
|
||||
return self.testLoop()
|
||||
|
||||
@@ -16,7 +16,6 @@ import re
|
||||
import base64
|
||||
import shutil
|
||||
|
||||
import sounddevice as sd
|
||||
import webview
|
||||
import webbrowser
|
||||
import app
|
||||
@@ -69,12 +68,14 @@ class StimGenThread(Thread):
|
||||
socketio.emit('processing-complete', {'data': ''}, namespace='/main')
|
||||
|
||||
|
||||
def run_matrix_thread(listN=None, sessionFilepath=None):
|
||||
def run_matrix_thread(listN=None, sessionFilepath=None, participant=None):
|
||||
global matThread
|
||||
if 'matThread' in globals():
|
||||
if matThread.isAlive() and isinstance(matThread, MatTestThread):
|
||||
matThread.join()
|
||||
matThread = MatTestThread(socketio=socketio, listN=listN, sessionFilepath=sessionFilepath)
|
||||
matThread = MatTestThread(socketio=socketio, listN=listN,
|
||||
sessionFilepath=sessionFilepath,
|
||||
participant=participant)
|
||||
matThread.start()
|
||||
|
||||
|
||||
@@ -120,7 +121,6 @@ def fullscreen():
|
||||
def manage_participant_page():
|
||||
# Find all pre-existing participants
|
||||
participants = find_participants()
|
||||
part_num = gen_participant_num(participants)
|
||||
return render_template("manage_participants.html", part_keys=participants.keys())
|
||||
|
||||
@socketio.on('delete_participant', namespace='/main')
|
||||
@@ -129,7 +129,7 @@ def manage_participant_delete(participant_str):
|
||||
del participants[participant_str]
|
||||
return render_template("manage_participants.html", part_keys=participants.keys())
|
||||
|
||||
@socketio.on('update_participant', namespace='/main')
|
||||
@socketio.on('update_participant_info', namespace='/main')
|
||||
def manage_participant_save(data):
|
||||
key = "participant_{}".format(data['number'])
|
||||
participants[key].set_info(data)
|
||||
@@ -221,7 +221,8 @@ def homepage():
|
||||
|
||||
@server.route('/matrix_test')
|
||||
def matrix_test_setup():
|
||||
return render_template("matrix_test_setup.html")
|
||||
participants = find_participants()
|
||||
return render_template("matrix_test_setup.html", part_keys=participants.keys())
|
||||
|
||||
@server.route('/matrix_test/run')
|
||||
def run_matrix_test():
|
||||
@@ -242,6 +243,7 @@ def clinician_mat_end():
|
||||
@server.route('/matrix_test/stimulus_generation')
|
||||
def matDecStim():
|
||||
return render_template("matrix_decode_stim.html")
|
||||
|
||||
@socketio.on('start_mat_test', namespace='/main')
|
||||
def start_mat_test(msg):
|
||||
'''
|
||||
@@ -249,22 +251,36 @@ def start_mat_test(msg):
|
||||
'''
|
||||
socketio.emit('participant_start_mat', {'data': ''}, namespace='/main', broadcast=True)
|
||||
listN = int(msg['listN'])
|
||||
part_key = msg['part_key']
|
||||
|
||||
run_matrix_thread(listN=listN)
|
||||
if part_key != "--":
|
||||
participant = participants[part_key]
|
||||
else:
|
||||
participant = None
|
||||
|
||||
run_matrix_thread(listN=listN, participant=participant)
|
||||
|
||||
|
||||
@socketio.on('load_mat_backup', namespace='/main')
|
||||
def start_backup_mat_test():
|
||||
def start_backup_mat_test(msg):
|
||||
'''
|
||||
Relay test start message to participant view
|
||||
'''
|
||||
socketio.emit('participant_start_mat', {'data': ''}, namespace='/main', broadcast=True)
|
||||
part_key = msg['part_key']
|
||||
if part_key != "--":
|
||||
participant = participants[part_key]
|
||||
folder = participant.data_paths["adaptive_matrix_data"]
|
||||
backupPath = os.path.join(folder, "mat_state.pik")
|
||||
else:
|
||||
participant = None
|
||||
backupPath = './mat_state.pik'
|
||||
|
||||
run_matrix_thread(sessionFilepath="./mat_state.pik")
|
||||
run_matrix_thread(sessionFilepath=backupPath)
|
||||
|
||||
|
||||
@socketio.on('load_mat_session', namespace='/main')
|
||||
def start_saved_mat_test():
|
||||
def start_saved_mat_test(msg):
|
||||
'''
|
||||
Relay test start message to participant view
|
||||
'''
|
||||
@@ -275,8 +291,14 @@ def start_saved_mat_test():
|
||||
filepath = filepath.decode("utf-8")
|
||||
else:
|
||||
return None
|
||||
|
||||
part_key = msg['part_key']
|
||||
if part_key != "--":
|
||||
participant = participants[part_key]
|
||||
else:
|
||||
participant = None
|
||||
socketio.emit('participant_start_mat', {'data': ''}, namespace='/main', broadcast=True)
|
||||
run_matrix_thread(sessionFilepath=filepath)
|
||||
run_matrix_thread(sessionFilepath=filepath, participant=participant)
|
||||
|
||||
|
||||
@socketio.on('run_mat_stim_gen', namespace='/main')
|
||||
|
||||
@@ -81,7 +81,7 @@ $(document).ready(function(){
|
||||
handedness: $('#handedness').val(),
|
||||
general_notes: $('#general_notes').val()
|
||||
}
|
||||
socket.emit('update_participant', form_data);
|
||||
socket.emit('update_participant_info', form_data);
|
||||
});
|
||||
|
||||
$('#delete').click(function(event) {
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
<div class="card">
|
||||
<div id="main-div" class="card-body">
|
||||
<form action="{{ url_for('matDecStim') }}" method="POST">
|
||||
<div class="form-group">
|
||||
<select class="form-control" name="participant" id="participant">
|
||||
<option>--</option>
|
||||
{% for p in part_keys %}
|
||||
<option>{{ p }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="open-mat-folder-container">Matrix data folder: </label>
|
||||
<br>
|
||||
<input type="text" id="mat-dir" name='mat_dir' value="./matrix_test/speech_components/" style="width:85%"></input>
|
||||
<button type="button" id="mat-dir-button" class="btn btn-primary">Browse...</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="open-save-folder-container">New data generation folder: </label>
|
||||
<br>
|
||||
<input type="text" id="save-dir" name='save_dir' style="width:85%"></input>
|
||||
<button type="button" id="save-dir-button" class="btn btn-primary">Browse...</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="listN">Number of lists:</label>
|
||||
<br>
|
||||
@@ -35,23 +37,17 @@
|
||||
|
||||
$('#load-backup').click(function(event) {
|
||||
// Send message to call stimulus generation function in Python
|
||||
socket.emit('load_mat_backup');
|
||||
socket.emit('load_mat_backup', {part_key: $("#participant").val()});
|
||||
return false;
|
||||
})
|
||||
$('#load-saved').click(function(event) {
|
||||
// Send message to call stimulus generation function in Python
|
||||
socket.emit('load_mat_session');
|
||||
socket.emit('load_mat_session', {part_key: $("#participant").val()});
|
||||
return false;
|
||||
})
|
||||
$('#submit').click(function(event) {
|
||||
// Send message to call stimulus generation function in Python
|
||||
socket.emit('start_mat_test', {listN: $("#listN").val()});
|
||||
return false;
|
||||
})
|
||||
|
||||
$('#save-dir-button').click(function(event) {
|
||||
// Send message to call stimulus generation function in Python
|
||||
socket.emit('open_save_dialog');
|
||||
socket.emit('start_mat_test', {listN: $("#listN").val(), part_key: $("#participant").val()});
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user