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
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)