def Initialize(self, indim, outdim):
				
		# compute how big everything should be
		itf = float(self.params['InnerTriangleSize'])
		otf = float(self.params['OuterTriangleSize'])
		scrw,scrh = self.screen.size
		scrsiz = min(scrw,scrh)
		circle_radius = scrsiz * 0.5 * float(self.params['CircleRadius'])
		siz = (scrsiz * otf * 0.866,   scrsiz * otf * 0.75)
		
		# use a handy AppTools.Boxes.box object as the coordinate frame for the triangle
		b = box(size=siz, position=(scrw/2.0,scrh/2.0 - siz[1]/6.0), sticky=True)
		center = b.map((0.5,2.0/3.0), 'position')
		self.positions = {'origin': numpy.matrix(center)}
		
		# draw the main triangle
		triangle = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(0,0,0,0.5))
		
		# the red target triangle
		b.anchor='bottom'
		b.scale(itf)
		self.positions['red'] = numpy.matrix(b.position)
		red = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(1,0.1,0.1))
		b.scale(1.0 / itf)

		# the green target triangle
		b.anchor='upperleft'
		b.scale(itf)
		self.positions['green'] = numpy.matrix(b.position)
		green = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(0.1,1,0.1))
		b.scale(1.0 / itf);

		# the blue target triangle
		b.anchor='upperright'
		b.scale(itf)
		self.positions['blue'] = numpy.matrix(b.position)
		blue = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(0.1,0.1,1))
		b.scale(1.0 / itf);

		# and the arrow
		b.anchor='center'
		fac = (0.25,0.4)
		b.scale(fac)
		arrow = PolygonTexture(frame=b, vertices=((0.22,0.35),(0,0.35),(0.5,0),(1,0.35),(0.78,0.35),(0.78,0.75),(0.22,0.75),), color=(1,1,1), on=False, position=center)
		b.scale((1.0/fac[0],1.0/fac[1]))
				
		# store the significant points on the screen for later use
		self.p = numpy.concatenate((self.positions['red'],self.positions['green'],self.positions['blue']), axis=0)

		# let's have a black background
		self.screen.color = (0,0,0)
		
		# OK, now register all those stimuli, plus a few more, with the framework
		self.stimulus('circle',   z=-1,  stim=Disc(position=center, radius=circle_radius, color=(0,0,0)))
		self.stimulus('triangle', z=1,   stim=triangle)
		self.stimulus('red',      z=2,   stim=red)
		self.stimulus('green',    z=2,   stim=green)
		self.stimulus('blue',     z=2,   stim=blue)
		self.stimulus('cursor1',  z=3,   stim=Disc(position=center, radius=10, color=(1,1,1), on=False))
		self.stimulus('cursor2',  z=4,   stim=Disc(position=center, radius=8,  color=(0,0,0), on=False))
		self.stimulus('arrow',    z=4.5, stim=arrow)
		self.stimulus('cue',      z=5,   stim=VisualStimuli.Text(text='?', position=center, anchor='center', color=(1,1,1), font_size=50, on=False))
		self.stimulus('fixation', z=4.2, stim=Disc(position=center, radius=5, color=(1,1,1), on=False))
		
		# set up the strings that are going to be presented in the 'cue' stimulus
		self.cuetext = ['relax', 'feet', 'left', 'right']
		
		# load, and silently start, the continuous feedback sounds
		self.sounds = []
		if int(self.params['AudioFeedback']):
			wavmat = self.params['FeedbackWavs']
			for i in range(len(wavmat)):
				wavlist = wavmat[i]
				if len(wavlist) != 1: raise EndUserError, 'FeedbackWavs matrix should have 1 column'
				try: snd = WavTools.player(wavlist[0])
				except IOError: raise EndUserError, 'failed to load "%s"'%wavlist[0]
				self.sounds.append(snd)
				snd.vol = 0
				snd.play(-1)

		# finally, some fancy stuff from AppTools.StateMonitors, for the developer to check
		# that everything's working OK
		if int(self.params['ShowSignalTime']):
			# turn on state monitors iff the packet clock is also turned on
			addstatemonitor(self, 'Running', showtime=True)
			addstatemonitor(self, 'CurrentBlock')
			addstatemonitor(self, 'CurrentTrial')
			addstatemonitor(self, 'TargetClass')
			addstatemonitor(self, 'Learn')
			
			addphasemonitor(self, 'phase', showtime=True)

			m = addstatemonitor(self, 'fs_reg')
			m.func = lambda x: '% 6.1fHz' % x._regfs.get('SamplesPerSecond', 0)
			m.pargs = (self,)
			m = addstatemonitor(self, 'fs_avg')
			m.func = lambda x: '% 6.1fHz' % x.estimated.get('SamplesPerSecond',{}).get('global', 0)
			m.pargs = (self,)
			m = addstatemonitor(self, 'fs_run')
			m.func = lambda x: '% 6.1fHz' % x.estimated.get('SamplesPerSecond',{}).get('running', 0)
			m.pargs = (self,)
			m = addstatemonitor(self, 'fr_run')
			m.func = lambda x: '% 6.1fHz' % x.estimated.get('FramesPerSecond',{}).get('running', 0)
			m.pargs = (self,)
					
		self.distance = lambda a,b: numpy.sqrt((numpy.asarray(a-b)**2).sum(axis=-1))
		self.distance_scaling = (2.0 ** self.bits['DistanceFromCenter'] - 1.0) / self.distance(self.positions['green'], self.positions['red'])
	def Initialize(self, indim, outdim):
				
		# compute how big everything should be
		itf = float(self.params['InnerTriangleSize'])
		otf = float(self.params['OuterTriangleSize'])
		scrw,scrh = self.screen.size
		scrsiz = min(scrw,scrh)
		circle_radius = scrsiz * 0.5 * float(self.params['CircleRadius'])
		siz = (scrsiz * otf * 0.866,   scrsiz * otf * 0.75)
		
		# use a handy AppTools.Boxes.box object as the coordinate frame for the triangle
		b = box(size=siz, position=(scrw/2.0,scrh/2.0 - siz[1]/6.0), sticky=True)
		center = b.map((0.5,2.0/3.0), 'position')
		self.positions = {'origin': numpy.matrix(center)}
		
		# draw the main triangle
		triangle = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(0,0,0,0.5))
		
		# the red target triangle
		b.anchor='bottom'
		b.scale(itf)
		self.positions['red'] = numpy.matrix(b.position)
		red = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(1,0.1,0.1))
		b.scale(1.0 / itf)

		# the green target triangle
		b.anchor='upperleft'
		b.scale(itf)
		self.positions['green'] = numpy.matrix(b.position)
		green = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(0.1,1,0.1))
		b.scale(1.0 / itf);

		# the blue target triangle
		b.anchor='upperright'
		b.scale(itf)
		self.positions['blue'] = numpy.matrix(b.position)
		blue = PolygonTexture(frame=b, vertices=((0,1),(1,1),(0.5,0)), color=(0.1,0.1,1))
		b.scale(1.0 / itf);

		# and the arrow
		b.anchor='center'
		fac = (0.25,0.4)
		b.scale(fac)
		arrow = PolygonTexture(frame=b, vertices=((0.22,0.35),(0,0.35),(0.5,0),(1,0.35),(0.78,0.35),(0.78,0.75),(0.22,0.75),), color=(1,1,1), on=False, position=center)
		b.scale((1.0/fac[0],1.0/fac[1]))
				
		# store the significant points on the screen for later use
		self.p = numpy.concatenate((self.positions['red'],self.positions['green'],self.positions['blue']), axis=0)

		# let's have a black background
		self.screen.color = (0,0,0)
		
		# OK, now register all those stimuli, plus a few more, with the framework
		self.stimulus('circle',   z=-1,  stim=Disc(position=center, radius=circle_radius, color=(0,0,0)))
		self.stimulus('triangle', z=1,   stim=triangle)
		self.stimulus('red',      z=2,   stim=red)
		self.stimulus('green',    z=2,   stim=green)
		self.stimulus('blue',     z=2,   stim=blue)
		self.stimulus('cursor1',  z=3,   stim=Disc(position=center, radius=10, color=(1,1,1), on=False))
		self.stimulus('cursor2',  z=4,   stim=Disc(position=center, radius=8,  color=(0,0,0), on=False))
		self.stimulus('arrow',    z=4.5, stim=arrow)
		self.stimulus('cue',      z=5,   stim=VisualStimuli.Text(text='?', position=center, anchor='center', color=(1,1,1), font_size=50, on=False))
		self.stimulus('fixation', z=4.2, stim=Disc(position=center, radius=5, color=(1,1,1), on=False))
		
		# set up the strings that are going to be presented in the 'cue' stimulus
		self.cuetext = ['relax', 'feet', 'left', 'right']
		
		# load, and silently start, the continuous feedback sounds
		self.sounds = []
		if int(self.params['AudioFeedback']):
			wavmat = self.params['FeedbackWavs']
			for i in range(len(wavmat)):
				wavlist = wavmat[i]
				if len(wavlist) != 1: raise EndUserError, 'FeedbackWavs matrix should have 1 column'
				try: snd = WavTools.player(wavlist[0])
				except IOError: raise EndUserError, 'failed to load "%s"'%wavlist[0]
				self.sounds.append(snd)
				snd.vol = 0
				snd.play(-1)

		# finally, some fancy stuff from AppTools.StateMonitors, for the developer to check
		# that everything's working OK
		if int(self.params['ShowSignalTime']):
			# turn on state monitors iff the packet clock is also turned on
			addstatemonitor(self, 'Running', showtime=True)
			addstatemonitor(self, 'CurrentBlock')
			addstatemonitor(self, 'CurrentTrial')
			addstatemonitor(self, 'TargetClass')
			addstatemonitor(self, 'Learn')
			
			addphasemonitor(self, 'phase', showtime=True)

			m = addstatemonitor(self, 'fs_reg')
			m.func = lambda x: '% 6.1fHz' % x._regfs.get('SamplesPerSecond', 0)
			m.pargs = (self,)
			m = addstatemonitor(self, 'fs_avg')
			m.func = lambda x: '% 6.1fHz' % x.estimated.get('SamplesPerSecond',{}).get('global', 0)
			m.pargs = (self,)
			m = addstatemonitor(self, 'fs_run')
			m.func = lambda x: '% 6.1fHz' % x.estimated.get('SamplesPerSecond',{}).get('running', 0)
			m.pargs = (self,)
			m = addstatemonitor(self, 'fr_run')
			m.func = lambda x: '% 6.1fHz' % x.estimated.get('FramesPerSecond',{}).get('running', 0)
			m.pargs = (self,)
					
		self.distance = lambda a,b: numpy.sqrt((numpy.asarray(a-b)**2).sum(axis=-1))
		self.distance_scaling = (2.0 ** self.bits['DistanceFromCenter'] - 1.0) / self.distance(self.positions['green'], self.positions['red'])
    def initialize(cls, app, indim, outdim):
        if int(app.params['ContFeedbackEnable'])==1:
            if int(app.params['ShowSignalTime']):
                app.addstatemonitor('FBValue')
                app.addstatemonitor('FBBlock')
                app.addstatemonitor('Feedback')
                app.addstatemonitor('InRange')

            #===================================================================
            # Load fake data if we will be using fake feedback.
            #===================================================================
            if int(app.params['FakeFeedback']):
                import csv
                fp=app.params['FakeFile']
                app.fake_data = np.genfromtxt(fp, delimiter=',')
                np.random.shuffle(app.fake_data)

            #===================================================================
            # We need to know how many blocks per feedback period
            # so (non-bar) feedback can be scaled appropriately.
            #===================================================================
            fbdur = app.params['TaskDur'].val #feedback duration
            fbblks = fbdur * app.eegfs / app.spb #feedback blocks

            #===================================================================
            # Visual Feedback
            #===================================================================
            if app.params['VisualFeedback'].val:
                #===================================================================
                # Set a coordinate frame for the screen.
                #===================================================================
                scrsiz = min(app.scrw,app.scrh)
                siz = (scrsiz, scrsiz)
                b = box(size=siz, position=(app.scrw/2.0,app.scrh/2.0), sticky=True)
                #b is now our perfect box taking up as much of our screen as we are going to use.
                #its center is the center pixel, its width and height are equal to the smallest of screen width and height
                center = b.map((0.5,0.5), 'position') #what is the center pixel value? e.g.([400.0, 225.0])

                #===================================================================
                # TODO: Get the arrows working for more than 2 targets
                #===================================================================
                #===============================================================
                # b.scale(x=0.25,y=0.4)#How big should the arrow be, relative to the screen size
                # arrow = PolygonTexture(frame=b, vertices=((0.22,0.35),(0,0.35),(0.5,0),(1,0.35),(0.78,0.35),(0.78,0.75),(0.22,0.75),),\
                #                    color=(1,1,1), on=False, position=center)
                # app.stimulus('arrow', z=4.5, stim=arrow)#Register the arrow stimulus.
                #
                # b.scale(x=4.0, y=2.5)#Reset the box
                # b.anchor='center'#Reset the box
                #===============================================================

                #===============================================================
                # Target rectangles.
                #===============================================================
                targtw = 0.5
                for x in range(app.nclasses):
                    my_target = app.target_range[x]
                    targ_h = int((my_target[1] - my_target[0]) * scrsiz / 200.0)
                    targ_y = int(center[1] + (my_target[0] + my_target[1]) * scrsiz / 400.0)
                    targ_stim = Block(position = [center[0], targ_y], size = [targtw * scrsiz, targ_h], color=(1, 0.1, 0.1, 0.5), on=False)
                    app.stimulus('target_'+str(x), z=2, stim=targ_stim)

                #Our feedback will range from -10 to +10
                app.m=app.scrh/20.0#Conversion factor from signal amplitude to pixels.
                app.b_offset=app.scrh/2.0 #Input 0.0 should be at this pixel value.

                #===============================================================
                # Add feedback elements
                #===============================================================
                app.vfb_keys = []
                for j in range(app.nclasses):
                    if app.vfb_type[j]==0: #Bar
                        app.addbar(color=(0,0.9,0), pos=(app.scrw/2.0,app.b_offset), thickness=app.scrw/10, fac=app.m)
                        app.vfb_keys.append('barrect_' + str(len(app.bars)))
                        app.stimuli['bartext_'+ str(len(app.bars))].position=(50,50)#off in the lower corner
                        #app.stimuli['bartext_'+ str(len(app.bars))].color=[0,0,0]#hide it
                        app.stimuli['bartext_'+ str(len(app.bars))].on = False#hide it

                    elif app.vfb_type[j]==1: #Cursor
                        app.stimulus('cursor_'+str(j), z=3, stim=Disc(position=(app.scrw/2.0,app.b_offset), radius=10, color=(0.9,0.9,0.9), on=False))
                        app.vfb_keys.append('cursor_'+str(j))
                        #Set cursor speed so that it takes entire feedback duration to go from bottom to top at amplitude 1 (= 1xvar; =10% ERD; =10%MVC)
                        app.curs_speed = scrsiz / fbblks #pixels per block

                    elif app.vfb_type[j]==2: #Color-change circle.
                        app.col_zero = (0, 1, 0)#Green in the middle.
                        app.stimulus('col_circle_'+str(j), z=3, stim=Disc(position=center, radius=100, color=app.col_zero, on=False))
                        app.col_speed = 1.0*(2.0 / fbblks) #Colors will be mapped from -1 to +1. #Trying to double the speed to see if that helps.
                        app.vfb_keys.append('col_circle_'+str(j))

                    elif app.vfb_type[j]==3: #None
                        app.stimulus('cursor_'+str(j), z=-10, stim=Disc(radius=0, color=(0,0,0,0), on=False))
                        app.vfb_keys.append('cursor_'+str(j))

            #===================================================================
            # Audio Feedback
            #===================================================================
            if app.params['AudioFeedback'].val:
            # load, and silently start, the sounds
            # They will be used for cues and for feedback.
                app.sounds = []
                wavmat = app.params['AudioWavs']
                for i in range(len(wavmat)):
                    wavlist = wavmat[i]
                    if len(wavlist) != 1: raise EndUserError, 'FeedbackWavs matrix should have 1 column'
                    try: snd = WavTools.player(wavlist[0])
                    except IOError: raise EndUserError, 'failed to load "%s"'%wavlist[0]
                    app.sounds.append(snd)
                    snd.vol = 0
                    snd.play(-1)
                #Set the speed at which the fader can travel from -1 (sounds[0]) to +1 (sounds[1])
                app.fader_speed = 2 / fbblks

            #===================================================================
            # Handbox Feedback
            #===================================================================
            if app.params['HandboxFeedback'].val:
                from Handbox.HandboxInterface import Handbox
                serPort=app.params['HandboxPort'].val
                app.handbox=Handbox(port=serPort)
                #When x is +1, we have ERD relative to baseline
                #It should take fbblks at x=+1 to travel from 90 to 0
                app.hand_speed = -90 / fbblks #hand speed in degrees per block when x=+1

            #===================================================================
            # Neuromuscular Electrical Stimulation Feedback
            #===================================================================
            if app.params['NMESFeedback'].val:
                stimrange=np.asarray(app.params['NMESRange'].val,dtype='float64')#midpoint and max
                stim_min = 2*stimrange[0] - stimrange[1]
                from Handbox.NMESInterface import NMES
                serPort=app.params['NMESPort'].val
                app.nmes=NMES(port=serPort)
                app.nmes.width = 1.0

                #from Caio.NMES import NMESFIFO
                ##from Caio.NMES import NMESRING
                #app.nmes = NMESFIFO()
                ##app.nmes = NMESRING()
                #app.nmes.running = True

                #It should take fbblks at x=+1 to get intensity from min to max
                app.nmes_baseline = stimrange[0]
                app.nmes_max = stimrange[1]
                app.nmes_i = app.nmes.intensity
                app.nmes_speed = (stimrange[1]-stim_min) / float(fbblks) #nmes intensity rate of change per block when x=+1
    def Initialize(self, indim, outdim):       
        #=======================================================================
        # Set the list of TargetClasss (pseudorandomized)
        #=======================================================================
        n_trials = self.params['TrialsPerBlock'].val * self.params['BlocksPerRun'].val
        classes_per_cluster = self.params['ClusterTargets'].val
        trials_per_class = int(n_trials / self.nclasses)
        if classes_per_cluster == 0: #We will cycle through targets.
            self.target_codes = [item for sublist in [range(self.nclasses) for j in range(trials_per_class)] for item in sublist]
            self.target_codes = [x+1 for x in self.target_codes]
        elif classes_per_cluster ==1:
            self.target_codes = [1 + x / trials_per_class for x in range(n_trials)] #Forcing int yields e.g., [0,0,0,1,1,1,2,2,2]
            shuffle(self.target_codes)
        else:
            n_clusters = trials_per_class / classes_per_cluster
            temp = []
            for cc in range(n_clusters):
                temp2 = [[j for jj in range(classes_per_cluster)] for j in range(self.nclasses)] #Generate a list of clusters, one per target
                shuffle(temp2) #Shuffle the list of clusters
                temp.append(temp2) #Append the list of clusters to what we have already.
            self.target_codes = 1 + [x2 for x3 in [item for sublist in temp for item in sublist] for x2 in x3] #Flatten

        #=======================================================================
        # Screen
        #=======================================================================
        self.screen.color = (0,0,0) #let's have a black background
        self.scrw,self.scrh = self.screen.size #Get the screen dimensions.

        #===================================================================
        # Create a box object as the coordinate frame for the screen.
        # Manipulate its properties to get positional information for stimuli.
        #===================================================================
        scrsiz = min(self.scrw,self.scrh)
        siz = (scrsiz, scrsiz)
        b = box(size=siz, position=(self.scrw/2.0,self.scrh/2.0), sticky=True)
        center = b.map((0.5,0.5), 'position')
        self.positions = {'origin': np.matrix(center)} #Save the origin for later.

        #=======================================================================
        # Register the basic stimuli.
        #=======================================================================
        self.stimulus('cue', z=5, stim=VisualStimuli.Text(text='?', position=center, anchor='center', color=(1,1,1), font_size=50, on=False))
        self.stimulus('fixation', z=4.2, stim=Disc(position=center, radius=5, color=(1,1,1), on=False))

        #=======================================================================
        # Make a few variables easier to access.
        #=======================================================================
        self.eegfs = self.nominal['SamplesPerSecond'] #Sampling rate
        self.spb = self.nominal['SamplesPerPacket'] #Samples per block/packet
        self.block_dur = 1000*self.spb/self.eegfs#duration (ms) of a sample block
        self.taskMaxNBlocks = self.params['TaskMax'].val * self.eegfs / self.spb#Task will always go to response after this many blocks, even if extensions not ready

        #=======================================================================
        # State monitors for debugging.
        #=======================================================================
        if int(self.params['ShowSignalTime']):
            # turn on state monitors iff the packet clock is also turned on
            addstatemonitor(self, 'Running', showtime=True)
            addstatemonitor(self, 'CurrentBlock')
            addstatemonitor(self, 'CurrentTrial')
            addstatemonitor(self, 'TargetClass')
            addstatemonitor(self, 'LastTargetClass')
            addstatemonitor(self, 'TaskMinNBlocks')
            addphasemonitor(self, 'phase', showtime=True)

            m = addstatemonitor(self, 'fs_reg')
            m.func = lambda x: '% 6.1fHz' % x._regfs.get('SamplesPerSecond', 0)
            m.pargs = (self,)
            m = addstatemonitor(self, 'fs_avg')
            m.func = lambda x: '% 6.1fHz' % x.estimated.get('SamplesPerSecond',{}).get('global', 0)
            m.pargs = (self,)
            m = addstatemonitor(self, 'fs_run')
            m.func = lambda x: '% 6.1fHz' % x.estimated.get('SamplesPerSecond',{}).get('running', 0)
            m.pargs = (self,)
            m = addstatemonitor(self, 'fr_run')
            m.func = lambda x: '% 6.1fHz' % x.estimated.get('FramesPerSecond',{}).get('running', 0)
            m.pargs = (self,)

        if 'MSEnable' in self.params:	MagstimApp.initialize(self, indim, outdim)
        if 'DigitimerEnable' in self.params:	DigitimerApp.initialize(self, indim, outdim)
        if 'GatingEnable' in self.params:	GatingApp.initialize(self, indim, outdim)
        if 'ERPDatabaseEnable' in self.params:	ERPApp.initialize(self, indim, outdim)
        if 'ContFeedbackEnable' in self.params:	FeedbackApp.initialize(self, indim, outdim)
    def initialize(cls, app, indim, outdim):
        if int(app.params['ContFeedbackEnable']) == 1:
            if int(app.params['ShowSignalTime']):
                app.addstatemonitor('FBValue')
                app.addstatemonitor('FBBlock')
                app.addstatemonitor('Feedback')
                app.addstatemonitor('InRange')

            #===================================================================
            # Load fake data if we will be using fake feedback.
            #===================================================================
            if int(app.params['FakeFeedback']):
                import csv
                fp = app.params['FakeFile']
                app.fake_data = np.genfromtxt(fp, delimiter=',')
                np.random.shuffle(app.fake_data)

            #===================================================================
            # We need to know how many blocks per feedback period
            # so (non-bar) feedback can be scaled appropriately.
            #===================================================================
            fbdur = app.params['TaskDur'].val  #feedback duration
            fbblks = fbdur * app.eegfs / app.spb  #feedback blocks

            #===================================================================
            # Visual Feedback
            #===================================================================
            if app.params['VisualFeedback'].val:
                #===================================================================
                # Set a coordinate frame for the screen.
                #===================================================================
                scrsiz = min(app.scrw, app.scrh)
                siz = (scrsiz, scrsiz)
                b = box(size=siz,
                        position=(app.scrw / 2.0, app.scrh / 2.0),
                        sticky=True)
                #b is now our perfect box taking up as much of our screen as we are going to use.
                #its center is the center pixel, its width and height are equal to the smallest of screen width and height
                center = b.map(
                    (0.5, 0.5), 'position'
                )  #what is the center pixel value? e.g.([400.0, 225.0])

                #===================================================================
                # TODO: Get the arrows working for more than 2 targets
                #===================================================================
                #===============================================================
                # b.scale(x=0.25,y=0.4)#How big should the arrow be, relative to the screen size
                # arrow = PolygonTexture(frame=b, vertices=((0.22,0.35),(0,0.35),(0.5,0),(1,0.35),(0.78,0.35),(0.78,0.75),(0.22,0.75),),\
                #                    color=(1,1,1), on=False, position=center)
                # app.stimulus('arrow', z=4.5, stim=arrow)#Register the arrow stimulus.
                #
                # b.scale(x=4.0, y=2.5)#Reset the box
                # b.anchor='center'#Reset the box
                #===============================================================

                #===============================================================
                # Target rectangles.
                #===============================================================
                targtw = 0.5
                for x in range(app.nclasses):
                    my_target = app.target_range[x]
                    targ_h = int(
                        (my_target[1] - my_target[0]) * scrsiz / 200.0)
                    targ_y = int(center[1] + (my_target[0] + my_target[1]) *
                                 scrsiz / 400.0)
                    targ_stim = Block(position=[center[0], targ_y],
                                      size=[targtw * scrsiz, targ_h],
                                      color=(1, 0.1, 0.1, 0.5),
                                      on=False)
                    app.stimulus('target_' + str(x), z=2, stim=targ_stim)

                #Our feedback will range from -10 to +10
                app.m = app.scrh / 20.0  #Conversion factor from signal amplitude to pixels.
                app.b_offset = app.scrh / 2.0  #Input 0.0 should be at this pixel value.

                #===============================================================
                # Add feedback elements
                #===============================================================
                app.vfb_keys = []
                for j in range(app.nclasses):
                    if app.vfb_type[j] == 0:  #Bar
                        app.addbar(color=(0, 0.9, 0),
                                   pos=(app.scrw / 2.0, app.b_offset),
                                   thickness=app.scrw / 10,
                                   fac=app.m)
                        app.vfb_keys.append('barrect_' + str(len(app.bars)))
                        app.stimuli['bartext_' +
                                    str(len(app.bars))].position = (
                                        50, 50)  #off in the lower corner
                        #app.stimuli['bartext_'+ str(len(app.bars))].color=[0,0,0]#hide it
                        app.stimuli['bartext_' +
                                    str(len(app.bars))].on = False  #hide it

                    elif app.vfb_type[j] == 1:  #Cursor
                        app.stimulus('cursor_' + str(j),
                                     z=3,
                                     stim=Disc(position=(app.scrw / 2.0,
                                                         app.b_offset),
                                               radius=10,
                                               color=(0.9, 0.9, 0.9),
                                               on=False))
                        app.vfb_keys.append('cursor_' + str(j))
                        #Set cursor speed so that it takes entire feedback duration to go from bottom to top at amplitude 1 (= 1xvar; =10% ERD; =10%MVC)
                        app.curs_speed = scrsiz / fbblks  #pixels per block

                    elif app.vfb_type[j] == 2:  #Color-change circle.
                        app.col_zero = (0, 1, 0)  #Green in the middle.
                        app.stimulus('col_circle_' + str(j),
                                     z=3,
                                     stim=Disc(position=center,
                                               radius=100,
                                               color=app.col_zero,
                                               on=False))
                        app.col_speed = 1.0 * (
                            2.0 / fbblks
                        )  #Colors will be mapped from -1 to +1. #Trying to double the speed to see if that helps.
                        app.vfb_keys.append('col_circle_' + str(j))

                    elif app.vfb_type[j] == 3:  #None
                        app.stimulus('cursor_' + str(j),
                                     z=-10,
                                     stim=Disc(radius=0,
                                               color=(0, 0, 0, 0),
                                               on=False))
                        app.vfb_keys.append('cursor_' + str(j))

            #===================================================================
            # Audio Feedback
            #===================================================================
            if app.params['AudioFeedback'].val:
                # load, and silently start, the sounds
                # They will be used for cues and for feedback.
                app.sounds = []
                wavmat = app.params['AudioWavs']
                for i in range(len(wavmat)):
                    wavlist = wavmat[i]
                    if len(wavlist) != 1:
                        raise EndUserError, 'FeedbackWavs matrix should have 1 column'
                    try:
                        snd = WavTools.player(wavlist[0])
                    except IOError:
                        raise EndUserError, 'failed to load "%s"' % wavlist[0]
                    app.sounds.append(snd)
                    snd.vol = 0
                    snd.play(-1)
                #Set the speed at which the fader can travel from -1 (sounds[0]) to +1 (sounds[1])
                app.fader_speed = 2 / fbblks

            #===================================================================
            # Handbox Feedback
            #===================================================================
            if app.params['HandboxFeedback'].val:
                from Handbox.HandboxInterface import Handbox
                serPort = app.params['HandboxPort'].val
                app.handbox = Handbox(port=serPort)
                #When x is +1, we have ERD relative to baseline
                #It should take fbblks at x=+1 to travel from 90 to 0
                app.hand_speed = -90 / fbblks  #hand speed in degrees per block when x=+1

            #===================================================================
            # Neuromuscular Electrical Stimulation Feedback
            #===================================================================
            if app.params['NMESFeedback'].val:
                stimrange = np.asarray(app.params['NMESRange'].val,
                                       dtype='float64')  #midpoint and max
                stim_min = 2 * stimrange[0] - stimrange[1]
                from Handbox.NMESInterface import NMES
                serPort = app.params['NMESPort'].val
                app.nmes = NMES(port=serPort)
                app.nmes.width = 1.0

                #from Caio.NMES import NMESFIFO
                ##from Caio.NMES import NMESRING
                #app.nmes = NMESFIFO()
                ##app.nmes = NMESRING()
                #app.nmes.running = True

                #It should take fbblks at x=+1 to get intensity from min to max
                app.nmes_baseline = stimrange[0]
                app.nmes_max = stimrange[1]
                app.nmes_i = app.nmes.intensity
                app.nmes_speed = (stimrange[1] - stim_min) / float(
                    fbblks)  #nmes intensity rate of change per block when x=+1
예제 #6
0
    def Initialize(self, indim, outdim):
        #=======================================================================
        # Set the list of TargetClasss (pseudorandomized)
        #=======================================================================
        n_trials = self.params['TrialsPerBlock'].val * self.params[
            'BlocksPerRun'].val
        classes_per_cluster = self.params['ClusterTargets'].val
        trials_per_class = int(n_trials / self.nclasses)
        if classes_per_cluster == 0:  #We will cycle through targets.
            self.target_codes = [
                item for sublist in
                [range(self.nclasses) for j in range(trials_per_class)]
                for item in sublist
            ]
            self.target_codes = [x + 1 for x in self.target_codes]
        elif classes_per_cluster == 1:
            self.target_codes = [
                1 + x / trials_per_class for x in range(n_trials)
            ]  #Forcing int yields e.g., [0,0,0,1,1,1,2,2,2]
            shuffle(self.target_codes)
        else:
            n_clusters = trials_per_class / classes_per_cluster
            temp = []
            for cc in range(n_clusters):
                temp2 = [[j for jj in range(classes_per_cluster)]
                         for j in range(self.nclasses)
                         ]  #Generate a list of clusters, one per target
                shuffle(temp2)  #Shuffle the list of clusters
                temp.append(
                    temp2
                )  #Append the list of clusters to what we have already.
            self.target_codes = 1 + [
                x2 for x3 in [item for sublist in temp for item in sublist]
                for x2 in x3
            ]  #Flatten

        #=======================================================================
        # Screen
        #=======================================================================
        self.screen.color = (0, 0, 0)  #let's have a black background
        self.scrw, self.scrh = self.screen.size  #Get the screen dimensions.

        #===================================================================
        # Create a box object as the coordinate frame for the screen.
        # Manipulate its properties to get positional information for stimuli.
        #===================================================================
        scrsiz = min(self.scrw, self.scrh)
        siz = (scrsiz, scrsiz)
        b = box(size=siz,
                position=(self.scrw / 2.0, self.scrh / 2.0),
                sticky=True)
        center = b.map((0.5, 0.5), 'position')
        self.positions = {
            'origin': np.matrix(center)
        }  #Save the origin for later.

        #=======================================================================
        # Register the basic stimuli.
        #=======================================================================
        self.stimulus('cue',
                      z=5,
                      stim=VisualStimuli.Text(text='?',
                                              position=center,
                                              anchor='center',
                                              color=(1, 1, 1),
                                              font_size=50,
                                              on=False))
        self.stimulus('fixation',
                      z=4.2,
                      stim=Disc(position=center,
                                radius=5,
                                color=(1, 1, 1),
                                on=False))

        #=======================================================================
        # Make a few variables easier to access.
        #=======================================================================
        self.eegfs = self.nominal['SamplesPerSecond']  #Sampling rate
        self.spb = self.nominal['SamplesPerPacket']  #Samples per block/packet
        self.block_dur = 1000 * self.spb / self.eegfs  #duration (ms) of a sample block
        self.taskMaxNBlocks = self.params[
            'TaskMax'].val * self.eegfs / self.spb  #Task will always go to response after this many blocks, even if extensions not ready

        #=======================================================================
        # State monitors for debugging.
        #=======================================================================
        if int(self.params['ShowSignalTime']):
            # turn on state monitors iff the packet clock is also turned on
            addstatemonitor(self, 'Running', showtime=True)
            addstatemonitor(self, 'CurrentBlock')
            addstatemonitor(self, 'CurrentTrial')
            addstatemonitor(self, 'TargetClass')
            addstatemonitor(self, 'LastTargetClass')
            addstatemonitor(self, 'TaskMinNBlocks')
            addphasemonitor(self, 'phase', showtime=True)

            m = addstatemonitor(self, 'fs_reg')
            m.func = lambda x: '% 6.1fHz' % x._regfs.get('SamplesPerSecond', 0)
            m.pargs = (self, )
            m = addstatemonitor(self, 'fs_avg')
            m.func = lambda x: '% 6.1fHz' % x.estimated.get(
                'SamplesPerSecond', {}).get('global', 0)
            m.pargs = (self, )
            m = addstatemonitor(self, 'fs_run')
            m.func = lambda x: '% 6.1fHz' % x.estimated.get(
                'SamplesPerSecond', {}).get('running', 0)
            m.pargs = (self, )
            m = addstatemonitor(self, 'fr_run')
            m.func = lambda x: '% 6.1fHz' % x.estimated.get(
                'FramesPerSecond', {}).get('running', 0)
            m.pargs = (self, )

        if 'MSEnable' in self.params:
            MagstimApp.initialize(self, indim, outdim)
        if 'DigitimerEnable' in self.params:
            DigitimerApp.initialize(self, indim, outdim)
        if 'GatingEnable' in self.params:
            GatingApp.initialize(self, indim, outdim)
        if 'ERPDatabaseEnable' in self.params:
            ERPApp.initialize(self, indim, outdim)
        if 'ContFeedbackEnable' in self.params:
            FeedbackApp.initialize(self, indim, outdim)