# -*- coding: utf-8 -*- from psychopy import visual, core, logging from copy import deepcopy import sys import threading import u3 from time import sleep try: import Queue except ImportError: # Python 3 import queue as Queue ### Setting up Labjack data SCAN_FREQUENCY = 1000 d = None d = u3.U3() # To learn the if the U3 is an HV d.configU3() # For applying the proper calibration to readings. d.getCalibrationData() # Set the FIO0 to Analog d.configIO(FIOAnalog=3)# AIN0 and AIN1 d.streamConfig(NumChannels=2, PChannels=[0,1], NChannels=[31,31], Resolution=2, ScanFrequency=SCAN_FREQUENCY) class StreamDataReader(object): def __init__(self, device): self.device = device self.data = Queue.Queue() self.dataCount = 0 self.missed = 0 self.finished = False def readStreamData(self): self.finished = False # print("Start stream.") # start = datetime.now() try: self.device.streamStart() while not self.finished: # Calling with convert = False, because we are going to convert in # the main thread. returnDict = next(self.device.streamData(convert=False)) #returnDict = self.device.streamData(convert=False).next() # Python 2.5 if returnDict is None: print("No stream data") continue self.data.put_nowait(deepcopy(returnDict)) print("Stream stopped.\n") self.device.streamStop() except Exception: try: # Try to stop stream mode. Ignore exception if it fails. self.device.streamStop() except: pass self.finished = True e = sys.exc_info()[1] print("readStreamData exception: %s %s" % (type(e), e)) sdr = StreamDataReader(d) sdrThread = threading.Thread(target=sdr.readStreamData) # Here I'm setting up the animation. disable_gc = False #process_priority = 'realtime' # 'high' or 'realtime' myWin = visual.Window((1500, 900), fullscr=False, screen=0, allowGUI=False,allowStencil=False,monitor='testMonitor', units = 'deg', color=[0,0,0], colorSpace='rgb',blendMode='avg', useFBO=True, waitBlanking=True, process_priority = 'realtime' ) myWin.flip()#present it myStim = visual.PatchStim(myWin, tex=None, mask=None, color='white', size=2) myWin.recordFrameIntervals = False myClock = core.Clock() #just to keep track of time t = visual.TextStim(myWin) #create some stimuli Xinit = -20; Yinit = 0; grating = visual.GratingStim(win=myWin, mask="none", size=(2,1), pos=[Xinit,Yinit], sf=0, color=[1,-1,-1], autoLog=False) fixation = visual.GratingStim(win=myWin, mask= "none", size=(1,2), pos=[20,0], sf=0, color=[-1,-1,-1], autoLog=False) myWin.flip() myWin.recordFrameIntervals = True N_samples = 2000# Miliseconds we will collect data for. nCycles = N_samples/(1000/60)# Convert time to frames to control loop duration # Where we store data data0=[] data1=[] # Start the stream and begin loading the result into a Queue sdrThread.start() sleep(.1)# give some time before start presenting feedback for TrialsN in range(1): #Starting point for my moving stimulus in dva Xinit = -20; Yinit = 0; feedback = 0 message = visual.TextStim(win=myWin, text = feedback) grating = visual.GratingStim(win=myWin, mask="none", size=(2,1), pos=[Xinit,Yinit], sf=0, color=[1,-1,-1]) fixation = visual.GratingStim(win=myWin, mask= "none", size=(1,2), pos=[20,0], sf=0, color=[-1,-1,-1]) beep = 0; fixation.draw() myWin.flip() #draw the stimuli and update the window. This loops controls the time we call srd.data.get for frameN in range(int(round(nCycles))): # Pull results out of the Queue in a blocking manner. This works but the animation is delayed. # result = sdr.data.get(True, 1) # Pull results out of the Queue in a non-blocking manner. This crashes. result = sdr.data.get(False, 1) # Convert the raw bytes (result['result']) to voltage data. r = d.processStreamData(result['result']) # 2 time series to be analysed later. Just the first presents online values. data1.extend(r["AIN1"])# This gives 60000 data points rather than 2000 (2 seconds * 1000Hz Scan frequency) data0.extend(r["AIN0"]) # Get the last 50 AIN0 samples. To provide feedback last50 = data1[-50:]# This gives the right number of data points. feedback = round(sum(last50)/len(last50)) message.setText(text = feedback) message.draw() if frameN<11: grating.pos= (Xinit, 0) else: grating.pos += (0.75, 0)#advance phase by 0.05 of a cycle if grating.overlaps(fixation): beep = beep+1; fixation.color = [1, -1, -1] grating.color = [0, 0, 0] grating.draw() fixation.draw() myWin.logOnFlip(msg='frame=%i' %frameN, level=logging.EXP) myWin.flip()# everything inside the loop should be synced with the screen flip myWin.flip() # Close the device d.close() myWin.fullscr = False myWin.close()