def setupClocks(): global clocks clocks = { 'experiment': clock.Clock(), 'block': clock.Clock(), 'trial': clock.Clock(), 'pause': clock.Clock() } print('Clocks done.')
def print_some_text(win, string, duration): text_obj_2 = visual.TextStim(win, text=string, pos=(0, 0)) this_clock = clock.Clock() while this_clock.getTime() < duration: text_obj_2.draw() win.flip() win.flip()
def show_info(win, file_name, text_size, screen_width, insert='', show_time=999999): """ Clear way to show info message into screen. :param name: part name :param data: beh data :param win: :param file_name: :param screen_width: :param text_size: :param insert: extra text for read_text_from_file :return: """ hello_msg = read_text_from_file(os.path.join(file_name), insert=insert) hello_msg = visual.TextStim(win=win, antialias=True, font=u'Arial', text=hello_msg, height=text_size, wrapWidth=screen_width, color=u'black', alignHoriz='center', alignVert='center') hello_msg.draw() timer = clock.Clock() win.callOnFlip(timer.reset) event.clearEvents() win.flip() while timer.getTime() < show_time: event.clearEvents(eventType='mouse') key = event.getKeys() if key in [['q'], ['return'], ['space']]: if key == ['q']: logging.critical('Experiment finished by user! {} pressed.'.format(key[0])) exit(0) break win.flip()
def main(): """ Main program function to start the experiment manager an initializes needed dependencies Params: None Returns: None """ subject_data = get_subject_info() summary_data = defaultdict(list) summary_data["ID"].append(subject_data["ID"]) summary_data["Sex"].append(subject_data["Gender"]) summary_data["Age"].append(subject_data["Age"]) folder = f"ID_{subject_data['ID']}" if not os.path.isdir(f"./data/{folder}"): os.makedirs(f"./data/{folder}") win = visual.Window(Constants.WINDOW_SIZE, units="pix", fullscr=Constants.FULLSCREEN, color=Constants.BACKGROUND_COLOR) # NOTE: pixel units are not scalable. mouse = event.Mouse() timer = clock.Clock() manager = ExperimentManager(win, mouse, timer, folder, summary_data) while manager.is_running: manager.update() print(summary_data) summary_file = "./data/Summary.csv" if not os.path.isfile(summary_file): with open(summary_file, mode="w+") as file: pandas.DataFrame(summary_data).to_csv(file) else: with open(summary_file, mode="a") as file: pandas.DataFrame(summary_data).to_csv(file, header=False)
def run(self): ''' check the current value of Y --> then, change the color --> done! ''' curtime = 0 square_to_be_colorized = self.st['square'] cl = clock.Clock( ) # yeah...well, we make a second clock. should not be too off in seconds. while curtime < self.tmax: time.sleep(G['EX_PR_SLEEPTIME']) curtime = cl.getTime() # so, what is the y pos? ypos = self.nfsignalContainer[ 0] #this changes due to the other thread... rnew, gnew, bnew = my_color_calculator(self.hb, self.he, self.thrContainer[0], self.colorgap, ypos, 1, -1) square_to_be_colorized.setFillColor((rnew, gnew, bnew), colorSpace='rgb') square_to_be_colorized.setLineColor('black') # then, what is the color? # square_to_be_colorized.fillColor = (rnew, gnew, bnew) if G['EX_INTERACTIONMODE'] == 'master': pass # call staircase calculator now, that will make things ready for the next (feedback) step.
def play_movie(win, movie): timer = clock.Clock() movie.seek(0) # go back to 0 seconds movie.play() # I think we need to say play... while timer.getTime() < movie.duration: movie.draw() win.flip()
def run(self): ''' 1) (re-set) vertices of the line (i.e. add to them) 2) update the position of the crosshair according to curvalue and time 3) handle the patches, too. ''' # print self.nfvalueContainer thrline = self.st['thermo_lines'] # set positions... for l in thrline: oldstart = l.start oldend = l.end l.start = (oldstart[0], self.thrContainer[0] ) #* self.scaling[1]) l.end = (oldend[0], self.thrContainer[0]) # * self.scaling[1]) # print(l.pos) # drawing comes later. scaling = self.scaling curtime = 0 cl = clock.Clock( ) # yeah...well, we make a second clock. should not be too off in seconds. while curtime < self.tmax: time.sleep(G['EX_PR_SLEEPTIME']) curtime = cl.getTime() # so, what is the y pos? ypos = self.nfsignalContainer[0] rnew, gnew, bnew = my_color_calculator(self.hb, self.he, self.thrContainer[0], self.colorgap, ypos, 1, -1) # then, what is the color? thermo_thermometer_container = self.st['thermo_thermometer'] thermocolor = (rnew, gnew, bnew) thermovert = [(coord[0] * scaling[0], coord[1] * scaling[1]) for coord in [(-0.25, -1), (0.25, -1), (0.25, ypos), (-0.25, ypos)]] replacement_thermo = visual.ShapeStim(self.win, lineWidth=1.5, lineColor='white', fillColor=thermocolor, vertices=thermovert) thermo_thermometer_container[0] = replacement_thermo if G['EX_INTERACTIONMODE'] == 'master': pass # call staircase calculator now, that will make things ready for the next (feedback) step.
def __init__(self, name): """ Initialization... """ self._getInfo(name) self._clock = clock.Clock() self._setupLogfile() self._setupWindows() self._setupResponseBox() self._setupExperimentHandler() self._routines = list()
def test_it(G): cl = clock.Clock() # while cl.getTime() < 1: #i in range(1000):e runit = True while runit: print cl.getTime() yield From(asyncio.sleep(0)) if cl.getTime() > 1: runit = False if cl.getTime() > 0.5: #pass print(1 / 0)
def waitTrigger(win, runNum, acqNum, qrDur=.05, qrPos=(-.5, -.5), qrSize=.2): data = {"acqNum": acqNum, "runNum": runNum, "trialStart": time.time()} print("Waiting for trigger pulse ... or key stroke '5'") event.waitKeys(keyList=['5']) clk = clock.Clock() data["runStart"] = time.time() qr = visual.ImageStim(win, qrcode.make(str(data)), pos=qrPos) qr.size = qr.size * qrSize qr.draw() win.flip() core.wait(qrDur) return clk
def __init__(self, win, pos, name, detail_file, sub_id, test_id, width=0.15, height=0.1, color=(178, 178, 178)): self.name = name self.rect = Rect(win, height=height, width=width, units='norm', pos=pos) self.rect.setFillColor(color=color, colorSpace='rgb255') self.rect.setLineColor(color=color, colorSpace='rgb255') self.mouse = event.Mouse(win=win) self.state = self.COVER self.time = 0 self.single_time = 0 self.last_state = self.COVER self.last_time = 0 self.clk = clock.Clock() self.detail_file = detail_file self.sub_id = sub_id self.test_id = test_id
def main(): """Creates a sample client that reads data from a TCP server (see demo/server.py). Data is written to a rawdata.csv file, as well as a buffer.db sqlite3 database. These files are written in whichever directory the script was run. The client can be stopped with a Keyboard Interrupt (Ctl-C).""" import time import sys from psychopy import clock # Allow the script to be run from the bci root, acquisition dir, or # demo dir. sys.path.append('.') sys.path.append('..') sys.path.append('../..') from bcipy.acquisition.client import DataAcquisitionClient from bcipy.acquisition.devices import supported_device from bcipy.acquisition.protocols.dsi.dsi_connector import DsiConnector # Start the server with the command: # python bcipy/acquisition/datastream/tcp_server.py --name DSI --port 9000 device_spec = supported_device('DSI') connection_params = {'host': '127.0.0.1', 'port': 9000} connector = DsiConnector(connection_params=connection_params, device_spec=device_spec) # Use default processor (FileWriter), buffer, and clock. client = DataAcquisitionClient(connector=connector, clock=clock.Clock()) try: client.start_acquisition() print("\nCollecting data for 3s... (Interrupt [Ctl-C] to stop)\n") while True: time.sleep(3) print(f"Number of samples: {client.get_data_len()}") client.stop_acquisition() client.cleanup() break except IOError as e: print(f'{e.strerror}; make sure you started the server.') except KeyboardInterrupt: print("Keyboard Interrupt") client.stop_acquisition() client.cleanup()
def main(): """Creates a sample client that reads data from a TCP server (see demo/server.py). Data is written to a rawdata.csv file, as well as a buffer.db sqlite3 database. These files are written in whichever directory the script was run. The client can be stopped with a Keyboard Interrupt (Ctl-C).""" import time import sys from psychopy import clock # Allow the script to be run from the bci root, acquisition dir, or # demo dir. sys.path.append('.') sys.path.append('..') sys.path.append('../..') from bcipy.acquisition.client import DataAcquisitionClient from bcipy.acquisition.protocols import registry # pylint: disable=invalid-name Device = registry.find_device('DSI') dsi_device = Device(connection_params={'host': '127.0.0.1', 'port': 9000}) # Use default processor (FileWriter), buffer, and clock. client = DataAcquisitionClient(device=dsi_device, clock=clock.Clock()) try: client.start_acquisition() print("\nCollecting data... (Interrupt [Ctl-C] to stop)\n") while True: time.sleep(10) print("Ten Second Passed") print("Number of samples: {0}".format(client.get_data_len())) client.stop_acquisition() client.cleanup() break except IOError as e: print(f'{e.strerror}; make sure you started the server.') except KeyboardInterrupt: print("Keyboard Interrupt") print("Number of samples: {0}".format(client.get_data_len())) client.stop_acquisition() client.cleanup()
def start_event_handler(): print('hallo!') eh = eventhandler.eventHandler({'a': 1, 'b': 2}, clock.Clock()) print(eh.is_alive()) print('hallo!') eh.start() print(eh.is_alive()) for i in range(10): eh.send_message('a') print(eh.is_alive()) time.sleep(0.5) eh.shutdown() return eh
def run(self): if G['EX_TESTSIGNALTYPE'] == 'random': while self.running is True: signal = random.random() / 2 + 0.25 self.lst[0] = signal time.sleep(G['EX_TESTSIGNALUPDATEINTERVAL']) elif G['EX_TESTSIGNALTYPE'] == 'sin': period = G['EX_TESTSIGNALPERIOD'] from math import sin, pi cl = clock.Clock() while self.running is True: signal = sin(cl.getTime() / float(period) * 2. * pi) self.lst[0] = signal time.sleep(G['EX_TESTSIGNALUPDATEINTERVAL'])
def wait_for_key(win, starttext, keys): # the text: text_obj = visual.TextStim(win, text=starttext, pos=(0, 0)) event.clearEvents() press_clock = clock.Clock() correctlyPressed = False draw_incorr_text = False while not correctlyPressed: text_obj.draw() if draw_incorr_text is True and press_clock.getTime() < 1.0: incor_text_obj.draw() else: draw_incorr_text = False win.flip() evs = event.getKeys(timeStamped=press_clock) if len(evs) > 0: buttonsPressed, timesPressed = zip(*evs) buttonPressed = buttonsPressed[0] if buttonsPressed[0] in keys: # f.e. MRI keys correctlyPressed = True # here we break the main loop! else: incor_text_obj = visual.TextStim(win, text="wrong button: %s" % (buttonPressed), pos=(0, -0.5)) draw_incorr_text = True press_clock.reset() win.flip()
def handle_gonogo(GLOBS): ''' This contains the experimenal logic of the Stop Task. A lot of work went into constructing the stimuli. Stimuli parameters are loaded into variables in the code above. Runs 136 trials of Go-Nogo. This function is to be run within the asyncio loop. ''' # we just need it here... STOP=1 GO=0 tooSoonTime = G['S']['tooSoonTime'] myMultiStairs = G['S']['myMultiStairs'] # if the time it took tov respond is smaller than this time --> invalid. numberOfResponses=0 G['S']['nextFLipTasks']=[] # stuff winflupper needs to do later on.. G['S']['clock']=[None] # set the visual contents here... # INITIAL SETTING G['S']['goNogoStim']=G['vstims']['S']['fix'] # yeah, do all kinds of init here. for trialNumber in range(len(G['S']['SSstopgo'])): thisDirection=random.choice(('al','ar')) # obtain this from the file!! LorR = thisDirection[1].upper() thisTrialType = G['S']['SSstopgo'][trialNumber] # this is a 0 (GO) or 1 (STOP) thisTrialType = [GO, STOP][int(thisTrialType)] # shady practices indeed -- so later on I cany say 'if this TrialType is GO:, etc' GorNG = ['Go', 'Stop'][int(thisTrialType)] thisISIWaitTime = G['S']['ISIwaitTime'][trialNumber] correctResponseSide = G['S']['correctResponseSides'][trialNumber] wrongResponseSide = G['S']['wrongResponseSides'][trialNumber] allResponses=[] responded=False # subj responded? tooManyResponses=False trialHandled=False if taskType is STOP: # this should be called only 40 times, since there are 40 stop trials... thisSSD, thisCondition = myMultiStairs.next() # I defined the myMultiStairs above. # this code tells the loop to only continue when continueTroutine is not False # otherwise it'll just keep yielding. # let winflipper make new clock G['S']['continueRoutine']=False G['S']['nextFlipTasks'].append([G['S']['makeNewClock'], G]) # the makeNewClock automatically makes things continue while G['S']['continueRoutine'] is False: yield From(asyncio.sleep(0)) cl=G['S']['clock'] # obtain the clock that was just made. # ok, we can proceed -- the clock has been set. G['S']['goNogoStim']=G['vstims']['S']['pre'] while cl.getTime() < 0.5: yield From(asyncio.sleep(0)) # obtain our next clock... # this code tells the loop to only continue when continueTroutine is not False # otherwise it'll just keep yielding. # let winflipper make new clock G['S']['continueRoutine']=False # make sure upon next window flow, we have a new clock set, and also - that marker is sent signalling the start of the new go/stop trial. G['S']['nextFlipTasks'].append([G['S']['makeNewClock'], G]) # the makeNewClock automatically makes things continue # send the trigger regarding the arrow, as soon as the windows flips G['S']['nextFlipTasks'].append([G['eh'].send_message, ['Begin'+GorNG+LorR]) while G['S']['continueRoutine'] is False: yield From(asyncio.sleep(0)) cl=G['S']['clock'] # obtain the clock that was just made. # this is where we show the arrow + find out whether a key is pressed: G['S']['goNogoStim']=G['vstims']['S'][thisDirection] currentTime = 0.0 while currentTime < 1.0: currentTime = cl.getTime() # set the stimulus to the proper direction (it's a choice, for now... -- but it's much much better to hard-code it) # make the arrow (+ circle) evs=event.getKeys(timeStamped=cl) if len(evs)>0: buttonsPressed, timesPressed = zip(*evs) # it's highly unlikely that two buttons are pressed in a signle # frame, but control for that anyway. allResponses.append((buttonsPressed[0], timesPressed[0])) numberOfResponses += 1 # LOG this event... (i.e. send trigger) # handle event: # once a button is pressed -- display fixation point again. if len(allResponses) > 0 and not responded: # 'clear' the visual window --> fixation cross, again: G['S']['goNogoStim']=G['vstims']['S']['fix'] responded=True buttonPressed, RTime = allResponses[0] if RTime < tooSoonTime: G['ev'].send_message('PressedTooSoon') else: if buttonsPressed[0] == BUTTONS[0]: G['ev'].send_message('RespL') elif buttonsPressed[0] == BUTTONS[1]: G['ev'].send_message('RespR') # if it's a stop trial, then make arrow red after X time if thisTrialType is STOP and not responded: if currentTime > thisSSD: G['S']['goNogoStim']=G['vstims']['S'][thisDirection+'r'] # here we wait... yield From(asyncio.sleep(0)) # # Stop / Inhibit Response Codes # 'BeginGoL':1, # 'BeginGoR':2, # 'BeginStopL':3, # 'BeginStopR':4, # # 'RespL':5, # 'RespR':6, # # 'CorrectGoL':11, # 'CorrectGoR':12, # 'CorrectStopL':13, # 'CorrectStopR':14, # 'ErrorCommission':15, # # # don't expect too many of these: # 'ErrorOmission':21, # 'PressedTooSoon':22, # 'TooManyResponses':23, # 'WrongSideErrorCommission':24, # 'WrongSideGo':25, # so the loop is done -- let's figure out what kind of trial this was. # taking care of the button press itself, as soon as button is pressed: if not trialHandled and responded: trialHandled=True if len(allResponses) > 1: trialOutcome = 'TooManyResponses' if trialType is STOP: myMultiStairs.addResponse(0) else: if RTime < tooSoonTime: trialOutcome = 'PressedTooSoon' if trialType is STOP: myMultiStairs.addResponse(0) else: if thisTrialType is STOP: if buttonPressed == correctResponseSide: trialOutcome = 'ErrorCommission' myMultiStairs.addResponse(0) elif buttonPressed == wrongResponseSide: trialOutcome = 'WrongSideErrorCommission' myMultiStairs.addResponse(0) elif thisTrialType is GO: if buttonPressed == correctResponseSide: trialOutcome = 'CorrectGo'+correctResponseSide # not yet... elif buttonPressed == wrongResponseSide: trialOutcome = 'WrongSideGo' # handle the 'response' if the button was NOT pressed: if not trialHandled and not responded: trialHandled = True if trialType is GO: trialOutcome = 'ErrorOmission' if trialType is STOP: trialOutcome = 'CorrectStop'+LorR myMultiStairs.addResponse(1) # so we send it out: G['ev'].send_message(trialOutcome) # obtain our next clock... # this code tells the loop to only continue when continueTroutine is not False # otherwise it'll just keep yielding. # let winflipper make new clock continueRoutineContainer[0]=False nextfliptasks.append([makeNewClock]) # the makeNewClock automatically makes things continue while continueRoutineContainer[0] is False: yield From(asyncio.sleep(0)) cl=clockContainer[0] # obtain the clock that was just made. # this is a nice place to save it to logfile: before the # send a report about the STOP trial, write a nice line: # logging.data('messa') logging.flush() # ok, we can proceed -- the clock has been set. goNogoStimContainer=sstims['fix'] while cl.getTime() < thisISIWaitTime: yield From(asyncio.sleep(0)) # the stop task should be finished now! # the visual task should also be finished around the same time. # so further stuff, we can do with basic instructions, wait times, etc #%% ASYNC V - Handle the Audio! # the audio stim list: # audio_stim_list = [[10.,20.,'audio',['left','40']],[112.5,130.,'audio',['left','40']],[242.5,260.,'audio',['left','40']],[50.,60.,'audio',['left','55']],[195.,205.,'audio',['left','55']],[312.5,330.,'audio',['left','55']],[30.,40.,'audio',['right','40']],[147.5,165.,'audio',['right','40']],[277.5,295.,'audio',['right','40']],[77.5,95.,'audio',['right','55']],[175.,185.,'audio',['right','55']],[215.,225.,'audio',['right','55']]] # make a more usable stim list: audio_stim_list = [ [10.0, 20.0, 'aud_l40'], [112.5, 130.0, 'aud_l40'], [242.5, 260.0, 'aud_l40'], [50.0, 60.0, 'aud_l55'], [195.0, 205.0, 'aud_l55'], [312.5, 330.0, 'aud_l55'], [30.0, 40.0, 'aud_r40'], [147.5, 165.0, 'aud_r40'], [277.5, 295.0, 'aud_r40'], [77.5, 95.0, 'aud_r55'], [175.0, 185.0, 'aud_r55'], [215.0, 225.0, 'aud_r55'] ] # load in the audio's timings, defined in seconds, so that later on, one could # input triggers into the EEG (or optionally -- send out triggers with the event handler) # 40 Hz: timings40Hz=np.loadtxt('stims/audio_40_ts.txt'); # 50 Hz: timings55Hz=np.loadtxt('stims/audio_55_ts.txt') # see also the figure_out_audio_timings.m file to further play with the audio's # waveforms. snd40hzL = sound.backend_pygame.SoundPygame(value='stims/audio_40Hz_L.wav',loops=0) snd40hzR = sound.backend_pygame.SoundPygame(value='stims/audio_40Hz_R.wav',loops=0) snd55hzL = sound.backend_pygame.SoundPygame(value='stims/audio_55Hz_L.wav',loops=0) snd55hzR = sound.backend_pygame.SoundPygame(value='stims/audio_55Hz_R.wav',loops=0) astims={ 'aud_l40':snd40hzL, 'aud_r40':snd40hzR, 'aud_l55':snd55hzL, 'aud_r55':snd55hzR } # put these into the variable, too... G['astims']=astims G['A']['audio_stim_list']=audio_stim_list G['A']['timings40Hz']=timings40Hz G['A']['timings55Hz']=timings5Hz @asyncio.coroutine def handle_audio(G): ''' this should handle the audio stimuli, using the async programming style. it starts a new clock and depending on timings, will start some audio samples, L or R, 40 or 55 Hz. ''' audioClock=clock.Clock() playing=False withinAudioBlock=False prevWithinAudioBlock=False RunAudio=True currentTime=audioClock.getTime() while currentTime < 340.: #currentTime < 340.: # print('hello') # print(currentTime) if not playing: # I can safely use this since only one audio is playing at a time. withinAudioBlock=False for item in audio_stim_list: b, e, stim = item if b < currentTime < e: currentStim = stim withinAudioBlock=True astims[stim].play() playDuration=astims[stim].getDuration() playing=True playClock=clock.Clock() print(stim) logging.data(stim) # eh.send_message(stim) else: if playClock.getTime() > playDuration: # figure out if something is playing playing=False # try dealing with begin and ending markers: if withinAudioBlock and not prevWithinAudioBlock: messg=currentStim.replace('_','_b') print(messg) logging.data(messg) # eh.send_message(stim) prevWithinAudioBlock=True elif prevWithinAudioBlock and not withinAudioBlock: messg=currentStim.replace('_','_e') print(messg) logging.data(messg) # eh.send_message(stim) prevWithinAudioBlock=False # this will stop this loop, probably: currentTime=audioClock.getTime() #if currentTime > 340.: # print('Stopping!') # RunAudio=False yield From(asyncio.sleep(0)) # pass control to someone else, while this guy sleeps a bit. #%% ASYNC II - The Visual handler ## set up the functions to be used in the end for asyncing through the loops: # load the vis table somewhere here - big mem space (.csv?) # Visual Helpers nextfliptasks=[] stimulusContents=[] def makeNewClock(): clockContainer.append(clock.Clock()) continueRoutineContainer[0]=True # load in the table that tells me all the stop signal stuff (.csv?) #% Frame-by-frame checkerboard List # load in the frame-list of the visual stimuli: i.e. saying when things should # be used: ASYNC_SLEEPTIME = 1/60.*0.75 with open('efl/fd.pkl','rb') as f: fd=pickle.load(f) with open('efl/complete_fd_list.pkl','rb') as f: complete_fd_list=pickle.load(f) # with open('efl/fd_with_markers.pkl','rb') as f: # fd_with_markers=pickle.load(f) with open('efl/fd_with_markers_II.pkl','rb') as f: fd_with_markers=pickle.load(f) @asyncio.coroutine def handle_visual(): ''' This flips the window, draws the stuff to be drawn, and calls functions to be called from the stop task. It is supposed to be run in the asyncio loop. ''' # logging.console.setLevel(logging.DEBUG) mainClock=mainClockContainer[0] frameCounter=0 previousShapes=[] mainCurrentTime=0 totFrames=len(fd_with_markers) # visualClock=clock.Clock() # this will run the entire length of the visual... # within this time, the stop signal task will (hopefully) finish. # OR... we can also just use a counter. while frameCounter < totFrames: # the workflow # 1) Prepare everything + draw # 2) Prepare markers # 3) win.flip() + the callOnFlip routines to be done. # all the visual stuff: frameIndex, visContents, markers = fd_with_markers[frameCounter] frameCounter += 1 # deal with the visuals -- using vstims which should be accessible # we get the list... # create the shapes to be drawn using list comprehension if len(visContents) > 0: shapes=[stim for stim in vstims[ind] for ind in visContents] else: shapes=[] # add the gonogo stimuli to them: if goNogoStimContainer[0] is not None: for stim in goNogoStimContainer[0]: shapes.append(goNogoStims) # draw them on our little canvas. for shape in shapes: shape.draw() # prepare the calls for the next iteration, including marlers; # deal with visual markers if len(markers) > 0: for marker in markers: win.callOnFlip(eventHandler.handle,marker) for task in nextfliptasks: if len(task)==1: win.callOnFlip(task) elif len(task)==2: win.callOnFlip(task, args) # we flip the screen here - this will take ~ 16.66667 msec. win.flip() # sleep for a little while: yield From(asyncio.sleep(ASYNC_SLEEPTIME)) # do for loop for TIME (I suppose) # check vis table + draw stimuli # if there's an event - send to sync # check stimulus for stop + draw stimuli # pass on current time for audio presentation (this is another process) # AWAIT (!) -- to flip the window #%% ASYNC III - The Main Event Loop @asyncio.coroutine def test_it(): cl=clock.Clock() # while cl.getTime() < 1: #i in range(1000):e runit=True while runit: print cl.getTime() yield From(asyncio.sleep(0)) if cl.getTime() > 1: runit=False if cl.getTime() > 0.5: #pass print(1/0) @asyncio.coroutine def handle_exception(f, G, loop): print f print loop try: yield From(f(G)) except Exception: # print debug information print('---------------') print('---------------') print('ERROR OCCURRED:') print(sys.exc_info()[1]) traceback.print_tb(sys.exc_info()[2]) pending = asyncio.Task.all_tasks() for task in pending: task.cancel() # Now we should await task to execute it's cancellation. # Cancelled task raises asyncio.CancelledError that we can suppress: #with suppress(asyncio.CancelledError): # loop.run_until_complete(task) loop.stop() # stops the loop, gives an error for that, too. def run_main_loop(G): ''' This runs the stopingibition/visual/audio part of the paradigm using asyncio-replacement trollius. Before and after, we can still present other stimuli. ''' # something like this: mainClock=clock.Clock() mainClockContainer[0]=mainClock # put it into my list, that double-serves # as a pointer loop=asyncio.new_event_loop() asyncio.set_event_loop(loop) #tasks = [ # asyncio.async(handleVisual()), # asyncio.async(handleGonogo()), # asyncio.async(handleEscape()), # ] tasks_dbg = [ asyncio.async(handle_exception(test_it,G,loop)), asyncio.async(handle_exception(handle_audio,G,loop)), asyncio.async(handle_exception(handle_visual,G,loop)) #asyncio.async(handle_exception(handle_visual,loop)), #asyncio.async(handle_exception(handle_gonogo,loop)) ] tasks = [ asyncio.async(test_it(G)), asyncio.async(handle_audio(G)) ] # so to debug, just run tasks_dbg instead of tasks. loop.run_until_complete(asyncio.wait(tasks_dbg)) loop.close() #%% MAIN -- hope things work if __name__=="__main__": # do the stuff. run_main_loop() #%% The Rest # @asyncio.coroutine # def handle_exception_test_it(): # try: # yield From(test_it()) # except Exception: # # #print(sys.last_type) # #traceback.print_tb(sys.last_traceback) # #print("exception consumed") # # print('hallo!') # # print(traceback) # print(sys.exc_info()[1]) # traceback.print_tb(sys.exc_info()[2]) # # etype, evalue, etraceback = sys.exec_info() # # traceback.format_exc() # # print(traceback.fortmat_exec(etraceback)) # # @asyncio.coroutine # def handle_exception_handle_audio(): # try: # yield From(handle_audio()) # except Exception: # # #print(sys.last_type) # #traceback.print_tb(sys.last_traceback) # #print("exception consumed") # # print('hallo!') # # print(traceback) # print(sys.exc_info()[1]) # traceback.print_tb(sys.exc_info()[2]) # # # etype, evalue, etraceback = sys.exec_info() # # traceback.format_exc() # # print(traceback.fortmat_exec(etraceback)) # # # # we debug by CHAINING coroutines. Very very clear, yes. But it's necessity for now. # # would be nice to enable this feature in a nicer way for someone like me. #%% Getting Input # see: http://easygui.sourceforge.net/tutorial.html#enterbox # variable = easygui.enterbox('hello','title','text') # OR -- use psychopy's functions: # expName = 'loc_v1' # from the Builder filename that created this script # expInfo = {'participant':'', 'session':'001'} # dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) # # access via expInfo['participant'], etc. #%% Gonogo Thoughts # vis contents is a list that's accessible by the function # if the function changes its contents, then other functions will be able to # read in those contents, too. # I let the functions talk to each other using ... what? # visContents is a list from handleGoNogo that contains the stuff to be drawn # GoNogo's end # nexFlipTasks is a list/.. or a dict of stuff with function names and arguments # that handleVisual should call using win. # #class GoNogo(object): # def __init__(self, SSnumber, SSstopgo, myMultiStairs, myVisualContents,nextFlipTasks, newClock, continueRoutine): # self.SSnumber=SSnumber # self.SSstopgo=SSstopgo # self.myMultiStairs=myMultiStairs # self.myVisualContents=myVisualContents # self.nextFlipTasks=nextFlipTasks # self.newClock=newClock # self.continueRoutine=continueRoutine # # after some sleep, my brain might be able to conceive of how I could make this with a Object Oriented programming # in the event loop in any case I should definitely use some kind of function that yields. # or can I also make coroutine objects? # and.. how to implement this, then? #%% Starcase usage -- use the starcase to loop over the stop trials: # myMultiStair.next() # myMultiStair.addResponse(1) # # getting intensities (for later to average over): # # myMultiStair.staircases[3].intensities # for thisIntensity, thisCondition in myMultiStairs: # print(thisIntensity) # print(thisCondition) # myMultiStairs.addResponse(random.choice([0,1])) #%% # visual_evt_codes={'left':{'8':87,'13':137},'right':{'8':88,'13':138}} # # # these are markers for the frequency analysis # visual_evt_codes_begin={'left':{'8':83,'13':133},'right':{'8':84,'13':134}} # visual_evt_codes_end={'left':{'8':85,'13':135},'right':{'8':86,'13':136}} # # # these are the thread starts - which conveniently also denotify what your visual segments # # should BE - in case you wish to reconstruct the visual ERP # global visual_evt_codes_beginvisthread # visual_evt_codes_beginvisthread={'left':{'8':81,'13':131},'right':{'8':82,'13':132}} # # # # # # # audio_evt_codes={'left':{'40':41,'55':51},'right':{'40':42,'55':52}} # audio_evt_codes_begin={'left':{'40':43,'55':53},'right':{'40':44,'55':54}} # audio_evt_codes_end={'left':{'40':45,'55':55},'right':{'40':46,'55':56}} # # # txt_evt_codes = {'normal':100, 'oddball':101} #
def new_clock(x): x['S']['clock'] = clock.Clock() x['S']['continueRoutine'] = True
def test_it(): cl=clock.Clock()
#%% Initialize the Window win=visual.Window(size=(800,600), fullscr=False, allowGUI=True, winType='pyglet', waitBlanking=False) # since we're dealing with a couple of loops that are intermixed, and global variables are evil, at least # do this -- make a dict that contains all variables that are needed so that the intermixed loops all # require only ONE input argument, which helps me with the async stuff later on. # only use the G if it's going to be used later on in the gonogo, in the stop or in the visual. G=dict() #%% Handle logging G['mainClock']=clock.Clock() # figure out if there's a log directory, if not --> make it: if not os.path.exists(LOGDIR): os.makedirs(LOGDIR) # figure out which files reside within this logfile directory: if len(os.listdir(LOGDIR)) == 0: logcounter=0 else: # figure out biggest number: #logcounter = max([int(match.group(1)) #for match in [re.match(LOGFILEBASE+'([0-9]*)'+'.log',item) #for item in os.listdir(LOGDIR)]])
def __init__(self, win, test_file, sum_file, detail_file, sub_id, big_support=False): self.win = win self.test_file = test_file self.sum_file = sum_file self.detail_file = detail_file self.sub_id = sub_id self.test_id = self.test_file.split('.')[0] self.big_support = big_support self.clk = clock.Clock() self.start_time = 0 self.first_look = True # 处理文件输入 file_handle = open(os.path.join('tests', test_file), 'r', encoding='utf-8') self.attributes_num = int(file_handle.readline()) self.attributes_name = file_handle.readline().rstrip('\n').split(',') self.choices_num = int(file_handle.readline()) self.choices = [] for i in range(self.choices_num): choice = {} choice['choice_name'] = file_handle.readline().rstrip('\n') choice['attributes'] = [] for j in range(self.attributes_num): attribute_content = file_handle.readline().rstrip('\n') choice['attributes'].append(attribute_content) self.choices.append(choice) file_handle.close() # 小选择集随机取6个 if not big_support: self.choices_num = 6 random.shuffle(self.choices) self.choices = self.choices[:6] # 选项顺序随机打乱 random.shuffle(self.choices) # 写入表头 sum_write = ['sub_id', 'test_id', 'choice', 'decision_time'] for i in self.choices: for j in self.attributes_name: sum_write.append(i['choice_name'] + '_' + j) sum_file.write(','.join(sum_write)) sum_file.write('\n') detail_write = ('sub_id', 'test_id', 'action', 'time') detail_file.write(','.join(detail_write)) detail_file.write('\n') ''' if big_support: x轴(-0.8, 0.9),-0.95留给属性 y轴(-0.9, 0.9),0.9留给选项标签 else: x轴(-0.7, 0.8),-0.85留给属性 y轴(-0.5, 0.5),0.5留给选项标签 ''' # 生成labels self.labels = [] for i in range(self.choices_num): if self.big_support: self.labels.append(TextStim(win, text=self.choices[i]['choice_name'], height=0.04, pos=(1.7 / (min(12, self.choices_num) - 1) * (i % 12) - 0.8, 0.9 - 0.12 * (i // 12 * 8)), color=(0, 0, 0), colorSpace='rgb255', name='label'+self.choices[i]['choice_name'])) else: self.labels.append(TextStim(win, text=self.choices[i]['choice_name'], height=0.04, pos=(1.5 / (min(6, self.choices_num) - 1) * (i % 6) - 0.7, 0.5), color=(0, 0, 0), colorSpace='rgb255', name='label'+self.choices[i]['choice_name'])) # 生成hints self.hints = [] for i in range(self.attributes_num): if big_support: self.hints.append(TextStim(win, text=self.attributes_name[i], height=0.04, pos=(-0.95, 0.9 - 0.12 * (i+1)), units='norm', color=(0, 0, 0), colorSpace='rgb255', name='text'+self.attributes_name[i])) self.hints.append(TextStim(win, text=self.attributes_name[i], height=0.04, pos=(-0.95, 0.9 - 0.12 * (i+1+7+1)), units='norm', color=(0, 0, 0), colorSpace='rgb255', name='text'+self.attributes_name[i])) else: self.hints.append(TextStim(win, text=self.attributes_name[i], height=0.04, pos=(-0.85, 0.5 - 0.12 * (i+1)), units='norm', color=(0, 0, 0), colorSpace='rgb255', name='text'+self.attributes_name[i])) # 生成texts和covers self.texts = {} self.covers = {} for i in range(self.choices_num): choice_name = self.choices[i]['choice_name'] for j in range(self.attributes_num): attribute_name = self.attributes_name[j] attribute_content = self.choices[i]['attributes'][j] if self.big_support: self.texts[choice_name+'_'+attribute_name] = TextStim(win, text=attribute_content, height=0.04, pos=(1.7 / (min(12, self.choices_num) - 1) * (i % 12) - 0.8, 0.9 - 0.12 * (i // 12 * 8 + j + 1)), units='norm', color=(0, 0, 0), colorSpace='rgb255', name='text'+choice_name+attribute_name) self.covers[choice_name+'_'+attribute_name] = Cover(win, pos=(1.7 / (min(12, self.choices_num) - 1) * (i % 12) - 0.8, 0.9 - 0.12 * (i // 12 * 8 + j + 1)), name=choice_name+'_'+attribute_name, detail_file=self.detail_file, width=0.12, height=0.08, sub_id=self.sub_id, test_id=self.test_id) else: self.texts[choice_name+'_'+attribute_name] = TextStim(win, text=attribute_content, height=0.04, pos=(1.5 / (min(6, self.choices_num) - 1) * (i % 6) - 0.7, 0.5 - 0.12 * (j+1)), units='norm', color=(0, 0, 0), colorSpace='rgb255', name='text'+choice_name+attribute_name) self.covers[choice_name+'_'+attribute_name] = Cover(win, pos=(1.5 / (min(6, self.choices_num) - 1) * (i % 6) - 0.7, 0.5 - 0.12 * (j+1)), name=choice_name+'_'+attribute_name, detail_file=self.detail_file, width=0.12, height=0.08, sub_id=self.sub_id, test_id=self.test_id) self.buttons = [] for i in range(self.choices_num): if self.big_support: self.buttons.append(Button(win, pos=(1.7 / (min(12, self.choices_num) - 1) * (i % 12) - 0.8, 0.9 - 0.12 * (i // 12 * 8 + self.attributes_num + 1)), height=0.05, width=0.1, name=self.choices[i]['choice_name'])) else: self.buttons.append(Button(win, pos=(1.5 / (min(6, self.choices_num) - 1) * (i % 6) - 0.7, 0.5 - 0.12 * (self.attributes_num+1)), height=0.05, width=0.1, name=self.choices[i]['choice_name']))
# -*- coding: utf-8 -*- """ Created on Wed Sep 5 20:45:57 2018 @author: User """ import psychopy import eventhandler from psychopy import clock if __name__ == "__main__": eh = eventhandler.eventHandler({'a': 1, 'b': 2}, clock.Clock()) eh.start() eh.send_message('a')
get rid of this process -- call join later on from the main process ''' # also - send triggers via our network connection towards if not self._shutdown.is_set(): self._shutdown.set() else: print('already shut down!') # time.slee if __name__ == "__main__": # to test whether the LPT sends -- and it does! d = {'a': 1, 'b': 2, 'c': 101} cl = clock.Clock() cl = clock.Clock() eh = eventHandler(d, cl) # time.sleep(0.5) print(cl.getTime()) print('hallo!!!') ev = eventHandler(d, cl) # time.sleep(10) ev.start() print('event hander started')
def handle_visual(win): ''' This flips the window, draws the stuff to be drawn, and calls functions to be called from the stop task. It is supposed to be run in the asyncio loop. ''' mainClock=clock.Clock() # our main clock... frameCounter=0 previousShapes=[] mainCurrentTime=0 # this will run the entire length of the visual... # within this time, the stop signal task will (hopefully) finish. # OR... we can also just use a counter. while mainCurrentTime < 340. : # the workflow # 1) Prepare everything + draw # 2) Prepare markers # 3) win.flip() + the callOnFlip routines to be done. # all the visual stuff: frameIndex, visContents, markers = fd_with_markers[frameCounter] frameCounter += 1 # deal with the visuals -- using vstims which should be accessible # we get the list... # create the shapes to be drawn using list comprehension if len(visContents) > 0: shapes=[stim for stim in vstims[ind] for ind in visContents] else: shapes=[] # add the gonogo stimuli to them: for stim in goNogoStimContainer[0]: shapes.append(goNogoStims) # draw them on our little canvas. for shape in shapes: shape.draw() # prepare the calls for the next iteration, including marlers; # deal with visual markers if len(markers) > 0: for marker in markers: win.callOnFlip(eventHandler.handle,marker) for task in nextfliptasks: if len(task)==1: win.callOnFlip(task) elif len(task)==2: win.callOnFlip(task, args) # we flip the screen here - this will take ~ 16.66667 msec. win.flip() # sleep for a little while: yield From(asyncio.sleep(ASYNC_SLEEPTIME))
def run(self): ''' This part runs - with a copy of memory upon its creation - in the separate process So it should just look at the queue, see if something's up, and send a trigger when it does. ''' # do some while loop, checking for messages, and when one arrives --> # process it with both logfile (possibly) and with sending parallel # and also with. print('___->' + __name__) print(self.clock.getTime()) # do we even have a parallel port? #print('---------') #print('---------') #print('AT START OF RUN') #print('---------') #print('---------') print(self.LPTAddress) try: self._port = parallel.ParallelPort(self.LPTAddress) self._port.setData(0) # this is the 'reset' to 0 self._port_doreset = False # once done we shouldn't do it.. self._port_waitttime = 0.005 # wait 5 msec after a trigger.. except OSError: self._port = None self._port_doreset = False self._port_waitttime = None print('OS Does not seem to have a parallel port') # deactivate our parallel... self.sendParallel = False # so that's the logfile -- open op the socet, too: self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) to_be_lpted = [] # we start off empty here. to_be_written = [] # for sending it to a file. to_be_written_messages = [] lpt_decay_clock = clock.Clock() code_sending_in_progress = False send_last_one = False if self.sendLogFile: expLogger = open(self.newLogFile, 'w') # , logging.EXP) print('Opened: %s\n' % expLogger) while not self._shutdown.is_set(): time.sleep(0.0005) # take it easy on the CPU while not self._queue.empty(): try: message = self._queue.get() senttime = self._timequeue.get( ) # I want to check how long it takes to deal with the queue like this. code_to_send = self.messagedict[message] except: print('That code doesn\'' 't exist: %s\n' % message) break # print(message) # print(code_to_send) if self.sendParallel: # put em into our to-be-sent-by-lpt list: to_be_lpted.append(code_to_send) # self._port.setData(code_to_send) # following code is to reset to 0 of the LPT code output, after X msec. # only evaluate if the queue is empty == dealing with the latest marker. #if self._queue.empty(): # lasttime=self.clock.getTime() # self._port_doreset=True if self.sendTcpIp: # this is ultra-fast -- so no need to deal with this later. self.sock.sendto(unicode(code_to_send), (self.destip, self.destport)) if self.sendLogFile: # might be slow - better make sure all codes are sent first to_be_written.append(code_to_send) to_be_written_messages.append(message) # heretime2=self.clock.getTime() # print('code: %d\t time sent: %.6f time logged: %.6f, diff = %.6f' % (code_to_send, senttime, heretime2, heretime2-senttime)) # print('writing stuff took: %.3f msec' % ((heretime2-heretime)*1000)); if self.sendParallel: # avoid jamming up and missing triggers -- at the cost of making sure some temporal inaccuracy. # IF not too many codes to send out, things should work out. if not code_sending_in_progress and len(to_be_lpted) > 0: tmpcode = to_be_lpted.pop(0) self._port.setData(tmpcode) lpt_decay_clock.reset() # reset the clock... code_sending_in_progress = True if len( to_be_lpted ) == 0: # after popping, see if we need to send the mast one. send_last_one = True # so send the last one (as 0) if not code_sending_in_progress and send_last_one: self._port.setData(0) lpt_decay_clock.reset() # reset the clock... send_last_one = False code_sending_in_progress = True if code_sending_in_progress and lpt_decay_clock.getTime( ) > self.LPTTriggerWaiting: code_sending_in_progress = False # so we can move on to the next code. if self.sendLogFile: if len(to_be_written) > 0: # print(to_be_written) wtmpcode = to_be_written.pop(0) wtmpcode_message = to_be_written_messages.pop(0) heretime = self.clock.getTime() # simplified logfile for data analysis: simplestr = '%.6f\t%.6f\t%.6f\t%d\n' % ( senttime, heretime, heretime - senttime, wtmpcode) expLogger.write(simplestr) # a more in-depth log of what was going on: # logging.data(mystr) # and write it to the psychopy main logifles, too. if self.printToTerminal: if wtmpcode in self.printToTerminalAllowed: mystr = 'code: %d, message was: %s\ttime sent: %.6f time logged: %.6f, diff = %.6f' % ( wtmpcode, wtmpcode_message, senttime, heretime, heretime - senttime) print(mystr) # # this is onlyt true if port needs to be reset, otherwise leave as-is. # if self.sendParallel and self._port_doreset: # # check the time - 10msec passed? # if (self.clock.getTime() - lasttime) > self._port_waitttime: # self._port.setData(0) # self._port_doreset=False # at the end of the while loop, we have set the shutdown event - so do it. if self.sendLogFile: # give our system a little bit of time to actually write the file: time.sleep(1) expLogger.close() print('Closed: %s\n' % expLogger)
def pre_mainloop(self): MostBasicPsychopyFeedback.pre_mainloop(self) # do the trick -- SAVE all of those things! --> and put it in settings.pkl. v = dict() v['caption'] = self.caption v['color'] = self.color v['fontheight'] = self.fontheight v['STARTKEYS'] = self.STARTKEYS v['EX_THRLINEWIDTH'] = self.EX_THRLINEWIDTH v['EX_COLORGAP'] = self.EX_COLORGAP v['EX_TVSP'] = self.EX_TVSP v['EX_TPAUSE'] = self.EX_TPAUSE v['EX_NREGULATE'] = self.EX_NREGULATE v['EX_NTRANSFER'] = self.EX_NTRANSFER v['EX_SHOWCHECKORCROSS'] = self.EX_SHOWCHECKORCROSS v['EX_SHOWCHECKORCROSSTRANSFER'] = self.EX_SHOWCHECKORCROSSTRANSFER v['EX_SHOWPOINTS'] = self.EX_SHOWPOINTS v['EX_SQUARESIZE'] = self.EX_SQUARESIZE v['EX_UPREGTEXT'] = self.EX_UPREGTEXT v['EX_TESTSIGNALUPDATEINTERVAL'] = self.EX_TESTSIGNALUPDATEINTERVAL v['EX_NREST'] = self.EX_NREST v['EX_SCALING'] = self.EX_SCALING v['EX_INTERACTIONMODE'] = self.EX_INTERACTIONMODE v['EX_NOBSERVE'] = self.EX_NOBSERVE v['EX_NOREGTEXT'] = self.EX_NOREGTEXT v['EX_TINSTR'] = self.EX_TINSTR v['EX_THERMOCLIMS'] = self.EX_THERMOCLIMS v['EX_GRAPHICSMODE'] = self.EX_GRAPHICSMODE v['EX_STAIRCASEMANIPULATION'] = self.EX_STAIRCASEMANIPULATION v['EX_POINTS_PENALTY'] = self.EX_POINTS_PENALTY v['EX_TESTSIGNALPERIOD'] = self.EX_TESTSIGNALPERIOD v['EX_TMARK'] = self.EX_TMARK v['EX_TESTNFNOISE'] = self.EX_TESTNFNOISE v['EX_PATCHCOLOR'] = self.EX_PATCHCOLOR v['EX_TJITT'] = self.EX_TJITT v['EX_TFB'] = self.EX_TFB v['EX_POINTS_REWARD'] = self.EX_POINTS_REWARD v['EX_PR_SLEEPTIME'] = self.EX_PR_SLEEPTIME v['EX_TESTSIGNALTYPE'] = self.EX_TESTSIGNALTYPE v['EX_BUTTONS'] = self.EX_BUTTONS v['EX_INSTR'] = self.EX_INSTR v['EX_RUNS'] = self.EX_RUNS v['EX_SND_LOWESTTONE'] = self.EX_SND_LOWESTTONE v['EX_SND_HIGHESTTONE'] = self.EX_SND_HIGHESTTONE v['EX_EMG_THERMOWIDTH'] = self.EX_EMG_THERMOWIDTH v['EX_EMG_THERMOHEIGHT'] = self.EX_EMG_THERMOHEIGHT v['EX_EMG_THERMOEDGE'] = self.EX_EMG_THERMOEDGE v['EX_TXT_COUNTER'] = self.EX_TXT_COUNTER v['MONITOR_PIXWIDTH'] = self.MONITOR_PIXWIDTH v['MONITOR_PIXHEIGHT'] = self.MONITOR_PIXHEIGHT v['MONITOR_WIDTH'] = self.MONITOR_WIDTH v['MONITOR_HEIGHT'] = self.MONITOR_HEIGHT v['MONITOR_DISTANCE'] = self.MONITOR_DISTANCE v['MONITOR_GAMMA'] = self.MONITOR_GAMMA v['MONITOR_FPS'] = self.MONITOR_FPS v['MONITOR_USEDEGS'] = self.MONITOR_USEDEGS v['MONITOR_DEGS_WIDTHBASE'] = self.MONITOR_DEGS_WIDTHBASE v['MONITOR_DEGS_HEIGHTBASE'] = self.MONITOR_DEGS_HEIGHTBASE v['MONITOR_FLIPHORIZONTAL'] = self.MONITOR_FLIPHORIZONTAL v['MONITOR_FLIPVERTICAL'] = self.MONITOR_FLIPVERTICAL v['MONITOR_RECORDFRAMEINTERVALS'] = self.MONITOR_RECORDFRAMEINTERVALS v['MONITOR_NSCREENS'] = self.MONITOR_NSCREENS v['MONITOR_DISPLAYONSCREEN'] = self.MONITOR_DISPLAYONSCREEN v['MONITOR_FULLSCR'] = self.MONITOR_FULLSCR v['MONITOR_ALLOWGUI'] = self.MONITOR_ALLOWGUI v['LOG_PATHFILE'] = self.LOG_PATHFILE v['LOG_PATHFILE_EVENT'] = self.LOG_PATHFILE_EVENT v['EVENT_LPT_TRIGGER_WAIT'] = self.EVENT_LPT_TRIGGER_WAIT v['EVENT_destip'] = self.EVENT_destip v['EVENT_destport'] = self.EVENT_destport v['EVENT_LPTAddress'] = self.EVENT_LPTAddress v['EVENT_LPTTrigWaitTime'] = self.EVENT_LPTTrigWaitTime v['EVENT_TRIGLOG'] = self.EVENT_TRIGLOG v['EVENT_sendParallel'] = self.EVENT_sendParallel v['EVENT_sendTcpIp'] = self.EVENT_sendTcpIp v['EVENT_sendLogFile'] = self.EVENT_sendLogFile v['EVENT_printToTerminal'] = self.EVENT_printToTerminal v['EVENT_printToTerminalAllowed'] = self.EVENT_printToTerminalAllowed # so these are NOW control parameters: v['EX_TUNING_TYPE'] = self.EX_TUNING_TYPE # = 'thr' # alternatives are 'linear', and maybe 'fancy' v['EX_TUNING_PARAMS'] = self.EX_TUNING_PARAMS # = [1.0, 0.0] # linear requires a slope and offset. - eill not be used if it's not 'linear' v['EX_WIN_CONDITION'] = self.EX_WIN_CONDITION # = 'time_above_thr' v['EX_WIN_PARAMS'] = self.EX_WIN_PARAMS # = [0.25] # 25 % of the time, it needs to be above the threshold... v['EX_NUMBEROFSETS'] = self.EX_NUMBEROFSETS # = 6 # how long (sets of 6) do we wish our experiment to have?? Determines also our staircases. v['EX_MIXOFSETS'] = self.EX_MIXOFSETS # = {'train':3, 'transfer':1, 'observe':1, 'rest':1} v['EX_STAIRIDENTIFIER'] = self.EX_STAIRIDENTIFIER # = '0001' # needed to keep track of the staircases. v['EX_XorV_RESET_POINTS'] = self.EX_XorV_RESET_POINTS # = False # at the start of the day --> this should be True. # use the Cpntrol Parameters: CP = self.CP # control parameters... # create G, put it into self too.. G = dict() G['v'] = v self.G = G # we need this in order to continue working as if we're doing it using the normal (test) script... for key in G['v']: G[key] = G['v'][ key] # this is actually superfluous. But removing it might possibly break things. # the main clock mainClock = clock.Clock() G['mainClock'] = mainClock # screen/monitor... G = init_screen(G) # we need to do this # logging... logging.setDefaultClock(G['mainClock']) newLogFile = create_incremental_filename(G['v']['LOG_PATHFILE']) expLogger = logging.LogFile( newLogFile, logging.EXP) # the correct loglevel should be EXP! print(expLogger) logging.LogFile(newLogFile, logging.EXP) # the correct loglevel should be EXP! print('made new logfile: ' + newLogFile) for key in G['v'].keys(): logging.data("{key}: {value}".format(key=key, value=G['v'][key])) logging.flush() G['logging'] = logging # put into the G, which is in self # event handler... G = init_eventcodes(G) # and this?? G = start_eh(G) init_staircases_quest(G) st = make_stimuli(G, CP) pr = init_programs(G, st, CP) ex = define_experiment( G, st, pr, CP) # pr is passed to define_experiment, but then we won't need... self.st = st self.ex = ex # take care of the randomization(s)... trialopts = [] trialopts.append([1, 1, 2, 1, 3, 4]) trialopts.append([1, 1, 2, 1, 4, 3]) trialopts.append([1, 1, 2, 3, 1, 4]) trialopts.append([1, 1, 2, 4, 1, 3]) trialopts.append([1, 1, 3, 1, 2, 4]) trialopts.append([1, 1, 3, 1, 4, 2]) trialopts.append([1, 1, 3, 2, 1, 4]) trialopts.append([1, 1, 3, 4, 1, 2]) trialopts.append([1, 1, 4, 1, 3, 2]) trialopts.append([1, 1, 4, 1, 2, 3]) trialopts.append([1, 1, 4, 3, 1, 2]) trialopts.append([1, 1, 4, 2, 1, 3]) trialopts.append([1, 2, 1, 4, 1, 3]) trialopts.append([1, 2, 1, 3, 1, 4]) trialopts.append([1, 3, 1, 4, 1, 2]) trialopts.append([1, 3, 1, 2, 1, 4]) trialopts.append([1, 4, 1, 2, 1, 3]) trialopts.append([1, 4, 1, 3, 1, 2]) random.shuffle(trialopts) random.shuffle(trialopts) random.shuffle(trialopts) # 3 time shuffle, for good luck :-) # computational anathema and heretic! my_trial_sequence = flatten( trialopts[0:G['v']['EX_RUNS']]) # we do 5 of them. my_trial_definitions = { 1: 'train', 2: 'transfer', 3: 'observe', 4: 'rest' } # so to debug, just run tasks_dbg instead of tasks. for t_i in my_trial_sequence: self.runlist = iter( [my_trial_definitions[i] for i in my_trial_sequence]) # the ev loop we're going to be using.. loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.loop = loop if G['EX_TESTNFNOISE'] is True: self.loop.create_task(pr['GenTestSignal'](G, st, CP)) logging.flush() G['logging'] = logging G['cl'] = clock.Clock( ) # init the trial-by-trial clock here and put into G...
def makeNewClock(): clockContainer.append(clock.Clock())
hist1 = visual.TextStim(win, text='', pos=(-.1, .8), font='Latin Modern Roman') hist2 = visual.TextStim(win, text='', pos=(-.2, .8), font='Latin Modern Roman') hist3 = visual.TextStim(win, text='', pos=(-.3, .8), font='Latin Modern Roman') hist4 = visual.TextStim(win, text='', pos=(-.4, .8), font='Latin Modern Roman') hist5 = visual.TextStim(win, text='', pos=(-.5, .8), font='Latin Modern Roman') hist6 = visual.TextStim(win, text='', pos=(-.6, .8), font='Latin Modern Roman') hist = [hist6, hist5, hist4, hist3, hist2, hist1, hist0] ## Creates ending object end = visual.TextStim(win, text='Koniec tej części badania.', pos=(0.5, 0), font='Latin Modern Roman') ## Initialize the clock and clear keys buffer myClock = clock.Clock() event.clearEvents() ## Display first Instruction instruction.draw() win.flip() event.waitKeys(keyList=['space'], clearEvents=True) ## Display second instruction instruction2.draw() win.flip() event.waitKeys(keyList=['space'], clearEvents=True) ## Creates file name file_name = 'data/' + condition + '_' + myDlg.data[0] + '.csv'
def makeNewClock(): clockContainer.append(clock.Clock()) continueRoutineContainer[0]=True
iti = 2 # intertrial interval # ======= setup hardwares ======= mon = monitors.Monitor('hospital6') mon.setDistance(57) # View distance cm mon.setSizePix([1920, 1080]) mon.setWidth(52.71) # cm myWin = visual.Window([1000, 1000], units='deg', monitor=mon, color=(-1, -1, -1), checkTiming=True) fps = myWin.getActualFrameRate() # sometimes this call fails... event.globalKeys.clear() event.globalKeys.add(key='q', func=core.quit) # global quit globalClock = clock.Clock() kb = keyboard.Keyboard() # create kb object # let's do some calculation before going further speedFrame = speedDeg / fps # how many deg/frame speedPixFrame = monitorunittools.deg2pix(speedFrame, mon) dotSizePix = monitorunittools.deg2pix( dotSize, mon) # calculate dotSizePix for DotStim object nDots = round(np.pi * fieldRadius**2 * dotDensity) # calcuate nDots maxFrames = int(round(maxDur / myWin.monitorFramePeriod)) # define trial handler stimList = [] for t in dirRange: for d in stimDir: stimList.append({'dirRange': t, 'direction': d})