Combining Pixel Mode GB and buttonSchedules
This demo creates buttonschedules for four buttons and enables Pixel Mode GB. A stimulus is presented with a pixel drawn in the top lefthand corner to generate a digital output trigger. Button presses are logged and saved to .csv. The stimulus and trigger update on button press.
#Beginning of experiment - initialize
from psychopy import visual
from pypixxlib import _libdpx as dp
import pandas as pd
def enableButtonSchedules():
#Create our digital output waveforms. Each button press (rising edge) triggers a
#1 msec trig on the corresponding dout pin, followed by 2 msec on low.
#We'll use the dual /MRI as our example. DinChannels will depend on your button box type, you can use the PyPixx Digital I/O demo to verify your channel mappings.
#Note that if PixelModeGB is enabled it will control dout 8-23, dout waveforms which try to alter these will have no effect
#Din0 - Red
redWaveform = [1, 0, 0]
#Din1 - Yellow
yellowWaveform = [2, 0, 0]
#Din2 - Green
greenWaveform = [4, 0, 0]
#Din3 - Blue
blueWaveform = [8, 0, 0]
#Let's write the waveforms into the DPx memory. The address is set by 0 + 4096*channel_of_desired_digital_in_trigger
redAdd = 0+4096*0
yellowAdd = 0+4096*1
greenAdd = 0+4096*2
blueAdd = 0+4096*3
#write schedules into ram
dp.DPxWriteRam(redAdd, redWaveform)
dp.DPxWriteRam(yellowAdd, yellowWaveform)
dp.DPxWriteRam(greenAdd, greenWaveform)
dp.DPxWriteRam(blueAdd, blueWaveform)
#configure buffer-- only need to configure the first one, rest will follow the same format
dp.DPxSetDoutBuff(redAdd, len(redWaveform)*2)
dp.DPxSetDoutSched(0, 10, 'hz', len(redWaveform)+1)
dp.DPxUpdateRegCache()
#turn off debounce so button jitter is suppressed
dp.DPxEnableDinDebounce()
#Enable button schedules, set mode to 1 for RPx /MRI setup
dp.DPxEnableDoutButtonSchedules()
dp.DPxSetDoutButtonSchedulesMode(1)
dp.DPxWriteRegCache()
def Trigger2RGB(trigger):
#helper function determines pixel mode RGB 255 colour value based on 24-bit trigger (in decimal, base 10)
#returns a list with R, G and B elements
# return [red, green, blue]
return [ trigger%256, (trigger>>8)%256, (trigger>>16)%256]
def drawPixelModeTrigger(win, pixelValue):
#takes a pixel colour and draws it as a single pixel in the top left corner of the window
#window must cover top left of screen to work
#interpolate must be set to FALSE before color is set
#call this just before flip to ensure pixel is drawn over other stimuli
topLeftCorner = [-win.size[0]/2, win.size[1]/2]
line = visual.Line(
win=win,
units = 'pix',
start=topLeftCorner,
end=[topLeftCorner[0]+1, topLeftCorner[1]],
interpolate = False,
colorSpace = 'rgb255',
lineColor = pixelValue)
line.draw()
#-----------------------------------------------------------------------------
#SCRIPT START
#Open
dp.DPxOpen()
#Initialize pixelModeGB
dp.DPxEnableDoutPixelModeGB()
#enableButtonSchedules
enableButtonSchedules()
#enable DinLog for retrieving copy of button presses
myDict = dp.DPxSetDinLog()
dp.DPxStartDinLog()
dp.DPxUpdateRegCache()
column_headers = ['TimeTag','DigitalInput']
#create a list of arbitrary trig vals-- dout 8 and 9 here
trigList = [2**9,2**8,2**9]
#stimulus colors
colors = ['red', 'green', 'blue']
##STIMULUS PRESENTATION
# Create a window
win = visual.Window(screen=1, fullscr=True, color='black', units='pix')
for i in range(0,3):
# Create a stimulus (e.g., a square)
stimulus = visual.Rect(win, width=100, height=100, fillColor=colors[i], pos=(0, 0))
stimulus.draw()
#draw trigger pixel
triggerPixelVal = Trigger2RGB(trigList[i])
drawPixelModeTrigger(win, triggerPixelVal)
win.flip()
# Wait for a button press to continue
while True:
dp.DPxUpdateRegCache()
dp.DPxGetDinStatus(myDict)
#listen for 2 events: button press/release
if myDict['newLogFrames'] > 1:
data = dp.DPxReadDinLog(myDict, myDict['newLogFrames'])
# Create a DataFrame using pandas
trial_frame = pd.DataFrame(data, columns=column_headers)
if (i==0):
exp_data=trial_frame
else:
exp_data = pd.concat([exp_data, trial_frame])
break
# Save the DataFrame to a CSV file
csv_filename = 'sample_data.csv'
exp_data.to_csv(csv_filename, index=False)
#Shut down
dp.DPxStopAllScheds()
dp.DPxDisableDoutPixelModeGB()
dp.DPxWriteRegCache()
dp.DPxClose()
win.close()