示例#1
0
class CVEggStimText:
    # Some are overwritten by the init func. Here for reference
    text = "NULL"
    font_sz = 50
    anchor = "center"
    t = 1
    tscale = "seconds"

    # initme's arguments are : (text,font-sz,time,t-unit,screen)
    def initMe(self, arg_text, arg_font_sz, arg_t, arg_tscale, arg_screen, arg_r=1.0, arg_g=1.0, arg_b=1.0):
        # member vars init
        self.text = arg_text
        self.font_sz = arg_font_sz
        self.t = arg_t
        self.tscale = arg_tscale
        self.color = (arg_r, arg_g, arg_b)
        # dyn vars
        text_vegg = Text(
            text=self.text,
            color=self.color,
            position=(arg_screen.size[0] / 2, arg_screen.size[1] / 2),
            font_size=self.font_sz,
            anchor=self.anchor,
        )
        viewport_vegg = Viewport(screen=arg_screen, size=arg_screen.size, stimuli=[text_vegg])
        # Set up the pres var
        self.pres_vegg = Presentation(go_duration=(arg_t, arg_tscale), viewports=[viewport_vegg])

    def show(self):
        # print self.text_vegg
        self.pres_vegg.go()
示例#2
0
def showImage(screen, img, duration=1):

	def quitKey(event):
		if event.key == pygame.locals.K_SPACE:
			quit()

	def click(event):
		quit()

	def quit(dummy_arg=None):
		image.parameters.go_duration = (0,'frames')

	img = Image.open(img)

	#create textures
	tex = Texture(img)

	x = screen.size[0] / 2
	y = screen.size[1] / 2

	stimulus = TextureStimulus(texture = tex, position = (x, y), anchor = 'center')

	#create viewports
	viewport = Viewport(screen=screen, stimuli=[stimulus])

	if duration:
		image = Presentation(go_duration=(duration, 'seconds'), viewports=[viewport])
	else:
		image = Presentation(go_duration=('forever', ''), viewports=[viewport])
		image.parameters.handle_event_callbacks=[(pygame.locals.QUIT, quit),(pygame.locals.KEYDOWN, quitKey), (pygame.locals.MOUSEBUTTONDOWN, click)]

	image.go()
示例#3
0
def showInstructions(screen, text, textSize=60, textcolor=(255, 255, 255)):
    #create our instruction screen
    #load up the instruction text

    insStim, insView = printText(screen, text, textSize, textcolor)

    instructions = Presentation(go_duration=('forever', ), viewports=[insView])

    #add a quit function and a handler to go with it
    def quitKey(event):
        if event.key == pygame.locals.K_SPACE:
            quit()

    def click(event):
        quit()

    def quit(dummy_arg=None):
        instructions.parameters.go_duration = (0, 'frames')

    instructions.parameters.handle_event_callbacks = [
        (pygame.locals.QUIT, quit), (pygame.locals.KEYDOWN, quitKey),
        (pygame.locals.MOUSEBUTTONDOWN, click)
    ]

    #show instructions
    instructions.go()
示例#4
0
def showStimulus(screen, text, colour):
    word, viewport = printWord(screen, text, 200, colour)
    p = Presentation(go_duration=(0.5, 'seconds'), viewports=[viewport])
    p.go()
    start = time.clock()
    exit = 0
    while not exit:
        data = raw_lpt_module.inp(0x379) & 0x20
        if not data:
            RT = time.clock()
            p.parameters.go_duration = (0.032, 'seconds')
            #dataList.append ([text, colour, start, RT])
            exit = 1
        else:
            pass
示例#5
0
def showStimulus(screen, text, colour):
	word, viewport = printWord(screen, text, 200, colour)
	p = Presentation(go_duration=(0.5,'seconds'),viewports=[viewport])
	p.go()
	start = time.clock()
	exit = 0
	while not exit:
		data = raw_lpt_module.inp(0x379) & 0x20
		if not data:
			RT = time.clock()
			p.parameters.go_duration = (0.032, 'seconds')
			#dataList.append ([text, colour, start, RT])
			exit = 1
		else:
			pass
    def __init__(self):
        global w, h
        self._running = True

        # Initialize screen
        # TODO
        # Set fullscreen
        self.screen = get_default_screen()

        # Get dimension of the screen
        w = self.screen.size[0]
        h = self.screen.size[1]

        # Initialize Targets
        self.TopTarget = Target2D()
        self.BotTarget = Target2D()
        self.LeftTarget = Target2D()
        self.RightTarget = Target2D()

        # Message
        self.mess = Text(text='Please wait for next trial...',
                         color=(1.0, 0.5, 0.5),
                         position=(w/2, h*0.8),
                         font_size=50,
                         anchor='center',
                         on=True)

        # Arrows
        self.arrow = TextureStimulus()

        # Viewports to stick graphical objects to screen
        self.viewport1 = Viewport(screen=self.screen,
                                  stimuli=[self.TopTarget, self.BotTarget, self.LeftTarget, self.RightTarget])      # For Targets
        self.viewport2 = Viewport(screen=self.screen,
                                  stimuli=[self.arrow])                                                  # For cue (and other things)
        self.viewport3 = Viewport(screen=self.screen,
                                  stimuli=[self.mess])                                                  # For cue (and other things)

        # Presentations (for controlling timing)
        self.initialize = Presentation(go_duration=(duration_init, 'seconds'), viewports=[self.viewport3])
        self.targetShow = Presentation(go_duration=(duration_target, 'seconds'), viewports=[self.viewport1])
        self.cueShow = Presentation(go_duration=(duration_cue, 'seconds'), viewports=[self.viewport2])

        # For result
        self.TargetLog = np.zeros((numTrial, 2))     # First column: target code,
示例#7
0
文件: Task1.py 项目: unshur/OpenPsyc
def showStimulus(screen, text, colour, useLPT=True):
	word, viewport = printWord(screen, text, 200, colour)
	p = Presentation(go_duration=(stroopDuration,'seconds'),viewports=[viewport])
	
	if useLPT:
		p.go()
		start = time.clock()
		exit = 0
		while not exit:
			data = raw_lpt_module.inp(0x379) & 0x20		
			#print data
			if not data:
				#print "hello"
				RT = time.clock()
				p.parameters.go_duration = (blank, 'seconds')
				subject.inputData(trial, "text", text)
				subject.inputData(trial, "colour", colour)
				subject.inputData(trial, "RT", RT)
				exit = 1
			else:
				pass
示例#8
0
def showImage(screen, img, duration=1):
    def quitKey(event):
        if event.key == pygame.locals.K_SPACE:
            quit()

    def click(event):
        quit()

    def quit(dummy_arg=None):
        image.parameters.go_duration = (0, 'frames')

    img = Image.open(img)

    #create textures
    tex = Texture(img)

    x = screen.size[0] / 2
    y = screen.size[1] / 2

    stimulus = TextureStimulus(texture=tex, position=(x, y), anchor='center')

    #create viewports
    viewport = Viewport(screen=screen, stimuli=[stimulus])

    if duration:
        image = Presentation(go_duration=(duration, 'seconds'),
                             viewports=[viewport])
    else:
        image = Presentation(go_duration=('forever', ''), viewports=[viewport])
        image.parameters.handle_event_callbacks = [
            (pygame.locals.QUIT, quit), (pygame.locals.KEYDOWN, quitKey),
            (pygame.locals.MOUSEBUTTONDOWN, click)
        ]

    image.go()
示例#9
0
def showInstructions(screen,  text, textSize=60, textcolor=(255, 255, 255)):
	#create our instruction screen
	#load up the instruction text

	insStim, insView = printText(screen, text, textSize, textcolor)

	instructions = Presentation(go_duration=('forever',), viewports=[insView])

	#add a quit function and a handler to go with it
	def quitKey(event):
		if event.key == pygame.locals.K_SPACE:
			quit()

	def click(event):
		quit()

	def quit(dummy_arg=None):
		instructions.parameters.go_duration = (0,'frames')

	instructions.parameters.handle_event_callbacks=[(pygame.locals.QUIT, quit),(pygame.locals.KEYDOWN, quitKey), (pygame.locals.MOUSEBUTTONDOWN, click)]

	#show instructions
	instructions.go()
示例#10
0
    def set_stimuli(self, stimuli, trigger=None, kb_controller=False):
        """Now that we have our stimuli, we initialize everything we can"""
        viewport = Viewport(screen=self.screen, size=self.screen.size, stimuli=stimuli)

        # We disable "check_events" so that we don't lose "instantaneous" key
        # presses and can check these in our Response classes
        self.presentation = Presentation(viewports=[viewport], check_events=False)

        if trigger:
            trigger_controller = KeyboardTriggerInController(trigger)
            self.presentation.add_controller(self.presentation, "trigger_go_if_armed", trigger_controller)
            self.presentation.set(trigger_go_if_armed=0)

        if kb_controller:
            self.keyboard_controller = KeyboardResponseController()
            self.presentation.add_controller(None, None, self.keyboard_controller)
示例#11
0
 def initMe(self, arg_text, arg_font_sz, arg_t, arg_tscale, arg_screen, arg_r=1.0, arg_g=1.0, arg_b=1.0):
     # member vars init
     self.text = arg_text
     self.font_sz = arg_font_sz
     self.t = arg_t
     self.tscale = arg_tscale
     self.color = (arg_r, arg_g, arg_b)
     # dyn vars
     text_vegg = Text(
         text=self.text,
         color=self.color,
         position=(arg_screen.size[0] / 2, arg_screen.size[1] / 2),
         font_size=self.font_sz,
         anchor=self.anchor,
     )
     viewport_vegg = Viewport(screen=arg_screen, size=arg_screen.size, stimuli=[text_vegg])
     # Set up the pres var
     self.pres_vegg = Presentation(go_duration=(arg_t, arg_tscale), viewports=[viewport_vegg])
示例#12
0
    def set_stims(self, stim_list, stim_dict, stim_seq_file): 
        self.stim_list = stim_list
        self.stim_dict = stim_dict
        self.stim_seq = yaml.load(stim_seq_file)

        viewport = Viewport(screen=self.screen,
                    size=self.screen.size,
                    stimuli=self.stim_list)

        # Need to at least wait for the first trigger if this is going to work.
        go_duration = (self.TR * len(self.stim_seq), 'seconds')
        self.presentation = Presentation(go_duration=go_duration,
                trigger_go_if_armed=0,
                viewports=[viewport])

        self.presentation.add_controller(None, None, 
                FunctionController(during_go_func=self.update) )
        self.presentation.add_controller(None, None, self.keyboard_controller)
        # Adding this so that we can start the stimuli ahead of time
        self.presentation.add_controller(self.presentation,'trigger_go_if_armed',
                                    self.firstTTL_trigger)
示例#13
0
        gamma_scale += 0.05
        do_gamma()
    elif event.key in [pygame.locals.K_KP_MINUS, pygame.locals.K_MINUS]:
        gamma_scale -= 0.05
        do_gamma()


def do_gamma():
    global gamma_scale, text2
    r = (np.arange(256) * 256 * gamma_scale).astype('i')
    g = r
    b = r
    worked = pygame.display.set_gamma_ramp(r, g, b)
    if worked:
        text2.parameters.text = "set_gamma_ramp(r,g,b): success"
    else:
        text2.parameters.text = "set_gamma_ramp(r,g,b): failure"


do_gamma()  # set gamma once initially

handle_event_callbacks = [(pygame.locals.QUIT, quit),
                          (pygame.locals.KEYDOWN, keydown)]

# Create an instance of the Presentation class
p = Presentation(viewports=[viewport],
                 handle_event_callbacks=handle_event_callbacks)

# Go!
p.run_forever()
示例#14
0
taskend = Text(text=' ',
               color=(1.0, 1.0, 1.0),
               position=(d_screen_half_x, d_screen_half_y + 160),
               font_size=60,
               anchor='center')

viewportIntro = Viewport(screen=screen)
viewport = Viewport(screen=screen,
                    stimuli=[
                        title, title2, left_choice, right_choice, left_choice2,
                        right_choice2, newset, taskend, fixation
                    ])

p = Presentation(
    go_duration=(2000, 'seconds'),  # run for longer than needed
    trigger_go_if_armed=0,  #wait for trigger
    viewports=[viewport, viewportIntro])


def getState(t):
    global qIndex, screenText, screenText2, ip, question, gn_keystroke, subQ, amountRow, delay, krow, blocknum, amount, amountD, amountI, currentdelay, trialnum
    global isi, isi_index, now, firsttime, response, stim_onset, newseton, goodRow, taskendon, fixon, customdelays, amtText, amtText0I, amtText0D

    if (t > isi + isi_array[isi_index]):
        newseton = 0
        fixon = 0
        taskendon = 0
        if firsttime:
            now = int(round(random()))
            stim_onset = t
            firsttime = 0
示例#15
0
import VisionEgg
VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()

from VisionEgg.Core import *
from VisionEgg.FlowControl import Presentation
from VisionEgg.Gratings import *
from VisionEgg.PyroHelpers import *

pyro_server = PyroServer()

# get visionegg stimulus ready to go
screen = get_default_screen()
stimulus = SinGrating2D(temporal_freq_hz=0.0)
viewport = Viewport(screen=screen,stimuli=[stimulus])
p = Presentation(go_duration=(5.0,'seconds'),viewports=[viewport])

# make a controller, serve it via pyro, and glue it to the Presentation
tf_controller = PyroConstantController(during_go_value=0.0)
pyro_server.connect(tf_controller,'tf_controller')
p.add_controller(stimulus,'temporal_freq_hz', tf_controller)

quit_controller = PyroConstantController(during_go_value=0)
pyro_server.connect(quit_controller,'quit_controller')
p.add_controller(p,'quit', quit_controller)

# get listener controller and register it
p.add_controller(None,None, pyro_server.create_listener_controller())

# initialize graphics to between presentations state
p.run_forever()
示例#16
0
import VisionEgg
VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()

from VisionEgg.Core import *
from VisionEgg.FlowControl import Presentation
from VisionEgg.Gratings import *
import VisionEgg.Daq
from VisionEgg.DaqLPT import *

# Normal stuff (from grating demo):
screen = get_default_screen()
stimulus = SinGrating2D(position         = ( screen.size[0]/2.0, screen.size[1]/2.0 ),
                        anchor           = 'center',
                        size             = ( 300.0 , 300.0 ),
                        spatial_freq     = 10.0 / screen.size[0], # units of cycles/pixel
                        temporal_freq_hz = 5.0,
                        orientation      = 45.0 )
viewport = Viewport( screen=screen, stimuli=[stimulus] )
p = Presentation(go_duration=(5.0,'seconds'),viewports=[viewport])

# Create a trigger output controller
trigger_out_controller = LPTTriggerOutController()

# Add the trigger output controller to the presentation's list of controllers
p.add_controller(None,None,trigger_out_controller)

# Go!
p.go()
示例#17
0
class VisualSpellerVE(MainloopFeedback):
    '''
    Visual Speller with six circles like the classical HexOSpell.
    '''

    # Triggers: look in Marker
    END_LEVEL1, END_LEVEL2 = 244, 245  # end of hex levels
    COPYSPELLING_FINISHED = 246
    STIMULUS = [[11, 12, 13, 14, 15, 16], [21, 22, 23, 24, 25, 26]]
    RESPONSE = [[51, 52, 53, 54, 55, 56], [61, 62, 63, 64, 65, 66]]
    TARGET_ADD = 20
    ERROR_ADD = 100
    COUNTDOWN_STIMULI = 239
    ERROR_POTENTIAL = 96  # send if error potential is classified

    def init(self):
        '''
        initialize parameters
        '''
        self.log_filename = 'VisualSpellerVE.log'

        self.geometry = [0, 0, 1280, 800]  ## size

        self.letterbox_size = (60, 60)
        self.osc_size = 40
        self.font_size_phrase = 60  # the spelled phrase at the top
        self.font_size_current_letter = 80  # the spelled phrase at the top
        self.font_size_countdown = 150  # number during countdown
        self.desired_phrase = ""

        ## colors:
        self.bg_color = (0., 0., 0.)
        self.phrase_color = (0.2, 0.0, 1.0)
        self.current_letter_color = (1.0, 0.0, 0.0)
        self.countdown_color = (0.2, 0.0, 1.0)
        self.osc_color = (1, 1, 1)

        self.letter_set = [['A','B','C','D','E'], \
                           ['F','G','H','I','J'], \
                           ['K','L','M','N','O'], \
                           ['P','Q','R','S','T'], \
                           ['U','V','W','X','Y'], \
                           ['Z','_','.',',','<']]
        self.fullscreen = False
        self.use_oscillator = True
        self.offline = True
        self.copy_spelling = True  # in copy-spelling mode, selection of the target symbol is forced
        self.debug = False
        self.nCountdown = 5
        self.nr_sequences = 6
        self.randomize_sequence = True  # set to False to present a fixed stimulus sequence
        self.min_dist = 2  # Min number of intermediate flashes bef. a flash is repeated twice

        self.stimulus_duration = 0.083  # 5 frames @60 Hz = 83ms flash
        self.interstimulus_duration = 0.1
        self.animation_time = 1
        self.wait_before_classify = 1.
        self.feedback_duration = 1.
        self.feedback_ErrP_duration = 1.0
        self.wait_after_start = 0.

        # Countdown options
        self.do_animation = True
        self.synchronized_countdown = True
        if (self.synchronized_countdown):
            self.do_animation = False

        self.countdown_level1 = True
        self.countdown_level2 = True

        self.countdown_shapes = {
            'circle': FilledCircle,
            'hexagon': FilledHexagon
        }
        self.countdown_shape_select = 'hexagon'
        self.countdown_shape_color = (0.7, 0.7, 0.7)
        self.countdown_shape_on = True
        self.countdown_blinking_nr = 5  #number of pre-sequence stimuli(1 sec is approx. 5 frames at 60 Hz)

        self.wait_after_early_stopping = 3  #sec
        self.abort_trial = False
        self.output_per_stimulus = True
        self.use_ErrP_detection = False

        self.serialtrigger = False

        # FIXME: this should be fixed properly
        try:
            self.serialport = serialport.SerialPort(13)
        except:
            self.serialport = None
        self.send_parallel_bak = self.send_parallel

        if self.debug:
            msg = "!!! YOU\'RE IN DEBUG MODE! CLASSIFICATION WILL BE RANDOM OR KEYBOARD CONTROLLED !!!"
            self.logger.warning(msg)

    def pre_mainloop(self):

        ## logging
        assert (len(self.log_filename) != 0
                )  # 'log_filename' must not be empty string!
        logger.setLevel(logging.ERROR)
        handler = logging.FileHandler(self.log_filename, 'w')
        handler.setLevel(logging.INFO)
        formatter = logging.Formatter("%(asctime)s: %(message)s")
        handler.setFormatter(formatter)
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(handler)

        self._nr_elements = 6
        self._idx_backdoor = 5
        self._init_classifier_output()
        self._classified_element = -1
        self._classified_letter = -1
        for s in self.desired_phrase:
            assert s in [l for ls in self.letter_set
                         for l in ls]  # invalid letters in desired phrase!
        self._spelled_phrase = ""
        self._spelled_letters = ""
        self._desired_letters = self.desired_phrase
        self._copyspelling_finished = False
        #        if self.offline:
        #            self.__idle()                # In offline mode: set the first to-be-spelled letter

        self._spellerHeight = self.geometry[3] - self.letterbox_size[1]
        self._centerPos = (self.geometry[2] / 2., self._spellerHeight / 2.)

        self._nr_letters = 0
        for i in xrange(len(self.letter_set)):
            self._nr_letters += len(self.letter_set[i])

        self._current_level = 1  # Index of current level
        self._current_sequence = 0  # Index of current sequence
        self._current_stimulus = 0  # Index of current stimlus
        self._current_countdown = self.nCountdown
        self.random = random.Random(clock())
        self._debug_classified = None

        ## init states:
        self._state_countdown = True
        if not self.countdown_level1:
            self._state_countdown = False
            self._state_trial = True
        else:
            #self._state_countdown = not self.offline
            self._state_trial = False

        self._state_classify = False
        self._state_feedback = False
        self._state_abort = False

        ## init containers for VE elements:
        self._ve_elements = []

        ## oscillator state:
        if not self.use_oscillator:
            self.osc_color = self.bg_color
            self.osc_size = 0

        ## call subclass-specific pre_mainloop:
        self.prepare_mainloop()

        ## build screen elements:
        self.__init_screen()
        if self.offline:
            self.__idle()
        if self.abort_trial:
            '''
            Start listener for abort_trial event eg.
            '''

        ## delay after play (might be useful for filters...)
        pygame.time.wait(int(self.wait_after_start * 1000))
        self.logger.info("waiting %d seconds after play." %
                         self.wait_after_start)

        ## send start trigger:
        self.send_parallel(marker.RUN_START)
        self.logger.info("[TRIGGER] %d" % marker.RUN_START)

        ## error potential classifier:
        self._ErrP_classifier = None

    def on_interaction_event(self, data):
        self.logger.debug('interaction event')
        serial = data.get('serialtrigger', None)
        if serial is None:
            return
        if serial:
            self.logger.debug('using serial port')
            self.send_parallel = self.serialport.send
        else:
            self.logger.debug('using parallel port')
            self.send_parallel = self.send_parallel_bak

    def post_mainloop(self):
        """
        Sends end marker to parallel port.
        """

        if self.abort_trial:
            '''
            Stop listener for abort_trial event
           '''
            pass

        pygame.time.wait(500)
        self.send_parallel(marker.RUN_END)
        self.logger.info("[TRIGGER] %d" % marker.RUN_END)
        pygame.time.wait(500)
        self._presentation.set(quit=True)
        self._screen.close()

    def __init_screen(self):
        ## create screen:
        if not self.fullscreen:
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d, %d' % (self.geometry[0],
                                                             self.geometry[1])
        self._screen = Screen(size=(self.geometry[2], self.geometry[3]),
                              fullscreen=self.fullscreen,
                              bgcolor=self.bg_color,
                              sync_swap=True)

        ## create letter box on top:
        self._ve_letterbox = Target2D(position=(self._centerPos[0],
                                                self.geometry[3] * (1 - 0.01) -
                                                self.letterbox_size[1] / 2.),
                                      size=(self.letterbox_size[0],
                                            self.letterbox_size[1]),
                                      color=self.phrase_color)
        self._ve_innerbox = Target2D(position=(self._centerPos[0],
                                               self.geometry[3] * (1 - 0.01) -
                                               self.letterbox_size[1] / 2.),
                                     size=(self.letterbox_size[0] - 6,
                                           self.letterbox_size[1] - 6),
                                     color=self.bg_color)

        self._current_letter_position = (self._centerPos[0],
                                         self.geometry[3] * (1 - 0.015) -
                                         self.letterbox_size[1] / 2.)
        self._ve_current_letter = Text(
            position=self._current_letter_position,
            text=(len(self._desired_letters[:1]) == 0 and " "
                  or self._desired_letters[:1]),
            font_size=self.font_size_current_letter,
            color=self.current_letter_color,
            anchor='center')

        self._ve_desired_letters = Text(
            position=(self._centerPos[0] + 5 + self.letterbox_size[0] / 2.,
                      self._current_letter_position[1]),
            text=(len(self._desired_letters[1:]) == 0 and " "
                  or self._desired_letters[1:]),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor='left')

        self._ve_spelled_phrase = Text(
            position=(self._centerPos[0] - 5 - self.letterbox_size[0] / 2.,
                      self._current_letter_position[1]),
            text=(len(self._spelled_phrase) == 0 and " "
                  or self._spelled_phrase),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor='right')

        # if we're in free spelling mode, we hide all text fields but
        # the _ve_spelled_phrase. we also need a multiline
        # _ve_spelled_phrase instead of the single lined one
        if self.offline == self.copy_spelling == False:
            self._spelled_phrase = "   "
            self._ve_spelled_phrase = WrappedText(
                position=(0, self._current_letter_position[1]),
                text=(len(self._spelled_phrase) == 0 and " "
                      or self._spelled_phrase),
                font_size=self.font_size_phrase,
                color=self.phrase_color,
                size=(float(self.geometry[2]), float(self.geometry[3])))
            for i in self._ve_letterbox, self._ve_innerbox, self._ve_current_letter, self._ve_desired_letters:
                i.set(on=False)

        ## add word box to elementlist:
        self._ve_elements.extend([
            self._ve_letterbox, self._ve_innerbox, self._ve_current_letter,
            self._ve_desired_letters, self._ve_spelled_phrase
        ])

        ## create countdown:
        self._ve_countdown = Text(position=self._centerPos,
                                  text=" ",
                                  font_size=self.font_size_countdown,
                                  color=self.countdown_color,
                                  anchor='center',
                                  on=False)

        ## create countdown shapes
        self._ve_countdown_shape = self.countdown_shapes[
            self.countdown_shape_select](radius=90,
                                         position=self._centerPos,
                                         color=self.countdown_shape_color,
                                         on=False)

        ## create oscillator circle:
        self._ve_oscillator = FilledCircle(position=(self.osc_size / 2 + 10,
                                                     self.osc_size / 2 + 10),
                                           radius=self.osc_size / 2,
                                           color=self.osc_color,
                                           on=False)

        ## create shapes and letters:
        self.init_screen_elements()

        ## add remaining elements to element list:
        self._ve_elements.extend([
            self._ve_countdown_shape, self._ve_countdown, self._ve_oscillator
        ])

        ## add elements to viewport:
        self._viewport = Viewport(screen=self._screen,
                                  stimuli=self._ve_elements)
        self._presentation = Presentation(viewports=[self._viewport],
                                          handle_event_callbacks=[
                                              (pygame.KEYDOWN,
                                               self.keyboard_input),
                                              (pygame.QUIT, self.__stop)
                                          ])

    def play_tick(self):
        """
        called every loop, if in play mode.
        """

        self.pre_play_tick()

        if self._state_countdown:
            self.pre__countdown()
            self.__countdown()
            self.post__countdown()
        elif self._state_trial:
            self.pre__trial()
            self.__trial()
            self.post__trial()
        elif self._state_classify:
            self.pre__classify()
            self.__classify()
            self.post__classify()
        elif self._state_feedback:
            self.pre__feedback()
            self.__feedback()
            self.post__feedback()
        elif self._state_abort:
            self.__abort()
            self.post__abort()
        else:
            self.pre__idle()
            self.__idle()
            self.post__idle()
        self.post_play_tick()

    def __stop(self, *args):
        self.on_stop()

    def __idle(self):
        if self.offline and len(self._desired_letters) > 0:
            # add new letter:
            for e in xrange(len(self.letter_set)):
                for l in xrange(len(self.letter_set[e])):
                    if self._desired_letters[0] == self.letter_set[e][l]:
                        self._classified_element = e
                        self._classified_letter = l
            if self.countdown_level1:
                self._state_countdown = True
            else:
                self._state_trial = True
        else:
            ## otherwise just wait until a new letter is sent:
            self._presentation.set(go_duration=(0.1, 'seconds'))
            self._presentation.go()

    def __countdown(self):
        def blink():
            i = 0
            while (i < self.countdown_blinking_nr):
                self._ve_countdown_shape.set(on=True)
                self._ve_countdown.set(text="%d" % self._current_countdown,
                                       on=True)
                self.send_parallel(self.COUNTDOWN_STIMULI)
                self.logger.info("[TRIGGER] %d" % self.COUNTDOWN_STIMULI)
                self._presentation.set(go_duration=(self.stimulus_duration,
                                                    'seconds'))
                self._presentation.go()
                self._ve_countdown_shape.set(on=False)
                self._ve_countdown.set(on=False)
                self._presentation.set(
                    go_duration=(self.interstimulus_duration, 'seconds'))
                self._presentation.go()
                i = i + 1

        if self._current_countdown == self.nCountdown:
            self.send_parallel(marker.COUNTDOWN_START)
            self.logger.info("[TRIGGER] %d" % marker.COUNTDOWN_START)
            self.set_countdown_screen()
            self._ve_countdown.set(on=True)
            self._ve_countdown_shape.set(on=self.countdown_shape_on)
            self._presentation.set(go_duration=(1, 'seconds'))

        self._ve_countdown.set(text="%d" % self._current_countdown)
        self._presentation.go()
        self._current_countdown = (self._current_countdown -
                                   1) % self.nCountdown

        if self.synchronized_countdown and self._current_countdown == 1:
            self.set_synchronized_countdown_screen()
            blink()
            self._current_countdown = self.nCountdown
            self.set_standard_screen()
            self._state_countdown = False
            self._state_trial = True
            self._ve_countdown.set(on=False)
            self._ve_countdown_shape.set(on=False)
            self._ve_countdown.set(color=self.countdown_color)

        if self._current_countdown == 0:
            # Executed only if self.synchronized_countdown = False
            self._current_countdown = self.nCountdown
            self.set_standard_screen()
            pygame.time.wait(10)
            self._state_countdown = False
            self._state_trial = True
            self._ve_countdown_shape.set(on=False)
            self._ve_countdown.set(on=False)
            self._ve_countdown.set(color=self.countdown_color)

    def __trial(self):

        if self._current_sequence == 0 and self._current_stimulus == 0:

            #level 1 animation when there is no countdown
            if self._current_level == 1 and not self.countdown_level1:
                if self.do_animation:
                    self.set_countdown_screen()
                self.set_standard_screen()
            # generate random sequences:
            if self.randomize_sequence:
                self.flash_sequence = []
                for _ in range(self.nr_sequences):
                    random_flash_sequence(self,
                                          set=range(self._nr_elements),
                                          min_dist=self.min_dist,
                                          seq_len=self._nr_elements)
            # or else use fixed sequence:
            else:
                self.flash_sequence = range(self._nr_elements)

        if self.randomize_sequence:
            currentStimulus = self.flash_sequence[self._current_sequence *
                                                  self._nr_elements +
                                                  self._current_stimulus]
        else:
            currentStimulus = self.flash_sequence[self._current_stimulus]
        # set stimulus:
        self.stimulus(currentStimulus, True)
        #self._ve_oscillator.set(on=True)

        if self.abort_trial and self.abort_trial_check():
            # restart trial on abort_trial event:
            self._state_trial = False
            self._state_abort = True
            return

        # check if current stimulus is target and then send trigger:
        target_add = 0
        if len(self._desired_letters) > 0:
            if self._current_level == 1:
                if self._desired_letters[:1] in self.letter_set[
                        currentStimulus]:
                    # current stimulus is target group:
                    target_add = self.TARGET_ADD
            else:
                if currentStimulus == self._idx_backdoor:
                    # current stimulus is backdoor:
                    if not self._desired_letters[:1] in self.letter_set[
                            self._classified_element]:
                        # we are in the wrong group. backdoor is target:
                        target_add = self.TARGET_ADD
                else:
                    # current stimulus is no backdoor:
                    if self._desired_letters[:1] == self.letter_set[
                            self._classified_element][currentStimulus]:
                        # current stimulus is target symbol:
                        target_add = self.TARGET_ADD

        self.send_parallel(self.STIMULUS[self._current_level -
                                         1][currentStimulus] + target_add)
        self.logger.info(
            "[TRIGGER] %d" %
            (self.STIMULUS[self._current_level - 1][currentStimulus] +
             target_add))

        # present stimulus:
        self._presentation.set(go_duration=(self.stimulus_duration, 'seconds'))
        self._presentation.go()

        # reset to normal:
        self._ve_oscillator.set(on=False)
        self.stimulus(currentStimulus, False)

        # present interstimulus:
        self._presentation.set(go_duration=(self.interstimulus_duration,
                                            'seconds'))
        self._presentation.go()

        if self.debug:
            self.on_control_event(
                {'cl_output': (self.random.random(), currentStimulus + 1)})

        ## TODO: check here for classification !!!!
        if self.output_per_stimulus:
            # increase
            self._current_stimulus = (self._current_stimulus +
                                      1) % self._nr_elements
            if self._current_stimulus == 0:
                self._current_sequence = (self._current_sequence +
                                          1) % self.nr_sequences

            # check for end of trial:
            if self._current_sequence == 0 and self._current_stimulus == 0:

                # send trigger:
                if self._current_level == 1:
                    self.send_parallel(self.END_LEVEL1)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL1)
                else:
                    self.send_parallel(self.END_LEVEL2)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL2)

                # decide how to continue:
                self._state_trial = False
                self._state_classify = True
        else:
            # increase
            self._current_stimulus = (self._current_stimulus +
                                      1) % self._nr_elements
            if self._current_stimulus == 0:
                self._current_sequence = (self._current_sequence +
                                          1) % self.nr_sequences
                if self.check_classification(self._current_sequence + 1):
                    self._state_trial = False
                    self._state_classify = True
                    pygame.time.wait(self.wait_after_early_stopping * 1000)

            if self._current_sequence == 0 and self._current_stimulus == 0:

                # send trigger:
                if self._current_level == 1:
                    self.send_parallel(self.END_LEVEL1)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL1)
                else:
                    self.send_parallel(self.END_LEVEL2)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL2)

                # decide how to continue:
                self._state_trial = False
                self._state_classify = True

    def check_classification(self, nr):
        #print self._classifier_output
        means = [None] * self._nr_elements
        minimum = maxint
        classified = None
        for ii in range(self._nr_elements):
            means[ii] = sum(self._classifier_output[ii]) / nr
            if means[ii] < minimum:
                minimum = means[ii]
                classified = ii + 1

        print "\n**** Class: %d (mean=%f)\n" % (classified,
                                                means[classified - 1])
        return classified

    def __classify(self):

        ## wait until all classifier outputs are received:
        self._presentation.set(go_duration=(self.wait_before_classify,
                                            'seconds'))
        self._presentation.go()
        if self.offline:
            if self._current_level == 1:
                classified = self._classified_element
            else:
                classified = self._classified_letter
        elif not self._debug_classified == None:
            classified = self._debug_classified
            self._debug_classified = None
        else:
            if self.output_per_stimulus:
                nClassified = sum([
                    len(self._classifier_output[i])
                    for i in xrange(self._nr_elements)
                ])
                if nClassified < self._nr_elements * self.nr_sequences:
                    pygame.time.wait(20)
                    print 'not enough classifier-outputs received! (something may be wrong)'
                    return

                ## classify and set output:
                means = [None] * self._nr_elements
                minimum = maxint
                classified = None
                for ii in range(self._nr_elements):
                    means[ii] = sum(
                        self._classifier_output[ii]) / self.nr_sequences
                    if means[ii] < minimum:
                        minimum = means[ii]
                        classified = ii
                print "\n**** Class: %d (mean=%f)\n" % (classified + 1,
                                                        means[classified])
            else:
                means = [None] * self._nr_elements
                minimum = maxint
                classified = None
                for ii in range(self._nr_elements):
                    means[ii] = sum(
                        self._classifier_output[ii]) / self.nr_sequences
                    if means[ii] < minimum:
                        minimum = means[ii]
                        classified = ii
                print "\n**** Class: %d (mean=%f)\n" % (classified + 1,
                                                        means[classified])

            ## Reset classifier output to empty lists
            self._init_classifier_output()

        error_add = 0
        ## evaluate classification:
        if self._current_level == 1:
            self._classified_element = classified
            if len(self._desired_letters
                   ) > 0 and not self._desired_letters[:1] in self.letter_set[
                       classified]:
                # wrong group selected:
                error_add = self.ERROR_ADD
        else:
            self._classified_letter = classified
            if self._classified_letter == self._idx_backdoor:
                ## backdoor classified:
                if len(self._desired_letters
                       ) > 0 and self._desired_letters[:1] in self.letter_set[
                           self._classified_element]:
                    # backdoor selection wrong:
                    error_add = self.ERROR_ADD
            else:
                ## no backdoor classified:
                spelled_letter = self.letter_set[self._classified_element][
                    self._classified_letter]
                if len(self._desired_letters
                       ) > 0 and spelled_letter != self._desired_letters[:1]:
                    # wrong letter spelled:
                    error_add = self.ERROR_ADD

        ## send response trigger:
        self.send_parallel(self.RESPONSE[self._current_level - 1][classified] +
                           error_add)
        self.logger.info(
            "[TRIGGER] %d" %
            (self.RESPONSE[self._current_level - 1][classified] + error_add))

        self._state_classify = False
        self._state_feedback = True

    def __feedback(self):
        self._state_feedback = False

        ## call subclass method:
        self.feedback()

        ## check ErrP classification:
        if self.use_ErrP_detection:
            t = 0
            while self._ErrP_classifier is None and t < 1000:
                t += 50
                pygame.time.wait(50)
            if self._ErrP_classifier is None:
                print "no ErrP classifier received! "
            if self._ErrP_classifier:
                self.send_parallel(self.ERROR_POTENTIAL)
                self.logger.info("[TRIGGER] %d" % (self.ERROR_POTENTIAL))

        ## call subclass method:
        if not self.countdown_level2:
            self.switch_level()

        ## update phrases:
        if ((self._current_level == 2)
                and  # only update, if we are at the end of level 2,
            (self._classified_letter != self._idx_backdoor
             or self.copy_spelling)
                and  # if copyspelling off, we have no backdoor selected
            (self._ErrP_classifier is None or not self._ErrP_classifier)
            ):  # no ErrP was detected (or ErrP detection is off)
            spelled_letter = ""
            if self.copy_spelling:
                ## in copy spelling we force the desired letter to be spelled
                if len(self._desired_letters) > 0:
                    spelled_letter = self._desired_letters[:1]
                else:
                    print "??? moved beyond desired phrase in copy spelling ???"
            else:
                spelled_letter = self.letter_set[self._classified_element][
                    self._classified_letter]

            ## update desired phrase:
            if len(self._desired_letters) > 0:
                if spelled_letter == self._desired_letters[:1]:
                    # correct letter spelled:
                    self._desired_letters = self._desired_letters[
                        1:]  # remove first letter
                else:
                    # wrong letter spelled:
                    if spelled_letter == "<":
                        self._desired_letters = self._spelled_phrase[
                            -1:] + self._desired_letters
                    else:
                        self._desired_letters = "<" + self._desired_letters
                if len(self._desired_letters) == 0:
                    self._copyspelling_finished = True

            ## update spelled phrase:
            self._spelled_letters += spelled_letter
            if spelled_letter == "<":
                self._spelled_phrase = self._spelled_phrase[:-1]
            else:
                self._spelled_phrase += spelled_letter

            ## update screen phrases:
            self.logger.info('Current Phrase:')
            self.logger.info(self._spelled_phrase)
            self._ve_spelled_phrase.set(
                text=(len(self._spelled_phrase) == 0 and " "
                      or self._spelled_phrase))
            self._ve_current_letter.set(
                text=(len(self._desired_letters[:1]) == 0 and " "
                      or self._desired_letters[:1]))
            self._ve_desired_letters.set(
                text=(len(self._desired_letters[1:]) == 0 and " "
                      or self._desired_letters[1:]))

        if self.use_ErrP_detection and self._ErrP_classifier:
            self._state_trial = True

        else:
            if self._current_level == 1:
                # continue with level2 trial:
                if self.countdown_level2:
                    self._state_countdown = True
                else:
                    self._state_trial = True

            elif not self.offline:
                # start countdown
                if self.countdown_level1:
                    self._state_countdown = True
                else:
                    self._state_trial = True

            # set new level:
            self._current_level = 3 - self._current_level

        ## reset ErrP_classifier:
        self._ErrP_classifier = None

        # check copyspelling:
        if self._copyspelling_finished:
            self._copyspelling_finished = False
            self.on_control_event({'print': 0})  # print desired phrase
            self.on_control_event({'print': 1})  # print spelled phrase
            self.on_control_event({'print': 2})  # print all spelled letters
            self.send_parallel(self.COPYSPELLING_FINISHED)
            self.logger.info("[TRIGGER] %d" % (self.COPYSPELLING_FINISHED))
            pygame.time.wait(50)

    def __abort(self):

        # play warning sound

        def sine_array_onecycle(hz, peak, sample_rate):
            length = sample_rate / float(hz)
            omega = NP.pi * 2 / length
            xvalues = NP.arange(int(length)) * omega
            return (peak * NP.sin(xvalues))

        def sine_array(hz, peak, samples_rate):
            return NP.resize(sine_array_onecycle(hz, peak, sample_rate),
                             (sample_rate, ))

        sample_rate = 44100
        pygame.mixer.init(sample_rate, -16,
                          2)  # 44.1kHz, 16-bit signed, stereo
        f = sine_array(8000, 1, sample_rate)
        f = NP.array(zip(f, f))
        sound = pygame.sndarray.make_sound(f)
        channel = sound.play(-1)
        channel.set_volume(0.2, 0.2)
        pygame.time.delay(1000)
        sound.stop()

        if self._current_level == 1 and self.countdown_level1:
            self._state_countdown = True
        elif self._current_level == 2 and self.countdown_level2:
            self._state_countdown = True
        else:
            self._state_trial = True

        self._init_classifier_output()

    def _init_classifier_output(self):
        ## Empty lists
        self._classifier_output = [list() for _ in xrange(self._nr_elements)]

    def abort_trial_check(self):
        '''
        Check if event is an abort trial event
        '''
        return False

    def keyboard_input(self, event):
        if event.key == pygame.K_ESCAPE:
            self.on_stop()
        elif event.key == pygame.K_KP_ENTER:
            self.on_control_event({'print': 0})  # print desired phrase
            self.on_control_event({'print': 1})  # print spelled phrase
            self.on_control_event({'print': 2})  # print all spelled letters
        elif event.key == pygame.K_DELETE:
            # The DELETE key empties the spelled text shown this works
            # only in free spelling mode (i.e. offline and copy_spelling
            # are set to False)
            if self.offline == self.copy_spelling == False:
                self.logger.info('Clearing Text.')
                self._spelled_phrase = "   "
        elif self.debug:
            if ((event.key >= pygame.K_a and event.key <= pygame.K_z)
                    or (event.key == pygame.K_LESS)
                    or (event.key == pygame.K_PERIOD)
                    or (event.key == pygame.K_COMMA)):
                self.on_control_event({'new_letter': chr(event.key).upper()})
            elif event.key == pygame.K_MINUS:
                self.on_control_event({'new_letter': chr(pygame.K_UNDERSCORE)})
            elif event.key == pygame.K_BACKSPACE:
                self.on_control_event({'new_letter': chr(pygame.K_LESS)})
            elif event.key == pygame.K_SPACE:
                self.on_control_event({'new_letter': chr(pygame.K_UNDERSCORE)})
            elif event.key == pygame.K_UP and self.use_ErrP_detection:
                self.on_control_event({'cl_output': (1, 7)})
            elif event.key == pygame.K_DOWN and self.use_ErrP_detection:
                self.on_control_event({'cl_output': (0, 7)})
            if not self.offline:
                if (event.key >= pygame.K_0 and event.key <= pygame.K_5):
                    self._debug_classified = int(chr(event.key))
                elif (event.key >= pygame.K_KP0 and event.key <= pygame.K_KP5):
                    self._debug_classified = int(chr(event.key - 208))

    def on_control_event(self, data):
        self.logger.info("[CONTROL_EVENT] %s" % str(data))
        if data.has_key(u'cl_output'):
            # classification output was sent:
            score_data = data[u'cl_output']
            cl_out = score_data[0]
            iSubstim = int(score_data[1])  # evt auch "Subtrial"
            if iSubstim in range(1, 7):
                self._classifier_output[iSubstim - 1].append(cl_out)
            elif self.use_ErrP_detection:
                self._ErrP_classifier = cl_out
        elif data.has_key('new_letter'):
            # get new letter to spell:
            self._desired_letters += data['new_letter']
            self._ve_current_letter.set(
                text=(len(self._desired_letters[:1]) == 0 and " "
                      or self._desired_letters[:1]))
            self._ve_desired_letters.set(
                text=(len(self._desired_letters[1:]) == 0 and " "
                      or self._desired_letters[1:]))

        elif data.has_key(u'print'):
            if data[u'print'] == 0:
                self.logger.info("[DESIRED_PHRASE] %s" % self.desired_phrase)
            elif data[u'print'] == 1:
                self.logger.info("[SPELLED_PHRASE] %s" % self._spelled_phrase)
            elif data[u'print'] == 2:
                self.logger.info("[SPELLED_LETTERS] %s" %
                                 self._spelled_letters)

    '''
    ==========================
    == METHODS TO OVERLOAD: ==
    ==========================
    '''

    def init_screen_elements(self):
        '''
        overwrite this function in subclass.
        '''
        pass

    def prepare_mainloop(self):
        '''
        overwrite this function in subclass.
        '''
        pass

    def set_countdown_screen(self):
        '''
        set screen how it should look during countdown.
        overwrite this function in subclass.
        '''
        pass

    def set_standard_screen(self):
        '''
        set screen elements to standard state.
        overwrite this function in subclass.
        '''
        pass

    def set_synchronized_countdown_screen(self):
        '''
        set screen elements to for the synchronized countdown.
        overwrite this function in subclass.
        '''
        pass

    def stimulus(self, i_element, on=True):
        '''
        turn on/off the stimulus elements and turn off/on the normal elements.
        overwrite this function in subclass.
        '''
        pass

    def feedback(self):
        '''
        set screen how it should look during feedback presentation.
        overwrite this function in subclass.
        '''
        pass

    def switch_level(self):
        '''
        overwrite this function in subclass.
        '''
        pass

    def pre_play_tick(self):
        pass

    def post_play_tick(self):
        pass

    def pre__countdown(self):
        pass

    def post__countdown(self):
        pass

    def pre__trial(self):
        pass

    def post__trial(self):
        pass

    def pre__classify(self):
        pass

    def post__classify(self):
        pass

    def pre__feedback(self):
        pass

    def post__feedback(self):
        pass

    def pre__idle(self):
        pass

    def post__idle(self):
        pass

    def post__abort(self):
        pass
示例#18
0
文件: sart.py 项目: unshur/OpenPsyc
pygame.font.init()

pygame.mixer.init()

sound = pygame.mixer.Sound("beep.wav")

sound.play()

for s in stimList:
    trial += 1
    print s
    RT = 0
    acc = 0

    w, v = printWord(screen, str(s), 48, [255, 255, 255])
    p = Presentation(go_duration=[0.675, 'seconds'], viewports=[v])
    p.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN, key_handler)
                                           ]
    p.go()

    sub.inputData(trial, "RT", RT)
    sub.inputData(trial, "acc", acc)
    sub.inputData(trial, "s", s)
    sub.inputData(trial, "target", target)

    sub.printData()

sound.play()

sub.printData()
示例#19
0
        sub.inputData(trial, "largecolor", cDict[color])
        sub.inputData(trial, "yellowButton", yellowB)
        sub.inputData(trial, "blueButton", blueB)

        print color

        if block == "overlapping":
            phase = ""
            fname = "%s_%s_%s_%s_%s_OL.bmp" % (ratio, n1, color, size,
                                               exemplar)

            t = Texture(Image.open(os.path.join(stimLib, fname)))
            s = TextureStimulus(texture=t, position=(x, y), anchor='center')
            texture_object = s.parameters.texture.get_texture_object()
            v = Viewport(screen=screen, stimuli=[s])
            p = Presentation(go_duration=('forever', ), viewports=[v])
            p.add_controller(
                None, None,
                FunctionController(during_go_func=put_image_overlapping,
                                   temporal_variables=TIME_SEC_ABSOLUTE))
            p.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN,
                                                    keyFunc)]
            p.go()

        else:
            if side == "large":
                fname1 = "%s_%s_%s_%s_%s_S2.bmp" % (ratio, n1, color, size,
                                                    exemplar)
                fname2 = "%s_%s_%s_%s_%s_S1.bmp" % (ratio, n1, color, size,
                                                    exemplar)
            else:
示例#20
0
# Generate some images
image_list = []
for i in range(num_images):
    image = Image.new("RGB",image_size,(0,0,255)) # Blue background
    draw = ImageDraw.Draw(image)
    line_x = image_size[0]/float(num_images) * i
    draw.line((line_x, 0, line_x, image_size[1]), fill=(255,255,255))
    image_list.append(image)

texture_list = map(Texture,image_list) # create instances of Texture from images

screen = get_default_screen()

stimulus = TextureStimulus(texture=texture_list[0],
                           position = (screen.size[0]/2.0,screen.size[1]/2.0),
                           anchor='center',
                           size=image_size)

viewport = Viewport(screen=screen,
                    stimuli=[stimulus])

p = Presentation(go_duration=(num_images*duration_per_image,'seconds'),viewports=[viewport])

def put_image(t):
    i = int(t/duration_per_image) # choose image
    stimulus.parameters.texture = texture_list[i]
p.add_controller(None,None,FunctionController(during_go_func=put_image))

p.go()
示例#21
0
target_bottom = 0.2 * screen.size[1] - shift_unit
stim_range_half = (target_top - target_bottom) / 2.0
score_factor = 90.0 / (30.0 * 0.5)  # assume 30 maximum TRs at maximum -.5
# "score" to go from 90 to 0 deg

# Create a Viewport instance
viewport = Viewport(screen=screen, \
                    stimuli=[arrowStimulus,textAA,centerStim,taskStimulus,\
                             tach1,tach2,tach3,tach4,tach5,tach6,tach7,tach8,\
                             tach9,tach10,tach11,tach12,tach13,tach14,tach15,\
                             tach12,tach16,tach17,tach18,tach19,tachLabelR,\
                             tachLabelL])

# the Vision Egg's runtime control abilities.
p = Presentation( go_duration=(Num_Secs,'seconds'), \
                  trigger_go_if_armed=0, \
                  viewports=[viewport])

# calculate a few variables we need
next_stim_time = 0
direction = 1.0
last_direction = 1.0
arrow_scale = 0
arrowColor = 0
score = 90.0
first_loop = 1
start_time = 0
StimCount = -1
stimVis = 0
fbVis = 0
stimText = "+"
示例#22
0
    draw = ImageDraw.Draw(image)
    line_x = image_size[0] / float(num_images) * i
    draw.line((line_x, 0, line_x, image_size[1]), fill=(255, 255, 255))
    image_list.append(image)

texture_list = map(Texture,
                   image_list)  # create instances of Texture from images

screen = get_default_screen()

stimulus = TextureStimulus(texture=texture_list[0],
                           position=(screen.size[0] / 2.0,
                                     screen.size[1] / 2.0),
                           anchor='center',
                           size=image_size)

viewport = Viewport(screen=screen, stimuli=[stimulus])

p = Presentation(go_duration=(num_images * duration_per_image, 'seconds'),
                 viewports=[viewport])


def put_image(t):
    i = int(t / duration_per_image)  # choose image
    stimulus.parameters.texture = texture_list[i]


p.add_controller(None, None, FunctionController(during_go_func=put_image))

p.go()
示例#23
0
    position=(screen.size[0] / 2, screen.size[1] / 2),
)

cur_time = Text(
    text="",
    font_size=15,
    color=(.75, .75, .75),
    anchor='lowerleft',
    position=(0, 0),
)

viewport_instructions = Viewport(screen=screen,
                                 stimuli=[instructions, cur_time])
attend_face = Viewport(screen=screen, stimuli=[instructions_attendFACE])
attend_scene = Viewport(screen=screen, stimuli=[instructions_attendSCENE])
p1 = Presentation(go_duration=('forever', ), viewports=[viewport_instructions])
p1.add_controller(None, None, FunctionController(during_go_func=displayTime))
p1.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN, waitForTrigger)
                                        ]

# setup main experimental loop
loadStims = 0
wrote_response = 0

stimulus = TextureStimulus(
    anchor='center',
    size=stimuli_size,
    position=(screen.size[0] / 2.0, screen.size[1] / 2.0),
    texture_min_filter=gl.GL_LINEAR,
    shrink_texture_ok=1,
    # PW 2012/11/26
示例#24
0
drum = SpinningDrum(texture=texture, shrink_texture_ok=1)

# Create a perspective projection for the spinning drum
perspective = SimplePerspectiveProjection(fov_x=90.0)

# Create a viewport with this projection
drum_viewport = Viewport(screen=screen, projection=perspective, stimuli=[drum])

##################################################
#  Create an instance of the Presentation class  #
##################################################

# Add target_viewport last so its stimulus is drawn last. This way the
# target is always drawn after (on top of) the drum and is therefore
# visible.
p = Presentation(go_duration=(10.0, 'seconds'),
                 viewports=[drum_viewport, target_viewport])

########################
#  Define controllers  #
########################

# calculate a few variables we need
mid_x = screen.size[0] / 2.0
mid_y = screen.size[1] / 2.0
max_vel = min(screen.size[0], screen.size[1]) * 0.4


# define target position as a function of time
def get_target_position(t):
    global mid_x, mid_y, max_vel
    return (
示例#25
0
    random.shuffle(ns_list2)
    if ns_list1[-1] != ns_list2[0]:
        ns_list = ns_list1 + ns_list2
        badshuffle = False

print len(ns_list)
print ns_list

lastSoln = 0

mems = 0
calcs = 0

print "PRESS SPACE TO START"

pause = Presentation(go_duration=('forever', ), viewports=[fixCross])
pause.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN,
                                            pause_handler)]
pause.go()

for ns in ns_list:
    #reset state vars
    misfire = 0
    verify = 0
    problem = None
    soln = None
    orig_strat = ns[1]

    problem = Problem(ns[0])

    ns = problem.row['ns']
    def doSim(self, trial, road, duration, tau, doEyetrack):

        # Measure sample rate in order to calculate delay buffer
        sample_rate = self.screen.measure_refresh_rate(2.0)
        print "Sample rate: " + str(sample_rate)
        #sample_rate = 60

        self.doEyetrack = doEyetrack

        self.pos_ring = RingBuffer(self.center,
                                   int(math.floor(tau * sample_rate)) + 1)
        print("Ring Buffer:: size: " + str(self.pos_ring.size))

        if doEyetrack:
            import pylink
            from EyeLinkCoreGraphicsVE import EyeLinkCoreGraphicsVE

            self.tracker = pylink.EyeLink()
            if self.tracker == None:
                print "Error: Eyelink is not connected"
                sys.exit()

            genv = EyeLinkCoreGraphicsVE(self.screen, self.tracker)
            pylink.openGraphicsEx(genv)

            #Opens the EDF file.
            edfFileName = "TRIAL" + str(trial) + ".EDF"
            self.tracker.openDataFile(edfFileName)

            pylink.flushGetkeyQueue()

            self.tracker.sendCommand("screen_pixel_coords =	0 0 %d %d" %
                                     (VisionEgg.config.VISIONEGG_SCREEN_W,
                                      VisionEgg.config.VISIONEGG_SCREEN_H))

            tracker_software_ver = 0
            eyelink_ver = self.tracker.getTrackerVersion()
            if eyelink_ver == 3:
                tvstr = self.tracker.getTrackerVersionString()
                vindex = tvstr.find("EYELINK CL")
                tracker_software_ver = int(
                    float(tvstr[(vindex + len("EYELINK CL")):].strip()))

            if eyelink_ver >= 2:
                self.tracker.sendCommand("select_parser_configuration 0")
                if eyelink_ver == 2:  #turn off scenelink camera stuff
                    self.tracker.sendCommand("scene_camera_gazemap = NO")
            else:
                self.tracker.sendCommand("saccade_velocity_threshold = 35")
                self.tracker.sendCommand(
                    "saccade_acceleration_threshold = 9500")

            # set EDF file contents
            self.tracker.sendCommand(
                "file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON"
            )
            if tracker_software_ver >= 4:
                self.tracker.sendCommand(
                    "file_sample_data	= LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET"
                )
            else:
                self.tracker.sendCommand(
                    "file_sample_data	= LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS")

            # set link data (used for gaze cursor)
            self.tracker.sendCommand(
                "link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON")
            if tracker_software_ver >= 4:
                self.tracker.sendCommand(
                    "link_sample_data	= LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET"
                )
            else:
                self.tracker.sendCommand(
                    "link_sample_data	= LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS")

            if not self.doneSetup:
                self.tracker.doTrackerSetup()
                self.doneSetup = True
            else:
                while 1:
                    try:
                        error = self.tracker.doDriftCorrect(
                            self.screen.size[0] / 2, self.screen.size[1] / 2,
                            1, 1)
                        if error != 27:  # ?? from example
                            break
                        else:
                            self.tracker.doTrackerSetup()
                    except:
                        break

        self.screen.parameters.bgcolor = 106.0 / 255.0, 147.0 / 255.0, 0.0
        # Load road data from file and create an image
        roadArray = numpy.loadtxt('road' + str(road) + '.txt')

        # Convert to a Path
        roadPath = ImagePath.Path(
            map(lambda xy: (xy[0], xy[1]), roadArray.tolist()))

        # Use Path to create a plot of the road
        im = Image.new("RGB", (2000, 100), (50, 50, 50))
        draw = ImageDraw.Draw(im)

        # draw each side of the road separately
        draw.line(roadPath[:4000], fill=(200, 200, 200))
        draw.line(roadPath[4000:], fill=(200, 200, 200))

        del draw

        # Lay out a road texture in the x-z plane
        roadTexture = Texture(im)

        del im

        eye_height = 2.5

        vertices = [(-10, -eye_height, 0), (-10, -eye_height, -1000),
                    (10, -eye_height, 0), (10, -eye_height, -1000)]

        rect = TextureStimulus3D(texture=roadTexture,
                                 lowerleft=vertices[0],
                                 lowerright=vertices[1],
                                 upperleft=vertices[2],
                                 upperright=vertices[3])

        # We will use these later for our camera transforms
        self.camera_matrix = ModelView()
        self.frame_timer = FrameTimer()

        self.outf = open(
            'steersim-' + str(trial) + '-' + str(road) + '-out.txt', 'wb')

        # Vewport for the road
        viewport3D = Viewport(
            screen=self.screen,
            projection=SimplePerspectiveProjection(fov_x=75.2),
            camera_matrix=self.camera_matrix,
            stimuli=[rect])

        # Construct a sky
        sky_l = 0
        sky_r = self.screen.size[0]
        sky_t = self.screen.size[1]
        sky_b = self.screen.size[1] / 2

        sky_vertices = [(sky_l, sky_t, 0), (sky_r, sky_t, 0),
                        (sky_r, sky_b, 0), (sky_l, sky_b, 0)]

        sky = Rectangle3D(color=(144.0 / 255.0, 190.0 / 255.0, 1.0),
                          vertex1=sky_vertices[0],
                          vertex2=sky_vertices[1],
                          vertex3=sky_vertices[2],
                          vertex4=sky_vertices[3])

        wheelTexture = Texture('wheel.png')
        self.wheel = TextureStimulus(texture=wheelTexture,
                                     internal_format=gl.GL_RGBA,
                                     position=(self.center, -75),
                                     anchor='center')

        # display the sky in its own viewport
        viewport2D = Viewport(screen=self.screen)
        viewport2D.parameters.stimuli = [sky, self.wheel]

        self.init_state()

        askText = Text(text='Press a key to start',
                       anchor='center',
                       position=(self.center, self.screen.size[1] / 2))
        splash = Viewport(screen=self.screen)
        splash.parameters.stimuli = [askText]
        self.askForNext = Presentation(go_duration=(0.5, 'seconds'),
                                       viewports=[splash])
        self.askForNext.add_controller(
            None, None, FunctionController(during_go_func=self.wait_for_key))
        self.askForNext.parameters.enter_go_loop = True
        self.askForNext.run_forever()

        self.simPres = Presentation(go_duration=(duration, 'seconds'),
                                    viewports=[viewport3D, viewport2D],
                                    handle_event_callbacks=[
                                        (pygame.KEYDOWN, self.check_keypress)
                                    ])
        self.simPres.add_controller(
            None, None, FunctionController(during_go_func=self.update))

        if doEyetrack:
            startTime = pylink.currentTime()
            self.tracker.sendMessage("SYNCTIME %d" %
                                     (pylink.currentTime() - startTime))
            error = self.tracker.startRecording(1, 1, 1, 1)
            self.tracker.sendMessage("PRES %d START" % (trial))

        self.simPres.go()

        if doEyetrack:
            self.tracker.sendMessage("PRES %d END" % (trial))
            self.tracker.stopRecording()

            # File transfer and cleanup!
            self.tracker.setOfflineMode()
            pylink.msecDelay(500)
            #Close the file and transfer it to Display PC
            self.tracker.closeDataFile()
            self.tracker.receiveDataFile(edfFileName, edfFileName)

        self.outf.close()

        if self.quit:
            raise SystemExit
示例#27
0
文件: exp.py 项目: jeffzemla/oft_exp
                    anchor='center',
                    size=(300.0, 300.0),
                    signal_fraction=cohLevel,
                    signal_direction_deg=dirx,
                    velocity_pixels_per_sec=100.0,
                    dot_lifespan_sec=0.08,
                    dot_size=3.0,
                    num_dots=200)

# Create a Viewport instance
viewport = Viewport(
    screen=screen,
    stimuli=[str_instruct_1, fixation, dotStim, str_instruct_2, sampleFix])

p = Presentation(
    go_duration=(exp_length, 'seconds'),
    trigger_go_if_armed=0,  #wait for trigger
    viewports=[viewport])

#initialize log file
logname = time.strftime('_%m-%d-%Y_%Hh-%Mm.csv')
logname = 'log_' + ss_num + logname
logfile = open(logname, 'w')
logfile.write("# LOGFILE: {0}\n".format(logname))
logfile.write("# Coherence,Direction,Response\n")

#################################
#  Main procedure               #
#################################


def getState(t):
示例#28
0
screen = get_default_screen()
screen.parameters.bgcolor = (0, 0, 0)
pygame.font.init()

###UNCHANGING STIMULI

#strat selection
fixText, fixCross = printText(screen, '', 60, (255, 255, 255))

#generate texts
strat2 = "\n\nDescribe your strategy"
stratText, stratPort = printText(screen, strat2, 60, (255, 255, 255))

pauseText, pausePort = printText(screen, "paused", 60, (255, 255, 255))

p4 = Presentation(go_duration=(problemTime, 'seconds'))
p = Presentation(go_duration=('forever', ))

#strat selection
startText, startCross = printWord(screen, 'Press the SPACEBAR to start', 60, (255, 255, 255))

pause = Presentation(go_duration=('forever', ), viewports=[startCross])
pause.parameters.handle_event_callbacks=[(pygame.locals.KEYDOWN, pause_handler)]  
pause.go()

p3 = Presentation(go_duration=(0.5, 'seconds'), viewports=[fixCross])

p2 = Presentation(go_duration=(diffTime, 'seconds'), viewports=[stratPort])
p2.parameters.handle_event_callbacks=[(pygame.locals.KEYDOWN, diff_handler)]        

示例#29
0
screen = get_default_screen()

# Set the background color to white (RGBA).
screen.parameters.bgcolor = (1.0,1.0,1.0,1.0)

# Create an instance of the Target2D class with appropriate parameters.
target = Target2D(size  = (25.0,10.0),
                  color      = (0.0,0.0,0.0,1.0), # Set the target color (RGBA) black
                  orientation = -45.0)

# Create a Viewport instance
viewport = Viewport(screen=screen, stimuli=[target])

# Create an instance of the Presentation class.  This contains the
# the Vision Egg's runtime control abilities.
p = Presentation(go_duration=(10.0,'seconds'),viewports=[viewport])

#######################
#  Define controller  #
#######################

# calculate a few variables we need
mid_x = screen.size[0]/2.0
mid_y = screen.size[1]/2.0
max_vel = min(screen.size[0],screen.size[1]) * 0.4

# define position as a function of time
def get_target_position(t):
    global mid_x, mid_y, max_vel
    return ( max_vel*sin(0.1*2.0*pi*t) + mid_x , # x
             max_vel*sin(0.1*2.0*pi*t) + mid_y ) # y
    dot_lifespan_sec        = 5.0,
    dot_size                = 3.0,
    num_dots                = 100
)

###############################################################
#  Create viewport - intermediary between stimuli and screen  #
###############################################################

viewport = Viewport(screen=screen, stimuli=[stimulus])

########################################
#  Create presentation object and go!  #
########################################

p = Presentation(go_duration=(5.0,'seconds'), viewports=[viewport])

##############################################
#  Connect the controller with the stimulus  #
##############################################

keyboard_response = KeyboardResponseController()

# Add the keyboard controller to the presentation's list of controllers
p.add_controller(None, None, keyboard_response)

########
#  Go  #
########

for i in range(3):
示例#31
0
                     velocity_pixels_per_sec=10.0,
                     dot_lifespan_sec=5.0,
                     dot_size=3.0,
                     num_dots=100)

###############################################################
#  Create viewport - intermediary between stimuli and screen  #
###############################################################

viewport = Viewport(screen=screen, stimuli=[stimulus])

########################################
#  Create presentation object and go!  #
########################################

p = Presentation(go_duration=(5.0, 'seconds'), viewports=[viewport])

##############################################
#  Connect the controller with the stimulus  #
##############################################

keyboard_response = KeyboardResponseController()

# Add the keyboard controller to the presentation's list of controllers
p.add_controller(None, None, keyboard_response)

########
#  Go  #
########

for i in range(3):
示例#32
0
class SimpleVisionEgg:
    keyboard_controller = None
    trigger_controller = None
    screen = None
    presentation = None
    keys = None
    presses = None
    releases = None

    def __init__(self):
        """We break up initialization a bit as we need to go back and forth with
        some information.  In this case, we need screen size before specifying
        the stimuli"""
        
        # pasted in from where it used to be at the beginning of the script
        # used to be outside of any methods...
        VisionEgg.start_default_logging()
        VisionEgg.watch_exceptions()
        # get screen size for setting fullscreen resolution
        # comment this block out if you don't want to use full-screen.
        screen = pygame.display.set_mode((0,0))
        WIDTH, HEIGHT = screen.get_size()
        pygame.quit()
        VisionEgg.config.VISIONEGG_SCREEN_W = WIDTH
        VisionEgg.config.VISIONEGG_SCREEN_H = HEIGHT

        self.screen = get_default_screen()
        self.keys = []
        self.presses = []
        self.releases = []

    def set_stimuli(self, stimuli, trigger=None, kb_controller=False):
        """Now that we have our stimuli, we initialize everything we can"""
        viewport = Viewport(screen=self.screen, size=self.screen.size, 
                           stimuli=stimuli)

        # We disable "check_events" so that we don't lose "instantaneous" key
        # presses and can check these in our Response classes
        self.presentation = Presentation(viewports=[viewport],
                check_events=False)

        if trigger:
            trigger_controller = KeyboardTriggerInController(trigger)
            self.presentation.add_controller(self.presentation, 
                                    'trigger_go_if_armed', trigger_controller)
            self.presentation.set(trigger_go_if_armed=0)

        if kb_controller:
            self.keyboard_controller = KeyboardResponseController()
            self.presentation.add_controller(None, None, self.keyboard_controller)


    def set_functions(self, update=None, pause_update=None):
        """Interface for cognac.StimulusController or similar"""
        self.presentation.add_controller(None, None,
                     FunctionController(during_go_func=update, 
                                        between_go_func=pause_update,
                                        return_type=NoneType) )


    def go(self, go_duration=('forever',)):
        self.presentation.parameters.go_duration = go_duration
        self.presentation.go()

    def pause(self):
        self.presentation.parameters.go_duration = (0, 'frames')

    def get_new_response(self, t, min_interval=2.0 / 60, releases=False):
        """(key, press) = get_new_response(self, t, min_interval=2.0 / 60)

        DEPRECATED!

        Use this function to get responses from the keyboard controller in real
        time.

        Returns (None, None) if no new response is available.
        Maintains three instance variables - keys, presses and releases, which
        you can also access directly (but they won't be updated during loops
        where you don't call this function)

        This function makes a number of assumptions and is a little brittle
        right now.  By not hard-coding the min_interval and maybe using key
        presses and release events directly, we'd have a much better function.
        But I don't really care right now.

        DJC
        """
        raise DeprecationWarning("please use pygame directly, as in" +
                                 "StimController.Response")
        # Note - this is deprecated anyway, but it'd probably make more sense to
        # use the keyboard_controller.get_responses() to simply get the keys
        # that are down _right_now_
        press_time = self.keyboard_controller.get_time_last_response_since_go()
        key = self.keyboard_controller.get_last_response_since_go()

        # Our first response!
        if len(self.keys) == 0:
            if key:
                self.keys.append(key)
                self.presses.append(press_time)
                self.releases.append(None)

                if releases:
                    return (key, None)
                else:
                    return (key, press_time)

            else:
                return (None, None)

                    
        # We haven't seen a key press for min_interval
        if t >= press_time + min_interval and not self.releases[-1]:
            # This is only approximate!
            self.releases[-1] = t 
            if releases:
                return (self.keys[-1], t)
            else:
                return (None, None)

        # We've seen a release, or we see a new key
        if (self.releases[-1] and press_time > self.releases[-1]) or \
                key != self.keys[-1]:
            if not self.releases[-1]:
                self.releases[-1] = press_time
            self.keys.append(key)
            self.presses.append(press_time)
            self.releases.append(None)

            if releases:
                return (key, None)
            else:
                return (key, press_time)

        return (None, None)

    def get_responses(self, timeToSubtract=0, min_interval=2.0/60):
        """
        Use this function to post-process the results of a KeyboardController

        VisionEgg's keyboard libraries records a keypress and timestamp every
        time something is down.  So if a key is held down for 100 ms, there will
        be an entry in the keylist for every sample during that 100ms.  This is
        a bit much; I'd rather just save onsets and offsets for every key.  This
        function evaluates that.
        """

        ''' 
        If we're using the FORP, this isn't necessary, as events have no duration; 
        they are represented as instantaneous keypresses.

        -- John
        '''

        response = self.keyboard_controller.get_responses_since_go()
        responseTime = self.keyboard_controller.get_time_responses_since_go()

        # If I've only got one item in my response list, then it's silly to worry about onset/offset.  Just keep it.
        if len(response) < 2:
            return (response,responseTime)
        
        # Save the first response, as by definition that's the first onset:
        goodResp = [response[0]]
        goodRespTime = [responseTime[0]-timeToSubtract]

        # Now step through every other item in the response list to check for unique-ness.
        for i in range(1,len(responseTime)):

            if (not(response[i] == response[i-1]) or \
                    (responseTime[i] - responseTime[i-1] > \
                         min_interval)):
                # ie, if something changed, or we have a long gap:
                
                offsetResp = [] # we might want to save an offset
                for item in response[i-1]: # loop through last item's data
                    if (responseTime[i] - responseTime[i-1] < \
                            min_interval) and \
                            not(item in response[i]):
                        # Bit clunky.  Basically, holding down a key while pressing another creates
                        # a unique response.  So if you only let up one of those keys, code the
                        # offset just for that key.
                        offsetResp.append(item+'_Off')
                    else:
                        # it's been long enough that everything that was on should be called off.
                        offsetResp.append(item+'_Off')

                if len(offsetResp) > 0:
                    # If there's offset stuff to worry about, save it.
                    goodResp.append(offsetResp)
                    goodRespTime.append(responseTime[i-1]-timeToSubtract)
                
                # Save the new (onset) response.
                goodResp.append(response[i])
                goodRespTime.append(responseTime[i]-timeToSubtract)

        # The final event should be an offset for whatever was down.
        offsetResp = []
        for item in response[-1]:
            offsetResp.append(item+'_Off')
        goodResp.append(offsetResp) #goodResp.append(response[-1]+'_Off')
        goodRespTime.append(responseTime[-1]-timeToSubtract)

        return (goodResp, goodRespTime)
示例#33
0
文件: Task1.py 项目: unshur/OpenPsyc
trial = 1
experiment = "numbers"

enoughPractice = False

while not enoughPractice:
	pracList = stroop.makePracticeList()
	for item in pracList:
		showStimulus(screen, item[0], item[1])
		trial += 1
		
	#experimenter prompt
	pracText, pracView = printWord(screen, 'Press SPACE TO CONTINUE, R TO REDO', 60, (255, 255, 255))

	pause = Presentation(go_duration=('forever', ), viewports=[pracView])
	pause.parameters.handle_event_callbacks=[(pygame.locals.KEYDOWN, practice_handler)]  
	pause.go()



"""
TRADITIONAL STROOP
1.  run trad stroop, 32 trials, 8 colour words
"""

trials = 32
colourWords = ["red", "blue", "green", "white", "yellow", "pink", "orange", "grey"]
colours = [[255, 0, 0], [0, 0, 255], [0, 255, 0], [255, 255, 255], [255, 255, 0], [255, 0, 255], [255, 153, 51], [100, 100, 100]]

Stroop = stroop.Stroop(colourWords, True, colours)
示例#34
0
import VisionEgg
VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()

from VisionEgg.Core import *
from VisionEgg.FlowControl import Presentation
from VisionEgg.Gratings import *
from VisionEgg.PyroHelpers import *

pyro_server = PyroServer()

# get visionegg stimulus ready to go
screen = get_default_screen()
stimulus = SinGrating2D()
viewport = Viewport(screen=screen,stimuli=[stimulus])
p = Presentation(viewports=[viewport])

# make a controller, serve it via pyro, and glue it to the Presentation
tf_controller = PyroConstantController(during_go_value=0.0)
pyro_server.connect(tf_controller,'tf_controller')
p.add_controller(stimulus,'temporal_freq_hz', tf_controller)

sf_controller = PyroConstantController(during_go_value=0.0)
pyro_server.connect(sf_controller,'sf_controller')
p.add_controller(stimulus,'spatial_freq', sf_controller)

contrast_controller = PyroConstantController(during_go_value=0.0)
pyro_server.connect(contrast_controller,'contrast_controller')
p.add_controller(stimulus,'contrast', contrast_controller)

orient_controller = PyroConstantController(during_go_value=0.0)
示例#35
0
class TRStimController:
    """This is a relatively simple controller that simply updates what's on the
    screen every TR (which is the next occurrence of keyboard input of '5' after
    the TR length is exceeded.  Currently it sets one stimulus on, and all
    others off, though we may want to change that to turn a list of stimuli on
    eventually"""
    # 3T laptop forp sends TTL pulses as "5"; buttons as "1","2","3","4"
    # John used to do things this way:
    # trigger_in_controller = KeyboardTriggerInController(pygame.locals.K_5)
    
    # Expected length of 1 TR
    TR = 2.0
    # Time interval after which we assume we missed the trigger
    eps = 0.1

    t = 0
    trial_times = None
    missed_trigs = None
    stim_list = []
    stim_dict = {}
    stim_seq = []

    keyboard_controller = None
    presentation = None
    screen = None

    def __init__(self, TR=None, eps=None):
        # Get the initial setup
        if TR:
            self.TR = TR 
        if eps:
            self.eps = eps

        self.trial_times = []
        self.missed_trigs = []
        self.state = self.state_generator()

        self.screen = get_default_screen()

        # background black (RGBA)
        self.screen.parameters.bgcolor = (0.0,0.0,0.0,0.0)

        self.keyboard_controller = KeyboardResponseController()
        self.firstTTL_trigger = KeyboardTriggerInController(K_5)
        
    def set_stims(self, stim_list, stim_dict, stim_seq_file): 
        self.stim_list = stim_list
        self.stim_dict = stim_dict
        self.stim_seq = yaml.load(stim_seq_file)

        viewport = Viewport(screen=self.screen,
                    size=self.screen.size,
                    stimuli=self.stim_list)

        # Need to at least wait for the first trigger if this is going to work.
        go_duration = (self.TR * len(self.stim_seq), 'seconds')
        self.presentation = Presentation(go_duration=go_duration,
                trigger_go_if_armed=0,
                viewports=[viewport])

        self.presentation.add_controller(None, None, 
                FunctionController(during_go_func=self.update) )
        self.presentation.add_controller(None, None, self.keyboard_controller)
        # Adding this so that we can start the stimuli ahead of time
        self.presentation.add_controller(self.presentation,'trigger_go_if_armed',
                                    self.firstTTL_trigger)

    def run(self):
        self.presentation.go()
        self.screen.close()    

    def update(self, t):
        self.t = t
        try:
            self.state.next()
        except StopIteration:
            # shouldn't really happen, what with epsilon and all...
            self.blank_all_stims()

    def blank_all_stims(self):
        for stim in self.stim_list:
            stim.parameters.on=False

    def state_generator(self):
        for stim_info in self.stim_seq:
            self.trial_times.append(self.t)
            self.blank_all_stims()
            try:
                for stim_name, params in stim_info.items():
                    stim = self.stim_dict[stim_name]
                    stim.parameters.on = True
                    try:
                        for name, value in params.items():
                            setattr(stim.parameters, name, value)
                    except AttributeError:
                        # params was None or something else we don't deal with
                        pass
            except AttributeError:
                # We assume a no-colon single token / key
                self.stim_dict[stim_info].parameters.on = True


            # Don't even bother 'til we're close to the expected TR time
            while self.t - self.trial_times[-1] < self.TR - 2*self.eps:
                yield

            while self.t - self.trial_times[-1] < self.TR + self.eps:
                # Handle the rare case when a key might register between
                # function calls - THIS WOULD NEVER HAPPEN WITH VisionEgg as
                # written!
                while True:
                    keys = self.keyboard_controller.get_responses_since_go()
                    times = \
                        self.keyboard_controller.get_time_responses_since_go()
                    if len(keys) == len(times):
                        break

                i = None
                try:
                    # Find the last value of '5' without inline reversal of keys/times
                    # VisionEgg returns "responses" as a list of lists of chars, not just a list of chars...
                    i = len(keys)-1-list(reversed(keys)).index(['5'])
                except ValueError:
                    pass
                
                # If anybody presses the escape key, quit entirely.
                try:
                    needToQuit = keys.index(['escape'])
                    #self.presentation = None
                    #exit()
                except ValueError:
                    pass

                if i and times[i] > self.trial_times[-1]:
                    break
                else:
                    yield

            if self.t - self.trial_times[-1] >= self.TR + self.eps:
                # We missed a TR (we think)
                self.missed_trigs.append(self.t)
                self.t = self.trial_times[-1] + self.TR


    def get_responses(self, timeToSubtract=0, min_interval=2.0/60):
        """
        This function isn't especially elegant, but it's functional.

        VisionEgg's keyboard libraries records a keypress and timestamp every
        time something is down.  So if a key is held down for 100 ms, there will
        be an entry in the keylist for every sample during that 100ms.  This is
        a bit much; I'd rather just save onsets and offsets for every key.  This
        function evaluates that.
        """

        ''' 
        If we're using the FORP, this isn't necessary, as events have no duration; 
        they are represented as instantaneous keypresses.

        -- John
        '''

        response = self.keyboard_controller.get_responses_since_go()
        responseTime = self.keyboard_controller.get_time_responses_since_go()

        # If I've only got one item in my response list, then it's silly to worry about onset/offset.  Just keep it.
        if len(response) < 2:
            return (response,responseTime)
        
        # Save the first response, as by definition that's the first onset:
        goodResp = [response[0]]
        goodRespTime = [responseTime[0]-timeToSubtract]

        # Now step through every other item in the response list to check for unique-ness.
        for i in range(1,len(responseTime)):

            if (not(response[i] == response[i-1]) or \
                    (responseTime[i] - responseTime[i-1] > \
                         min_interval)):
                # ie, if something changed, or we have a long gap:
                
                offsetResp = [] # we might want to save an offset
                for item in response[i-1]: # loop through last item's data
                    if (responseTime[i] - responseTime[i-1] < \
                            min_interval) and \
                            not(item in response[i]):
                        # Bit clunky.  Basically, holding down a key while pressing another creates
                        # a unique response.  So if you only let up one of those keys, code the
                        # offset just for that key.
                        offsetResp.append(item+'_Off')
                    else:
                        # it's been long enough that everything that was on should be called off.
                        offsetResp.append(item+'_Off')

                if len(offsetResp) > 0:
                    # If there's offset stuff to worry about, save it.
                    goodResp.append(offsetResp)
                    goodRespTime.append(responseTime[i-1]-timeToSubtract)
                
                # Save the new (onset) response.
                goodResp.append(response[i])
                goodRespTime.append(responseTime[i]-timeToSubtract)

        # The final event should be an offset for whatever was down.
        offsetResp = []
        for item in response[-1]:
            offsetResp.append(item+'_Off')
        goodResp.append(offsetResp) #goodResp.append(response[-1]+'_Off')
        goodRespTime.append(responseTime[-1]-timeToSubtract)

        return (goodResp, goodRespTime)
示例#36
0
文件: exp.py 项目: jeffzemla/oft_exp
dotStim = DotArea2D( position                = ( screen_half_x, screen_half_y ),
                      anchor                  = 'center',
                      size                    = ( 300.0 , 300.0 ),
                      signal_fraction         = cohLevel,
                      signal_direction_deg    = dirx,
                      velocity_pixels_per_sec = 100.0,
                      dot_lifespan_sec        = 0.08,
                      dot_size                = 3.0, 
                      num_dots                = 200)

# Create a Viewport instance
viewport = Viewport(screen=screen, stimuli=[str_instruct_1, fixation, dotStim, str_instruct_2, sampleFix])

p = Presentation(
    go_duration = (exp_length,'seconds'),
    trigger_go_if_armed = 0,            #wait for trigger
    viewports = [viewport])

#initialize log file
logname=time.strftime('_%m-%d-%Y_%Hh-%Mm.csv')
logname='log_'+ss_num+logname
logfile = open(logname, 'w')
logfile.write("# LOGFILE: {0}\n".format(logname))
logfile.write("# Coherence,Direction,Response\n")

#################################
#  Main procedure               #
#################################

def getState(t):
    global fixOn, dotsOn, changeCoh, changeDir, keyPressed, fixOn_start, dotsOn_start, rt, main_curr, block_total, block_curr, practicenum, blocktype, sampleFixOn
示例#37
0
# Set the background color to white (RGBA).
screen.parameters.bgcolor = (1.0,1.0,1.0,1.0)

# Create an instance of the Target2D class with appropriate parameters.
target = Target2D(size  = (25.0,10.0),
                  anchor = 'center',
                  color      = (0.0,0.0,0.0,1.0), # Set the target color (RGBA) black
                  orientation = -45.0)

# Create a Viewport instance
viewport = Viewport(screen=screen, stimuli=[target])

# Create an instance of the Presentation class.  This contains the
# the Vision Egg's runtime control abilities.
p = Presentation(go_duration=(10.0,'seconds'),viewports=[viewport])

#######################
#  Define controller  #
#######################

# calculate a few variables we need
mid_x = screen.size[0]/2.0
mid_y = screen.size[1]/2.0
max_vel = min(screen.size[0],screen.size[1]) * 0.4

# define position as a function of time
def get_target_position(t):
    global mid_x, mid_y, max_vel
    return ( max_vel*sin(0.1*2.0*pi*t) + mid_x , # x
             max_vel*sin(0.1*2.0*pi*t) + mid_y ) # y
示例#38
0
 # first block images


#####################
## RUNTIME CONTROL ##
#####################

count = 0

while (count<1):
    # Create a Viewport instance (initialized just to display instructions)
    viewport = Viewport(screen=screen, stimuli=[introTexts[count]])


    # Create an instance of the Presentation class.  (Runtime control)
    p = Presentation(go_duration=('forever',), viewports=[viewport])


    # Register Event Handlers
    p.parameters.handle_event_callbacks = \
        [(pygame.locals.QUIT, quit), (pygame.locals.KEYDOWN, keydown), (pygame.locals.KEYUP, keyup)]

    count = count + 1



#
# Script to show only example from targets.
#

def showTargets(viewport):
示例#39
0
class VisualSpellerVE(MainloopFeedback):
    """
    Visual Speller with six circles like the classical HexOSpell.
    """

    # Triggers: look in Marker
    END_LEVEL1, END_LEVEL2 = 244, 245  # end of hex levels
    COPYSPELLING_FINISHED = 246
    STIMULUS = [[11, 12, 13, 14, 15, 16], [21, 22, 23, 24, 25, 26]]
    RESPONSE = [[51, 52, 53, 54, 55, 56], [61, 62, 63, 64, 65, 66]]
    TARGET_ADD = 20
    ERROR_ADD = 100
    COUNTDOWN_STIMULI = 239
    ERROR_POTENTIAL = 96  # send if error potential is classified

    def init(self):
        """
        initialize parameters
        """
        self.log_filename = "VisualSpellerVE.log"

        self.geometry = [0, 0, 1280, 800]  ## size

        self.letterbox_size = (60, 60)
        self.osc_size = 40
        self.font_size_phrase = 60  # the spelled phrase at the top
        self.font_size_current_letter = 80  # the spelled phrase at the top
        self.font_size_countdown = 150  # number during countdown
        self.desired_phrase = ""

        ## colors:
        self.bg_color = (0.0, 0.0, 0.0)
        self.phrase_color = (0.2, 0.0, 1.0)
        self.current_letter_color = (1.0, 0.0, 0.0)
        self.countdown_color = (0.2, 0.0, 1.0)
        self.osc_color = (1, 1, 1)

        self.letter_set = [
            ["A", "B", "C", "D", "E"],
            ["F", "G", "H", "I", "J"],
            ["K", "L", "M", "N", "O"],
            ["P", "Q", "R", "S", "T"],
            ["U", "V", "W", "X", "Y"],
            ["Z", "_", ".", ",", "<"],
        ]
        self.fullscreen = False
        self.use_oscillator = True
        self.offline = True
        self.copy_spelling = True  # in copy-spelling mode, selection of the target symbol is forced
        self.debug = False
        self.nCountdown = 5
        self.nr_sequences = 6
        self.randomize_sequence = True  # set to False to present a fixed stimulus sequence
        self.min_dist = 2  # Min number of intermediate flashes bef. a flash is repeated twice

        self.stimulus_duration = 0.083  # 5 frames @60 Hz = 83ms flash
        self.interstimulus_duration = 0.1
        self.animation_time = 1
        self.wait_before_classify = 1.0
        self.feedback_duration = 1.0
        self.feedback_ErrP_duration = 1.0
        self.wait_after_start = 0.0

        # Countdown options
        self.do_animation = True
        self.synchronized_countdown = True
        if self.synchronized_countdown:
            self.do_animation = False

        self.countdown_level1 = True
        self.countdown_level2 = True

        self.countdown_shapes = {"circle": FilledCircle, "hexagon": FilledHexagon}
        self.countdown_shape_select = "hexagon"
        self.countdown_shape_color = (0.7, 0.7, 0.7)
        self.countdown_shape_on = True
        self.countdown_blinking_nr = 5  # number of pre-sequence stimuli(1 sec is approx. 5 frames at 60 Hz)

        self.wait_after_early_stopping = 3  # sec
        self.abort_trial = False
        self.output_per_stimulus = True
        self.use_ErrP_detection = False

        self.serialtrigger = False
        self.serialport = serialport.SerialPort(13)
        self.send_parallel_bak = self.send_parallel

        if self.debug:
            msg = "!!! YOU'RE IN DEBUG MODE! CLASSIFICATION WILL BE RANDOM OR KEYBOARD CONTROLLED !!!"
            self.logger.warning(msg)

    def pre_mainloop(self):

        ## logging
        assert len(self.log_filename) != 0  # 'log_filename' must not be empty string!
        logger.setLevel(logging.ERROR)
        handler = logging.FileHandler(self.log_filename, "w")
        handler.setLevel(logging.INFO)
        formatter = logging.Formatter("%(asctime)s: %(message)s")
        handler.setFormatter(formatter)
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(handler)

        self._nr_elements = 6
        self._idx_backdoor = 5
        self._init_classifier_output()
        self._classified_element = -1
        self._classified_letter = -1
        for s in self.desired_phrase:
            assert s in [l for ls in self.letter_set for l in ls]  # invalid letters in desired phrase!
        self._spelled_phrase = ""
        self._spelled_letters = ""
        self._desired_letters = self.desired_phrase
        self._copyspelling_finished = False
        #        if self.offline:
        #            self.__idle()                # In offline mode: set the first to-be-spelled letter

        self._spellerHeight = self.geometry[3] - self.letterbox_size[1]
        self._centerPos = (self.geometry[2] / 2.0, self._spellerHeight / 2.0)

        self._nr_letters = 0
        for i in xrange(len(self.letter_set)):
            self._nr_letters += len(self.letter_set[i])

        self._current_level = 1  # Index of current level
        self._current_sequence = 0  # Index of current sequence
        self._current_stimulus = 0  # Index of current stimlus
        self._current_countdown = self.nCountdown
        self.random = random.Random(clock())
        self._debug_classified = None

        ## init states:
        self._state_countdown = True
        if not self.countdown_level1:
            self._state_countdown = False
            self._state_trial = True
        else:
            # self._state_countdown = not self.offline
            self._state_trial = False

        self._state_classify = False
        self._state_feedback = False
        self._state_abort = False

        ## init containers for VE elements:
        self._ve_elements = []

        ## oscillator state:
        if not self.use_oscillator:
            self.osc_color = self.bg_color
            self.osc_size = 0

        ## call subclass-specific pre_mainloop:
        self.prepare_mainloop()

        ## build screen elements:
        self.__init_screen()
        if self.offline:
            self.__idle()
        if self.abort_trial:
            """
            Start listener for abort_trial event eg.
            """

        ## delay after play (might be useful for filters...)
        pygame.time.wait(int(self.wait_after_start * 1000))
        self.logger.info("waiting %d seconds after play." % self.wait_after_start)

        ## send start trigger:
        self.send_parallel(marker.RUN_START)
        self.logger.info("[TRIGGER] %d" % marker.RUN_START)

        ## error potential classifier:
        self._ErrP_classifier = None

    def on_interaction_event(self, data):
        self.logger.debug("interaction event")
        serial = data.get("serialtrigger", None)
        if serial is None:
            return
        if serial:
            self.logger.debug("using serial port")
            self.send_parallel = self.serialport.send
        else:
            self.logger.debug("using parallel port")
            self.send_parallel = self.send_parallel_bak

    def post_mainloop(self):
        """
        Sends end marker to parallel port.
        """

        if self.abort_trial:
            """
            Stop listener for abort_trial event
           """
            pass

        pygame.time.wait(500)
        self.send_parallel(marker.RUN_END)
        self.logger.info("[TRIGGER] %d" % marker.RUN_END)
        pygame.time.wait(500)
        self._presentation.set(quit=True)
        self._screen.close()

    def __init_screen(self):
        ## create screen:
        if not self.fullscreen:
            os.environ["SDL_VIDEO_WINDOW_POS"] = "%d, %d" % (self.geometry[0], self.geometry[1])
        self._screen = Screen(
            size=(self.geometry[2], self.geometry[3]), fullscreen=self.fullscreen, bgcolor=self.bg_color, sync_swap=True
        )

        ## create letter box on top:
        self._ve_letterbox = Target2D(
            position=(self._centerPos[0], self.geometry[3] * (1 - 0.01) - self.letterbox_size[1] / 2.0),
            size=(self.letterbox_size[0], self.letterbox_size[1]),
            color=self.phrase_color,
        )
        self._ve_innerbox = Target2D(
            position=(self._centerPos[0], self.geometry[3] * (1 - 0.01) - self.letterbox_size[1] / 2.0),
            size=(self.letterbox_size[0] - 6, self.letterbox_size[1] - 6),
            color=self.bg_color,
        )

        self._current_letter_position = (
            self._centerPos[0],
            self.geometry[3] * (1 - 0.015) - self.letterbox_size[1] / 2.0,
        )
        self._ve_current_letter = Text(
            position=self._current_letter_position,
            text=(len(self._desired_letters[:1]) == 0 and " " or self._desired_letters[:1]),
            font_size=self.font_size_current_letter,
            color=self.current_letter_color,
            anchor="center",
        )

        self._ve_desired_letters = Text(
            position=(self._centerPos[0] + 5 + self.letterbox_size[0] / 2.0, self._current_letter_position[1]),
            text=(len(self._desired_letters[1:]) == 0 and " " or self._desired_letters[1:]),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor="left",
        )

        self._ve_spelled_phrase = Text(
            position=(self._centerPos[0] - 5 - self.letterbox_size[0] / 2.0, self._current_letter_position[1]),
            text=(len(self._spelled_phrase) == 0 and " " or self._spelled_phrase),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor="right",
        )

        # if we're in free spelling mode, we hide all text fields but
        # the _ve_spelled_phrase. we also need a multiline
        # _ve_spelled_phrase instead of the single lined one
        if self.offline == self.copy_spelling == False:
            self._spelled_phrase = "   "
            self._ve_spelled_phrase = WrappedText(
                position=(0, self._current_letter_position[1]),
                text=(len(self._spelled_phrase) == 0 and " " or self._spelled_phrase),
                font_size=self.font_size_phrase,
                color=self.phrase_color,
                size=(float(self.geometry[2]), float(self.geometry[3])),
            )
            for i in self._ve_letterbox, self._ve_innerbox, self._ve_current_letter, self._ve_desired_letters:
                i.set(on=False)

        ## add word box to elementlist:
        self._ve_elements.extend(
            [
                self._ve_letterbox,
                self._ve_innerbox,
                self._ve_current_letter,
                self._ve_desired_letters,
                self._ve_spelled_phrase,
            ]
        )

        ## create countdown:
        self._ve_countdown = Text(
            position=self._centerPos,
            text=" ",
            font_size=self.font_size_countdown,
            color=self.countdown_color,
            anchor="center",
            on=False,
        )

        ## create countdown shapes
        self._ve_countdown_shape = self.countdown_shapes[self.countdown_shape_select](
            radius=90, position=self._centerPos, color=self.countdown_shape_color, on=False
        )

        ## create oscillator circle:
        self._ve_oscillator = FilledCircle(
            position=(self.osc_size / 2 + 10, self.osc_size / 2 + 10),
            radius=self.osc_size / 2,
            color=self.osc_color,
            on=False,
        )

        ## create shapes and letters:
        self.init_screen_elements()

        ## add remaining elements to element list:
        self._ve_elements.extend([self._ve_countdown_shape, self._ve_countdown, self._ve_oscillator])

        ## add elements to viewport:
        self._viewport = Viewport(screen=self._screen, stimuli=self._ve_elements)
        self._presentation = Presentation(
            viewports=[self._viewport],
            handle_event_callbacks=[(pygame.KEYDOWN, self.keyboard_input), (pygame.QUIT, self.__stop)],
        )

    def play_tick(self):
        """
        called every loop, if in play mode.
        """

        self.pre_play_tick()

        if self._state_countdown:
            self.pre__countdown()
            self.__countdown()
            self.post__countdown()
        elif self._state_trial:
            self.pre__trial()
            self.__trial()
            self.post__trial()
        elif self._state_classify:
            self.pre__classify()
            self.__classify()
            self.post__classify()
        elif self._state_feedback:
            self.pre__feedback()
            self.__feedback()
            self.post__feedback()
        elif self._state_abort:
            self.__abort()
            self.post__abort()
        else:
            self.pre__idle()
            self.__idle()
            self.post__idle()
        self.post_play_tick()

    def __stop(self, *args):
        self.on_stop()

    def __idle(self):
        if self.offline and len(self._desired_letters) > 0:
            # add new letter:
            for e in xrange(len(self.letter_set)):
                for l in xrange(len(self.letter_set[e])):
                    if self._desired_letters[0] == self.letter_set[e][l]:
                        self._classified_element = e
                        self._classified_letter = l
            if self.countdown_level1:
                self._state_countdown = True
            else:
                self._state_trial = True
        else:
            ## otherwise just wait until a new letter is sent:
            self._presentation.set(go_duration=(0.1, "seconds"))
            self._presentation.go()

    def __countdown(self):
        def blink():
            i = 0
            while i < self.countdown_blinking_nr:
                self._ve_countdown_shape.set(on=True)
                self._ve_countdown.set(text="%d" % self._current_countdown, on=True)
                self.send_parallel(self.COUNTDOWN_STIMULI)
                self.logger.info("[TRIGGER] %d" % self.COUNTDOWN_STIMULI)
                self._presentation.set(go_duration=(self.stimulus_duration, "seconds"))
                self._presentation.go()
                self._ve_countdown_shape.set(on=False)
                self._ve_countdown.set(on=False)
                self._presentation.set(go_duration=(self.interstimulus_duration, "seconds"))
                self._presentation.go()
                i = i + 1

        if self._current_countdown == self.nCountdown:
            self.send_parallel(marker.COUNTDOWN_START)
            self.logger.info("[TRIGGER] %d" % marker.COUNTDOWN_START)
            self.set_countdown_screen()
            self._ve_countdown.set(on=True)
            self._ve_countdown_shape.set(on=self.countdown_shape_on)
            self._presentation.set(go_duration=(1, "seconds"))

        self._ve_countdown.set(text="%d" % self._current_countdown)
        self._presentation.go()
        self._current_countdown = (self._current_countdown - 1) % self.nCountdown

        if self.synchronized_countdown and self._current_countdown == 1:
            self.set_synchronized_countdown_screen()
            blink()
            self._current_countdown = self.nCountdown
            self.set_standard_screen()
            self._state_countdown = False
            self._state_trial = True
            self._ve_countdown.set(on=False)
            self._ve_countdown_shape.set(on=False)
            self._ve_countdown.set(color=self.countdown_color)

        if self._current_countdown == 0:
            # Executed only if self.synchronized_countdown = False
            self._current_countdown = self.nCountdown
            self.set_standard_screen()
            pygame.time.wait(10)
            self._state_countdown = False
            self._state_trial = True
            self._ve_countdown_shape.set(on=False)
            self._ve_countdown.set(on=False)
            self._ve_countdown.set(color=self.countdown_color)

    def __trial(self):

        if self._current_sequence == 0 and self._current_stimulus == 0:

            # level 1 animation when there is no countdown
            if self._current_level == 1 and not self.countdown_level1:
                if self.do_animation:
                    self.set_countdown_screen()
                self.set_standard_screen()
            # generate random sequences:
            if self.randomize_sequence:
                self.flash_sequence = []
                for _ in range(self.nr_sequences):
                    random_flash_sequence(
                        self, set=range(self._nr_elements), min_dist=self.min_dist, seq_len=self._nr_elements
                    )
            # or else use fixed sequence:
            else:
                self.flash_sequence = range(self._nr_elements)

        if self.randomize_sequence:
            currentStimulus = self.flash_sequence[self._current_sequence * self._nr_elements + self._current_stimulus]
        else:
            currentStimulus = self.flash_sequence[self._current_stimulus]
        # set stimulus:
        self.stimulus(currentStimulus, True)
        # self._ve_oscillator.set(on=True)

        if self.abort_trial and self.abort_trial_check():
            # restart trial on abort_trial event:
            self._state_trial = False
            self._state_abort = True
            return

        # check if current stimulus is target and then send trigger:
        target_add = 0
        if len(self._desired_letters) > 0:
            if self._current_level == 1:
                if self._desired_letters[:1] in self.letter_set[currentStimulus]:
                    # current stimulus is target group:
                    target_add = self.TARGET_ADD
            else:
                if currentStimulus == self._idx_backdoor:
                    # current stimulus is backdoor:
                    if not self._desired_letters[:1] in self.letter_set[self._classified_element]:
                        # we are in the wrong group. backdoor is target:
                        target_add = self.TARGET_ADD
                else:
                    # current stimulus is no backdoor:
                    if self._desired_letters[:1] == self.letter_set[self._classified_element][currentStimulus]:
                        # current stimulus is target symbol:
                        target_add = self.TARGET_ADD

        self.send_parallel(self.STIMULUS[self._current_level - 1][currentStimulus] + target_add)
        self.logger.info("[TRIGGER] %d" % (self.STIMULUS[self._current_level - 1][currentStimulus] + target_add))

        # present stimulus:
        self._presentation.set(go_duration=(self.stimulus_duration, "seconds"))
        self._presentation.go()

        # reset to normal:
        self._ve_oscillator.set(on=False)
        self.stimulus(currentStimulus, False)

        # present interstimulus:
        self._presentation.set(go_duration=(self.interstimulus_duration, "seconds"))
        self._presentation.go()

        if self.debug:
            self.on_control_event({"cl_output": (self.random.random(), currentStimulus + 1)})

        ## TODO: check here for classification !!!!
        if self.output_per_stimulus:
            # increase
            self._current_stimulus = (self._current_stimulus + 1) % self._nr_elements
            if self._current_stimulus == 0:
                self._current_sequence = (self._current_sequence + 1) % self.nr_sequences

            # check for end of trial:
            if self._current_sequence == 0 and self._current_stimulus == 0:

                # send trigger:
                if self._current_level == 1:
                    self.send_parallel(self.END_LEVEL1)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL1)
                else:
                    self.send_parallel(self.END_LEVEL2)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL2)

                # decide how to continue:
                self._state_trial = False
                self._state_classify = True
        else:
            # increase
            self._current_stimulus = (self._current_stimulus + 1) % self._nr_elements
            if self._current_stimulus == 0:
                self._current_sequence = (self._current_sequence + 1) % self.nr_sequences
                if self.check_classification(self._current_sequence + 1):
                    self._state_trial = False
                    self._state_classify = True
                    pygame.time.wait(self.wait_after_early_stopping * 1000)

            if self._current_sequence == 0 and self._current_stimulus == 0:

                # send trigger:
                if self._current_level == 1:
                    self.send_parallel(self.END_LEVEL1)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL1)
                else:
                    self.send_parallel(self.END_LEVEL2)
                    self.logger.info("[TRIGGER] %d" % self.END_LEVEL2)

                # decide how to continue:
                self._state_trial = False
                self._state_classify = True

    def check_classification(self, nr):
        # print self._classifier_output
        means = [None] * self._nr_elements
        minimum = maxint
        classified = None
        for ii in range(self._nr_elements):
            means[ii] = sum(self._classifier_output[ii]) / nr
            if means[ii] < minimum:
                minimum = means[ii]
                classified = ii + 1

        print "\n**** Class: %d (mean=%f)\n" % (classified, means[classified - 1])
        return classified

    def __classify(self):

        ## wait until all classifier outputs are received:
        self._presentation.set(go_duration=(self.wait_before_classify, "seconds"))
        self._presentation.go()
        if self.offline:
            if self._current_level == 1:
                classified = self._classified_element
            else:
                classified = self._classified_letter
        elif not self._debug_classified == None:
            classified = self._debug_classified
            self._debug_classified = None
        else:
            if self.output_per_stimulus:
                nClassified = sum([len(self._classifier_output[i]) for i in xrange(self._nr_elements)])
                if nClassified < self._nr_elements * self.nr_sequences:
                    pygame.time.wait(20)
                    print "not enough classifier-outputs received! (something may be wrong)"
                    return

                ## classify and set output:
                means = [None] * self._nr_elements
                minimum = maxint
                classified = None
                for ii in range(self._nr_elements):
                    means[ii] = sum(self._classifier_output[ii]) / self.nr_sequences
                    if means[ii] < minimum:
                        minimum = means[ii]
                        classified = ii
                print "\n**** Class: %d (mean=%f)\n" % (classified + 1, means[classified])
            else:
                means = [None] * self._nr_elements
                minimum = maxint
                classified = None
                for ii in range(self._nr_elements):
                    means[ii] = sum(self._classifier_output[ii]) / self.nr_sequences
                    if means[ii] < minimum:
                        minimum = means[ii]
                        classified = ii
                print "\n**** Class: %d (mean=%f)\n" % (classified + 1, means[classified])

            ## Reset classifier output to empty lists
            self._init_classifier_output()

        error_add = 0
        ## evaluate classification:
        if self._current_level == 1:
            self._classified_element = classified
            if len(self._desired_letters) > 0 and not self._desired_letters[:1] in self.letter_set[classified]:
                # wrong group selected:
                error_add = self.ERROR_ADD
        else:
            self._classified_letter = classified
            if self._classified_letter == self._idx_backdoor:
                ## backdoor classified:
                if (
                    len(self._desired_letters) > 0
                    and self._desired_letters[:1] in self.letter_set[self._classified_element]
                ):
                    # backdoor selection wrong:
                    error_add = self.ERROR_ADD
            else:
                ## no backdoor classified:
                spelled_letter = self.letter_set[self._classified_element][self._classified_letter]
                if len(self._desired_letters) > 0 and spelled_letter != self._desired_letters[:1]:
                    # wrong letter spelled:
                    error_add = self.ERROR_ADD

        ## send response trigger:
        self.send_parallel(self.RESPONSE[self._current_level - 1][classified] + error_add)
        self.logger.info("[TRIGGER] %d" % (self.RESPONSE[self._current_level - 1][classified] + error_add))

        self._state_classify = False
        self._state_feedback = True

    def __feedback(self):
        self._state_feedback = False

        ## call subclass method:
        self.feedback()

        ## check ErrP classification:
        if self.use_ErrP_detection:
            t = 0
            while self._ErrP_classifier is None and t < 1000:
                t += 50
                pygame.time.wait(50)
            if self._ErrP_classifier is None:
                print "no ErrP classifier received! "
            if self._ErrP_classifier:
                self.send_parallel(self.ERROR_POTENTIAL)
                self.logger.info("[TRIGGER] %d" % (self.ERROR_POTENTIAL))

        ## call subclass method:
        if not self.countdown_level2:
            self.switch_level()

        ## update phrases:
        if (
            (self._current_level == 2)
            and (  # only update, if we are at the end of level 2,
                self._classified_letter != self._idx_backdoor or self.copy_spelling
            )
            and (  # if copyspelling off, we have no backdoor selected
                self._ErrP_classifier is None or not self._ErrP_classifier
            )
        ):  # no ErrP was detected (or ErrP detection is off)
            spelled_letter = ""
            if self.copy_spelling:
                ## in copy spelling we force the desired letter to be spelled
                if len(self._desired_letters) > 0:
                    spelled_letter = self._desired_letters[:1]
                else:
                    print "??? moved beyond desired phrase in copy spelling ???"
            else:
                spelled_letter = self.letter_set[self._classified_element][self._classified_letter]

            ## update desired phrase:
            if len(self._desired_letters) > 0:
                if spelled_letter == self._desired_letters[:1]:
                    # correct letter spelled:
                    self._desired_letters = self._desired_letters[1:]  # remove first letter
                else:
                    # wrong letter spelled:
                    if spelled_letter == "<":
                        self._desired_letters = self._spelled_phrase[-1:] + self._desired_letters
                    else:
                        self._desired_letters = "<" + self._desired_letters
                if len(self._desired_letters) == 0:
                    self._copyspelling_finished = True

            ## update spelled phrase:
            self._spelled_letters += spelled_letter
            if spelled_letter == "<":
                self._spelled_phrase = self._spelled_phrase[:-1]
            else:
                self._spelled_phrase += spelled_letter

            ## update screen phrases:
            self.logger.info("Current Phrase:")
            self.logger.info(self._spelled_phrase)
            self._ve_spelled_phrase.set(text=(len(self._spelled_phrase) == 0 and " " or self._spelled_phrase))
            self._ve_current_letter.set(text=(len(self._desired_letters[:1]) == 0 and " " or self._desired_letters[:1]))
            self._ve_desired_letters.set(
                text=(len(self._desired_letters[1:]) == 0 and " " or self._desired_letters[1:])
            )

        if self.use_ErrP_detection and self._ErrP_classifier:
            self._state_trial = True

        else:
            if self._current_level == 1:
                # continue with level2 trial:
                if self.countdown_level2:
                    self._state_countdown = True
                else:
                    self._state_trial = True

            elif not self.offline:
                # start countdown
                if self.countdown_level1:
                    self._state_countdown = True
                else:
                    self._state_trial = True

            # set new level:
            self._current_level = 3 - self._current_level

        ## reset ErrP_classifier:
        self._ErrP_classifier = None

        # check copyspelling:
        if self._copyspelling_finished:
            self._copyspelling_finished = False
            self.on_control_event({"print": 0})  # print desired phrase
            self.on_control_event({"print": 1})  # print spelled phrase
            self.on_control_event({"print": 2})  # print all spelled letters
            self.send_parallel(self.COPYSPELLING_FINISHED)
            self.logger.info("[TRIGGER] %d" % (self.COPYSPELLING_FINISHED))
            pygame.time.wait(50)

    def __abort(self):

        # play warning sound

        def sine_array_onecycle(hz, peak, sample_rate):
            length = sample_rate / float(hz)
            omega = NP.pi * 2 / length
            xvalues = NP.arange(int(length)) * omega
            return peak * NP.sin(xvalues)

        def sine_array(hz, peak, samples_rate):
            return NP.resize(sine_array_onecycle(hz, peak, sample_rate), (sample_rate,))

        sample_rate = 44100
        pygame.mixer.init(sample_rate, -16, 2)  # 44.1kHz, 16-bit signed, stereo
        f = sine_array(8000, 1, sample_rate)
        f = NP.array(zip(f, f))
        sound = pygame.sndarray.make_sound(f)
        channel = sound.play(-1)
        channel.set_volume(0.2, 0.2)
        pygame.time.delay(1000)
        sound.stop()

        if self._current_level == 1 and self.countdown_level1:
            self._state_countdown = True
        elif self._current_level == 2 and self.countdown_level2:
            self._state_countdown = True
        else:
            self._state_trial = True

        self._init_classifier_output()

    def _init_classifier_output(self):
        ## Empty lists
        self._classifier_output = [list() for _ in xrange(self._nr_elements)]

    def abort_trial_check(self):
        """
        Check if event is an abort trial event
        """
        return False

    def keyboard_input(self, event):
        if event.key == pygame.K_ESCAPE:
            self.on_stop()
        elif event.key == pygame.K_KP_ENTER:
            self.on_control_event({"print": 0})  # print desired phrase
            self.on_control_event({"print": 1})  # print spelled phrase
            self.on_control_event({"print": 2})  # print all spelled letters
        elif event.key == pygame.K_DELETE:
            # The DELETE key empties the spelled text shown this works
            # only in free spelling mode (i.e. offline and copy_spelling
            # are set to False)
            if self.offline == self.copy_spelling == False:
                self.logger.info("Clearing Text.")
                self._spelled_phrase = "   "
        elif self.debug:
            if (
                (event.key >= pygame.K_a and event.key <= pygame.K_z)
                or (event.key == pygame.K_LESS)
                or (event.key == pygame.K_PERIOD)
                or (event.key == pygame.K_COMMA)
            ):
                self.on_control_event({"new_letter": chr(event.key).upper()})
            elif event.key == pygame.K_MINUS:
                self.on_control_event({"new_letter": chr(pygame.K_UNDERSCORE)})
            elif event.key == pygame.K_BACKSPACE:
                self.on_control_event({"new_letter": chr(pygame.K_LESS)})
            elif event.key == pygame.K_SPACE:
                self.on_control_event({"new_letter": chr(pygame.K_UNDERSCORE)})
            elif event.key == pygame.K_UP and self.use_ErrP_detection:
                self.on_control_event({"cl_output": (1, 7)})
            elif event.key == pygame.K_DOWN and self.use_ErrP_detection:
                self.on_control_event({"cl_output": (0, 7)})
            if not self.offline:
                if event.key >= pygame.K_0 and event.key <= pygame.K_5:
                    self._debug_classified = int(chr(event.key))
                elif event.key >= pygame.K_KP0 and event.key <= pygame.K_KP5:
                    self._debug_classified = int(chr(event.key - 208))

    def on_control_event(self, data):
        self.logger.info("[CONTROL_EVENT] %s" % str(data))
        if data.has_key(u"cl_output"):
            # classification output was sent:
            score_data = data[u"cl_output"]
            cl_out = score_data[0]
            iSubstim = int(score_data[1])  # evt auch "Subtrial"
            if iSubstim in range(1, 7):
                self._classifier_output[iSubstim - 1].append(cl_out)
            elif self.use_ErrP_detection:
                self._ErrP_classifier = cl_out
        elif data.has_key("new_letter"):
            # get new letter to spell:
            self._desired_letters += data["new_letter"]
            self._ve_current_letter.set(text=(len(self._desired_letters[:1]) == 0 and " " or self._desired_letters[:1]))
            self._ve_desired_letters.set(
                text=(len(self._desired_letters[1:]) == 0 and " " or self._desired_letters[1:])
            )

        elif data.has_key(u"print"):
            if data[u"print"] == 0:
                self.logger.info("[DESIRED_PHRASE] %s" % self.desired_phrase)
            elif data[u"print"] == 1:
                self.logger.info("[SPELLED_PHRASE] %s" % self._spelled_phrase)
            elif data[u"print"] == 2:
                self.logger.info("[SPELLED_LETTERS] %s" % self._spelled_letters)

    """
    ==========================
    == METHODS TO OVERLOAD: ==
    ==========================
    """

    def init_screen_elements(self):
        """
        overwrite this function in subclass.
        """
        pass

    def prepare_mainloop(self):
        """
        overwrite this function in subclass.
        """
        pass

    def set_countdown_screen(self):
        """
        set screen how it should look during countdown.
        overwrite this function in subclass.
        """
        pass

    def set_standard_screen(self):
        """
        set screen elements to standard state.
        overwrite this function in subclass.
        """
        pass

    def set_synchronized_countdown_screen(self):
        """
        set screen elements to for the synchronized countdown.
        overwrite this function in subclass.
        """
        pass

    def stimulus(self, i_element, on=True):
        """
        turn on/off the stimulus elements and turn off/on the normal elements.
        overwrite this function in subclass.
        """
        pass

    def feedback(self):
        """
        set screen how it should look during feedback presentation.
        overwrite this function in subclass.
        """
        pass

    def switch_level(self):
        """
        overwrite this function in subclass.
        """
        pass

    def pre_play_tick(self):
        pass

    def post_play_tick(self):
        pass

    def pre__countdown(self):
        pass

    def post__countdown(self):
        pass

    def pre__trial(self):
        pass

    def post__trial(self):
        pass

    def pre__classify(self):
        pass

    def post__classify(self):
        pass

    def pre__feedback(self):
        pass

    def post__feedback(self):
        pass

    def pre__idle(self):
        pass

    def post__idle(self):
        pass

    def post__abort(self):
        pass
def aplicacion():
  global p,inten,coord
  pos=[0.4,0.5,0.6,0.7,0.8]
  pos2=[1.3,1.4,1.5,1.6,1.7,1.8]
  rellenar()
  shuffle(coord)
  i = len(coord)-1
  target.parameters.position = coord[i][:2]
  (xpos,ypos)=target.parameters.position
  x=xpos-screen.size[0]/2
  y=ypos-screen.size[1]/2
  anrad=math.atan2(y, x)
  angrad=math.degrees(anrad)
 
  if angrad>=0:
      if angrad<=90: 
        orientacion=-45
        xx=2.0
        yy=2.0
      else:
       orientacion=-135
       xx=-2.0
       yy=2.0
  else:
      aux=angrad*(-1)
      if aux<=90:
        orientacion=45
        xx=2.0
        yy=-2.0
      else:
        orientacion=135
        xx=-2.0
        yy=-2.0
  
  fixpoint.parameters.position=((screen.size[0]/2.0)+xx, (screen.size[1]/2.0)+yy)
  fixpoint.parameters.orientation=orientacion
  
  
  viewport = Viewport(screen=screen, stimuli=[fixpoint,fixcirc])
  p = Presentation(go_duration=(1.0,'seconds'),viewports=[viewport])
  p.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN, keydown),
                                       (pygame.locals.KEYUP, keyup),
                                       (pygame.locals.QUIT, quit_app)]
  p.add_controller(None, None, FunctionController(during_go_func=settings))
  #winsound.PlaySound('instruccion',winsound.SND_FILENAME)
  p.go()
  
  while len(coord)!= 0:
    if end:
        break
    i = len(coord)-1
    target.parameters.position = coord[i][:2]
    dur=pos[random.randrange(0,4,1)]
    (xpos,ypos)=target.parameters.position
    x=xpos-screen.size[0]/2
    y=ypos-screen.size[1]/2
    anrad=math.atan2(y, x)
    angrad=math.degrees(anrad)
    #fixpoint.parameters.orientation=(-angrad) 
    if angrad>=0:
      if angrad<=90: 
        orientacion=-45
        xx=2.0
        yy=2.0
      else:
       orientacion=-135
       xx=-2.0
       yy=2.0
    else:
      aux=angrad*(-1)
      if aux<=90:
        orientacion=45
        xx=2.0
        yy=-2.0
      else:
        orientacion=135
        xx=-2.0
        yy=-2.0
  
    fixpoint.parameters.position=((screen.size[0]/2.0)+xx, (screen.size[1]/2.0)+yy)
    fixpoint.parameters.orientation=orientacion
    
  
    viewport = Viewport(screen=screen, stimuli=[fixpoint,fixcirc])
    p = Presentation(go_duration=(dur,'seconds'),viewports=[viewport])
    p.parameters.handle_event_callbacks = [ (pygame.locals.QUIT, quit_app)]
	
    
    p.add_controller(None, None, FunctionController(during_go_func=settings))
    p.go()

    inten = coord[i][-1]
    target.parameters.color = (1.0,1.0,1.0,inten)      #Se muestra el estimulo Duracion 0.3 segundos
    viewport = Viewport(screen=screen, stimuli=[target,fixpoint,fixcirc])
    p = Presentation(go_duration=(0.3,'seconds'),viewports=[viewport])
    p.parameters.handle_event_callbacks = [ (pygame.locals.QUIT, quit_app)]
                          
    p.add_controller(None, None, FunctionController(during_go_func=settings))
    p.go()
    target.parameters.color = (0.0,0.0,0.0,1.0)  #Desaparece el estimulo tiempo para registrar
    viewport = Viewport(screen=screen, stimuli=[target,fixpoint,fixcirc])
    dur2=pos[random.randrange(0,4,1)]
    p = Presentation(go_duration=(dur2,'seconds'),viewports=[viewport])
    p.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN, keydown),
                                       (pygame.locals.KEYUP, keyup),
                                       (pygame.locals.QUIT, quit_app)]
    p.add_controller(None, None, FunctionController(during_go_func=settings))
    p.go()
    coord.pop()

#####################
## RUNTIME CONTROL ##
#####################


count = 0

while (count<len(introTexts)): # DJ CHANGE 4/23/12
    # Create a Viewport instance (initialized just to display instructions)
    viewport = Viewport(screen=screen, stimuli=[introTexts[count], introTexts_bottomline[count]])

    # Create an instance of the Presentation class.  (Runtime control)
    # note that timeBetweenBlocks/2 is used here to match the time of each between-block frame.
    p = Presentation(go_duration=(timeBetweenBlocks/2,'seconds'), viewports=[viewport])

    # Register Event Handlers so we can speed things up or quit early if we need to
    p.parameters.handle_event_callbacks = \
        [(pygame.locals.QUIT, quit), (pygame.locals.KEYDOWN, keydown), (pygame.locals.KEYUP, keyup)]

    p.between_presentations()
    p.go()

    count = count+1

#####################################################################
## Here the intro text is complete, entering the image block loop   ##
#####################################################################

示例#42
0
文件: fouse.py 项目: pwighton/fouse
)

instructions_attendSCENE = Text(
    text="Attend to SCENES",
    font_size=32,
    color=(1, 1, 1),
    anchor="center",
    position=(screen.size[0] / 2, screen.size[1] / 2),
)

cur_time = Text(text="", font_size=15, color=(0.75, 0.75, 0.75), anchor="lowerleft", position=(0, 0))

viewport_instructions = Viewport(screen=screen, stimuli=[instructions, cur_time])
attend_face = Viewport(screen=screen, stimuli=[instructions_attendFACE])
attend_scene = Viewport(screen=screen, stimuli=[instructions_attendSCENE])
p1 = Presentation(go_duration=("forever",), viewports=[viewport_instructions])
p1.add_controller(None, None, FunctionController(during_go_func=displayTime))
p1.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN, waitForTrigger)]

# setup main experimental loop
loadStims = 0
wrote_response = 0

stimulus = TextureStimulus(
    anchor="center",
    size=stimuli_size,
    position=(screen.size[0] / 2.0, screen.size[1] / 2.0),
    texture_min_filter=gl.GL_LINEAR,
    shrink_texture_ok=1,
    # PW 2012/11/26
    mipmaps_enabled=False,
示例#43
0
# Set the background color to white (RGBA).
screen.parameters.bgcolor = (1.0, 1.0, 1.0, 1.0)

# Create an instance of the Target2D class with appropriate parameters.
target = Target2D(
    size=(25.0, 10.0),
    color=(0.0, 0.0, 0.0, 1.0),  # Set the target color (RGBA) black
    orientation=-45.0)

# Create a Viewport instance
viewport = Viewport(screen=screen, stimuli=[target])

# Create an instance of the Presentation class.  This contains the
# the Vision Egg's runtime control abilities.
p = Presentation(go_duration=(10.0, 'seconds'), viewports=[viewport])

#######################
#  Define controller  #
#######################

# calculate a few variables we need
mid_x = screen.size[0] / 2.0
mid_y = screen.size[1] / 2.0
max_vel = min(screen.size[0], screen.size[1]) * 0.4


# define position as a function of time
def get_target_position(t):
    global mid_x, mid_y, max_vel
    return (
示例#44
0
VisionEgg.start_default_logging()
VisionEgg.watch_exceptions()

from VisionEgg.Core import *
from VisionEgg.FlowControl import Presentation
from VisionEgg.Textures import *
import pygame.image
import OpenGL.GL as gl

filename = os.path.join(VisionEgg.config.VISIONEGG_SYSTEM_DIR, "data",
                        "visionegg.bmp")
pygame_surface = pygame.image.load(filename)
texture = Texture(pygame_surface)

screen = get_default_screen()

# Create the instance of TextureStimulus
stimulus = TextureStimulus(texture=texture,
                           position=(screen.size[0] / 2.0,
                                     screen.size[1] / 2.0),
                           anchor='center',
                           size=texture.size,
                           mipmaps_enabled=0,
                           texture_min_filter=gl.GL_LINEAR,
                           shrink_texture_ok=1)

viewport = Viewport(screen=screen, stimuli=[stimulus])

p = Presentation(go_duration=(5.0, 'seconds'), viewports=[viewport])
p.go()
示例#45
0
from VisionEgg.Core import *
from VisionEgg.FlowControl import Presentation, FunctionController
from VisionEgg.Textures import *
import math, os

max_speed = 100.0 # degrees per second

def angle_as_function_of_time(t):
    return max_speed*math.cos(t)

def contrast_as_function_of_time(t):
    return abs(math.cos(2*math.pi*t*0.2))

filename = os.path.join(config.VISIONEGG_SYSTEM_DIR,"data","panorama.jpg")
texture = Texture(filename)

screen = get_default_screen()
projection = SimplePerspectiveProjection(fov_x=90.0)
stimulus = SpinningDrum(texture=texture,shrink_texture_ok=1)
viewport = Viewport(screen=screen,
                    size=screen.size,
                    projection=projection,
                    stimuli=[stimulus])
p = Presentation(go_duration=(10.0,'seconds'),viewports=[viewport])
p.add_controller(stimulus,'angular_position', FunctionController(during_go_func=angle_as_function_of_time))
p.add_controller(stimulus,'contrast', FunctionController(during_go_func=contrast_as_function_of_time))
p.go()


示例#46
0
def keyup(event):
    global up, down, left, right
    if event.key == pygame.locals.K_UP:
        up = 0
    elif event.key == pygame.locals.K_DOWN:
        down = 0
    elif event.key == pygame.locals.K_RIGHT:
        right = 0
    elif event.key == pygame.locals.K_LEFT:
        left = 0


# Create an instance of the Presentation class.  This contains the
# the Vision Egg's runtime control abilities.
p = Presentation(go_duration=('forever', ), viewports=[viewport])


def quit(event):
    p.parameters.go_duration = (0, 'frames')


p.parameters.handle_event_callbacks = [(pygame.locals.QUIT, quit),
                                       (pygame.locals.KEYDOWN, keydown),
                                       (pygame.locals.KEYUP, keyup)]

#############################################################
#  Connect the controllers with the variables they control  #
#############################################################

p.add_controller(None, None,
示例#47
0
        "Error: Use MPEG file as command line argument - Press Esc to quit",
        position=(screen.size[0] / 2, screen.size[1]),
        anchor='top',
        font_size=24,
        color=(1.0, 0.0, 0.0))
    text2 = Text(
        text="(If you have a free MPEG to contribute, it could go here.)",
        position=(screen.size[0] / 2, screen.size[1] / 2),
        anchor='center',
        font_size=20,
        color=(1.0, 1.0, 1.0))
    viewport = Viewport(screen=screen, stimuli=[text, text2])

    p = Presentation(
        go_duration=('forever', ),
        viewports=[viewport],
        handle_event_callbacks=[(pygame.locals.QUIT, quit),
                                (pygame.locals.KEYDOWN, keydown)],
    )
    p.go()
    sys.exit(1)

movie = pygame.movie.Movie(filename)

width, height = movie.get_size()
scale_x = screen.size[0] / float(width)
scale_y = screen.size[1] / float(height)
scale = min(scale_x, scale_y)  # maintain aspect ratio

# create pygame surface (buffer to draw uncompressed movie data into)
pygame_surface = pygame.surface.Surface((width, height))
示例#48
0
from VisionEgg.Gratings import *
import VisionEgg.Daq
from VisionEgg.DaqLPT import *

# Normal stuff (from grating demo):
screen = get_default_screen()
stimulus = SinGrating2D(on               = 1, # turn grating is off when not in go loop
                        position         = ( screen.size[0]/2.0, screen.size[1]/2.0 ),
                        anchor           = 'center',
                        size             = ( 300.0 , 300.0 ),
                        spatial_freq     = 10.0 / screen.size[0],
                        temporal_freq_hz = 5.0,
                        orientation      = 45.0 )
viewport = Viewport( screen=screen, stimuli=[stimulus] )
p = Presentation(go_duration=(5.0,'seconds'),
                 trigger_go_if_armed=0, # wait for trigger
                 viewports=[viewport])

# Stimulus on controller
stimulus_on_controller = ConstantController(during_go_value=0,between_go_value=1)

# Create a trigger input controller
trigger_in_controller = LPTTriggerInController()

# Add the trigger output controller to the presentation's list of controllers
p.add_controller(stimulus,'on',stimulus_on_controller)
p.add_controller(p,'trigger_go_if_armed',trigger_in_controller)

# Go!
p.go()
示例#49
0
                       pygame.locals.K_EQUALS]:
        gamma_scale += 0.05
        do_gamma()
    elif event.key in [pygame.locals.K_KP_MINUS,
                       pygame.locals.K_MINUS]:
        gamma_scale -= 0.05
        do_gamma()
        
def do_gamma():
    global gamma_scale, text2
    r = (np.arange(256)*256*gamma_scale).astype('i')
    g = r
    b = r
    worked = pygame.display.set_gamma_ramp(r,g,b)
    if worked:
        text2.parameters.text = "set_gamma_ramp(r,g,b): success"
    else:
        text2.parameters.text = "set_gamma_ramp(r,g,b): failure"

do_gamma() # set gamma once initially

handle_event_callbacks = [(pygame.locals.QUIT, quit),
                          (pygame.locals.KEYDOWN, keydown)]

# Create an instance of the Presentation class
p = Presentation(viewports=[viewport],
                 handle_event_callbacks=handle_event_callbacks)

# Go!
p.run_forever()
示例#50
0

# default strategy
strategy = None

trial = 1

# STIMULI

# Fixation Cross
fixText, fixCross = printWord(screen, "*", 120, (255, 255, 255))
errorText, errorPort = printWord(screen, "X", 120, (1.0, 0.1, 0.1))

print "PRESS SPACE TO START"

pause = Presentation(go_duration=("forever",), viewports=[fixCross])
pause.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN, pause_handler)]
pause.go()

problemQ = []

while len(mag_problems):

    if problemQ:
        stim = problemQ[2]
        n1 = problemQ[0]
        n2 = problemQ[1]
    else:
        p = mag_problems.pop(0)
        n1 = p[0]
        n2 = p[1]
示例#51
0
    def __init_screen(self):
        ## create screen:
        if not self.fullscreen:
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d, %d' % (self.geometry[0],
                                                             self.geometry[1])
        self._screen = Screen(size=(self.geometry[2], self.geometry[3]),
                              fullscreen=self.fullscreen,
                              bgcolor=self.bg_color,
                              sync_swap=True)

        ## create letter box on top:
        self._ve_letterbox = Target2D(position=(self._centerPos[0],
                                                self.geometry[3] * (1 - 0.01) -
                                                self.letterbox_size[1] / 2.),
                                      size=(self.letterbox_size[0],
                                            self.letterbox_size[1]),
                                      color=self.phrase_color)
        self._ve_innerbox = Target2D(position=(self._centerPos[0],
                                               self.geometry[3] * (1 - 0.01) -
                                               self.letterbox_size[1] / 2.),
                                     size=(self.letterbox_size[0] - 6,
                                           self.letterbox_size[1] - 6),
                                     color=self.bg_color)

        self._current_letter_position = (self._centerPos[0],
                                         self.geometry[3] * (1 - 0.015) -
                                         self.letterbox_size[1] / 2.)
        self._ve_current_letter = Text(
            position=self._current_letter_position,
            text=(len(self._desired_letters[:1]) == 0 and " "
                  or self._desired_letters[:1]),
            font_size=self.font_size_current_letter,
            color=self.current_letter_color,
            anchor='center')

        self._ve_desired_letters = Text(
            position=(self._centerPos[0] + 5 + self.letterbox_size[0] / 2.,
                      self._current_letter_position[1]),
            text=(len(self._desired_letters[1:]) == 0 and " "
                  or self._desired_letters[1:]),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor='left')

        self._ve_spelled_phrase = Text(
            position=(self._centerPos[0] - 5 - self.letterbox_size[0] / 2.,
                      self._current_letter_position[1]),
            text=(len(self._spelled_phrase) == 0 and " "
                  or self._spelled_phrase),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor='right')

        # if we're in free spelling mode, we hide all text fields but
        # the _ve_spelled_phrase. we also need a multiline
        # _ve_spelled_phrase instead of the single lined one
        if self.offline == self.copy_spelling == False:
            self._spelled_phrase = "   "
            self._ve_spelled_phrase = WrappedText(
                position=(0, self._current_letter_position[1]),
                text=(len(self._spelled_phrase) == 0 and " "
                      or self._spelled_phrase),
                font_size=self.font_size_phrase,
                color=self.phrase_color,
                size=(float(self.geometry[2]), float(self.geometry[3])))
            for i in self._ve_letterbox, self._ve_innerbox, self._ve_current_letter, self._ve_desired_letters:
                i.set(on=False)

        ## add word box to elementlist:
        self._ve_elements.extend([
            self._ve_letterbox, self._ve_innerbox, self._ve_current_letter,
            self._ve_desired_letters, self._ve_spelled_phrase
        ])

        ## create countdown:
        self._ve_countdown = Text(position=self._centerPos,
                                  text=" ",
                                  font_size=self.font_size_countdown,
                                  color=self.countdown_color,
                                  anchor='center',
                                  on=False)

        ## create countdown shapes
        self._ve_countdown_shape = self.countdown_shapes[
            self.countdown_shape_select](radius=90,
                                         position=self._centerPos,
                                         color=self.countdown_shape_color,
                                         on=False)

        ## create oscillator circle:
        self._ve_oscillator = FilledCircle(position=(self.osc_size / 2 + 10,
                                                     self.osc_size / 2 + 10),
                                           radius=self.osc_size / 2,
                                           color=self.osc_color,
                                           on=False)

        ## create shapes and letters:
        self.init_screen_elements()

        ## add remaining elements to element list:
        self._ve_elements.extend([
            self._ve_countdown_shape, self._ve_countdown, self._ve_oscillator
        ])

        ## add elements to viewport:
        self._viewport = Viewport(screen=self._screen,
                                  stimuli=self._ve_elements)
        self._presentation = Presentation(viewports=[self._viewport],
                                          handle_event_callbacks=[
                                              (pygame.KEYDOWN,
                                               self.keyboard_input),
                                              (pygame.QUIT, self.__stop)
                                          ])
示例#52
0
    def __init_screen(self):
        ## create screen:
        if not self.fullscreen:
            os.environ["SDL_VIDEO_WINDOW_POS"] = "%d, %d" % (self.geometry[0], self.geometry[1])
        self._screen = Screen(
            size=(self.geometry[2], self.geometry[3]), fullscreen=self.fullscreen, bgcolor=self.bg_color, sync_swap=True
        )

        ## create letter box on top:
        self._ve_letterbox = Target2D(
            position=(self._centerPos[0], self.geometry[3] * (1 - 0.01) - self.letterbox_size[1] / 2.0),
            size=(self.letterbox_size[0], self.letterbox_size[1]),
            color=self.phrase_color,
        )
        self._ve_innerbox = Target2D(
            position=(self._centerPos[0], self.geometry[3] * (1 - 0.01) - self.letterbox_size[1] / 2.0),
            size=(self.letterbox_size[0] - 6, self.letterbox_size[1] - 6),
            color=self.bg_color,
        )

        self._current_letter_position = (
            self._centerPos[0],
            self.geometry[3] * (1 - 0.015) - self.letterbox_size[1] / 2.0,
        )
        self._ve_current_letter = Text(
            position=self._current_letter_position,
            text=(len(self._desired_letters[:1]) == 0 and " " or self._desired_letters[:1]),
            font_size=self.font_size_current_letter,
            color=self.current_letter_color,
            anchor="center",
        )

        self._ve_desired_letters = Text(
            position=(self._centerPos[0] + 5 + self.letterbox_size[0] / 2.0, self._current_letter_position[1]),
            text=(len(self._desired_letters[1:]) == 0 and " " or self._desired_letters[1:]),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor="left",
        )

        self._ve_spelled_phrase = Text(
            position=(self._centerPos[0] - 5 - self.letterbox_size[0] / 2.0, self._current_letter_position[1]),
            text=(len(self._spelled_phrase) == 0 and " " or self._spelled_phrase),
            font_size=self.font_size_phrase,
            color=self.phrase_color,
            anchor="right",
        )

        # if we're in free spelling mode, we hide all text fields but
        # the _ve_spelled_phrase. we also need a multiline
        # _ve_spelled_phrase instead of the single lined one
        if self.offline == self.copy_spelling == False:
            self._spelled_phrase = "   "
            self._ve_spelled_phrase = WrappedText(
                position=(0, self._current_letter_position[1]),
                text=(len(self._spelled_phrase) == 0 and " " or self._spelled_phrase),
                font_size=self.font_size_phrase,
                color=self.phrase_color,
                size=(float(self.geometry[2]), float(self.geometry[3])),
            )
            for i in self._ve_letterbox, self._ve_innerbox, self._ve_current_letter, self._ve_desired_letters:
                i.set(on=False)

        ## add word box to elementlist:
        self._ve_elements.extend(
            [
                self._ve_letterbox,
                self._ve_innerbox,
                self._ve_current_letter,
                self._ve_desired_letters,
                self._ve_spelled_phrase,
            ]
        )

        ## create countdown:
        self._ve_countdown = Text(
            position=self._centerPos,
            text=" ",
            font_size=self.font_size_countdown,
            color=self.countdown_color,
            anchor="center",
            on=False,
        )

        ## create countdown shapes
        self._ve_countdown_shape = self.countdown_shapes[self.countdown_shape_select](
            radius=90, position=self._centerPos, color=self.countdown_shape_color, on=False
        )

        ## create oscillator circle:
        self._ve_oscillator = FilledCircle(
            position=(self.osc_size / 2 + 10, self.osc_size / 2 + 10),
            radius=self.osc_size / 2,
            color=self.osc_color,
            on=False,
        )

        ## create shapes and letters:
        self.init_screen_elements()

        ## add remaining elements to element list:
        self._ve_elements.extend([self._ve_countdown_shape, self._ve_countdown, self._ve_oscillator])

        ## add elements to viewport:
        self._viewport = Viewport(screen=self._screen, stimuli=self._ve_elements)
        self._presentation = Presentation(
            viewports=[self._viewport],
            handle_event_callbacks=[(pygame.KEYDOWN, self.keyboard_input), (pygame.QUIT, self.__stop)],
        )
示例#53
0
    initial_controller=ConstantController(during_go_value=(10,'seconds'))
    )
go_controller = tcp_listener.create_tcp_controller(
    tcp_name="go",
    initial_controller=ConstantController(during_go_value=0)
    )

# Create the instance SinGrating with appropriate parameters
stimulus = SinGrating2D(anchor='center')

# Create a viewport (with default pixel coordinate system)
# with stimulus
viewport = Viewport( screen=screen, stimuli=[stimulus] )

# Create an instance of the Presentation class
p = Presentation(viewports=[viewport],check_events=1)

# Register the controller functions, connecting them with the parameters they control
p.add_controller(None,None, tcp_listener) # Actually listens to the TCP socket
p.add_controller(stimulus,'on', on_controller)
p.add_controller(stimulus,'contrast', contrast_controller)
p.add_controller(stimulus,'position', center_controller)
p.add_controller(stimulus,'size', size_controller)
p.add_controller(stimulus,'spatial_freq', spatial_freq_controller)
p.add_controller(stimulus,'temporal_freq_hz', temporal_freq_controller)
p.add_controller(stimulus,'phase_at_t0', phase_controller)
p.add_controller(stimulus,'orientation', orientation_controller)
p.add_controller(stimulus,'num_samples', num_samples_controller)
p.add_controller(stimulus,'bit_depth', bit_depth_controller)
p.add_controller(p,'go_duration', go_duration_controller)
p.add_controller(p,'enter_go_loop', go_controller)
示例#54
0

#default strategy
strategy = None

trial = 1

#STIMULI

#Fixation Cross
fixText, fixCross = printWord(screen, '*', 120, (255, 255, 255))
errorText, errorPort = printWord(screen, 'X', 120, (1., .1, .1))

print "PRESS SPACE TO START"

pause = Presentation(go_duration=('forever', ), viewports=[fixCross])
pause.parameters.handle_event_callbacks = [(pygame.locals.KEYDOWN,
                                            pause_handler)]
pause.go()

problemQ = []

while len(mag_problems):

    if problemQ:
        stim = problemQ[2]
        n1 = problemQ[0]
        n2 = problemQ[1]
    else:
        p = mag_problems.pop(0)
        n1 = p[0]
示例#55
0
 def __init_presentation(self):
     """ Provide a standard presentation object. """
     self.presentation = Presentation(
         handle_event_callbacks=self._event_handlers)
示例#56
0
#####################################
#  Initialize OpenGL window/screen  #
#####################################

screen = get_default_screen()

######################################
#  Create sinusoidal grating object  #
######################################

stimulus = SinGrating2D(position         = ( screen.size[0]/2.0, screen.size[1]/2.0 ),
                        anchor           = 'center',
                        size             = ( 300.0 , 300.0 ),
                        spatial_freq     = 10.0 / screen.size[0], # units of cycles/pixel
                        temporal_freq_hz = 1.0,
                        orientation      = 45.0 )

###############################################################
#  Create viewport - intermediary between stimuli and screen  #
###############################################################

viewport = Viewport( screen=screen, stimuli=[stimulus] )

########################################
#  Create presentation object and go!  #
########################################

p = Presentation(go_duration=(5.0,'seconds'),viewports=[viewport])
p.go()
示例#57
0
class VisionEggView(object):
    """ This class handles VisionEgg internals and the creation of
    common/standard stimuli like centered words, a fixation cross or
    a countdown. Inherit this and pass the type to VisionEggFeedback
    for customization.
    """
    def __init__(self):
        self.__init_attributes()

    def __init_attributes(self):
        """ Setup internal attributes. """
        self._logger = logging.getLogger('VisionEggView')
        self._logger.addHandler(logging.FileHandler('log'))
        self._screen_acquired = False
        self._viewports = []

    def set_trigger_function(self, trigger):
        self._trigger = trigger

    def set_event_handlers(self, event_handlers):
        """ Set pygame/VisionEgg event handler function. """
        self._event_handlers = event_handlers

    def set_iterator_semaphore(self, flag):
        """ Specify the object to be used as semaphore for iterators.
        See L{Switcherator} for more.
        """
        self._iter = lambda it: Switcherator(flag, it)

    def update_parameters(self, **kwargs):
        """ Apply new parameters set from pyff. """
        for k, v in kwargs.iteritems():
            setattr(self, '_' + k, v)
        if self._screen_acquired:
            self.reinit()

    def acquire(self):
        """ Allow L{update_parameters} initialize VisionEgg. """
        self._screen_acquired = True

    def reinit(self):
        """ Initialize VisionEgg objects. """
        self.__init_screen()
        self.__init_presentation()
        self.__init_viewports()
        self.init()
        self.__init_text()

    def init(self):
        """ Overload this for additional custom VisionEgg
        initialization.
        """
        pass

    def __init_screen(self):
        """ Create the VisionEgg Screen object using the pyff
        configuration parameters 'fullscreen' and 'geometry' and the
        font and background colors according to parameters
        'font_color_name' and 'bg_color'.
        """
        params = {'fullscreen': self._fullscreen, 'sync_swap': True}
        if not self._fullscreen:
            os.environ['SDL_VIDEO_WINDOW_POS'] = '%d, %d' % (self._geometry[0],
                                                             self._geometry[1])
            params['size'] = self._geometry[2:]
        self.screen = Screen(**params)
        self._set_bg_color()
        self._set_font_color()

    def __init_presentation(self):
        """ Provide a standard presentation object. """
        self.presentation = Presentation(
            handle_event_callbacks=self._event_handlers)

    def __init_viewports(self):
        """ Provide a standard viewport. """
        self._standard_viewport = Viewport(screen=self.screen)
        self.add_viewport(self._standard_viewport)

    def __init_text(self):
        """ Provide a text in the screen center for standard stimuli and
        fixation cross etc.
        """
        sz = self.screen.size
        self._center_text = self.add_color_word(position=(sz[0] / 2.,
                                                          sz[1] / 2.),
                                                font_size=self._font_size)

    def add_viewport(self, viewport):
        """ Add an additional custom viewport object to the list of
        viewports.
        """
        self._viewports.append(viewport)
        self.presentation.set(viewports=self._viewports)

    def clear_stimuli(self):
        """ Remove all existing stimuli in the standard viewport. """
        self.set_stimuli()

    def add_stimuli(self, *stimuli):
        """ Add additional custom stimulus objects to the list of
        stimuli. TextList instances need their own Viewport, as they
        consist of multiple stimulus objects that are deleted everytime
        they change, and so the Viewport needs to have a reference to
        the containing TextList, otherwise they get lost.
        """
        text_lists = filter(lambda s: isinstance(s, TextList), stimuli)
        if text_lists:
            for text in text_lists:
                self.add_viewport(Viewport(screen=self.screen, stimuli=text))
            stimuli = filter(lambda s: not isinstance(s, TextList), stimuli)
        stimuli = self._standard_viewport.parameters.stimuli + list(stimuli)
        if stimuli:
            self.set_stimuli(*stimuli)

    def set_stimuli(self, *stimuli):
        """ Set the list of stimulus objects.  """
        self._standard_viewport.set(stimuli=list(stimuli))

    def add_text_stimulus(self, text, font_size=None, **kw):
        if not kw.has_key('anchor'):
            kw['anchor'] = 'center'
        font_size = font_size or self._font_size
        txt = VisionEgg.Text.Text(text=text, font_size=font_size, **kw)
        self.add_stimuli(txt)
        return txt

    def add_color_word(self, text='', font_size=None, **kw):
        font_size = font_size or self._font_size
        txt = ColorWord(text=text, symbol_size=font_size, **kw)
        self.add_stimuli(txt)
        return txt

    def add_image_stimulus(self, **kw):
        if not kw.has_key('anchor'):
            kw['anchor'] = 'center'
        img = TextureStimulus(**kw)
        self.add_stimuli(img)
        return img

    def _create_color(self, name):
        try:
            if isinstance(name, tuple):
                return Color(*name).normalize()
            else:
                return Color(str(name)).normalize()
        except ValueError:
            self._logger.warn('No such pygame.Color: %s' % str(name))

    def _set_font_color(self):
        """ Set the standard font color by pygame name. """
        self._font_color = (self._create_color(self._font_color_name)
                            or Color(1, 1, 1, 255).normalize())

    def _set_bg_color(self):
        """ Set the standard background color by pygame name. """
        c = (self._create_color(self._bg_color)
             or Color(0, 0, 0, 255).normalize())
        self.screen.set(bgcolor=c)

    def present_frames(self, num_frames):
        """ Launch the presentation main loop for a given number of
        frames.
        """
        self.presentation.set(go_duration=(num_frames, 'frames'))
        self.presentation.go()

    def present(self, sec):
        self.presentation.set(go_duration=(sec, 'seconds'))
        self.presentation.go()

    def update(self):
        """ Repaint the canvas for one frame to update changed stimuli.
        """
        self.present_frames(1)

    def center_word(self, text, color=None):
        """ Set the standard word in the screen center. """
        self._center_text.set(text=text)
        self._center_text.set(colors=color or (self._font_color
                                               for l in self._center_text))

    def clear_center_word(self):
        """ Remove the center word from the screen. """
        self.center_word('')
        self.update()

    def present_center_word(self, text, seconds, color=None):
        self.center_word(text, color)
        self.present(seconds)
        self.clear_center_word()

    def ask(self, question=True):
        """ Loop indefinitely until answered() is called. If question is
        True, a question mark is shown in the center.
        """
        if question:
            self.center_word('?')
        self.presentation.run_forever()
        self.presentation.set(quit=False)
        self.clear_center_word()

    def answered(self):
        """ Abort the current presentation (usually the question mark)
        after subject input. For thread safety, the screen shouldn't be
        changed here.
        """
        self.presentation.set(quit=True)

    def show_fixation_cross(self):
        """ Display the pyff parameter 'fixation_cross_symbol' for the
        period of time given by pyff parameter 'fixation_cross_time'.
        """
        self.center_word(self._fixation_cross_symbol)
        self._trigger(marker.FIXATION_START, wait=True)
        self.present(self._fixation_cross_time)
        self._trigger(marker.FIXATION_END, wait=True)

    def countdown(self):
        """ Display a countdown according to pyff parameters
        'countdown_start' and 'countdown_symbol_duration'.
        """
        self._trigger(marker.COUNTDOWN_START, wait=True)
        for i in self._iter(reversed(xrange(self._countdown_start + 1))):
            self.center_word(str(i))
            self.present(self._countdown_symbol_duration)
        self._trigger(marker.COUNTDOWN_END, wait=True)
        self.clear_center_word()

    def close(self):
        """ Shut down the screen. """
        self._screen_acquired = False
        self.screen.close()

    def quit(self):
        """ Stop the presentation. """
        self.presentation.set(quit=True)
        self.presentation.set(go_duration=(1, 'frames'))