def runTrialState(state_code, trial, myWin, io, all_stim): # Init time related DVs for trial to 0 trial['DV_%s_START'%(state_code)] = 0 trial['DV_%s_VIS_ONSET'%(state_code)] = 0.0 trial['DV_%s_SND_ONSET'%(state_code)] = 0 trial['DV_%s_END'%(state_code)] = 0.0 state_screen = trial['%s_VIS'%(state_code)] if state_screen: state_screen=u''+str(state_screen).lower().strip() if state_screen == '.': state_screen = None graphics_pos = trial['%s_VPOS'%(state_code)] if graphics_pos: if graphics_pos == '.': graphics_pos = [0,0] if isinstance(graphics_pos, (list, tuple)): # reset it to a str for storage in hdf5 file trial['%s_VPOS'%(state_code)]=str(graphics_pos) else: graphics_pos = [0,0] state_audio = trial['%s_SND'%(state_code)] if state_audio: state_audio=u''+str(state_audio).strip() if state_audio == '.': state_audio = None state_end_trig = StateTrigger.create(state_code,trial, all_stim['triggers']) show_pen = draw_pen_pos = draw_pen_trace = trial['%s_SHOWPEN'%(state_code)] if show_pen: draw_pen_pos = show_pen.upper().find('P')>=0 draw_pen_trace = show_pen.upper().find('T')>=0 clear_existing_traces = show_pen.upper().find('C')>=0 possible_state_stim = all_stim['trial']['%s'%(state_code)] actual_state_stim = [] if state_screen: if isImageFileCandidate(state_screen): img_stim = possible_state_stim['image'] img_stim.image = getImageFilePath(state_screen) img_stim.pos = graphics_pos actual_state_stim.append(img_stim) else: txt_stim = possible_state_stim['text'] txt_stim.text = state_screen txt_stim.pos = graphics_pos actual_state_stim.append(txt_stim) if state_audio: if state_audio.lower().endswith('.wav'): possible_state_stim['sound'].setFile(getAudioFilePath(state_audio)) else: # TODO: Write warning to log file that .wav audio is only supported state_audio = None if clear_existing_traces: all_stim['pen']['traces'].clear() # Display any state graphics and play any associated audio file if actual_state_stim: for stim in actual_state_stim: stim.draw() if state_audio: possible_state_stim['sound'].start() # If state has a visual stim, use it's flip time to equal the states # start time. if actual_state_stim: if draw_pen_trace: all_stim['pen']['traces'].draw() trial['DV_%s_START'%(state_code)] = trial['DV_%s_VIS_ONSET'%(state_code)] = myWin.flip() if state_audio: while not possible_state_stim['sound'].starttime: time.sleep(0.001) trial['DV_%s_SND_ONSET'%(state_code)] = possible_state_stim['sound'].starttime if trial['DV_%s_START'%(state_code)] == 0: # If state has an audio stim, but did not have a visual stim, # use the audio stim onset time to equal the states start time. trial['DV_%s_START'%(state_code)] = trial['DV_%s_SND_ONSET'%(state_code)] # If state had no audio and no visual stim, then use # current time as the states start time. if trial['DV_%s_START'%(state_code)] == 0: trial['DV_%s_START'%(state_code)] = core.getTime() io.clearEvents() state_end_trig.reset() # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Maintain current state for [state_code]_DUR seconds, or until # audio_stim has completed playing, whichever comes last. sample_evts=[] while (state_audio and possible_state_stim['sound'].status == PLAYING) or \ state_end_trig.fired(sample_evts) is False: # Redraw display and flip for stim in actual_state_stim: stim.draw() if draw_pen_pos or draw_pen_trace: sample_evts = tablet.getSamples() if draw_pen_trace: # Redraw stim based on tablet events all_stim['pen']['traces'].updateFromEvents(sample_evts) all_stim['pen']['traces'].draw() if draw_pen_pos and sample_evts: last_evt = sample_evts[-1] all_stim['pen']['pos'].updateFromEvent(last_evt) all_stim['pen']['pos'].draw() flip_time=myWin.flip() if terminateExperimentKeyPressed(keyboard): if state_audio: possible_state_stim['sound'].closeFile() return False if state_audio: possible_state_stim['sound'].closeFile() trial['DV_%s_END'%(state_code)] = core.getTime()
def runTrialState(state_code, trial, myWin, io, all_stim): # Init time related DVs for trial to 0 trial['DV_%s_START'%(state_code)] = 0 trial['DV_%s_VIS_ONSET'%(state_code)] = 0.0 trial['DV_%s_SND_ONSET'%(state_code)] = 0 trial['DV_%s_END'%(state_code)] = 0.0 state_screen = trial['%s_VIS'%(state_code)] if state_screen: state_screen=u''+str(state_screen).lower().strip() if state_screen == '.': state_screen = None graphics_pos = trial['%s_VPOS'%(state_code)] if graphics_pos: if graphics_pos == '.': graphics_pos = [0,0] if isinstance(graphics_pos, (list, tuple)): # reset it to a str for storage in hdf5 file trial['%s_VPOS'%(state_code)]=str(graphics_pos) else: graphics_pos = [0,0] state_audio = trial['%s_SND'%(state_code)] if state_audio: state_audio=u''+str(state_audio).strip() if state_audio == '.': state_audio = None state_end_trig = StateTrigger.create(state_code,trial, all_stim['triggers']) show_pen = draw_pen_pos = draw_pen_trace = trial['%s_SHOWPEN'%(state_code)] if show_pen: draw_pen_pos = show_pen.upper().find('P')>=0 draw_pen_trace = show_pen.upper().find('T')>=0 clear_existing_traces = show_pen.upper().find('C')>=0 possible_state_stim = all_stim['trial']['%s'%(state_code)] actual_state_stim = [] if state_screen: if isImageFileCandidate(state_screen): img_stim = possible_state_stim['image'] img_stim.image = getImageFilePath(state_screen) img_stim.pos = graphics_pos actual_state_stim.append(img_stim) else: txt_stim = possible_state_stim['text'] txt_stim.text = state_screen txt_stim.pos = graphics_pos actual_state_stim.append(txt_stim) if state_audio: if state_audio.lower().endswith('.wav'): possible_state_stim['sound'].setFile(getAudioFilePath(state_audio)) else: # TODO: Write warning to log file that .wav audio is only supported state_audio = None if clear_existing_traces: all_stim['pen']['traces'].clear() # Display any state graphics and play any associated audio file if actual_state_stim: for stim in actual_state_stim: stim.draw() if state_audio: possible_state_stim['sound'].start() # If state has a visual stim, use it's flip time to equal the states # start time. if actual_state_stim: if draw_pen_trace: all_stim['pen']['traces'].draw() trial['DV_%s_START'%(state_code)] = trial['DV_%s_VIS_ONSET'%(state_code)] = myWin.flip() if state_audio: while not possible_state_stim['sound'].starttime: time.sleep(0.001) trial['DV_%s_SND_ONSET'%(state_code)] = possible_state_stim['sound'].starttime if trial['DV_%s_START'%(state_code)] == 0: # If state has an audio stim, but did not have a visual stim, # use the audio stim onset time to equal the states start time. trial['DV_%s_START'%(state_code)] = trial['DV_%s_SND_ONSET'%(state_code)] # If state had no audio and no visual stim, then use # current time as the states start time. if trial['DV_%s_START'%(state_code)] == 0: trial['DV_%s_START'%(state_code)] = core.getTime() io.clearEvents() state_end_trig.reset() # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Maintain current state for [state_code]_DUR seconds, or until # audio_stim has completed playing, whichever comes last. sample_evts=[] key_evts_keys=[] while (state_audio and possible_state_stim['sound'].status == PLAYING) or \ state_end_trig.fired(samples = sample_evts, keys = key_evts_keys) is False: # Redraw display and flip for stim in actual_state_stim: stim.draw() if draw_pen_pos or draw_pen_trace: sample_evts = tablet.getSamples() if draw_pen_trace: # Redraw stim based on tablet events all_stim['pen']['traces'].updateFromEvents(sample_evts) all_stim['pen']['traces'].draw() if draw_pen_pos and sample_evts: last_evt = sample_evts[-1] all_stim['pen']['pos'].updateFromEvent(last_evt) all_stim['pen']['pos'].draw() flip_time=myWin.flip() if terminateExperimentKeyPressed(keyboard): if state_audio: possible_state_stim['sound'].closeFile() return False key_evts_keys = [k.key for k in keyboard.getPresses()] if state_audio: possible_state_stim['sound'].closeFile() trial['DV_%s_END'%(state_code)] = core.getTime()
def runPracticePeriod(window, io, pen_pos_stim=None, pen_traces_stim=None, audio_file = None, screen_stim = None, timeout= 30.0, exit_keys = (u' ', u'q', u'escape'), exit_stim = None): """ Performs the practice period at the start of an experiment. :param window: :param io: :param pen_pos_stim: :param pen_traces_stim: :param audio_file: :param screen_stim: :param timeout: :param exit_keys: :param exit_stim: :return: """ tablet = io.devices.tablet keyboard = io.devices.keyboard sound = None if audio_file: if getAudioFilePath(audio_file): sound = PlaySound(filename=getAudioFilePath(audio_file)) else: print("WARNING: PracticePeriod: Audio file not found: {}".format(getAudioFilePath(audio_file))) if screen_stim: for s in screen_stim.values(): s.draw() if sound: sound.start() practice_start_time = window.flip() io.sendMessageEvent(text="PRACTICE_STARTED", sec_time=practice_start_time) if sound: while sound.starttime is None: time.sleep(0.001) io.sendMessageEvent(text="PRACTICE_AUDIO_ONSET", sec_time=sound.starttime) lps = None io.clearEvents() # start tablet events tablet.reporting = True region_pressed = False while not region_pressed or (sound and sound.status == PLAYING): if exit_keys: keys_pressed = [ke.key for ke in keyboard.getPresses()] if list(set(exit_keys) & set(keys_pressed)): break if timeout and core.getTime() - practice_start_time >= timeout: break if screen_stim: for s in screen_stim.values(): s.draw() # Redraw stim based on tablet events tab_samples = tablet.getSamples() if pen_traces_stim: pen_traces_stim.updateFromEvents(tab_samples) if tab_samples: lps = tab_samples[-1] if (not sound or sound.status != PLAYING) and \ exit_stim and not region_pressed and \ exit_stim.contains(*lps.getNormPos()) and lps.pressure > 0: # End practice because pen was pressed on exit button image. region_pressed = True io.sendMessageEvent(text="REGION_TRIGGER: x:{}, y:{}".format(lps.x, lps.y), sec_time=lps.time) if pen_pos_stim and lps: pen_pos_stim.updateFromEvent(lps) else: lps = None if pen_traces_stim: pen_traces_stim.draw() if pen_pos_stim and lps: pen_pos_stim.draw() flip_time = window.flip() if pen_pos_stim and lps: io.sendMessageEvent(text="PEN_STIM_CHANGE: x:{}, " "y:{}, z:{}, pressure:{}, " "tilt:{}".format(lps.x, lps.y, lps.z, lps.pressure, lps.tilt), sec_time=flip_time) # >>> end of practice period <<<< # stop tablet events tablet.reporting = False if sound: io.sendMessageEvent(text="PRACTICE_AUDIO_COMPLETE", sec_time=sound.endtime) # clear the screen flip_time = window.flip() io.sendMessageEvent(text="PRACTICE_COMPLETE", sec_time=flip_time) if sound: sound.closeFile() sound = None if pen_traces_stim: pen_traces_stim.clear()
def runPracticePeriod(window, io, pen_pos_stim=None, pen_traces_stim=None, audio_file = None, screen_stim = None, timeout= 30.0, exit_keys = (u' ', u'q', u'escape'), exit_stim = None): """ Performs the practice period at the start of an experiment. :param window: :param io: :param pen_pos_stim: :param pen_traces_stim: :param audio_file: :param screen_stim: :param timeout: :param exit_keys: :param exit_stim: :return: """ tablet = io.devices.tablet keyboard = io.devices.keyboard sound = None if audio_file: if getAudioFilePath(audio_file): sound = PlaySound(filename=getAudioFilePath(audio_file)) else: print("WARNING: PracticePeriod: Audio file not found: {}".format(getAudioFilePath(audio_file))) if screen_stim: for s in screen_stim.values(): s.draw() if sound: sound.start() practice_start_time = window.flip() io.sendMessageEvent(text="PRACTICE_STARTED", sec_time=practice_start_time) if sound: while sound.starttime is None: time.sleep(0.001) io.sendMessageEvent(text="PRACTICE_AUDIO_ONSET", sec_time=sound.starttime) lps = None io.clearEvents() # start tablet events tablet.reporting = True region_pressed = False while not region_pressed or (sound and sound.status == PLAYING): if exit_keys: keys_pressed = [ke.key for ke in keyboard.getPresses()] if list(set(exit_keys) & set(keys_pressed)): break if timeout and core.getTime() - practice_start_time >= timeout: break if screen_stim: for s in screen_stim.values(): s.draw() # Redraw stim based on tablet events tab_samples = tablet.getSamples() if pen_traces_stim: pen_traces_stim.updateFromEvents(tab_samples) if tab_samples: lps = tab_samples[-1] if (not sound or sound.status != PLAYING) and \ exit_stim and not region_pressed and \ exit_stim.contains(*lps.getNormPos()) and lps.pressure > 0: # End practice because pen was pressed on exit button image. region_pressed = True io.sendMessageEvent(text="REGION_TRIGGER: x:{}, y:{}".format(lps.x, lps.y), sec_time=lps.time) if pen_pos_stim and lps: pen_pos_stim.updateFromEvent(lps) else: lps = None if pen_traces_stim: pen_traces_stim.draw() if pen_pos_stim and lps: pen_pos_stim.draw() flip_time = window.flip() if pen_pos_stim and lps: io.sendMessageEvent(text="PEN_STIM_CHANGE: x:{}, " "y:{}, z:{}, pressure:{}, " "tilt:{}".format(lps.x, lps.y, lps.z, lps.pressure, lps.tilt), sec_time=flip_time) # >>> end of practice period <<<< # stop tablet events tablet.reporting = False if sound: io.sendMessageEvent(text="PRACTICE_AUDIO_COMPLETE", sec_time=sound.endtime) # clear the screen flip_time = window.flip() io.sendMessageEvent(text="PRACTICE_COMPLETE", sec_time=flip_time) if sound: sound.closeFile() sound = None if pen_traces_stim: pen_traces_stim.clear()