class GlutTextBase(VisionEgg.Core.Stimulus): """DEPRECATED. Base class: don't instantiate this class directly. Base class that defines the common interface between the other glut-based text stimuli. Parameters ========== color -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) lowerleft -- (Sequence2 of Real) Default: (320, 240) on -- (Boolean) Default: True text -- (String) Default: the string to display """ parameters_and_defaults = { 'on': (True, ve_types.Boolean), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'lowerleft': ((320, 240), ve_types.Sequence2(ve_types.Real)), 'text': ('the string to display', ve_types.String) } def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self, **kw)
class GlutTextBase(VisionEgg.Core.Stimulus): """DEPRECATED. Base class: don't instantiate this class directly. Base class that defines the common interface between the other glut-based text stimuli. Parameters ========== color -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) lowerleft -- (Sequence2 of Real) Default: (320, 240) on -- (Boolean) Default: True text -- (String) Default: the string to display """ parameters_and_defaults = { 'on': (True, ve_types.Boolean), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'lowerleft': ((320, 240), ve_types.Sequence2(ve_types.Real)), 'text': ('the string to display', ve_types.String) } def __init__(self, **kw): if not hasattr(VisionEgg.config, "_GAVE_GLUT_TEXT_DEPRECATION"): logger = logging.getLogger('VisionEgg.Text') logger.warning("Using GlutTextBase class. This will be " "removed in a future release. Use " "VisionEgg.Text.Text instead.") VisionEgg.config._GAVE_GLUT_TEXT_DEPRECATION = 1 VisionEgg.Core.Stimulus.__init__(self, **kw)
def verify_parameters(self): """Perform type check on all parameters""" for parameter_name in dir(self.parameters): if parameter_name.startswith('__'): continue require_type = self.get_specified_type(parameter_name) this_type = ve_types.get_type(getattr(self.parameters,parameter_name)) ve_types.assert_type(this_type,require_type)
def verify_parameters(self): """Perform type check on all parameters""" for parameter_name in dir(self.parameters): if parameter_name.startswith("__"): continue require_type = self.get_specified_type(parameter_name) this_type = ve_types.get_type(getattr(self.parameters, parameter_name)) ve_types.assert_type(this_type, require_type)
def assert_type(*args): warnings.warn( "VisionEgg.assert_type() has been moved to " + "VisionEgg.ParameterTypes.assert_type()", DeprecationWarning, stacklevel=2, ) return ve_types.assert_type(*args)
class Channel(VisionEgg.ClassWithParameters): constant_parameters_and_defaults = { 'signal_type': (None, ve_types.Instance(SignalType)), 'daq_mode': (None, ve_types.Instance(DaqMode)), 'functionality': (None, ve_types.Instance(Functionality)), } def __init__(self, **kw): VisionEgg.ClassWithParameters.__init__(self, **kw) self.constant_parameters.signal_type.channel = self self.constant_parameters.daq_mode.channel = self self.constant_parameters.functionality.channel = self self.device = None # Not set yet def arm_trigger(self): raise NotImpelemetedError("This method must be overridden.")
def __init__(self, rec_duration=2, threshold=1000, chunk_size=800, rate=44100): # initialize a few important variables self.THRESHOLD = threshold # amplitude that triggers a pygame event self.CHUNK_SIZE = chunk_size # no. of samples to read from stream self.RATE = rate # sampling rate of the audio stream self.rec_duration = rec_duration # how long to record for self.rec_onset_time = None # time the present recording began self.rec_array = array('h') # holds the temporary audio data self.soundfile_path = 0 # number is converted to a string for filenames self.recording = False # is it recording the stream to disk self.sounds_to_save = {} # dict - holds filenames and sounds to save pa = pyaudio.PyAudio() # initialize pyaudio and open an audio stream self.sample_width = pa.get_sample_size(self.FORMAT) self.stream = pa.open(format=self.FORMAT, channels=1, rate=self.RATE, input=True, output=False, frames_per_buffer = self.CHUNK_SIZE) Flow.Controller.__init__(self, return_type = ve_types.get_type(None), eval_frequency = Flow.Controller.EVERY_FRAME, temporal_variables = Flow.Controller.TIME_SEC_SINCE_GO)
def get_type(value): warnings.warn( "VisionEgg.get_type() has been moved to " + "VisionEgg.ParameterTypes.get_type()", DeprecationWarning, stacklevel=2, ) return ve_types.get_type(value)
def __init__(self): VisionEgg.FlowControl.Controller.__init__(self, return_type=ve_types.get_type(None), eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME, temporal_variables=VisionEgg.FlowControl.Controller.TIME_SEC_SINCE_GO ) self.input = VisionEgg.DaqKeyboard.KeyboardInput()
def set(self, **kw): """Set a parameter with type-checked value This is the slow but safe way to set parameters. It is recommended to use this method in all but speed-critical portions of code. """ # Note that we don't overload __setattr__ because that would always slow # down assignment, not just when it was convenient. # # (We could make a checked_parameters attribute though.) for parameter_name in kw.keys(): setattr(self.parameters, parameter_name, kw[parameter_name]) require_type = self.get_specified_type(parameter_name) value = kw[parameter_name] this_type = ve_types.get_type(value) ve_types.assert_type(this_type, require_type) setattr(self.parameters, parameter_name, value)
def __init__(self, sweep): VisionEgg.FlowControl.Controller.__init__(self, return_type=ve_types.get_type(None), eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME, temporal_variables=VisionEgg.FlowControl.Controller.TIME_SEC_SINCE_GO ) self.input = MouseDirectionInput() self.sweep = sweep
def __init__(self): VisionEgg.FlowControl.Controller.__init__( self, return_type=ve_types.get_type(None), eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME, temporal_variables=VisionEgg.FlowControl.Controller. TIME_SEC_SINCE_GO) self.input = VisionEgg.DaqKeyboard.KeyboardInput()
def __init__(self, sweep): VisionEgg.FlowControl.Controller.__init__( self, return_type=ve_types.get_type(None), eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME, temporal_variables=VisionEgg.FlowControl.Controller. TIME_SEC_SINCE_GO) self.input = MouseDirectionInput() self.sweep = sweep
def __init__(self,server=None,**kw): """Called by PyroServer. Creates a PyroListenerController instance.""" if not isinstance(server,PyroServer): raise ValueError("Must specify a Pyro Server.") if 'eval_frequency' not in kw.keys(): kw['eval_frequency'] = VisionEgg.FlowControl.Controller.EVERY_FRAME if 'return_type' not in kw.keys(): kw['return_type'] = ve_types.get_type(None) VisionEgg.FlowControl.Controller.__init__(self,**kw) self.server=server
def __init__(self, server=None, **kw): """Called by PyroServer. Creates a PyroListenerController instance.""" if not isinstance(server, PyroServer): raise ValueError("Must specify a Pyro Server.") if 'eval_frequency' not in kw.keys(): kw['eval_frequency'] = VisionEgg.FlowControl.Controller.EVERY_FRAME if 'return_type' not in kw.keys(): kw['return_type'] = ve_types.get_type(None) VisionEgg.FlowControl.Controller.__init__(self, **kw) self.server = server
def __do_assignment_command(self,tcp_name,command,require_type): new_contained_controller = None match = SocketListenController._re_const.match(command) if match is not None: try: match_groups = self.__get_five_args(match.group(1)) kw_args = {} kw_args['during_go_value'] = match_groups[0] if match_groups[1] is not None: kw_args['between_go_value'] = match_groups[1] self.__process_common_args(kw_args,match_groups) kw_args.setdefault('return_type',require_type) new_contained_controller = VisionEgg.FlowControl.ConstantController(**kw_args) new_type = new_contained_controller.returns_type() ve_types.assert_type( new_type, require_type) except Exception, x: import traceback traceback.print_exc() self.socket.send("Error %s parsing const for %s: %s\n"%(x.__class__,tcp_name,x)) logger = logging.getLogger('VisionEgg.TCPController') logger.info("%s parsing const for %s: %s"%(x.__class__,tcp_name,x))
class Foo(ClassWithParameters): parameters_and_defaults = { 'position': ((320, 240), vtype.Sequence2(vtype.Real)), 'numCols': (15, vtype.UnsignedInteger), 'numRows': (15, vtype.UnsignedInteger), 'dotSize': (10, vtype.UnsignedInteger), 'scale': (50, vtype.Real), 'angle': (0, vtype.Real), 'gamma': (85, vtype.Real), 'aspectRatio': (1, vtype.Real), 'apertureSize': (300, vtype.Real), 'perturb': (False, vtype.Boolean), 'lighting': (False, vtype.Boolean), 'lightPos': ((100, 100, -100), vtype.Sequence3(vtype.Real)), 'foreground': ((0, 0, 0, 1), vtype.Sequence4(vtype.Real)), 'background': ((0.3, 0.3, 0.3, 1), vtype.Sequence4(vtype.Real)) } def __init__(self, **kw): ClassWithParameters.__init__(self, **kw) def __str__(self): return 'Foo'
def __do_assignment_command(self, tcp_name, command, require_type): new_contained_controller = None match = SocketListenController._re_const.match(command) if match is not None: try: match_groups = self.__get_five_args(match.group(1)) kw_args = {} kw_args['during_go_value'] = match_groups[0] if match_groups[1] is not None: kw_args['between_go_value'] = match_groups[1] self.__process_common_args(kw_args, match_groups) kw_args.setdefault('return_type', require_type) new_contained_controller = VisionEgg.FlowControl.ConstantController( **kw_args) new_type = new_contained_controller.returns_type() ve_types.assert_type(new_type, require_type) except Exception, x: import traceback traceback.print_exc() self.socket.send("Error %s parsing const for %s: %s\n" % (x.__class__, tcp_name, x)) logger = logging.getLogger('VisionEgg.TCPController') logger.info("%s parsing const for %s: %s" % (x.__class__, tcp_name, x))
def __init__(self, rec_duration = 2): pa = pyaudio.PyAudio() # initialize pyaudio and open an audio stream self.stream = pa.open(format = self.FORMAT, channels = 1, rate = self.RATE, input = True, output = False, frames_per_buffer = self.CHUNK_SIZE) # initialize a few important variables self.rec_duration = rec_duration # how long to record for self.rec_onset_time = None # time the present recording began self.rec_array = array('h') # holds the temporary audio data self.sample_width = pa.get_sample_size(self.FORMAT) self.soundfile_path = 0 # number is converted to a string for filenames Flow.Controller.__init__(self, return_type = ve_types.get_type(None), eval_frequency = Flow.Controller.EVERY_FRAME, temporal_variables = Flow.Controller.TIME_SEC_SINCE_GO)
class PygameText(VisionEgg.Textures.TextureStimulus): """Single line of text rendered using pygame/SDL true type fonts. Parameters ========== anchor -- specifies how position parameter is interpreted (String) Inherited from VisionEgg.Textures.TextureStimulus Default: lowerleft angle -- units: degrees, 0=right, 90=up (Real) Inherited from VisionEgg.Textures.TextureStimulus Default: 0.0 color -- texture environment color. alpha ignored (if given) for max_alpha parameter (AnyOf(Sequence3 of Real or Sequence4 of Real)) Inherited from VisionEgg.Textures.TextureStimulus Default: (1.0, 1.0, 1.0) depth_test -- perform depth test? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: False ignore_size_parameter -- (Boolean) Default: True mask -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>) Inherited from VisionEgg.Textures.TextureStimulus Default: (determined at runtime) max_alpha -- controls opacity. 1.0=copletely opaque, 0.0=completely transparent (Real) Inherited from VisionEgg.Textures.TextureStimulus Default: 1.0 on -- draw stimulus? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: True position -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Inherited from VisionEgg.Textures.TextureStimulus Default: (0.0, 0.0) size -- defaults to texture data size (units: eye coordinates) (Sequence2 of Real) Inherited from VisionEgg.Textures.TextureStimulus Default: (determined at runtime) text -- (AnyOf(String or Unicode)) Default: the string to display texture -- source of texture data (Instance of <class 'VisionEgg.Textures.Texture'>) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (determined at runtime) texture_mag_filter -- OpenGL filter enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: GL_LINEAR (9729) texture_min_filter -- OpenGL filter enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (GL enum determined at runtime) texture_wrap_s -- OpenGL texture wrap enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (GL enum determined at runtime) texture_wrap_t -- OpenGL texture wrap enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (GL enum determined at runtime) Constant Parameters =================== font_name -- short name (e.g. "arial") or full path to .ttf file (AnyOf(String or Unicode)) Default: (determined at runtime) font_size -- (UnsignedInteger) Default: 30 internal_format -- format with which OpenGL uses texture data (OpenGL data type enum) (Integer) Inherited from VisionEgg.Textures.TextureStimulus Default: GL_RGB (6407) mipmaps_enabled -- Are mipmaps enabled? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: True shrink_texture_ok -- Allow automatic shrinking of texture if too big? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: False """ parameters_and_defaults = { 'text': ( 'the string to display', #changing this redraws texture, may cause slowdown ve_types.AnyOf(ve_types.String, ve_types.Unicode)), 'ignore_size_parameter': ( True, # when true, draws text at 100% size ve_types.Boolean), } constant_parameters_and_defaults = { 'font_size': (30, ve_types.UnsignedInteger), 'font_name': ( None, # None = use default font ve_types.AnyOf(ve_types.String, ve_types.Unicode), 'short name (e.g. "arial") or full path to .ttf file'), } __slots__ = ( 'font', '_text', ) def __init__(self, **kw): if not pygame.font: raise RuntimeError("no pygame font module") if not pygame.font.get_init(): pygame.font.init() if not pygame.font.get_init(): raise RuntimeError("pygame doesn't init") # override some defaults if 'internal_format' not in kw.keys(): kw['internal_format'] = gl.GL_RGBA if 'mipmaps_enabled' not in kw.keys(): kw['mipmaps_enabled'] = 0 if 'texture_min_filter' not in kw.keys(): kw['texture_min_filter'] = gl.GL_LINEAR VisionEgg.Textures.TextureStimulus.__init__(self, **kw) cp = self.constant_parameters fontobject_args = (cp.font_name, cp.font_size) if fontobject_args not in _font_objects: # make global cache of font objects font_name, font_size = fontobject_args if not os.path.exists(font_name): if font_name is not None: new_font_name = pygame.font.match_font(font_name) if new_font_name is None: warnings.warn('no match for font "%s"' % font_name) font_name = new_font_name use_fontobject_args = (font_name, font_size) fontobject = pygame.font.Font(*use_fontobject_args) _font_objects[fontobject_args] = fontobject # get font object from global cache self.font = _font_objects[fontobject_args] self._render_text() def _render_text(self): p = self.parameters rendered_surf = self.font.render( p.text, 1, (255, 255, 255)) # pygame.Surface object # we could use put_new_image for speed (or put_sub_image for more) p.texture = VisionEgg.Textures.Texture(rendered_surf) self._reload_texture() self._text = p.text # cache string so we know when to re-render if p.ignore_size_parameter: p.size = p.texture.size def draw(self): p = self.parameters if p.texture != self._using_texture: # self._using_texture is from TextureStimulusBaseClass raise RuntimeError( "my texture has been modified, but it shouldn't be") if p.text != self._text: # new text self._render_text() if p.ignore_size_parameter: p.size = p.texture.size VisionEgg.Textures.TextureStimulus.draw(self) # call base class
def __init__(self, **kw): """Create self.parameters and set values.""" self.constant_parameters = Parameters() # create self.constant_parameters self.parameters = Parameters() # create self.parameters # Get a list of all classes this instance is derived from classes = recursive_base_class_finder(self.__class__) done_constant_parameters_and_defaults = [] done_parameters_and_defaults = [] done_kw = [] # Fill self.parameters with parameter names and set to default values for klass in classes: if klass == object: continue # base class of new style classes - ignore # Create self.parameters and set values to keyword argument if found, # otherwise to default value. # # If a class didn't override base class's parameters_and_defaults dictionary, don't deal with it twice if ( hasattr(klass, "parameters_and_defaults") and klass.parameters_and_defaults not in done_parameters_and_defaults ): for parameter_name in klass.parameters_and_defaults.keys(): # Make sure this parameter key/value pair doesn't exist already if hasattr(self.parameters, parameter_name): raise ValueError("More than one definition of parameter '%s'" % parameter_name) # Get default value and the type value, tipe = klass.parameters_and_defaults[parameter_name][:2] # Check tipe is valid if not ve_types.is_parameter_type_def(tipe): raise ValueError( "In definition of parameter '%s', %s is not a valid type declaration." % (parameter_name, tipe) ) # Was a non-default value passed for this parameter? if kw.has_key(parameter_name): value = kw[parameter_name] done_kw.append(parameter_name) # Allow None to pass as acceptable value -- lets __init__ set own defaults if value is not None: # Check anything other than None if not tipe.verify(value): print "parameter_name", parameter_name print "value", value print "type value", type(value) print "isinstance(value, numpy.ndarray)", isinstance(value, numpy.ndarray) print "tipe", tipe if not isinstance(value, numpy.ndarray): value_str = str(value) else: if Numeric.multiply.reduce(value.shape) < 10: value_str = str(value) # print array if it's smallish else: value_str = "(array data)" # don't pring if it's big raise TypeError( "Parameter '%s' value %s is type %s (not type %s) in %s" % (parameter_name, value_str, type(value), tipe, self) ) setattr(self.parameters, parameter_name, value) done_parameters_and_defaults.append(klass.parameters_and_defaults) # Same thing as above for self.constant_parameters: # # Create self.constant_parameters and set values to keyword argument if found, # otherwise to default value. # # If a class didn't override base class's parameters_and_defaults dictionary, don't deal with it twice if ( hasattr(klass, "constant_parameters_and_defaults") and klass.constant_parameters_and_defaults not in done_constant_parameters_and_defaults ): for parameter_name in klass.constant_parameters_and_defaults.keys(): # Make sure this parameter key/value pair doesn't exist already if hasattr(self.parameters, parameter_name): raise ValueError( "Definition of '%s' as variable parameter and constant parameter." % parameter_name ) if hasattr(self.constant_parameters, parameter_name): raise ValueError("More than one definition of constant parameter '%s'" % parameter_name) # Get default value and the type value, tipe = klass.constant_parameters_and_defaults[parameter_name][:2] if not ve_types.is_parameter_type_def(tipe): raise ValueError( "In definition of constant parameter '%s', %s is not a valid type declaration." % (parameter_name, tipe) ) # Was a non-default value passed for this parameter? if kw.has_key(parameter_name): value = kw[parameter_name] done_kw.append(parameter_name) # Allow None to pass as acceptable value -- lets __init__ set own default if type(value) != type(None): # Check anything other than None if not tipe.verify(value): if type(value) != Numeric.ArrayType: value_str = str(value) else: if Numeric.multiply.reduce(value.shape) < 10: value_str = str(value) # print array if it's smallish else: value_str = "(array data)" # don't pring if it's big raise TypeError( "Constant parameter '%s' value %s is type %s (not type %s) in %s" % (parameter_name, value_str, type(value), tipe, self) ) setattr(self.constant_parameters, parameter_name, value) done_constant_parameters_and_defaults.append(klass.constant_parameters_and_defaults) # Set self.parameters to the value in "kw" for kw_parameter_name in kw.keys(): if kw_parameter_name not in done_kw: raise ValueError( "parameter '%s' passed as keyword argument, but not specified by %s (or subclasses) as potential parameter" % (kw_parameter_name, self.__class__) )
class FilledCircle(VisionEgg.Core.Stimulus): """ A circular stimulus, typically used as a fixation point. (Note, this implementation almost certainly could be made faster using display lists.) Parameters ========== anchor -- how position parameter is used (String) Default: center anti_aliasing -- (Boolean) Default: True color -- color (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) num_triangles -- number of triangles used to draw circle (Integer) Default: 51 on -- draw? (Boolean) Default: True position -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) radius -- radius in eye coordinates (Real) Default: 2.0 """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'on': (True, ve_types.Boolean, 'draw?'), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'color'), 'anti_aliasing': (True, ve_types.Boolean), 'position': ( (320.0, 240.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'position in eye coordinates'), 'anchor': ('center', ve_types.String, 'how position parameter is used'), 'radius': (2.0, ve_types.Real, 'radius in eye coordinates'), 'num_triangles': (51, ve_types.Integer, 'number of triangles used to draw circle'), }) __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', ) def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self, **kw) self._gave_alpha_warning = 0 def draw(self): p = self.parameters # shorthand if p.on: # calculate center center = VisionEgg._get_center(p.position, p.anchor, (p.radius, p.radius)) gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glDisable(gl.GL_BLEND) if len(p.color) == 3: gl.glColor3f(*p.color) elif len(p.color) == 4: gl.glColor4f(*p.color) # Build filled circle from points # gl.glBegin(gl.GL_POINTS) # radius = int(math.ceil(p.radius)) # for i in range(-radius, radius): # for j in range(-radius, radius): # if(i * i + j * j < radius * radius): # gl.glVertex3f(p.position[0] + i, p.position[1] + j, 0.0) # gl.glEnd() # GL_POINTS # Build filled circle from triangles (this is typically faster # then the commented code above with the points) gl.glBegin(gl.GL_TRIANGLE_FAN) gl.glVertex3f(p.position[0], p.position[1], 0.0) angles = Numeric.arange(p.num_triangles) / float( p.num_triangles) * 2.0 * math.pi verts = Numeric.zeros((p.num_triangles, 2), Numeric.Float) verts[:, 0] = p.position[0] + p.radius * Numeric.cos(angles) verts[:, 1] = p.position[1] + p.radius * Numeric.sin(angles) for i in range(verts.shape[0]): gl.glVertex2fv(verts[i]) gl.glVertex2fv(verts[0]) gl.glEnd() # GL_TRIANGLE_FAN if p.anti_aliasing: if not self._gave_alpha_warning: if len(p.color) > 3 and p.color[3] != 1.0: logger = logging.getLogger('VisionEgg.Arrow') logger.warning("The parameter anti_aliasing is " "set to true in the Arrow " "stimulus class, but the color " "parameter specifies an alpha " "value other than 1.0. To " "acheive anti-aliasing, ensure " "that the alpha value for the " "color parameter is 1.0.") self._gave_alpha_warning = 1 # We've already drawn a filled polygon (aliased), now redraw # the outline of the polygon (with anti-aliasing). (Using # GL_POLYGON_SMOOTH results in artifactual lines where # triangles were joined to create quad, at least on some OpenGL # implementations.) # Calculate coverage value for each pixel of outline # and store as alpha gl.glEnable(gl.GL_LINE_SMOOTH) # Now specify how to use the alpha value gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) # Draw a second polygon in line mode, so the edges are anti-aliased gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) gl.glBegin(gl.GL_TRIANGLE_FAN) gl.glVertex3f(p.position[0], p.position[1], 0.0) angles = Numeric.arange(p.num_triangles) / float( p.num_triangles) * 2.0 * math.pi verts = Numeric.zeros((p.num_triangles, 2), Numeric.Float) verts[:, 0] = p.position[0] + p.radius * Numeric.cos(angles) verts[:, 1] = p.position[1] + p.radius * Numeric.sin(angles) for i in range(verts.shape[0]): gl.glVertex2fv(verts[i]) gl.glVertex2fv(verts[0]) gl.glEnd() # GL_TRIANGLE_FAN # Set the polygon mode back to fill mode gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL) gl.glDisable(gl.GL_LINE_SMOOTH)
class DotArea2D(VisionEgg.Core.Stimulus): """Random dots of constant velocity Every dot has the same velocity. Some fraction of the dots all move in the one direction, while the rest move in random directions. Dots wrap around edges. Each dot has a lifespan. This is just one example of the endless variations on drawing random dots. Parameters ========== anchor -- (String) Default: center anti_aliasing -- (Boolean) Default: True color -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) depth -- (Real) Default: (determined at runtime) dot_lifespan_sec -- (Real) Default: 5.0 dot_size -- (Real) Default: 4.0 on -- (Boolean) Default: True position -- (Sequence2 of Real) Default: (320.0, 240.0) signal_direction_deg -- (Real) Default: 90.0 signal_fraction -- (Real) Default: 0.5 size -- (Sequence2 of Real) Default: (300.0, 300.0) velocity_pixels_per_sec -- (Real) Default: 10.0 Constant Parameters =================== num_dots -- (UnsignedInteger) Default: 100 """ parameters_and_defaults = { 'on': (True, ve_types.Boolean), 'position': ( (320.0, 240.0), # in eye coordinates ve_types.Sequence2(ve_types.Real)), 'anchor': ('center', ve_types.String), 'size': ( (300.0, 300.0), # in eye coordinates ve_types.Sequence2(ve_types.Real)), 'signal_fraction': (0.5, ve_types.Real), 'signal_direction_deg': (90.0, ve_types.Real), 'velocity_pixels_per_sec': (10.0, ve_types.Real), 'dot_lifespan_sec': (5.0, ve_types.Real), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'dot_size': ( 4.0, # pixels ve_types.Real), 'anti_aliasing': (True, ve_types.Boolean), 'depth': ( None, # set for depth testing ve_types.Real), 'center': ( None, # DEPRECATED -- don't use ve_types.Sequence2(ve_types.Real), "", VisionEgg.ParameterDefinition.DEPRECATED), } constant_parameters_and_defaults = { 'num_dots': (100, ve_types.UnsignedInteger), } __slots__ = ( 'x_positions', 'y_positions', 'random_directions_radians', 'last_time_sec', 'start_times_sec', '_gave_alpha_warning', ) def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self, **kw) # store positions normalized between 0 and 1 so that re-sizing is ok num_dots = self.constant_parameters.num_dots # shorthand self.x_positions = RandomArray.uniform(0.0, 1.0, (num_dots, )) self.y_positions = RandomArray.uniform(0.0, 1.0, (num_dots, )) self.random_directions_radians = RandomArray.uniform( 0.0, 2 * math.pi, (num_dots, )) self.last_time_sec = VisionEgg.time_func() self.start_times_sec = None # setup variable, assign later self._gave_alpha_warning = 0 def draw(self): # XXX This method is not speed-optimized. I just wrote it to # get the job done. (Nonetheless, it seems faster than the C # version commented out above.) p = self.parameters # shorthand if p.center is not None: if not hasattr(VisionEgg.config, "_GAVE_CENTER_DEPRECATION"): logger = logging.getLogger('VisionEgg.Dots') logger.warning("Specifying DotArea2D by deprecated " "'center' parameter deprecated. Use " "'position' parameter instead. (Allows " "use of 'anchor' parameter to set to " "other values.)") VisionEgg.config._GAVE_CENTER_DEPRECATION = 1 p.anchor = 'center' p.position = p.center[0], p.center[ 1] # copy values (don't copy ref to tuple) if p.on: # calculate center center = VisionEgg._get_center(p.position, p.anchor, p.size) if p.anti_aliasing: if len(p.color) == 4 and not self._gave_alpha_warning: if p.color[3] != 1.0: logger = logging.getLogger('VisionEgg.Dots') logger.warning("The parameter anti_aliasing is " "set to true in the DotArea2D " "stimulus class, but the color " "parameter specifies an alpha " "value other than 1.0. To " "acheive the best anti-aliasing, " "ensure that the alpha value for " "the color parameter is 1.0.") self._gave_alpha_warning = 1 gl.glEnable(gl.GL_POINT_SMOOTH) # allow max_alpha value to control blending gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) else: gl.glDisable(gl.GL_BLEND) now_sec = VisionEgg.time_func() if self.start_times_sec is not None: # compute extinct dots and generate new positions replace_indices = Numeric.nonzero( Numeric.greater(now_sec - self.start_times_sec, p.dot_lifespan_sec)) Numeric.put(self.start_times_sec, replace_indices, now_sec) new_x_positions = RandomArray.uniform(0.0, 1.0, (len(replace_indices), )) Numeric.put(self.x_positions, replace_indices, new_x_positions) new_y_positions = RandomArray.uniform(0.0, 1.0, (len(replace_indices), )) Numeric.put(self.y_positions, replace_indices, new_y_positions) new_random_directions_radians = RandomArray.uniform( 0.0, 2 * math.pi, (len(replace_indices), )) Numeric.put(self.random_directions_radians, replace_indices, new_random_directions_radians) else: # initialize dot extinction values to random (uniform) distribution self.start_times_sec = RandomArray.uniform( now_sec - p.dot_lifespan_sec, now_sec, (self.constant_parameters.num_dots, )) signal_num_dots = int( round(p.signal_fraction * self.constant_parameters.num_dots)) time_delta_sec = now_sec - self.last_time_sec self.last_time_sec = now_sec # reset for next loop x_increment_normalized = math.cos( p.signal_direction_deg / 180.0 * math.pi ) * p.velocity_pixels_per_sec / p.size[0] * time_delta_sec y_increment_normalized = -math.sin( p.signal_direction_deg / 180.0 * math.pi ) * p.velocity_pixels_per_sec / p.size[1] * time_delta_sec self.x_positions[:signal_num_dots] += x_increment_normalized self.y_positions[:signal_num_dots] += y_increment_normalized num_random_dots = self.constant_parameters.num_dots - signal_num_dots random_x_increment_normalized = Numeric.cos( self.random_directions_radians[signal_num_dots:] ) * p.velocity_pixels_per_sec / p.size[0] * time_delta_sec random_y_increment_normalized = -Numeric.sin( self.random_directions_radians[signal_num_dots:] ) * p.velocity_pixels_per_sec / p.size[1] * time_delta_sec self.x_positions[signal_num_dots:] += random_x_increment_normalized self.y_positions[signal_num_dots:] += random_y_increment_normalized self.x_positions = Numeric.fmod(self.x_positions, 1.0) # wrap self.y_positions = Numeric.fmod(self.y_positions, 1.0) self.x_positions = Numeric.fmod(self.x_positions + 1, 1.0) # wrap again for values < 1 self.y_positions = Numeric.fmod(self.y_positions + 1, 1.0) xs = (self.x_positions - 0.5) * p.size[0] + center[0] ys = (self.y_positions - 0.5) * p.size[1] + center[1] if len(p.color) == 3: gl.glColor3f(*p.color) elif len(p.color) == 4: gl.glColor4f(*p.color) gl.glPointSize(p.dot_size) # Clear the modeview matrix gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() gl.glDisable(gl.GL_TEXTURE_2D) if p.depth is None: depth = 0.0 else: gl.glEnable(gl.GL_DEPTH_TEST) depth = p.depth zs = (depth, ) * len(xs) # make N tuple with repeat value of depth draw_dots(xs, ys, zs) if p.anti_aliasing: gl.glDisable(gl.GL_POINT_SMOOTH) # turn off gl.glPopMatrix()
class SinGrating2D(LuminanceGratingCommon): """Sine wave grating stimulus This is a general-purpose, realtime sine-wave luminace grating generator. To acheive an arbitrary orientation, this class rotates a textured quad. To draw a grating with sides that always remain horizontal and vertical, draw a large grating in a small viewport. (The viewport will clip anything beyond its edges.) Parameters ========== anchor -- specifies how position parameter is interpreted (String) Default: center bit_depth -- precision with which grating is calculated and sent to OpenGL (UnsignedInteger) Inherited from LuminanceGratingCommon Default: 8 color1 -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) color2 -- optional color with which to perform interpolation with color1 in RGB space (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (determined at runtime) contrast -- (Real) Default: 1.0 depth -- (Real) Default: (determined at runtime) ignore_time -- (Boolean) Default: False mask -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>) Default: (determined at runtime) max_alpha -- (Real) Default: 1.0 num_samples -- (UnsignedInteger) Default: 512 on -- draw stimulus? (Boolean) Default: True orientation -- (Real) Default: 0.0 pedestal -- (Real) Default: 0.5 phase_at_t0 -- (Real) Default: 0.0 position -- (units: eye coordinates) (Sequence2 of Real) Default: (320.0, 240.0) recalculate_phase_tolerance -- (Real) Default: (determined at runtime) size -- defines coordinate size of grating (in eye coordinates) (Sequence2 of Real) Default: (640.0, 480.0) spatial_freq -- frequency defined relative to coordinates defined in size parameter (units: cycles/eye_coord_unit) (Real) Default: 0.0078125 t0_time_sec_absolute -- (Real) Default: (determined at runtime) temporal_freq_hz -- (Real) Default: 5.0 """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'on':(True, ve_types.Boolean, "draw stimulus?"), 'mask':(None, # allows window onto otherwise (tilted) rectangular grating ve_types.Instance(VisionEgg.Textures.Mask2D), "optional masking function"), 'contrast':(1.0, ve_types.Real), 'pedestal':(0.5, ve_types.Real), 'position':((320.0,240.0), # in eye coordinates ve_types.Sequence2(ve_types.Real), "(units: eye coordinates)"), 'anchor':('center', ve_types.String, "specifies how position parameter is interpreted"), 'depth':(None, # if not None, turns on depth testing and allows for occlusion ve_types.Real), 'size':((640.0,480.0), ve_types.Sequence2(ve_types.Real), "defines coordinate size of grating (in eye coordinates)", ), 'spatial_freq':(1.0/128.0, # cycles/eye coord units ve_types.Real, "frequency defined relative to coordinates defined in size parameter (units: cycles/eye_coord_unit)", ), 'temporal_freq_hz':(5.0, # hz ve_types.Real), 't0_time_sec_absolute':(None, # Will be assigned during first call to draw() ve_types.Real), 'ignore_time':(False, # ignore temporal frequency variable - allow control purely with phase_at_t0 ve_types.Boolean), 'phase_at_t0':(0.0, # degrees [0.0-360.0] ve_types.Real), 'orientation':(0.0, # 0=right, 90=up ve_types.Real), 'num_samples':(512, # number of spatial samples, should be a power of 2 ve_types.UnsignedInteger), 'max_alpha':(1.0, # controls "opacity": 1.0 = completely opaque, 0.0 = completely transparent ve_types.Real), 'color1':((1.0, 1.0, 1.0), # alpha is ignored (if given) -- use max_alpha parameter ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'color2':(None, # perform interpolation with color1 in RGB space. ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "optional color with which to perform interpolation with color1 in RGB space"), 'recalculate_phase_tolerance':(None, # only recalculate texture when phase is changed by more than this amount, None for always recalculate. (Saves time.) ve_types.Real), }) __slots__ = ( '_texture_object_id', '_last_phase', ) def __init__(self,**kw): LuminanceGratingCommon.__init__(self,**kw) p = self.parameters # shorthand self._texture_object_id = gl.glGenTextures(1) if p.mask: gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB) gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id) # Do error-checking on texture to make sure it will load max_dim = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE) if p.num_samples > max_dim: raise NumSamplesTooLargeError("Grating num_samples too large for video system.\nOpenGL reports maximum size of %d"%(max_dim,)) self.calculate_bit_depth_dependencies() w = p.size[0] inc = w/float(p.num_samples) phase = 0.0 # this data won't get used - don't care about phase self._last_phase = phase floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1 texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype).tostring() # Because the MAX_TEXTURE_SIZE method is insensitive to the current # state of the video system, another check must be done using # "proxy textures". gl.glTexImage1D(gl.GL_PROXY_TEXTURE_1D, # target 0, # level self.gl_internal_format, # video RAM internal format p.num_samples, # width 0, # border self.format, # format of texel data self.gl_type, # type of texel data texel_data) # texel data (irrelevant for proxy) if gl.glGetTexLevelParameteriv(gl.GL_PROXY_TEXTURE_1D, # Need PyOpenGL >= 2.0 0, gl.GL_TEXTURE_WIDTH) == 0: raise NumSamplesTooLargeError("Grating num_samples is too wide for your video system!") # If we got here, it worked and we can load the texture for real. gl.glTexImage1D(gl.GL_TEXTURE_1D, # target 0, # level self.gl_internal_format, # video RAM internal format p.num_samples, # width 0, # border self.format, # format of texel data self.gl_type, # type of texel data texel_data) # texel data # Set texture object defaults gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_S,gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_T,gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR) if p.color2 is not None: if VisionEgg.Core.gl_renderer == 'ATi Rage 128 Pro OpenGL Engine' and VisionEgg.Core.gl_version == '1.1 ATI-1.2.22': logger = logging.getLogger('VisionEgg.Gratings') logger.warning("Your video card and driver have known " "bugs which prevent them from rendering " "color gratings properly.") def __del__(self): gl.glDeleteTextures( [self._texture_object_id] ) def draw(self): p = self.parameters # shorthand if p.on: # calculate center center = VisionEgg._get_center(p.position,p.anchor,p.size) if p.mask: gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB) gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id) gl.glEnable(gl.GL_TEXTURE_1D) gl.glDisable(gl.GL_TEXTURE_2D) if p.bit_depth != self.cached_bit_depth: self.calculate_bit_depth_dependencies() # Clear the modeview matrix gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() # Rotate about the center of the texture gl.glTranslate(center[0], center[1], 0) gl.glRotate(p.orientation,0,0,1) if p.depth is None: gl.glDisable(gl.GL_DEPTH_TEST) depth = 0.0 else: gl.glEnable(gl.GL_DEPTH_TEST) depth = p.depth # allow max_alpha value to control blending gl.glEnable( gl.GL_BLEND ) gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA ) if p.color2: gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_BLEND) gl.glTexEnvfv(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_COLOR, p.color2) ## alpha is ignored because the texture base internal format is luminance else: gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE) if p.t0_time_sec_absolute is None and not p.ignore_time: p.t0_time_sec_absolute = VisionEgg.time_func() w = p.size[0] inc = w/float(p.num_samples) if p.ignore_time: phase = p.phase_at_t0 else: t_var = VisionEgg.time_func() - p.t0_time_sec_absolute phase = t_var*p.temporal_freq_hz*-360.0 + p.phase_at_t0 if p.recalculate_phase_tolerance is None or abs(self._last_phase - phase) > p.recalculate_phase_tolerance: self._last_phase = phase # we're re-drawing the phase at this angle floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1 texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype) # PyOpenGL 2.0.1.09 has a bug, so use our own wrapper _vegl.veglTexSubImage1D(gl.GL_TEXTURE_1D, # target 0, # level 0, # x offset p.num_samples, # width self.format, # format of new texel data self.gl_type, # type of new texel data texel_data) # new texel data if 0: compare_array = numpy.empty(texel_data.shape,dtype=texel_data.dtype) pixels = _vegl.veglGetTexImage(gl.GL_TEXTURE_1D, # target 0, # level self.format, # format self.gl_type, # type compare_array) assert numpy.allclose( compare_array, texel_data ) h_w = p.size[0]/2.0 h_h = p.size[1]/2.0 l = -h_w r = h_w b = -h_h t = h_h # in the case of only color1, # the texel data multiplies color1 to produce a color # with color2, # the texel data linearly interpolates between color1 and color2 gl.glColor4f(p.color1[0],p.color1[1],p.color1[2],p.max_alpha) if p.mask: p.mask.draw_masked_quad(0.0,1.0,0.0,1.0, # l,r,b,t for texture coordinates l,r,b,t, # l,r,b,t in eye coordinates depth ) # also in eye coordinates else: # draw unmasked quad gl.glBegin(gl.GL_QUADS) gl.glTexCoord2f(0.0,0.0) gl.glVertex3f(l,b,depth) gl.glTexCoord2f(1.0,0.0) gl.glVertex3f(r,b,depth) gl.glTexCoord2f(1.0,1.0) gl.glVertex3f(r,t,depth) gl.glTexCoord2f(0.0,1.0) gl.glVertex3f(l,t,depth) gl.glEnd() # GL_QUADS gl.glDisable(gl.GL_TEXTURE_1D) gl.glPopMatrix()
kw_args['during_go_eval_string'] = string.replace(match_groups[0],r"\n","\n") if match_groups[1] is not None: kw_args['between_go_eval_string'] = string.replace(match_groups[1],r"\n","\n") self.__process_common_args(kw_args,match_groups) kw_args.setdefault('return_type',require_type) new_contained_controller = VisionEgg.FlowControl.EvalStringController(**kw_args) if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_DURING_GO): logger = logging.getLogger('VisionEgg.TCPController') logger.debug('Executing "%s" as safety check.'%(kw_args['during_go_eval_string'],)) new_contained_controller._test_self(1) if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_BETWEEN_GO): logger = logging.getLogger('VisionEgg.TCPController') logger.debug('Executing "%s" as safety check.'%(kw_args['between_go_eval_string'],)) new_contained_controller._test_self(0) new_type = new_contained_controller.returns_type() ve_types.assert_type( new_type, require_type) except Exception, x: new_contained_controller = None self.socket.send("Error %s parsing eval_str for %s: %s\n"%(x.__class__,tcp_name,x)) logger = logging.getLogger('VisionEgg.TCPController') logger.info("%s parsing eval_str for %s: %s"%(x.__class__,tcp_name,x)) else: match = SocketListenController._re_exec_str.match(command) if match is not None: try: kw_args = {} match_groups = match.groups() if match_groups[0] == '*': kw_args['restricted_namespace'] = 0 else: kw_args['restricted_namespace'] = 1
class WrappedText(VisionEgg.Core.Stimulus): """Multi-line text stimulus. No fancy formatting, but line breaks ('\\n') are preserved, and text is wrapped to fit within the stimulus boundaries.""" parameters_and_defaults = { 'on': (True, ve_types.Boolean), 'position': ((0.0, 0.0), ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'size': (None, ve_types.Sequence2(ve_types.Real), """Defaults to the size of the screen."""), 'text': ('hello', ve_types.AnyOf(ve_types.String, ve_types.Unicode)), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))) } constant_parameters_and_defaults = { 'font_name': (None, ve_types.AnyOf(ve_types.String, ve_types.Unicode), "Name of font to use. If None, use the default font"), 'font_size': (30, ve_types.UnsignedInteger) } def __init__(self, **kw): """Initialize the object, perform the initial line-splitting""" VisionEgg.Core.Stimulus.__init__(self, **kw) if self.parameters.size is None: self.parameters.size = (VisionEgg.config.VISIONEGG_SCREEN_W, VisionEgg.config.VISIONEGG_SCREEN_H) self._splitText() def _splitText(self): """Split a single string into multiple lines of text, storing each as a VisionEgg.Text.Text instance""" p = self.parameters cp = self.constant_parameters self._text = p.text textAreaWidth = None maxLineLength = len(self._text) minLineLength = 1 lineLength = maxLineLength while ((textAreaWidth > p.size[0]) or ((maxLineLength - minLineLength) > 1)) and (maxLineLength > 1): nextPosition = p.position self._textLines = [] try: textLineList = [] for text in self._text.split("\n"): if text == "": textLineList.append("") else: textLineList.extend(textwrap.wrap(text, lineLength)) textAreaWidth = None for textLine in textLineList: if textLine != "": line = VisionEgg.Text.Text(text=textLine, position=nextPosition, anchor="upperleft", ignore_size_parameter=True, color=p.color, font_name=cp.font_name, font_size=cp.font_size) textAreaWidth = max(textAreaWidth, line.parameters.size[0]) self._textLines.append(line) nextPosition = (nextPosition[0], nextPosition[1] - line.parameters.size[1]) # Stop adding lines if the text area's height has been reached if (p.position[1] - nextPosition[1]) > p.size[1]: break except VisionEgg.Textures.TextureTooLargeError: textAreaWidth = p.size[0] + 1 if textAreaWidth > p.size[0]: maxLineLength = lineLength else: minLineLength = lineLength lineLength = (maxLineLength + minLineLength) / 2 def draw(self): """Draw the lines of text on the screen""" p = self.parameters if p.on: if p.text != self._text: self._splitText() for line in self._textLines: line.parameters.color = p.color line.draw()
def assert_type(*args): warnings.warn("VisionEgg.assert_type() has been moved to "+\ "VisionEgg.ParameterTypes.assert_type()", DeprecationWarning, stacklevel=2) return ve_types.assert_type(*args)
class Triangle(DisplayListStimulus): """ An equilateral triangle. Parameters ========== anti_aliasing -- (Boolean) Default: True color -- color (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) on -- draw? (Boolean) Default: True position -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) side -- side length """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'anchor': ('center', ve_types.String, 'how position parameter is used'), 'on': (True, ve_types.Boolean, 'draw?'), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'color'), 'color_edge': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'color for the edge'), 'anti_aliasing': (True, ve_types.Boolean), 'position': ( (320.0, 240.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'position in eye coordinates'), 'side': (10., ve_types.Real, 'side length'), 'width': (1., ve_types.Real, 'line width'), }) __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', ) def __init__(self, **kw): DisplayListStimulus.__init__(self, **kw) self._gave_alpha_warning = 0 def _draw(self): p = self.parameters side = p.side height = side * numpy.sqrt(3) / 2. center = VisionEgg._get_center(p.position, p.anchor, (side, height)) position = numpy.array(center) hh = height / 2 ll = position - (hh, hh) lr = position - (-hh, hh) u = position + (0., hh) gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glDisable(gl.GL_BLEND) gl.glColor(p.color) gl.glBegin(gl.GL_TRIANGLES) self._draw_vertices(ll, lr, u) gl.glEnd() gl.glColor(p.color_edge) if p.anti_aliasing: gl.glEnable(gl.GL_LINE_SMOOTH) gl.glLineWidth(p.width) gl.glBegin(gl.GL_LINE_STRIP) self._draw_vertices(ll, lr, u, ll) gl.glEnd() gl.glDisable(gl.GL_LINE_SMOOTH)
class CircleSector(DisplayListStimulus): """ A sector of a circular stimulus, optionally filled. Parameters ========== anchor -- how position parameter is used (String) Default: center anti_aliasing -- (Boolean) Default: True color -- color (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) num_triangles -- number of triangles used to draw circle (Integer) Default: 51 on -- draw? (Boolean) Default: True position -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) radius -- radius in eye coordinates (Real) Default: 2.0 """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'on': (True, ve_types.Boolean, 'draw?'), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'color'), 'color_edge': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'color for the circle edge'), 'anti_aliasing': (True, ve_types.Boolean), 'position': ( (320.0, 240.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'position in eye coordinates'), 'anchor': ('center', ve_types.String, 'how position parameter is used'), 'radius': (2.0, ve_types.Real, 'radius in eye coordinates'), 'num_triangles': (51, ve_types.Integer, 'number of triangles used to draw circle'), 'start': (0., ve_types.Real, 'start angle'), 'end': (360., ve_types.Real, 'end angle'), 'disk': (True, ve_types.Boolean, 'draw the interior?'), 'circle': (True, ve_types.Boolean, 'draw the edge?'), 'circle_width': (1., ve_types.Real, 'line width of the circle edge'), }) __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', ) def __init__(self, **kw): DisplayListStimulus.__init__(self, **kw) self._gave_alpha_warning = 0 def _draw(self): p = self.parameters center = VisionEgg._get_center(p.position, p.anchor, (p.radius, p.radius)) gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glDisable(gl.GL_BLEND) gl.glColor(p.color) start, end = p.start, p.end if end < start: start -= 360. start, end = map(numpy.deg2rad, (start, end)) frac = (end - start) / (2 * numpy.pi) num_triangles = float(p.num_triangles) * frac angles = numpy.linspace(start, end, num_triangles) verts = numpy.zeros((num_triangles, 2)) verts[:, 0] = center[0] + p.radius * numpy.cos(angles) verts[:, 1] = center[1] + p.radius * numpy.sin(angles) if p.disk: gl.glBegin(gl.GL_TRIANGLE_FAN) gl.glVertex(center) self._draw_vertices(*verts) gl.glEnd() if p.anti_aliasing: gl.glEnable(gl.GL_LINE_SMOOTH) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) # Draw a second polygon in line mode, so the edges are anti-aliased gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) gl.glBegin(gl.GL_TRIANGLE_FAN) gl.glVertex(center) self._draw_vertices(*verts) gl.glEnd() gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL) gl.glDisable(gl.GL_LINE_SMOOTH) if p.circle: if p.anti_aliasing: gl.glEnable(gl.GL_LINE_SMOOTH) gl.glColor(p.color_edge) gl.glLineWidth(p.circle_width) gl.glBegin(gl.GL_LINES) for i in range(verts.shape[0] - 1): self._draw_vertices(verts[i], verts[i + 1]) gl.glEnd() gl.glDisable(gl.GL_LINE_SMOOTH)
class Line(DisplayListStimulus): """ A line. Parameters ========== anti_aliasing -- (Boolean) Default: True color -- color (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) on -- draw? (Boolean) Default: True position -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) end -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (420.0, 240.0) """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'on': (True, ve_types.Boolean, 'draw?'), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'color'), 'anti_aliasing': (True, ve_types.Boolean), 'position': ( (320.0, 240.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'position in eye coordinates'), 'end': ( (420.0, 240.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'end point in eye coordinates'), 'width': (1., ve_types.Real, 'line width'), }) __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', ) def __init__(self, **kw): DisplayListStimulus.__init__(self, **kw) self._gave_alpha_warning = 0 def _draw(self): p = self.parameters gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glDisable(gl.GL_BLEND) gl.glColor(p.color) if p.anti_aliasing: gl.glEnable(gl.GL_LINE_SMOOTH) gl.glLineWidth(p.width) gl.glBegin(gl.GL_LINES) gl.glVertex(p.position) gl.glVertex(p.end) gl.glEnd() gl.glDisable(gl.GL_LINE_SMOOTH)
def __init__(self, **kw): """Create self.parameters and set values.""" self.constant_parameters = Parameters( ) # create self.constant_parameters self.parameters = Parameters() # create self.parameters # Get a list of all classes this instance is derived from classes = recursive_base_class_finder(self.__class__) done_constant_parameters_and_defaults = [] done_parameters_and_defaults = [] done_kw = [] # Fill self.parameters with parameter names and set to default values for klass in classes: if klass == object: continue # base class of new style classes - ignore # Create self.parameters and set values to keyword argument if found, # otherwise to default value. # # If a class didn't override base class's parameters_and_defaults dictionary, don't deal with it twice if hasattr( klass, 'parameters_and_defaults' ) and klass.parameters_and_defaults not in done_parameters_and_defaults: for parameter_name in klass.parameters_and_defaults.keys(): # Make sure this parameter key/value pair doesn't exist already if hasattr(self.parameters, parameter_name): raise ValueError( "More than one definition of parameter '%s'" % parameter_name) # Get default value and the type value, tipe = klass.parameters_and_defaults[ parameter_name][:2] # Check tipe is valid if not ve_types.is_parameter_type_def(tipe): raise ValueError( "In definition of parameter '%s', %s is not a valid type declaration." % (parameter_name, tipe)) # Was a non-default value passed for this parameter? if kw.has_key(parameter_name): value = kw[parameter_name] done_kw.append(parameter_name) # Allow None to pass as acceptable value -- lets __init__ set own defaults if value is not None: # Check anything other than None if not tipe.verify(value): print 'parameter_name', parameter_name print 'value', value print 'type value', type(value) print 'isinstance(value, numpy.ndarray)', isinstance( value, numpy.ndarray) print 'tipe', tipe if not isinstance(value, numpy.ndarray): value_str = str(value) else: if Numeric.multiply.reduce(value.shape) < 10: value_str = str( value) # print array if it's smallish else: value_str = "(array data)" # don't pring if it's big raise TypeError( "Parameter '%s' value %s is type %s (not type %s) in %s" % (parameter_name, value_str, type(value), tipe, self)) setattr(self.parameters, parameter_name, value) done_parameters_and_defaults.append( klass.parameters_and_defaults) # Same thing as above for self.constant_parameters: # # Create self.constant_parameters and set values to keyword argument if found, # otherwise to default value. # # If a class didn't override base class's parameters_and_defaults dictionary, don't deal with it twice if hasattr( klass, 'constant_parameters_and_defaults' ) and klass.constant_parameters_and_defaults not in done_constant_parameters_and_defaults: for parameter_name in klass.constant_parameters_and_defaults.keys( ): # Make sure this parameter key/value pair doesn't exist already if hasattr(self.parameters, parameter_name): raise ValueError( "Definition of '%s' as variable parameter and constant parameter." % parameter_name) if hasattr(self.constant_parameters, parameter_name): raise ValueError( "More than one definition of constant parameter '%s'" % parameter_name) # Get default value and the type value, tipe = klass.constant_parameters_and_defaults[ parameter_name][:2] if not ve_types.is_parameter_type_def(tipe): raise ValueError( "In definition of constant parameter '%s', %s is not a valid type declaration." % (parameter_name, tipe)) # Was a non-default value passed for this parameter? if kw.has_key(parameter_name): value = kw[parameter_name] done_kw.append(parameter_name) # Allow None to pass as acceptable value -- lets __init__ set own default if type(value) != type(None): # Check anything other than None if not tipe.verify(value): if type(value) != Numeric.ArrayType: value_str = str(value) else: if Numeric.multiply.reduce(value.shape) < 10: value_str = str( value) # print array if it's smallish else: value_str = "(array data)" # don't pring if it's big raise TypeError( "Constant parameter '%s' value %s is type %s (not type %s) in %s" % (parameter_name, value_str, type(value), tipe, self)) setattr(self.constant_parameters, parameter_name, value) done_constant_parameters_and_defaults.append( klass.constant_parameters_and_defaults) # Set self.parameters to the value in "kw" for kw_parameter_name in kw.keys(): if kw_parameter_name not in done_kw: raise ValueError( "parameter '%s' passed as keyword argument, but not specified by %s (or subclasses) as potential parameter" % (kw_parameter_name, self.__class__))
class CheckBoard(Stimulus): """A checkboard stimulus, typically used as a aux stimulus for whitenoise. Parameters ========== anchor -- how position parameter is used (String) Default: center color -- color (256 jet colormap ) Default: 0(gray) on -- draw? (Boolean) Default: True position -- position in eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) size -- size in eye coordinates (Sequence2 of Real) Default: (4.0, 4.0) """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'on': (True, ve_types.Boolean, 'draw?'), 'bgcolor': ((0.5, 0.5, 0.5), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'backgroud color'), 'linecolor': ((0.5, 0.0, 0.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'grid line color'), 'cellcolor': ('gbr', ve_types.String, 'color map for the range [0.0,1.0]'), 'colorindex': (None, ve_types.Sequence(ve_types.Integer), 'color index in jet colormap'), 'drawline': (False, ve_types.Boolean, 'draw line?'), 'orientation': (0.0, ve_types.Real), 'position': ( (320.0, 240.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), 'position in eye coordinates'), 'anchor': ('center', ve_types.String, 'how position parameter is used'), 'size': ( (100.0, 100.0), # horiz and vertical size ve_types.Sequence2(ve_types.Real), 'size in eye coordinates'), 'grid': ( (8, 8), # grid dimension of the checkboard ve_types.Sequence2(ve_types.Integer), 'grid dimension'), 'center': ( None, # DEPRECATED -- don't use ve_types.Sequence2(ve_types.Real), 'position in eye coordinates', VisionEgg.ParameterDefinition.DEPRECATED), }) def __init__(self, **kw): Stimulus.__init__(self, **kw) self.parameters.colorindex = np.zeros(self.parameters.grid) self.parameters.colorindex.fill(0.5) def draw(self): p = self.parameters # shorthand if p.center is not None: p.anchor = 'center' p.position = p.center[0], p.center[ 1] # copy values (don't copy ref to tuple) if p.on: # calculate center center = VisionEgg._get_center(p.position, p.anchor, p.size) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() gl.glTranslate(center[0], center[1], 0.0) gl.glRotate(p.orientation, 0.0, 0.0, 1.0) if len(p.bgcolor) == 3: gl.glColor3f(*p.bgcolor) elif len(p.bgcolor) == 4: gl.glColor4f(*p.bgcolor) gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) w = p.size[0] / 2.0 #grid half-size h = p.size[1] / 2.0 m = p.size[0] / p.grid[0] #cell size n = p.size[1] / p.grid[1] i = range(p.grid[0]) #grid index j = range(p.grid[1]) #draw colorful cell # vertices_list = [((-w+column*m, h-(row+1)*n, 0.0),(-w+column*m, h-row*n, 0.0),\ # (-w+(column+1)*m, h-row*n, 0.0),(-w+(column+1)*m, h-row*n, 0.0))\ # for column in j for row in i] vertices_list = [((-w+column*m, h-(row+1)*n, 0.0),(-w+column*m, h-row*n, 0.0),\ (-w+(column+1)*m, h-row*n, 0.0),(-w+(column+1)*m, h-(row+1)*n, 0.0))\ for column in j for row in i] colors_list = [ colormap(p.colorindex[row, column], color=p.cellcolor) * 4 for column in j for row in i ] #flattening the vertices and colors vertices_flat = [ num for tuple in vertices_list for vertex in tuple for num in vertex ] colors_flat = [num for tuple in colors_list for num in tuple] vertices = np.array(vertices_flat) colors = np.array(colors_flat) vertices.shape = (-1, 3) colors.shape = (-1, 3) gl.glVertexPointerd(vertices) gl.glColorPointerd(colors) gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glEnableClientState(gl.GL_COLOR_ARRAY) gl.glDisable(gl.GL_LIGHTING) gl.glDrawArrays(gl.GL_QUADS, 0, p.grid[0] * p.grid[1] * 4) #draw grid lines if p.drawline: if len(p.linecolor) == 3: gl.glColor3f(*p.linecolor) elif len(p.linecolor) == 4: gl.glColor4f(*p.linecolor) row_list = [((-w, h - i * n), (w, h - i * n)) for i in range(p.grid[1] + 1)] col_list = [((-w + i * m, h), (-w + i * m, -h)) for i in range(p.grid[0] + 1)] ver_row_flat = [ num for tuple in row_list for vertex in tuple for num in vertex ] ver_col_flat = [ num for tuple in col_list for vertex in tuple for num in vertex ] vertices_row = np.array(ver_row_flat) vertices_col = np.array(ver_col_flat) vertices_row.shape = (-1, 2) vertices_col.shape = (-1, 2) gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glDisableClientState(gl.GL_COLOR_ARRAY) gl.glVertexPointerd(vertices_row) gl.glDrawArrays(gl.GL_LINES, 0, (p.grid[1] + 1) * 2) gl.glVertexPointerd(vertices_col) gl.glDrawArrays(gl.GL_LINES, 0, (p.grid[0] + 1) * 2) # gl.glBegin(gl.GL_LINES); # for i in range(p.grid[1] + 1): # gl.glVertex2f(-w, h - i * n) # gl.glVertex2f(w, h - i * n) # for i in range(p.grid[0] + 1): # gl.glVertex2f(-w + i * m, h) # gl.glVertex2f(-w + i * m, -h) # gl.glEnd(); gl.glPopMatrix() #save checkboard to file def save(self): import time, os (year, month, day, hour24, min, sec) = time.localtime(time.time())[:6] trial_time_str = "%04d%02d%02d_%02d%02d%02d" % (year, month, day, hour24, min, sec) dummy_filename = os.path.abspath(os.curdir)+ os.path.sep + 'screenshoot' + \ os.path.sep + 'checkboard' + trial_time_str + '.jpg'
class PangoText(VisionEgg.Textures.TextureStimulus): """text rendered using pango. Parameters ========== anchor -- specifies how position parameter is interpreted (String) Inherited from VisionEgg.Textures.TextureStimulus Default: lowerleft angle -- units: degrees, 0=right, 90=up (Real) Inherited from VisionEgg.Textures.TextureStimulus Default: 0.0 color -- texture environment color. alpha ignored (if given) for max_alpha parameter (AnyOf(Sequence3 of Real or Sequence4 of Real)) Inherited from VisionEgg.Textures.TextureStimulus Default: (1.0, 1.0, 1.0) depth_test -- perform depth test? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: False ignore_size_parameter -- (Boolean) Default: True mask -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>) Inherited from VisionEgg.Textures.TextureStimulus Default: (determined at runtime) max_alpha -- controls opacity. 1.0=copletely opaque, 0.0=completely transparent (Real) Inherited from VisionEgg.Textures.TextureStimulus Default: 1.0 on -- draw stimulus? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: True position -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Inherited from VisionEgg.Textures.TextureStimulus Default: (0.0, 0.0) size -- defaults to texture data size (units: eye coordinates) (Sequence2 of Real) Inherited from VisionEgg.Textures.TextureStimulus Default: (determined at runtime) text -- (AnyOf(String or Unicode)) Default: the string to display texture -- source of texture data (Instance of <class 'VisionEgg.Textures.Texture'>) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (determined at runtime) texture_mag_filter -- OpenGL filter enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: GL_LINEAR (9729) texture_min_filter -- OpenGL filter enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (GL enum determined at runtime) texture_wrap_s -- OpenGL texture wrap enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (GL enum determined at runtime) texture_wrap_t -- OpenGL texture wrap enum (Integer) Inherited from VisionEgg.Textures.TextureStimulusBaseClass Default: (GL enum determined at runtime) Constant Parameters =================== font_descr_string -- font description passed to Pango.FontDescription (AnyOf(String or Unicode)) Default: normal 20 internal_format -- format with which OpenGL uses texture data (OpenGL data type enum) (Integer) Inherited from VisionEgg.Textures.TextureStimulus Default: GL_RGB (6407) mipmaps_enabled -- Are mipmaps enabled? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: True shrink_texture_ok -- Allow automatic shrinking of texture if too big? (Boolean) Inherited from VisionEgg.Textures.TextureStimulus Default: False """ parameters_and_defaults = { 'text': ( 'the string to display', #changing this redraws texture, may cause slowdown ve_types.AnyOf(ve_types.String, ve_types.Unicode)), 'ignore_size_parameter': ( True, # when true, draws text at 100% size ve_types.Boolean), } constant_parameters_and_defaults = { 'font_descr_string': ( 'normal 20', ve_types.AnyOf(ve_types.String, ve_types.Unicode), 'font description passed to Pango.FontDescription', ), } __slots__ = ('_text', ) def __init__(self, **kw): # override some defaults if 'internal_format' not in kw.keys(): kw['internal_format'] = gl.GL_RGBA if 'mipmaps_enabled' not in kw.keys(): kw['mipmaps_enabled'] = 0 if 'texture_min_filter' not in kw.keys(): kw['texture_min_filter'] = gl.GL_LINEAR VisionEgg.Textures.TextureStimulus.__init__(self, **kw) self._render_text() def _render_text(self): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0) cr = pangocairo.CairoContext(cairo.Context(surface)) layout = cr.create_layout() descr = pango.FontDescription( self.constant_parameters.font_descr_string) layout.set_font_description(descr) p = self.parameters layout.set_text(p.text) ink, rect = layout.get_pixel_extents() w, h = rect[2], rect[3] surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) cr = pangocairo.CairoContext(cairo.Context(surface)) cr.set_source_rgba(0., 0., 0., 0.) cr.paint() cr.move_to(-rect[0], -rect[1]) cr.set_source_rgba(1., 1., 1., 1.) cr.show_layout(layout) buf = surface.get_data() rendered_surf = numpy.frombuffer(buf, numpy.uint8) rendered_surf.shape = (h, w, 4) rendered_surf = rendered_surf[:: -1] # flip UD (should do this in cairo) # we could use put_new_image for speed (or put_sub_image for more) p.texture = VisionEgg.Textures.Texture(rendered_surf) self._reload_texture() self._text = p.text # cache string so we know when to re-render if p.ignore_size_parameter: p.size = p.texture.size def draw(self): p = self.parameters if p.texture != self._using_texture: # self._using_texture is from TextureStimulusBaseClass raise RuntimeError( "my texture has been modified, but it shouldn't be") if p.text != self._text: # new text self._render_text() if p.ignore_size_parameter: p.size = p.texture.size VisionEgg.Textures.TextureStimulus.draw(self) # call base class
class Rectangle3D(VisionEgg.Core.Stimulus): """Solid color rectangle positioned explicitly by four vertices. Parameters ========== color -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0, 1.0) on -- (Boolean) Default: True vertex1 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (-10.0, 0.0, -10.0) vertex2 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (-10.0, 0.0, 10.0) vertex3 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (10.0, 0.0, 10.0) vertex4 -- units: eye coordinates (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (10.0, 0.0, -10.0) """ parameters_and_defaults = { 'on': (True, ve_types.Boolean), 'blending_enabled': (False, ve_types.Boolean), # different default than TextureStimulus3D due to not break backwards compatibility 'depth_test': (False, ve_types.Boolean), 'color': ((1.0, 1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'vertex1': ((-10.0, 0.0, -10.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "units: eye coordinates"), 'vertex2': ((-10.0, 0.0, 10.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "units: eye coordinates"), 'vertex3': ((10.0, 0.0, 10.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "units: eye coordinates"), 'vertex4': ((10.0, 0.0, -10.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "units: eye coordinates"), } def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self, **kw) def draw(self): p = self.parameters # shorthand if p.on: if len(p.color) == 3: gl.glColor3f(*p.color) elif len(p.color) == 4: gl.glColor4f(*p.color) gl.glDisable(gl.GL_TEXTURE_2D) if p.depth_test: gl.glEnable(gl.GL_DEPTH_TEST) else: gl.glDisable(gl.GL_DEPTH_TEST) if p.blending_enabled: gl.glEnable(gl.GL_BLEND) else: gl.glDisable(gl.GL_BLEND) gl.glBegin(gl.GL_QUADS) gl.glVertex(*p.vertex1) gl.glVertex(*p.vertex2) gl.glVertex(*p.vertex3) gl.glVertex(*p.vertex4) gl.glEnd() # GL_QUADS
new_contained_controller = VisionEgg.FlowControl.EvalStringController( **kw_args) if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_DURING_GO): logger = logging.getLogger('VisionEgg.TCPController') logger.debug('Executing "%s" as safety check.' % (kw_args['during_go_eval_string'], )) new_contained_controller._test_self(1) if not (new_contained_controller.eval_frequency & VisionEgg.FlowControl.Controller.NOT_BETWEEN_GO): logger = logging.getLogger('VisionEgg.TCPController') logger.debug('Executing "%s" as safety check.' % (kw_args['between_go_eval_string'], )) new_contained_controller._test_self(0) new_type = new_contained_controller.returns_type() ve_types.assert_type(new_type, require_type) except Exception, x: new_contained_controller = None self.socket.send("Error %s parsing eval_str for %s: %s\n" % (x.__class__, tcp_name, x)) logger = logging.getLogger('VisionEgg.TCPController') logger.info("%s parsing eval_str for %s: %s" % (x.__class__, tcp_name, x)) else: match = SocketListenController._re_exec_str.match(command) if match is not None: try: kw_args = {} match_groups = match.groups() if match_groups[0] == '*': kw_args['restricted_namespace'] = 0
class Arrow(VisionEgg.Core.Stimulus): """Arrow stimulus. Parameters ========== anchor -- (String) Default: center anti_aliasing -- (Boolean) Default: True color -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) on -- (Boolean) Default: True orientation -- (Real) Default: 0.0 position -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) size -- (Sequence2 of Real) Default: (64.0, 16.0) """ parameters_and_defaults = { 'on': (True, ve_types.Boolean), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'anti_aliasing': (True, ve_types.Boolean), 'orientation': ( 0.0, # 0.0 degrees = right, 90.0 degrees = up ve_types.Real), 'position': ( (320.0, 240.0), # In eye coordinates ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "units: eye coordinates"), 'anchor': ('center', ve_types.String), 'size': ( (64.0, 16.0), # In eye coordinates ve_types.Sequence2(ve_types.Real)), } __slots__ = VisionEgg.Core.Stimulus.__slots__ + ('_gave_alpha_warning', ) def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self, **kw) self._gave_alpha_warning = 0 def draw(self): p = self.parameters # Shorthand if p.on: # Calculate center center = VisionEgg._get_center(p.position, p.anchor, p.size) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() gl.glTranslate(center[0], center[1], 0.0) gl.glRotate(-p.orientation, 0.0, 0.0, 1.0) if len(p.color) == 3: gl.glColor3f(*p.color) elif len(p.color) == 4: gl.glColor4f(*p.color) gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) w = p.size[0] / 2.0 h = p.size[1] / 2.0 gl.glBegin(gl.GL_QUADS) # Draw Rectangle gl.glVertex3f(0.25 * w, h, 0.0) gl.glVertex3f(-w, h, 0.0) gl.glVertex3f(-w, -h, 0.0) gl.glVertex3f(0.25 * w, -h, 0.0) gl.glEnd() # GL_QUADS gl.glBegin(gl.GL_TRIANGLES) # Draw Triangle gl.glVertex3f(1.00 * w, 0.0 * h, 0.0) # Top gl.glVertex3f(0.25 * w, -3.0 * h, 0.0) gl.glVertex3f(0.25 * w, 3.0 * h, 0.0) gl.glEnd() # GL_QUADS if p.anti_aliasing: if not self._gave_alpha_warning: if len(p.color) > 3 and p.color[3] != 1.0: logger = logging.getLogger('VisionEgg.Arrow') logger.warning("The parameter anti_aliasing is " "set to true in the Arrow " "stimulus class, but the color " "parameter specifies an alpha " "value other than 1.0. To " "acheive anti-aliasing, ensure " "that the alpha value for the " "color parameter is 1.0.") self._gave_alpha_warning = 1 # We've already drawn a filled polygon (aliased), now redraw # the outline of the polygon (with anti-aliasing). (Using # GL_POLYGON_SMOOTH results in artifactual lines where # triangles were joined to create quad, at least on some OpenGL # implementations.) # Calculate coverage value for each pixel of outline # and store as alpha gl.glEnable(gl.GL_LINE_SMOOTH) # Now specify how to use the alpha value gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) # Draw a second polygon in line mode, so the edges are anti-aliased gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) gl.glBegin(gl.GL_QUADS) gl.glVertex3f(0.25 * w, h, 0.0) # Draw Rectangle gl.glVertex3f(-w, h, 0.0) gl.glVertex3f(-w, -h, 0.0) gl.glVertex3f(0.25 * w, -h, 0.0) gl.glVertex3f(1.00 * w, 0.0 * h, 0.0) # Draw Triangle gl.glVertex3f(0.25 * w, -3.0 * h, 0.0) gl.glVertex3f(0.25 * w, 3.0 * h, 0.0) gl.glEnd() # GL_QUADS # Set the polygon mode back to fill mode gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL) gl.glDisable(gl.GL_LINE_SMOOTH) gl.glPopMatrix()
def get_type(value): warnings.warn("VisionEgg.get_type() has been moved to "+\ "VisionEgg.ParameterTypes.get_type()", DeprecationWarning, stacklevel=2) return ve_types.get_type(value)
class Target2D(VisionEgg.Core.Stimulus): """Rectanglular stimulus. Parameters ========== anchor -- specifies how position parameter is interpreted (String) Default: center anti_aliasing -- (Boolean) Default: True center -- DEPRECATED: don't use (Sequence2 of Real) Default: (determined at runtime) color -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) on -- draw stimulus? (Boolean) (Boolean) Default: True orientation -- (Real) Default: 0.0 position -- units: eye coordinates (AnyOf(Sequence2 of Real or Sequence3 of Real or Sequence4 of Real)) Default: (320.0, 240.0) size -- units: eye coordinates (Sequence2 of Real) Default: (64.0, 16.0) """ parameters_and_defaults = { 'on': (True, ve_types.Boolean, "draw stimulus? (Boolean)"), 'color': ((1.0, 1.0, 1.0), ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'anti_aliasing': (True, ve_types.Boolean), 'orientation': (0.0, ve_types.Real), 'position': ((320.0, 240.0), ve_types.AnyOf(ve_types.Sequence2(ve_types.Real), ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "units: eye coordinates"), 'anchor': ('center', ve_types.String, "specifies how position parameter is interpreted"), 'size': ((64.0, 16.0), ve_types.Sequence2(ve_types.Real), "units: eye coordinates"), 'center': (None, ve_types.Sequence2(ve_types.Real), "DEPRECATED: don't use"), } __slots__ = ('_gave_alpha_warning', ) def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self, **kw) self._gave_alpha_warning = 0 def draw(self): p = self.parameters # shorthand if p.center is not None: if not hasattr(VisionEgg.config, "_GAVE_CENTER_DEPRECATION"): logger = logging.getLogger('VisionEgg.MoreStimuli') logger.warning("Specifying Target2D by deprecated " "'center' parameter deprecated. Use " "'position' parameter instead. (Allows " "use of 'anchor' parameter to set to " "other values.)") VisionEgg.config._GAVE_CENTER_DEPRECATION = 1 p.anchor = 'center' p.position = p.center[0], p.center[ 1] # copy values (don't copy ref to tuple) if p.on: # calculate center center = VisionEgg._get_center(p.position, p.anchor, p.size) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() gl.glTranslate(center[0], center[1], 0.0) gl.glRotate(p.orientation, 0.0, 0.0, 1.0) if len(p.color) == 3: gl.glColor3f(*p.color) elif len(p.color) == 4: gl.glColor4f(*p.color) gl.glDisable(gl.GL_DEPTH_TEST) gl.glDisable(gl.GL_TEXTURE_2D) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) w = p.size[0] / 2.0 h = p.size[1] / 2.0 gl.glBegin(gl.GL_QUADS) gl.glVertex3f(-w, -h, 0.0) gl.glVertex3f(w, -h, 0.0) gl.glVertex3f(w, h, 0.0) gl.glVertex3f(-w, h, 0.0) gl.glEnd() # GL_QUADS if p.anti_aliasing: if not self._gave_alpha_warning: if len(p.color) > 3 and p.color[3] != 1.0: logger = logging.getLogger('VisionEgg.MoreStimuli') logger.warning("The parameter anti_aliasing is " "set to true in the Target2D " "stimulus class, but the color " "parameter specifies an alpha " "value other than 1.0. To " "acheive anti-aliasing, ensure " "that the alpha value for the " "color parameter is 1.0.") self._gave_alpha_warning = 1 # We've already drawn a filled polygon (aliased), now # redraw the outline of the polygon (with # anti-aliasing). (Using GL_POLYGON_SMOOTH results in # artifactual lines where triangles were joined to # create quad, at least on some OpenGL # implementations.) # Calculate coverage value for each pixel of outline # and store as alpha gl.glEnable(gl.GL_LINE_SMOOTH) # Now specify how to use the alpha value gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) # Draw a second polygon in line mode, so the edges are anti-aliased gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) gl.glBegin(gl.GL_QUADS) gl.glVertex3f(-w, -h, 0.0) gl.glVertex3f(w, -h, 0.0) gl.glVertex3f(w, h, 0.0) gl.glVertex3f(-w, h, 0.0) gl.glEnd() # GL_QUADS # Set the polygon mode back to fill mode gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL) gl.glDisable(gl.GL_LINE_SMOOTH) gl.glPopMatrix()
class SinGrating3D(LuminanceGratingCommon): """Sine wave grating stimulus texture mapped onto quad in 3D This is a general-purpose, realtime sine-wave luminace grating generator. This 3D version doesn't support an orientation parameter. This could be implemented, but for now should be done by orienting the quad in 3D. Parameters ========== bit_depth -- precision with which grating is calculated and sent to OpenGL (UnsignedInteger) Inherited from LuminanceGratingCommon Default: 8 color1 -- (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, 1.0) color2 -- optional color with which to perform interpolation with color1 in RGB space (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (determined at runtime) contrast -- (Real) Default: 1.0 depth -- (Real) Default: (determined at runtime) depth_test -- perform depth test? (Boolean) Default: True ignore_time -- (Boolean) Default: False lowerleft -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (0.0, 0.0, -1.0) lowerright -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 0.0, -1.0) mask -- optional masking function (Instance of <class 'VisionEgg.Textures.Mask2D'>) Default: (determined at runtime) max_alpha -- (Real) Default: 1.0 num_samples -- (UnsignedInteger) Default: 512 on -- draw stimulus? (Boolean) Default: True pedestal -- (Real) Default: 0.5 phase_at_t0 -- (Real) Default: 0.0 polygon_offset_enabled -- perform polygon offset? (Boolean) Default: False polygon_offset_factor -- polygon factor (Real) Default: 1.0 polygon_offset_units -- polygon units (Real) Default: 1.0 recalculate_phase_tolerance -- (Real) Default: (determined at runtime) size -- defines coordinate size of grating (in eye coordinates) (Sequence2 of Real) Default: (1.0, 1.0) spatial_freq -- frequency defined relative to coordinates defined in size parameter (units; cycles/eye_coord_unit) (Real) Default: 4.0 t0_time_sec_absolute -- (Real) Default: (determined at runtime) temporal_freq_hz -- (Real) Default: 5.0 upperleft -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (0.0, 1.0, -1.0) upperright -- vertex position (units: eye coordinates) (AnyOf(Sequence3 of Real or Sequence4 of Real)) Default: (1.0, 1.0, -1.0) """ parameters_and_defaults = VisionEgg.ParameterDefinition({ 'on':(True, ve_types.Boolean, "draw stimulus?"), 'mask':(None, # allows window onto otherwise (tilted) rectangular grating ve_types.Instance(VisionEgg.Textures.Mask2D), "optional masking function"), 'contrast':(1.0, ve_types.Real), 'pedestal':(0.5, ve_types.Real), 'depth':(None, # if not None, turns on depth testing and allows for occlusion ve_types.Real), 'size':((1.0,1.0), # in eye coordinates ve_types.Sequence2(ve_types.Real), "defines coordinate size of grating (in eye coordinates)"), 'spatial_freq':(4.0, # cycles/eye coord units ve_types.Real, "frequency defined relative to coordinates defined in size parameter (units; cycles/eye_coord_unit)"), 'temporal_freq_hz':(5.0, # hz ve_types.Real), 't0_time_sec_absolute':(None, # Will be assigned during first call to draw() ve_types.Real), 'ignore_time':(False, # ignore temporal frequency variable - allow control purely with phase_at_t0 ve_types.Boolean), 'phase_at_t0':(0.0, # degrees [0.0-360.0] ve_types.Real), 'num_samples':(512, # number of spatial samples, should be a power of 2 ve_types.UnsignedInteger), 'max_alpha':(1.0, # controls "opacity": 1.0 = completely opaque, 0.0 = completely transparent ve_types.Real), 'color1':((1.0, 1.0, 1.0), # alpha is ignored (if given) -- use max_alpha parameter ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real))), 'color2':(None, # perform interpolation with color1 in RGB space. ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "optional color with which to perform interpolation with color1 in RGB space"), 'recalculate_phase_tolerance':(None, # only recalculate texture when phase is changed by more than this amount, None for always recalculate. (Saves time.) ve_types.Real), 'depth_test':(True, ve_types.Boolean, "perform depth test?"), 'lowerleft':((0.0,0.0,-1.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "vertex position (units: eye coordinates)"), 'lowerright':((1.0,0.0,-1.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "vertex position (units: eye coordinates)"), 'upperleft':((0.0,1.0,-1.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "vertex position (units: eye coordinates)"), 'upperright':((1.0,1.0,-1.0), # in eye coordinates ve_types.AnyOf(ve_types.Sequence3(ve_types.Real), ve_types.Sequence4(ve_types.Real)), "vertex position (units: eye coordinates)"), 'polygon_offset_enabled':(False, ve_types.Boolean, "perform polygon offset?"), 'polygon_offset_factor':(1.0, ve_types.Real, "polygon factor"), 'polygon_offset_units':(1.0, ve_types.Real, "polygon units"), }) __slots__ = ( '_texture_object_id', '_last_phase', ) def __init__(self,**kw): LuminanceGratingCommon.__init__(self,**kw) p = self.parameters # shorthand self._texture_object_id = gl.glGenTextures(1) if p.mask: gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB) gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id) # Do error-checking on texture to make sure it will load max_dim = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE) if p.num_samples > max_dim: raise NumSamplesTooLargeError("Grating num_samples too large for video system.\nOpenGL reports maximum size of %d"%(max_dim,)) self.calculate_bit_depth_dependencies() w = p.size[0] inc = w/float(p.num_samples) phase = 0.0 # this data won't get used - don't care about phase self._last_phase = phase floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1 texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype).tostring() # Because the MAX_TEXTURE_SIZE method is insensitive to the current # state of the video system, another check must be done using # "proxy textures". gl.glTexImage1D(gl.GL_PROXY_TEXTURE_1D, # target 0, # level self.gl_internal_format, # video RAM internal format p.num_samples, # width 0, # border self.format, # format of texel data self.gl_type, # type of texel data texel_data) # texel data (irrelevant for proxy) if gl.glGetTexLevelParameteriv(gl.GL_PROXY_TEXTURE_1D, # Need PyOpenGL >= 2.0 0, gl.GL_TEXTURE_WIDTH) == 0: raise NumSamplesTooLargeError("Grating num_samples is too wide for your video system!") # If we got here, it worked and we can load the texture for real. gl.glTexImage1D(gl.GL_TEXTURE_1D, # target 0, # level self.gl_internal_format, # video RAM internal format p.num_samples, # width 0, # border self.format, # format of texel data self.gl_type, # type of texel data texel_data) # texel data # Set texture object defaults gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_S,gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_WRAP_T,gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_1D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR) if p.color2 is not None: if VisionEgg.Core.gl_renderer == 'ATi Rage 128 Pro OpenGL Engine' and VisionEgg.Core.gl_version == '1.1 ATI-1.2.22': logger = logging.getLogger('VisionEgg.Gratings') logger.warning("Your video card and driver have known " "bugs which prevent them from rendering " "color gratings properly.") def __del__(self): gl.glDeleteTextures( [self._texture_object_id] ) def draw(self): p = self.parameters # shorthand if p.on: if p.mask: gl.glActiveTextureARB(gl.GL_TEXTURE0_ARB) if p.depth_test: gl.glEnable(gl.GL_DEPTH_TEST) else: gl.glDisable(gl.GL_DEPTH_TEST) if p.polygon_offset_enabled: gl.glEnable(gl.GL_POLYGON_OFFSET_EXT) gl.glPolygonOffset(p.polygon_offset_factor, p.polygon_offset_units) gl.glBindTexture(gl.GL_TEXTURE_1D,self._texture_object_id) gl.glEnable(gl.GL_TEXTURE_1D) gl.glDisable(gl.GL_TEXTURE_2D) if p.bit_depth != self.cached_bit_depth: self.calculate_bit_depth_dependencies() # allow max_alpha value to control blending gl.glEnable( gl.GL_BLEND ) gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA ) if p.color2: gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_BLEND) gl.glTexEnvfv(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_COLOR, p.color2) ## alpha is ignored because the texture base internal format is luminance else: gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE) if p.t0_time_sec_absolute is None and not p.ignore_time: p.t0_time_sec_absolute = VisionEgg.time_func() w = p.size[0] inc = w/float(p.num_samples) if p.ignore_time: phase = p.phase_at_t0 else: t_var = VisionEgg.time_func() - p.t0_time_sec_absolute phase = t_var*p.temporal_freq_hz*-360.0 + p.phase_at_t0 if p.recalculate_phase_tolerance is None or abs(self._last_phase - phase) > p.recalculate_phase_tolerance: self._last_phase = phase # we're re-drawing the phase at this angle floating_point_sin = numpy.sin(2.0*math.pi*p.spatial_freq*numpy.arange(0.0,w,inc,dtype=numpy.float)+(phase/180.0*math.pi))*0.5*p.contrast+p.pedestal floating_point_sin = numpy.clip(floating_point_sin,0.0,1.0) # allow square wave generation if contrast > 1 texel_data = (floating_point_sin*self.max_int_val).astype(self.numpy_dtype).tostring() gl.glTexSubImage1D(gl.GL_TEXTURE_1D, # target 0, # level 0, # x offset p.num_samples, # width self.format, # format of new texel data self.gl_type, # type of new texel data texel_data) # new texel data # in the case of only color1, # the texel data multiplies color1 to produce a color # with color2, # the texel data linearly interpolates between color1 and color2 gl.glColor4f(p.color1[0],p.color1[1],p.color1[2],p.max_alpha) if p.mask: p.mask.draw_masked_quad_3d(0.0,1.0,0.0,1.0, # for texture coordinates p.lowerleft,p.lowerright,p.upperright,p.upperleft) else: # draw unmasked quad gl.glBegin(gl.GL_QUADS) gl.glTexCoord2f(0.0,0.0) gl.glVertex(*p.lowerleft) gl.glTexCoord2f(1.0,0.0) gl.glVertex(*p.lowerright) gl.glTexCoord2f(1.0,1.0) gl.glVertex(*p.upperright) gl.glTexCoord2f(0.0,1.0) gl.glVertex(*p.upperleft) gl.glEnd() # GL_QUADS gl.glDisable(gl.GL_TEXTURE_1D) if p.polygon_offset_enabled: gl.glDisable(gl.GL_POLYGON_OFFSET_EXT)
class Buffered(DaqMode): parameters_and_defaults = { 'sample_rate_hz': (5000.0, ve_types.Real), 'duration_sec': (5.0, ve_types.Real), 'trigger': (None, ve_types.Instance(Trigger)), }
class Dots3D(VisionEgg.Core.Stimulus): """Random dots of constant velocity (3D) Every dot has the same 3D velocity. Each dot has a lifespan. Some dots can be black, while the rest are white. This is just one example of the endless variations on drawing random dots. Parameters ========== dot_lifespan_sec -- (Real) Default: 5.0 dot_size -- (Real) Default: 4.0 on -- (Boolean) Default: True signal_vec -- (Sequence3 of Real) Default: (0, 0, 0) start_position_mean -- (Sequence3 of Real) Default: (0, 0, 0) start_position_variance -- (Real) Default: 1 Constant Parameters =================== num_dark -- (UnsignedInteger) Default: 100 num_dots -- (UnsignedInteger) Default: 200 """ parameters_and_defaults = { 'on' : ( True, ve_types.Boolean ), 'start_position_mean' : ( ( 0,0,0 ), # in world coordinates ve_types.Sequence3(ve_types.Real) ), 'start_position_variance' : ( 1, ve_types.Real ), # sigma**2 'signal_vec' : ( ( 0,0,0 ), # in world coordinates ve_types.Sequence3(ve_types.Real) ), 'dot_size' : (4.0, # pixels ve_types.Real), 'dot_lifespan_sec' : ( 5.0, ve_types.Real ), } constant_parameters_and_defaults = { 'num_dots' : ( 200, ve_types.UnsignedInteger ), 'num_dark' : ( 100, # the number of total that are black ve_types.UnsignedInteger ), } __slots__ = ( 'centers', 'colors', 'last_time_sec', 'start_times_sec', ) def __init__(self, **kw): VisionEgg.Core.Stimulus.__init__(self,**kw) # store positions normalized around 0 so that re-sizing is ok num_dots = self.constant_parameters.num_dots # shorthand self.centers = np.random.standard_normal((3,num_dots)) self.colors = np.ones((num_dots,4)) self.colors[:self.constant_parameters.num_dark,:3] = 0 self.last_time_sec = VisionEgg.time_func() self.start_times_sec = None # setup variable, assign later def draw(self): # XXX This method is not speed-optimized. I just wrote it to # get the job done. (Nonetheless, it seems faster than the C # version commented out above.) p = self.parameters # shorthand now_sec = VisionEgg.time_func() if self.start_times_sec is not None: # compute extinct dots and generate new positions replace_indices = Numeric.nonzero( Numeric.greater( now_sec - self.start_times_sec, p.dot_lifespan_sec) ) Numeric.put( self.start_times_sec, replace_indices, now_sec ) new_centers = np.random.standard_normal((3,len(replace_indices))) for i in range(3): Numeric.put( self.centers[i,:], replace_indices, new_centers[i,:] ) else: # initialize dot extinction values to random (uniform) distribution self.start_times_sec = RandomArray.uniform( now_sec - p.dot_lifespan_sec, now_sec, (self.constant_parameters.num_dots,)) time_delta_sec = now_sec - self.last_time_sec self.last_time_sec = now_sec # reset for next loop self.centers = self.centers + np.array(p.signal_vec)[:,np.newaxis]*time_delta_sec xyz = self.centers*p.start_position_variance + np.array(p.start_position_mean)[:,np.newaxis] xs = xyz[0,:] ys = xyz[1,:] zs = xyz[2,:] if p.on: gl.glEnable( gl.GL_POINT_SMOOTH ) # allow max_alpha value to control blending gl.glEnable( gl.GL_BLEND ) gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA ) gl.glPointSize(p.dot_size) # Clear the modeview matrix gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() gl.glDisable(gl.GL_TEXTURE_2D) draw_dots(xs,ys,zs,self.colors) gl.glDisable( gl.GL_POINT_SMOOTH ) # turn off gl.glPopMatrix()
def __init__(self): global mouse_position VisionEgg.FlowControl.Controller.__init__(self, return_type=ve_types.get_type(None), eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME) self.between_go_eval = self.during_go_eval