I built the current version of BCI2000 (downloaded from TortoiseSVN in December 2022) a I want to use the BCPy2000 to develop an Application.
I developed a simple App code in order to learn about it and Everything seems to go perfect. However, when I read the .dat file generated, the states are not updated according to the current phase (I read the file through Matlab R2019b, using load_bcidat)
The code can be observed here:
Code: Select all
from BCPy2000.AppTools.Displays import fullscreen
from BCPy2000.AppTools.StateMonitors import addstatemonitor, addphasemonitor
class BciApplication(BciGenericApplication):
def Description(self):
return "Simple App"
def Construct(self):
self.define_param(
"PythonApp:Design int InitBaseline= 1 0 0 1 // record a initial and final 20 seconds baseline (boolean)",
"PythonApp:Screen int ScreenId= -1 -1 % % // on which screen should the stimulus window be opened - use -1 for last",
"PythonApp:Screen float WindowSize= 0.8 1.0 0.0 1.0 // size of the stimulus window, proportional to the screen",
)
self.define_state(
"BaselineOn 1 0 0 0",
)
def Preflight(self, sigprops):
trialsPerBlock = int(self.params['TrialsPerBlock'])
self.totalBlocks = int(self.params['BlocksPerRun'])
self.cueCounter = 0
self.blockCounter = 0
siz = float(self.params['WindowSize'])
screenid = int(self.params['ScreenId'])
fullscreen(scale=siz, id=screenid, frameless_window=(siz==1))
def Initialize(self, indim, outdim):
import psychopy.visual as psypy
self.scrw,self.scrh = self.screen.size
self.screen.color = (0x00,0x00,0x00)
self.stimulus('Baseline', z=1, stim=psypy.TextBox(self.screen.screen,text='BASELINE', size=[800,200],pos=(0,0),units='pix',font_size=90, font_color=[1,1,1],grid_horz_justification='center', grid_vert_justification='center'),on=False)
self.stimulus('StartCue', z=1, stim=psypy.TextBox(self.screen.screen,text='BLOCK STARTS', size=[800,200],pos=(0,0),units='pix',font_size=90, font_color=[1,1,1],grid_horz_justification='center', grid_vert_justification='center'),on=False)
self.stimulus('StopCue', z=1, stim=psypy.TextBox(self.screen.screen,text='BLOCK ENDS', size=[800,200],pos=(0,0),units='pix',font_size=90, font_color=[1,1,1],grid_horz_justification='center', grid_vert_justification='center'),on=False)
if True:
addstatemonitor(self, 'Running', showtime=True)
addstatemonitor(self, 'CurrentBlock')
addstatemonitor(self, 'CurrentTrial')
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,)
def StartRun(self):
pass
def Phases(self):
self.phase(name='baseline', duration=5000, next='stopcue')
self.phase(name='startcue', duration=1000, next='baseline')
self.phase(name='stopcue', duration=1000, next='startcue')
self.design(start='startcue', new_trial='cue', interblock='idle')
def Transition(self, phase):
if phase == 'baseline':
self.stimuli['Baseline'].on = True
else:
self.stimuli['Baseline'].on = False
if phase == 'startcue':
self.stimuli['StartCue'].on = True
self.states['CurrentBlock'] += 1
else:
self.stimuli['StartCue'].on = False
if phase == 'stopcue':
self.stimuli['StopCue'].on = True
else:
self.stimuli['StopCue'].on = False
self.states['BaselineOn'] = int(phase in ['baseline'])
def Process(self, sig):
pass # or not.
def Frame(self, phase):
pass
def Event(self, phase, event):
pass
def StopRun(self):
pass
Another problem that I don't know how to solve is how to finish the application without using the button Start, I tried changing the states['Running'] to 0, but it doesn't work.
Thanks in advance!