Ejemplo n.º 1
0
    def _addRuntimeInfoToDisplayConfig(self):
        
        if self not in Display._enabled_display_instances:
            Display._enabled_display_instances.append(self)
            
        display_config=self.getConfiguration()

        runtime_info=display_config.get('runtime_info',None)
        if runtime_info is None:        
            runtime_info=self._getRuntimeInfoByIndex(self.device_number)        
            display_config['runtime_info']=runtime_info

            self._createPsychopyCalibrationFile()
            
            
            pixel_width=runtime_info['pixel_width']
            pixel_height=runtime_info['pixel_height']
            
            
            phys_width=display_config["physical_dimensions"]['width']
            phys_height=display_config["physical_dimensions"]['height']
            phys_unit_type=display_config["physical_dimensions"]['unit_type']
            
             
            # add pixels_per_degree to runtime info
            ppd_x=misc.deg2pix(1.0,self._psychopy_monitor)#math.tan(math.radians(0.5))*2.0*viewing_distance*pixel_width/phys_width
            ppd_y=misc.deg2pix(1.0,self._psychopy_monitor)#math.tan(math.radians(0.5))*2.0*viewing_distance*pixel_height/phys_height
            runtime_info['pixels_per_degree']=ppd_x,ppd_y            
                    
            self. _calculateCoordMappingFunctions(pixel_width,pixel_height,phys_unit_type, phys_width,phys_height)
            
            left,top,right,bottom=runtime_info['bounds']
            coord_left,coord_top=self._pixel2DisplayCoord(left,top,self.device_number)
            coord_right,coord_bottom=self._pixel2DisplayCoord(right,bottom,self.device_number)
            runtime_info['coordinate_bounds']= coord_left,coord_top,coord_right,coord_bottom
Ejemplo n.º 2
0
    def draw(self, wind):
        ''' draws the maze to window wind'''
        try:
            self.maze.draw()
            return
        except AttributeError:
            'do nothing'
        elem=[]

        temp=np.array(self.lineXY)
        edges=visual.ElementArrayStim(wind,fieldShape='sqr',
            nElements=len(self.lineXY)*2,sizes=self.lw,units='deg',
            elementMask='circle',elementTex=None,
            xys=np.reshape(temp,(temp.shape[0]*2,2)))
        elem.append(edges)
        # todo try elem array instead of line
        for line in self.lineXY:
            #print line
            body=visual.Line(wind,line[0],line[1],
                lineWidth=deg2pix(self.lw,wind.monitor))
            elem.append(body)
        frame=visual.Rect(wind,width=self.dispSize[0],
            height=self.dispSize[1],lineColor=(1,1,1),pos=(0,0),
            lineWidth=deg2pix(self.lw,wind.monitor),units='deg')
        if len(self.lineXY)==0:
            self.maze=frame
        else:
            elem.append(frame)
            self.maze=visual.BufferImageStim(wind,stim=elem)
Ejemplo n.º 3
0
    def __init__(self,
                 size=(800, 600),
                 position=None,
                 units="pix",
                 monitor=None):
        """
        Parameters
        ----------

        size : *(800, 600)* or tuple
            tuple containing the width and the height of the window in pixel
        position : *None* or tuple
            if None screen center, otherwise the position given in a tuple 
            containing the center of the window relative to the center of
            the screen (positive values mean up/right)
        units : "pix", "deg", "cm", "norm" (optional)
            psychopy units to calculate size and position of the window. If
            units is different from "pix" monitor must be present. Default is
            "pix."
        monitor : psychopy.monitors.Monitor (optional)
            psychopy monitor object, that is used to convert units.


        """
        if units != "pix":
            if not monitor:
                raise ValueError(
                    "if units is not 'pix', monitor must be supplied")

        # convert to pixel
        if units == "deg":
            size = [misc.deg2pix(x, monitor) for x in size]
            if position:
                position = [misc.deg2pix(x, monitor) for x in position]
        elif units == "cm":
            size = [misc.cm2pix(x, monitor) for x in size]
            if position:
                position = [misc.cm2pix(x, monitor) for x in position]
        elif units == "norm":
            size = [
                int(monitor.getSizePix()[0] * (float(size[0]) / 2)),
                int(monitor.getSizePix()[1] * (float(size[1]) / 2))
            ]
            if position:
                position = [
                    int(monitor.getSizePix()[0] * position[0]),
                    int(monitor.getSizePix()[1] * position[1])
                ]
        else:
            raise ValueError(
                "only 'pix', 'deg', 'cm', or 'norm' are accepted units.")

        # call parent with calculated parameters
        super(PsyTMLPsychopy, self).__init__(size, position)
Ejemplo n.º 4
0
def traj2movie(traj,width=5,outsize=64,elem=None,wind=None,rot=2,
               hz=85.0,SX=0.3,SY=0.3,ST=20):
    ''' extracts window at position 0,0 of width WIDTH deg
        from trajectories and subsamples to OUTSIZExOUTSIZE pixels
        HZ - trajectory sampling frequency
        ROT - int number of rotations to output or float angle in radians 
        SX,SY,ST - standard deviation of gaussian filter in deg,deg,ms
        
    '''
    if type(wind)==type(None):
        close=True; wind=Q.initDisplay()
    else: close=False
    if type(elem)==type(None):
        elem=visual.ElementArrayStim(wind,fieldShape='sqr',
            nElements=traj.shape[1], sizes=Q.agentSize,
            elementMask=RING,elementTex=None,colors='white')
    try:
        sig=[ST/1000.0*hz]
        sig.append(deg2pix(SX,wind.monitor))
        sig.append(deg2pix(SY,wind.monitor))
        w=int(np.round(deg2pix(width,wind.monitor)/2.0))
        D=np.zeros((traj.shape[0],outsize,outsize,rot),dtype=np.uint8)
        Ims=[]
        for f in range(0,traj.shape[0]):
            Im=position2image(traj[f,:,:],wind=wind)
            cx=int(Im.size[0]/2.0);cy=int(Im.size[1]/2.0)
            Im=Im.crop(np.int32((cx-1.5*w,cy-1.5*w,cx+1.5*w,cy+1.5*w)))
            Im=np.asarray(Im,dtype=np.float32)
            Ims.append(Im)
        Ims=np.array(Ims)
        if np.any(np.array(sig)!=0):Ims=gaussian_filter(Ims,sig)
        if np.any(Ims>255): print 'warning, too large'
        if np.any(Ims<0): print 'warning, too small'
        Ims=np.uint8(np.round(Ims))
        for f in range(Ims.shape[0]):
            Im=Image.fromarray(np.array(Ims[f,:,:]))
            bb=int(Im.size[0]/2.0)
            I=Im.crop((bb-w,bb-w,bb+w,bb+w))
            I=np.asarray(I.resize((outsize,outsize),Image.ANTIALIAS))
            D[f,:,:,0]=I
            for r in range(1,rot):
                I2=Im.rotate(90/float(rot)*r)
                I2=I2.crop((bb-w,bb-w,bb+w,bb+w))
                I2=np.asarray(I2.resize((outsize,outsize),Image.ANTIALIAS))
                D[f,:,:,r]=I2
        if close: wind.close()
        return D
    except:
        if close: wind.close()
        raise
Ejemplo n.º 5
0
 def getCurrentFixation(self, units='deg'):
     ''' returns the triple gc,fc,fix
         where gc is current gaze position, fc is current fixation position (or nans if not available)
         and fix indicates whether a fixation is currently taking place
         units - units of output coordinates
                 'norm', 'pix', 'cm' and 'deg' are currently supported
     '''
     gc=self.getCurrentGazePosition(units=units)
     fd=self.fixdur/self.hz
     fc=self.fixsum/float(Settings.FUSS)#/float(max(self.fixdur,1))
     if units is 'cm': fc=deg2cm(fc, self.win.monitor)
     elif units is 'pix': fc=deg2pix(fc, self.win.monitor)
     elif units is 'norm': fc = deg2pix(fc, self.win.monitor) / self.win.size*2
     return gc,fc, fd>Settings.FIXMINDUR,0
Ejemplo n.º 6
0
 def degcoord2pix(self, degx, degy, display_index=None):
     if display_index == self.getIndex():
         return psychopy2displayPix(
             misc.deg2pix(
                 degx, self._psychopy_monitor), misc.cm2pix(
                 degy, self._psychopy_monitor))
     return degx, degy
Ejemplo n.º 7
0
 def degcoord2pix(self, degx, degy, display_index=None):
     if display_index == self.getIndex():
         return psychopy2displayPix(
             misc.deg2pix(
                 degx, self._psychopy_monitor), misc.cm2pix(
                 degy, self._psychopy_monitor))
     return degx, degy
Ejemplo n.º 8
0
        def __init__(self, tracker, win, settings):
            """ Initializes PsychopyCustomDisplay object.

            """
            super().__init__()
            self.tracker = tracker
            self.win = win
            self.settings = settings  # from session
            self.txtcol = -1
            #self.__target_beep__ = sound.Sound(800, secs=.1)  # THIS WILL GIVE A SEGFAULT!
            #self.__target_beep__done__ = sound.Sound(1200, secs=.1)  # THIS WILL GIVE A SEGFAULT!
            #self.__target_beep__error__ = sound.Sound(400, secs=.1)  # THIS WILL GIVE A SEGFAULT!
            self.backcolor = self.win.color

            dot_size_pix = misc.deg2pix(
                self.settings['eyetracker'].get('dot_size'), self.win.monitor)
            self.targetout = Circle(self.win,
                                    pos=(0, 0),
                                    radius=dot_size_pix,
                                    fillColor='black',
                                    units='pix',
                                    lineColor='black')

            self.targetin = Circle(self.win,
                                   pos=(0, 0),
                                   radius=3,
                                   fillColor=0,
                                   lineColor=0,
                                   units='pix',
                                   opacity=0)
            win.flip()
Ejemplo n.º 9
0
 def getOffScreenFrames(self):
     """ Returns a list of frames when the foreground stimulus is offscreen 
         UNFINISHED"""
     objectwidthDeg = int(self.terrain['objectwidthDeg'])
     mon = monitors.Monitors('testMonitor')
     objectwidthPix = misc.deg2pix(objectwidthDeg,mon)
     posx = array(self.posx)
Ejemplo n.º 10
0
    def _addRuntimeInfoToDisplayConfig(self):

        if self not in Display._enabled_display_instances:
            Display._enabled_display_instances.append(self)

        display_config = self.getConfiguration()

        runtime_info = display_config.get('runtime_info', None)
        if runtime_info is None:
            runtime_info = self._getRuntimeInfoByIndex(self.device_number)
            display_config['runtime_info'] = runtime_info

            if _ispkg is False:
                self._createPsychopyCalibrationFile()

            pixel_width = runtime_info['pixel_width']
            pixel_height = runtime_info['pixel_height']

            phys_width = display_config['physical_dimensions']['width']
            phys_height = display_config['physical_dimensions']['height']
            phys_unit_type = display_config['physical_dimensions']['unit_type']

            # add pixels_per_degree to runtime info
            try:
                from psychopy import misc
                # math.tan(math.radians(0.5))*2.0*viewing_distance*pixel_width/phys_width
                ppd_x = misc.deg2pix(1.0, self._psychopy_monitor)
                # math.tan(math.radians(0.5))*2.0*viewing_distance*pixel_height/phys_height
                ppd_y = misc.deg2pix(1.0, self._psychopy_monitor)
                runtime_info['pixels_per_degree'] = ppd_x, ppd_y
            except ImportError as e:
                pass

            self._calculateCoordMappingFunctions(pixel_width, pixel_height,
                                                 phys_unit_type, phys_width,
                                                 phys_height)

            left, top, right, bottom = runtime_info['bounds']
            coord_left, coord_top = self._pixel2DisplayCoord(
                left, top, self.device_number)
            coord_right, coord_bottom = self._pixel2DisplayCoord(
                right, bottom, self.device_number)
            runtime_info[
                'coordinate_bounds'] = coord_left, coord_top, coord_right, coord_bottom
Ejemplo n.º 11
0
    def __init__(self, size=(800, 600), position=None, units="pix",
                 monitor=None):
        """
        Parameters
        ----------

        size : *(800, 600)* or tuple
            tuple containing the width and the height of the window in pixel
        position : *None* or tuple
            if None screen center, otherwise the position given in a tuple 
            containing the center of the window relative to the center of
            the screen (positive values mean up/right)
        units : "pix", "deg", "cm", "norm" (optional)
            psychopy units to calculate size and position of the window. If
            units is different from "pix" monitor must be present. Default is
            "pix."
        monitor : psychopy.monitors.Monitor (optional)
            psychopy monitor object, that is used to convert units.


        """
        if units != "pix":
            if not monitor:
                raise ValueError("if units is not 'pix', monitor must be supplied")

        # convert to pixel
        if units == "deg":
            size = [misc.deg2pix(x, monitor) for x in size]
            if position:
                position = [misc.deg2pix(x, monitor) for x in position]
        elif units == "cm":
            size = [misc.cm2pix(x, monitor) for x in size]
            if position:
                position = [misc.cm2pix(x, monitor) for x in position]
        elif units == "norm":
            size = [int(monitor.getSizePix()[0] * (float(size[0])/2)), int(monitor.getSizePix()[1] * (float(size[1])/2))]
            if position:
                position = [int(monitor.getSizePix()[0] * position[0]), int(monitor.getSizePix()[1] * position[1])]
        else:
            raise ValueError("only 'pix', 'deg', 'cm', or 'norm' are accepted units.")
        
        # call parent with calculated parameters
        super(PsyTMLPsychopy, self).__init__(size, position)
Ejemplo n.º 12
0
def deg2norm_y(position, window):
    return pix2norm_y(deg2pix(position, window.monitor), window)
# Run through the trial in trialList
trial_no = 1
for trial in trials:
    
    # Set position of dot and draw it, and show (flip) it on the screen
    target_x, target_y = trial['posx']*sc_f,trial['posy']*sc_f
    dot.setPos((target_x, target_y))
    dot.draw()
    dot_center.setPos((target_x, target_y))
    dot_center.draw()   
    flip_time = win.flip() 
    
    # Send message about trial
    trial['trial_id']    = trial_no 
    trial['TRIAL_START'] = flip_time   
    trial['posx'] = misc.deg2pix(target_x,thisMon)    # Convert to pixels to match EDQ scripts
    trial['posy'] = misc.deg2pix(target_y,thisMon)    # Convert to pixels to match EDQ scripts

    
    # Show the dot for the duration specified in the Excel sheet
    # (would be more accurate to wait in multiples of the screen refresh rate)
    dot_duration = trial['dt']/1000.0
    core.wait(dot_duration)
    
    trial['TRIAL_END']=flip_time + dot_duration
    
    # Add trial info to iohub
    io.addRowToConditionVariableTable(trial.values()) 
    
    # increment trial number
    trial_no += 1
Ejemplo n.º 14
0
# set screen:
myWin = visual.Window(size=(PixW, PixH),
                      screen=0,
                      winType='pyglet',
                      allowGUI=False,
                      allowStencil=False,
                      fullscr=True,
                      monitor=moni,
                      color=[0, 0, 0],
                      colorSpace='rgb',
                      units='pix',
                      blendMode='avg',
                      autoLog=False)

# The size of the field.
fieldSizeinPix = np.round(misc.deg2pix(cfg.fovHeight, moni))

logFile.write('fieldSizeinDeg=' + unicode(cfg.fovHeight) + '\n')
logFile.write('fieldSizeinPix=' + unicode(fieldSizeinPix) + '\n')

# %% CONDITIONS

# get timings for apertures and motion directions
strPathParentUp = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                               '..'))
filename = os.path.join(
    strPathParentUp, 'Conditions',
    'Conditions_PrepRun_run' + str(expInfo['run']) + '.npz')
npzfile = np.load(filename)
conditions = npzfile["conditions"].astype('int8')
targets = npzfile["targets"]
Ejemplo n.º 15
0
    def preTrial(self, trial, calibTrial, win,autoDrift=False):
        '''Set up each trial with the eye tracker
        '''
        self.tracker.doSetup=False
        if calibTrial: cond = "Test/Calibration Trial"
        else: cond = "Non-test/no calibration trial"
        message ="record_status_message 'Trial %d %s'"%(trial+1, cond)
        self.tracker.sendCommand(message)
        msg = "TRIALID %s"%trial
        self.tracker.sendMessage(msg)
        #Do drift correction if necissary
        if calibTrial:
            win.flip()
            while True:
                try:
                    error = self.tracker.doDriftCorrect(self.screenSize[0]/2,self.screenSize[1]/2,1,1) 
                    if error != 27:
                        self.tracker.applyDriftCorrect()
                        break
                    else:
                        
                        #self.tracker.doTrackerSetup()
                        win.flip()
                except:
                    print("Exception")
                    break
            win.flip()

        print("Switching to record mode")
        error = self.tracker.startRecording(1,1,1,1)
        pylink.beginRealTimeMode(100)
        if error: return error
 
        if not self.tracker.waitForBlockStart(1000, 1, 0):
            endTrial()
            print "ERROR: No link samples received!"
            return "ABORT_EXPT"
        self.eye_used = self.tracker.eyeAvailable(); 
        #determine which eye(s) are available
        if self.eye_used == RIGHT_EYE:
            self.tracker.sendMessage("PRETRIAL EYE_USED 1 RIGHT")
        elif self.eye_used == LEFT_EYE :
            self.tracker.sendMessage("PRETRIAL EYE_USED 0 LEFT")
        elif self.eye_used == BINOCULAR:
            self.tracker.sendMessage("PRETRIAL EYE_USED 2 BINOCULAR")
        else:
            print "Error in getting the eye information!"
            return "ABORT_EXPT"
        self.tracker.flushKeybuttons(0)
        if autoDrift:
            self.tracker.target.setPos((0, 0))
            self.tracker.target.draw()
            win.flip()
            
            
            x,y=self.screenSize/2.0
            i=0
            leftFinished=False
            rightFinished=False
            core.wait(0.5)
            self.tracker.resetData()
            while i<10 and not (leftFinished and rightFinished):   
                sampleType = self.tracker.getNextData()
                if sampleType == pylink.FIXUPDATE:
                    sample = self.tracker.getFloatData()
                    gazePos=sample.getAverageGaze()
                    #self.sendMessage('eyePos %.3f %.3f type %d, eye %d'%(gazePos[0],gazePos[1],sample.getType(),sample.getEye()))
                    if (( (x-gazePos[0])**2+(y-gazePos[1])**2)**0.5<misc.deg2pix(3,win.monitor) and
                        gazePos[0]>0 and gazePos[0]<2*x and gazePos[1]>0 and gazePos[1]<2*y):
                        cmd='drift_correction %f %f %f %f' % (x-gazePos[0], y-gazePos[1],x,y)
                        if sample.getEye()==1: rightFinished=True; cmd+=' R'
                        else: leftFinished=True; cmd+=' L'
                        self.sendCommand(cmd)
                    else:
                        core.wait(0.1)
                        self.tracker.resetData()
                        i+=1
            if i==10:
                self.postTrial()
                self.tracker.doTrackerSetup()
                self.preTrial(trial, calibTrial, win,autoDrift)
            else: core.wait(0.25+random.random()/2)
            return
Ejemplo n.º 16
0
myWin = visual.Window(
    size=(PixW, PixH),
    screen=0,
    winType='pyglet',
    allowGUI=False,
    allowStencil=False,
    fullscr=True,
    monitor=moni,
    color=[0, 0, 0],
    colorSpace='rgb',
    units='pix',
    blendMode='avg',
    autoLog=False)

# The size of the field.
fieldSizeinPix = np.round(misc.deg2pix(cfg.fovHeight, moni))

logFile.write('fieldSizeinDeg=' + unicode(cfg.fovHeight) + '\n')
logFile.write('fieldSizeinPix=' + unicode(fieldSizeinPix) + '\n')


# %% CONDITIONS

strPathParentUp = os.path.abspath(
    os.path.join(os.path.dirname(__file__), '..'))
filename = os.path.join(strPathParentUp, 'conditions',
                        'Conditions_MotLoc_run' + str(expInfo['run']) +
                        '.npz')
npzfile = np.load(filename)
conditions = npzfile["conditions"].astype('int8')
targets = npzfile["targets"]
# for psychoph lab: make 'fullscr = True', set size =(1920, 1080)
myWin = visual.Window(
    size=(PixW, PixH),
    screen=0,
    winType='pyglet',  # winType : None, ‘pyglet’, ‘pygame’
    allowGUI=False,
    allowStencil=True,
    fullscr=True,  # for psychoph lab: fullscr = True
    monitor=moni,
    color=[0, 0, 0],
    colorSpace='rgb',
    units='pix',
    blendMode='avg')

# Speed of the dots (in deg per second)
speedPixPerSec = misc.deg2pix(30, moni)  # 0.01
# The size of the field.
fieldSizeinDeg = 24
fieldSizeinPix = np.round(misc.deg2pix(fieldSizeinDeg, moni))

logFile.write('speedPixPerSec=' + unicode(speedPixPerSec) + '\n')
logFile.write('fieldSizeinDeg=' + unicode(fieldSizeinDeg) + '\n')
logFile.write('fieldSizeinPix=' + unicode(fieldSizeinPix) + '\n')

# %%
"""CONDITIONS"""
# retrieve masks from npz file (stored in folder Masks)
str_path_masks = str_path_parent_up + os.path.sep + 'Masks' + \
    os.path.sep + str(expInfo['maskType']) + '.npy'
masks = np.load(str_path_masks)
# turn 0 to -1 (since later on this will be used as mask for GratingStim),
Ejemplo n.º 18
0
 def deg2pix(self,deg):
     return deg2pix(deg,self.monitor)
Ejemplo n.º 19
0
#CREATE BACKGROUND STIMULUS

grating = visual.GratingStim(window,tex="sin",mask="None",texRes=64,
       size=[160,160], sf=1, ori = 0, name='grating', autoLog=False, units = 'deg')
       
#CREATE BACKGROUND FRAME PARAMETERS (what changes between frames and how much)
bgFrame = {}

#CREATE BACKGROUND SWEEP PARAMETERS (what changes between sweeps, and in what order)  
bgSweep = {}

bgSweep['Ori'] = (range(0,360,45),0)
bgSweep['SF'] = ([0.2],1)
bgSweep['Contrast'] = ([1],3)
bgSweep['TF'] = ([2],2)
bgSweep['Phase'] = ([0],4)

#CREATE FOREGROUND STIMULUS
monitor = monitors.Monitor('testMonitor')
target = visual.GratingStim(window, tex = None, size = (misc.deg2pix(terrain.objectwidthDeg,monitor), misc.deg2pix(terrain.objectwidthDeg,monitor)), units = 'pix', color = -1, autoLog=False)
#img = visual.ImageStim(window, image = "C:\\Users\\derricw\\Pictures\\facepalm.jpg", size = [450,300], units = 'pix', autoLog=False) #creates an image from an image in specified directory
#CREATE FOREGROUND STIMULUS FRAME PARAMETERS (what changes between frames and how much (BESIDES XPOSITITON WHICH IS AUTOMATIC FOR THIS EXPERIMENT)
fgFrame = {}

#CREATE FOREGROUND SWEEP PARAMETERS (what changes between sweeps)
fgSweep = {}

#CREATE FORAGING CLASS INSTANCE
g = Foraging(window = window, terrain = terrain, params = params, bgStim = grating, bgFrame = bgFrame, bgSweep = bgSweep, fgStim = target)
#RUN IT
g.run()