def changeColor(node): lastColor = random.randint(0, 2) while True: node.color(Color[lastColor]) d = yield viztask.waitDraw() data = ' ,' + str(lastColor) + ',' + str(d.time) sub_rt.write('\n' + data) tmp_color = [0, 1, 2] tmp_color.remove(lastColor) lastColor = random.choice(tmp_color) yield viztask.waitTime(0.75)
def changeColor2(target=Target2): lastColor = random.randint(0, 2) i = 1 while True: target.color(tg2Colors[lastColor]) d = yield viztask.waitDraw() data = str(i) + ',' + str(lastColor) + ',' + str(d.time) sub_rt.write('\n' + data) tmp = [0, 1, 2] tmp.remove(lastColor) lastColor = random.choice(tmp) i += 1 yield viztask.waitTime(0.75)
def refreshing(clouds): index = 0 while True: clouds[index].remove() pos = np.random.uniform(low=-6, high=6, size=(cloudFreq / freq, 3)) pos[:, 1] = pos[:, 1] / 2 pos[:, 2] = pos[:, 2] - 5 viz.startLayer(viz.POINTS) viz.pointSize(2) for n in range(cloudFreq / freq): viz.vertex(pos[n, 0], pos[n, 1], pos[n, 2]) single_cloud = viz.endLayer() single_cloud.disable(viz.CULLING) single_cloud.setParent(Target) clouds.append(single_cloud) index += 1 yield viztask.waitDraw()
def cross_trial(start_time, wait_time, rt_deadline, remove, message="",training=False): """ Implements a single trial Parameters ========== start_time:float IF start_time == 0, wait for the next trigger pulse. Else, wait until start_time to begin the trial. wait_time:float time to wait until the cross should remove one of its lines rt_deadline:float if the subject did not respond more quickly than the deadline, tell them they blew it remove:str The portion of the cross to remove. Either "hbar" or "vbar". """ descr = {"onset":start_time, "duration":wait_time, "crossbar":remove} new_texture = hbar if remove == "vbar" else vbar if start_time == 0: yield vizact.waitsignal(TRIGGER_EVENT) else: while viz.tick() < start_time: yield viz.waitTime(0.01) # ---- If there's a message, display it for MESSAGE_TIME #block_text.message(message) #vizact.ontimer2(rate=MESSAGE_TIME, repeats=0,func=clear_text) # ---- Flash the cue quad.texture(cue) yield viztask.waitTime(0.5) quad.texture(cross) # ---- Wait the required time yield viztask.waitTime(wait_time) # ---- Set the new texture quad.texture(new_texture) #Wait for next frame to be drawn to screen d = yield viztask.waitDraw() #Save display time displayTime = d.time #Wait for a reaction reaction = yield viztask.waitAny( [HBAR_RESPONSE, VBAR_RESPONSE] ) time_at_response, = reaction.data.data[0] # How did they do?? # -> Hbar remains if reaction.condition is HBAR_RESPONSE: descr["acc_success"] = remove == "vbar" response = "hbar" # -> vbar remains if reaction.condition is VBAR_RESPONSE: descr["acc_success"] = remove == "hbar" response = "vbar" # print "removed:", remove,"responded:",response # Calculate reaction time reactionTime = time_at_response - displayTime descr["speed_success"] = reactionTime < rt_deadline success = descr["speed_success"] and descr["acc_success"] # What sort of feedback to give? #if training: # In training blocks, show the rt #yield training_display(reactionTime,descr["acc_success"]) #else: if success: yield success_display(reactionTime) else: failtype = "WRONG" if descr["speed_success"] else "TIMEOUT" yield fail_display(failtype, reactionTime) quad.texture(cross) descr["response"] = response descr["success"] = success descr["rt"] = reactionTime descr["rt_deadline"]= rt_deadline descr["changetime"] = d.time viztask.returnValue(descr)
def TrackTask(): prevPos = None allData = [] tRegained = 0 stage = 0 # 0: wait for track loss, 1: wait for track regained, 2: wait for trigger pull, 3: trigger pulled. check optical heading position ok, 4: trigger released, ready for next trigger pull that will start actual data collection t = 0. opticalHeadScrewed = False tCount = -1 while True: # wait for track regained stage = 0 while True: pos = setup.trackerDataFun() if prevPos is not None and pos['vive'] == prevPos['vive']: # position didn't change at all, not tracking if stage is not 1: setup.sounds.trialStart.play() print 'track lost' stage = 1 else: # get here only once vive position/orientation starts changing again if stage == 1: setup.sounds.trialCompleted.play() print 'track regained' tRegained = t stage = 2 if qCheckOptHeading else 4 # if not qCheckOptHeading, skip the check if stage == 2 and t - tRegained > nSecWait and ( steamvr.getControllerList()[0].isButtonDown(2) or viz.key.isDown('c', immediate=True)): # first press, check if optical heading position is ok stage = 3 if stage == 3 and not ( steamvr.getControllerList()[0].isButtonDown(2) or viz.key.isDown('c', immediate=True)): # button/trigger released stage = 4 if stage == 4 and ( steamvr.getControllerList()[0].isButtonDown(2) or viz.key.isDown('c', immediate=True)): # second press: time to record some data tCount += 1 break prevPos = pos # check position of optical heading markers is within expected range. Otherwise markers probably switched if qCheckOptHeading and stage in [3, 4] and any([ abs(p - m) > l for p, m, l in zip( pos['optical_heading'][:3], optHeadingPos, optHeadLims) ]): # optical markers screwed, notify if not opticalHeadScrewed: print 'optical heading error. current pose: ' + str( pos['optical_heading']) setup.sounds.alarm.play() opticalHeadScrewed = True else: opticalHeadScrewed = False # limit to update rate d = yield viztask.waitDraw() t = d.time # report position print 'capturing track data' setup.sounds.trialStart.play() count = 0 data = [] while count < trackRate * nSec: ti = setup.trackerDataFun() ti['timeStamp'] = d.time data.append(ti) count += 1 d = yield viztask.waitDraw() # store for later allData.append(data) setup.sounds.trialCompleted.play() # make filename if tCount + 1 == nTrial: time = datetime.datetime.now() fname = ''.join( (str(time.year) + str(time.month).zfill(2) + str(time.day).zfill(2) + str(time.hour).zfill(2) + str(time.minute).zfill(2) + str(time.second).zfill(2))) saveData = {} saveData['data'] = allData scio.savemat('data/' + fname, saveData, long_field_names=True, do_compression=True, oned_as='column') # done viz.quit()
def TrackTask(): prevPos = None tracking = False allData = [] tCount = -1 # run until number of trials finished, or forever while True: # wait for trigger press while not (steamvr.getControllerList()[0].isButtonDown(2) or viz.key.isDown('c', immediate=True)): pos = setup.trackerDataFun() if prevPos is not None and pos['vive'] == prevPos['vive']: # position didn't change at all, not tracking if tracking: print 'track lost' setup.sounds.trialStart.play() tracking = False else: if not tracking: print 'track regained' tracking = True prevPos = pos # store data upon keypress, or upon requested number of trials reached if (viz.key.isDown(viz.KEY_CONTROL_L, immediate=True) and viz.key.isDown('s', immediate=True) and len(allData) > 0) or (nTrial is not None and tCount == nTrial): # make filename time = datetime.datetime.now() fname = ''.join( (str(time.year) + str(time.month).zfill(2) + str(time.day).zfill(2) + str(time.hour).zfill(2) + str(time.minute).zfill(2) + str(time.second).zfill(2))) saveData = {} saveData['data'] = allData scio.savemat('data/' + fname, saveData, long_field_names=True, do_compression=True, oned_as='column') # done, either quit or notify and clear data store if nTrial is not None: viz.quit() else: setup.sounds.trialStart.play() allData = [] # limit to update rate d = yield viztask.waitDraw() # report position print 'capturing track data' tCount += 1 count = 0 data = [] while count < trackRate * nSec: ti = setup.trackerDataFun() ti['timeStamp'] = d.time data.append(ti) count += 1 d = yield viztask.waitDraw() # store for later allData.append(data) setup.sounds.trialCompleted.play() # Wait for trigger to release if still down if steamvr.getControllerList()[0].isButtonDown(2): yield viztask.waitSensorUp(steamvr.getControllerList()[0], steamvr.BUTTON_TRIGGER)
def TrackTask(): prevPos = None tracking = True allData = [] tRegained = 0. waitingForTrack = True t = 0. while True: # wait for trigger press while not (steamvr.getControllerList()[0].isButtonDown(2) or viz.key.isDown('c', immediate=True)): # limit to update rate d = yield viztask.waitDraw() # record n seconds of data tRegained = d.time while True: pos = setup.trackerDataFun() if prevPos is not None and pos['vive'] == prevPos['vive']: # position didn't change at all, not tracking if tracking: print 'track lost' allData = [] waitingForTrack = True tracking = False else: # get here only once vive position/orientation starts changing again if not tracking: print 'track regained' tRegained = t tracking = True if waitingForTrack and t - tRegained > nSecWait: # time to record some data waitingForTrack = False break pos['timeStamp'] = d.time prevPos = pos allData.append(pos) # limit to update rate d = yield viztask.waitDraw() t = d.time # calculate mean and SD for each variable of Vive means = [0.] * 6 SDs = [0.] * 6 for dat in allData: for i, e in enumerate(dat['vive']): means[i] += e N = len(allData) means = [x / N for x in means] # now SD for dat in allData: for i, e in enumerate(dat['vive']): SDs[i] += (e - means[i])**2 SDs = [math.sqrt(x) / (N - 1) for x in SDs] # NB: for analysis of simulataneous data, can just do it qualitative. plot position/orientation over time for both vive and # other source. see offset in time between curves, that gives you differential latency. # wait for threshold exceeded, until controller trigger pulled that stops things setup.sounds.trialStart.play() exceeded = [] d = yield viztask.waitDraw() visible = True while not (steamvr.getControllerList()[0].isButtonDown(2) or viz.key.isDown('c', immediate=True)): pos = setup.trackerDataFun() pos['timeStamp'] = d.time allData.append(pos) # check threshold qThresh = [ abs(x - m) > s * multiplier for x, m, s in zip(pos['vive'], means, SDs) ] if any(qThresh) and visible: for v in setup.visuals: v.visible(viz.OFF) visible = False exceeded.append( len(allData)) # store at which sample this happened # limit to screen update rate d = yield viztask.waitDraw() # save data and exit setup.sounds.trialCompleted.play() time = datetime.datetime.now() fname = ''.join( (str(time.year) + str(time.month).zfill(2) + str(time.day).zfill(2) + str(time.hour).zfill(2) + str(time.minute).zfill(2) + str(time.second).zfill(2))) saveData = {} saveData['data'] = allData saveData['means'] = means saveData['SDs'] = SDs saveData['multiplier'] = multiplier saveData['exceeded'] = exceeded scio.savemat('data/' + fname, saveData, long_field_names=True, do_compression=True, oned_as='column') # done viz.quit()