Shady Package
The World Class
- class Shady.World(width=None, height=None, left=None, top=None, screen=None, threaded=True, canvas=False, frame=False, fullScreenMode=None, visible=True, overlayMode=False, openglContextVersion=None, legacy=None, backend=None, acceleration=None, debugTiming=False, profile=False, syncType=-1, logfile=None, reportVersions=False, window=None, **kwargs)
Bases:
LinkGLA
Worldinstance encapsulates the window and rendering environment in which you draw stimuli. By default, aWorldwill fill one screen, but its size, offset and decoration can also be tailored explicitly if necessary. When you initialize aWorld, Shady creates an OpenGL program and compiles and links a vertex shader and a fragment shader to it: this is what allows signal generation, contrast modulation, windowing, gamma correction and dithering to be performed on the graphics processor.Once you have created the
World, you will probably want to call need to call theStimulus()method one or more times, to configure the things that should be drawn in it.- Parameters:
width (int) – width of drawable area in “screen coordinates” (which usually means pixels, but see the note below).
height (int) – height of drawable area in “screen coordinates” (which usually means pixels, but see the note below).
size (int, tuple or list) – width and height of drawable area in “screen coordinates” (see note below). If this is a single number, it is used for both width and height. If it is a
tupleorlist, it is interpreted as [width, height]. However, the separatewidthand/orheightarguments take precedence, if supplied.left (int) – horizontal offset from the edge of the screen, in “screen coordinates” (which usually means pixels, but see the note below).
top (int) – vertical offset from the top of the screen, in “screen coordinates” (which usually means pixels, but see the note below).
screen (int) – Screen number. 0 or
None(default) means use whichever is designated as the primary screen. A positive integer explicitly selects a screen number. The output of the globalScreens()function may help you choose the screen number you want.threaded (bool) – If you specify
threaded=False, theWorld’s main rendering/event- processing loop will not be started automatically: you will have to start it yourself, from the appropriate thread, using theRun()method. In this case, the best way to perform initialWorldconfiguration andStimuluscreation is to put the code in the body of aPrepare()method that you specify by subclassingWorld.With
threaded=True, a new thread will be created to perform all the work ofWorldconstruction and then, automatically, to run the main loop. Any subsequent call to theRun()method will do nothing except sleep until the thread ends. This is the easiest way to use Shady: you can then create and manipulate stimuli either from aPreparemethod, or from wherever else you want. This appears to work well on Windows, but will have problems (which can only partially be worked-around) on other operating systems: see theShady.Documentation.Concurrencydocstring or click here.canvas (bool) – If you set this to
Truea “canvas”Stimulusinstance will be created automatically, filling the screen behind other stimuli. If you do not create one automatically like this, you can do it later by calling theMakeCanvas()method. A canvas allows gamma-correction and dynamic-range enhancement tricks to be performed on the backdrop as well as on your foreground stimuli, and it allows theWorld’s “atmosphere” properties (backgroundColor,gamma,noiseAmplitudeand friends) to take effect: see theShady.Documentation.PreciseControlOfLuminancedocstring or click here.frame (bool) – Whether or not to draw a frame and title-/drag- bar around the window.
fullScreenMode (bool) – Default behavior is to create a window that exactly covers one screen. This can be done by creating an ordinary window that just happens to be the same size as the screen (
fullScreenMode=False) or by actually asking the system to change to full-screen mode (fullScreenMode=True). The default on Windows isFalse, since it allows you to switch windows (e.g. with alt-Tab) and still have the Shady window visible in the background (note however, that background windows have poor timing precision - to render precisely without skipping frames you will need to keep the window in the foreground). WithfullScreenMode=Truethis is impossible: the window will disappear when it loses focus. On the Mac, the default setting for full-sized windows isfullScreenMode=True, because this seems to be the only way to hide the menu bar at the top of the screen.For non-full-sized windows, the default is
fullScreenMode=False. If you set it toTruewhile also explicitly designating the size of theWorld, the OS will attempt to change resolution. This will probably be a bad idea for psychophysical applications on most modern screens: for rendering accuracy, you should address the screen at its native (maximum) resolution.(Experimental feature, only available when using the ShaDyLib accelerator:) you can also specify a number greater than 1 for
fullScreenMode, in which case Shady will try to use this as the refresh rate for the screen.visible (bool) – If you set this to
False, the window will be created off-screen and will only become visible when you set itsvisibleproperty toTrue.overlayMode (bool) – If set to
True, this causes the window to have a transparent background, to “float” above other windows, and to pass mouse events through to the windows behind it. This allows you to superimpose Shady stimuli on other applications’ windows without preventing the user from interacting with those applications. Depending on your graphics card, this may be computationally expensive, so (as always) take care to verify timing performance to the extent necessary.debugTiming (bool) – Every
Worldrecords the timing intervals between its frame callbacks, to aid in analyzing timing performance. If you setdebugTiming=True, it will record additional information that breaks down the allocation of this time. By default the setting will be propagated to everyStimulusinstance as well (set eachstim.debugTiming=Falseif this is not what you want—if there are many stimuli, then the timing debug calls themselves can start to have a measurable impact on performance).logfile (str) – Optionally specify the name of a text file which will log various pieces of useful diagnostic information. If your filename includes the substring
{}, this will be replaced by ayyyymmdd-HHMMSSlocal timestamp. If the file stem ends with-fullthenself.logger.logSystemInfoOnClosewill be set toTrueby default which means that a third-party program will be run when theWorldcloses, to record extensive system information (NB: on Windows the program isdxdiag.exewhich is time-consuming and produces lengthy logs). You can write to the log file yourself withself.logger.Log()reportVersions (bool) – If this is
True, theWorldinstance will call itsReportVersions()method to report version information to the console, as soon as it is set up.**kwargs – Managed property values can also be specified as optional keyword arguments during construction, for example:
w = World( ..., clearColor=[0,0,0.5], ... )
Note: The easiest way to create a
Worldis by omitting all geometry arguments. Then it will fill the display screen (the primary screen by default, but you can also specify thescreennumber explicitly). However, if you choose to use explicit geometry arguments (width,height,size,left,top) note that they are all in “screen coordinates”. Screen coordinates usually correspond to pixels, but in some systems (Macs with Retina screens) you may need to specify some fixed smaller proportion of the number of addressable pixels you actually want: for example, on a Late-2013 Macbook with 13-inch Retina screen,w = World(1280, 800)opens a window that actually has double that number of addressable pixels (2560 x 1600). After construction,w.sizewill indicate the correct (larger) number of pixels. Unfortunately, before construction, I have not yet found a general way of predicting the relationship between screen coordinates and pixels.- classmethod AddCustomUniform(name=None, defaultValue=None, **kwargs)
Modifies the class (
WorldorStimulus) so that it possesses one or more new managed properties, whose values are then accessible from inside the fragment shader. This must be performed beforeWorldconstruction.Example:
Shady.World.AddCustomUniform( 'spam', [1,2,3] ) Shady.Stimulus.AddCustomUniform( eggs=4, beans=[5,6] )
Either syntax can be used in either class. The keyword-argument syntax has the advantage of being able to define multiple new properties in one call.
The default values you supply dictate whether the new property is 1-, 2-, 3- or 4-dimensional. For a 1-dimensional property, the type of your default value also determines whether the property gets defined as an integer or floating-point variable. (2-, 3- or 4- dimensional properties are always re-cast as floating-point).
The corresponding uniform variables are then automatically made available in the fragment shader code, with the first letter of the property name getting capitalized and a ‘u’ prepended. So, as a consequence of the two lines in the example above, the modified shader would then contain these definitions:
uniform vec3 uSpam; uniform int uEggs; uniform vec2 uBeans;
…all of which is useless unless you actually write some custom shader functions that access the new variables. You might use the new variables in your own custom signal-function, modulation-function, windowing-function or color-transformation snippets.
- classmethod Properties(includeShortcuts=False)
Return a list of all managed properties of this class. (Class method)
- Parameters:
includeShortcuts – Determines whether
ManagedShortcutinstances should be included (True) or not (False; default) along withManagedPropertyinstances.- Returns:
A list of
ManagedProperty(and optionally alsoManagedShortcut) descriptor instances.
- classmethod SetDefault(**kwargs)
Affects the class. Sets the default values of named properties. In instances of the class created subsequently, managed properties will have the new default values.
Example:
cls.SetDefault( color=(1,0,0), rotation=90 )
- AddForeignStimulus(stimulus, name=None, z=0, **kwargs)
stimis either a class (or callable factory function) or an instance of a class. That class should have adraw()method. It is drawn on every frame with the Shady shader pipeline disabled (so, no automatic linearization or dithering, etc).The intention is to allow the use of one’s own custom OpenGL primitives in drawing unusual stimuli.
- AfterClose(func, *pargs, **kwargs)
This method registers a callable
func(and optionally the*pargsand**kwargsthat should be passed to it) that will be called just after theWorldcloses. The method is otherwise identical toBeforeClose()
- AnimationCallback(func=None)
Decorator version of
SetAnimationCallback()Examples:
w = Shady.World() @w.AnimationCallback def anim( self, t ): print( t )
- BeforeClose(func, *pargs, **kwargs)
This method registers a callable
func(and optionally the*pargsand**kwargsthat should be passed to it) that will be called just before theWorldcloses. One way to use this method is as a decorator—for example:w = Shady.World() @w.BeforeClose def Goodbye(): print( "goodbye" )
- Returns:
(1) when
funcis called, its return value will be inserted into this list; (2) theidof the list instance uniquely identifies the callback you have just registered, so it can be used as a handle for cancelling the function withCancelOnClose()- Return type:
an empty
list. This has two uses
- BoundingBox(worldCoordinates=False)
This method returns the
World’s bounding box, in pixels.- Parameters:
worldCoordinates (bool) – If
True, then theleftandbottomcoordinates are computed relative to theWorld’s ownanchor(so that gives you the bounding box within which you can draw stimuli, in coordinates aStimuluswould understand). IfFalse, thenleft = bottom = 0.- Returns:
[left, bottom], [width, height]pixel coordinates for theWorld.
- CancelOnClose(container)
Cancels a callback that had previously been scheduled to run at closing time by either
BeforeClose()orAfterClose(), either of which will have returned thecontainerthat you need to pass as the input argument here.
- Capture(pil=False, fullscreen=False, saveas='', size=None, origin=None, normalize='auto')
Takes a screenshot of the World and return the RGBA image data as a
numpyarray (pil=False) or as aPIL.Image.Imageinstance (pil=True).- Parameters:
pil (bool) – If
True, andPILorpillowis installed, anImageobject is returned. Otherwise, return anumpyarray (ifnumpyis installed) or a buffer containing the raw pixel information (if not).fullscreen (bool) – Normally, with
fullscreen=False, we capture just theWorldcontent. But if we specifyfullscreen=True, andPILorpillowis installed, and we’re on Windows, then theImageGrabmodule will be used to grab a shot of the whole screen as-is (including other windows and desktop content if theWorldfills only part of the screen or is partly obscured).saveas (str) – If a filename is specified here, and
PILorpillowis installed, then the image is automatically saved under the specified filename.size (tuple, list) – This is a sequence (tuple, list, or 1-D
numpyarray) containing 2 integers: width and height, in pixels. If unspecified (None), the size of theWorld(self.size) is assumed.origin (tuple, list) – This is a sequence (tuple, list, or 1-D
numpyarray) containing 2 integers: x and y, in pixels, indicating the offset in pixels between the lower left corner of theWorldand the lower left corner of the capture are. If unspecified (None),[0,0]is assumed.normalize (bool or ‘auto’) – If
False, return raw RGBA values as integers. IfTrue, return floating-point values normalized in the range 0 to 1, and furthermore undo the effects of the currentbitCombiningModeif any. If'auto', the default isFalseexcept when all the following conditions are met:numpyis installed,pilisFalse, andself.bitCombiningModeis non-zero.
- Returns:
A
PIL.Image.Imageobject (withpil=True, providedPILorpillowis installed) or anumpyarray (withpil=False) containing 8-bit RGBA pixel values.
- ClearDynamics()
Remove all property dynamics from the instance.
See also:
GetDynamic(),GetDynamics(),SetDynamic()
- CreatePropertyArray(propertyName, *stimuli)
This method returns a
PropertyArrayobject which contains anumpyarray. Each row of the array is the storage area for the named property of one of the specified stimuli. You can still address the property of each individualStimulusin the usual way, but now you also have the option of addressing them all at once in a single array operation, which may be much more efficient if there are many stimuli.- Parameters:
propertyName (str) – The name (or alias) of a fully-fledge
ManagedPropertyof theStimulusclass (for example,'color'or'position').*stimuli – This is flexible. You can pass the (string) names of
Stimulusinstances, or you can pass the instances themselves. You can pass them as separate arguments, and/or in tuples or lists. If you’re using names, you can even pass them as a single space-delimited string if you want.
- Returns:
a
PropertyArrayinstance whoseAattribute contains thenumpyarray.
Example:
import numpy, Shady w = Shady.World() p = numpy.linspace( -1.0, +1.0, 20, endpoint=True ) stims = [ w.Stimulus( xy=w.Place( p_i, 0 ), bgalpha=0, pp=1 ) for p_i in p ] position = w.CreatePropertyArray( 'xy', stims ) color = w.CreatePropertyArray( 'color', stims ) @w.AnimationCallback def Animate( self, t ): s = Shady.Sinusoid( t, p * 180 ) position.A[ :, 1 ] = 200 * s color.A[ :, 0 ] = 0.5 + 0.5 * s color.A[ :, 1 ] = 0.5 + 0.5 * s[ ::-1 ] color.A[ :, 2 ] = s ** 2 # one call with a few simple efficient numpy array operations # instead of 20 stimuli x 4 shortcuts = 80 dynamic function calls
- Culling(enable, alphaThreshold=0.25)
Depth culling is disabled by default. This means that where two stimuli overlap, every pixel is rendered in both stimuli. Depending on your stimulus arrangement, this may be a significant waste of resources.
Turn culling on with
Culling( True ). Instead of drawing all pixels of all stimuli in furthest-to-nearest order (the painter’s algorithm), Shady will now draw them in reverse painter’s order, nearest-to-furthest, omitting calculations that would affect already-drawn-to pixels.Depth culling is fine if all your stimuli are opaque. The disadvantage to depth culling is that it affects alpha blending and composition: when a stimulus with some transparent parts is overlapped on another stimulus, depth culling alone would cause the
clearColorof theWorldto be drawn where there should be transparency. A partial countermeasure to this is alpha culling, which will be turned on concurrently with the depth test unless you explicitly specify a negativealphaThreshold. With alpha culling, any pixel in any stimulus whose alpha is equal to or less thanalphaThresholdis simply omitted, and stimuli behind it will show through at that point even with depth culling enabled. The quality of some stimuli (e.g. antialiased text on a transparent background) will vary visibly depending on the threshold you choose, and will never be perfect. Note also that semi-transparent pixels (wherealphaThreshold < alpha < 1.0) may be rendered with inaccurate colors: stimulus colors get alpha-blended with theclearColor, not with the colors of the stimuli behind them.Use
Culling( False )to disable both depth and alpha culling.
- Defer(func, *pargs, **kwargs)
Any method that actually makes GL calls, such as
NewPage()orLoadTexture(), must be called from the same thread/context as the one where all other GL operations happen, otherwise you may fail to see any result and/or the program may crash. This is a workaround: if you call (for example)self.Defer( func, arg1, arg2, ... )thenfunc(arg1, arg2, ...)will be called at the end of the next frame.This function is already used, under-the-hood, by the
@DeferredCallmethod decorator, to make methods likeWorld.StimulusorStimulus.NewPagesafe. So there may be relatively few cases in which you need to use it directly.- Parameters:
func – this is the callable object to be called at the end of the next frame. Optionally, you may influence the order in which these pending tasks are performed by supplying a tuple
(priority, func)instead of justfunc. The numeric valueprioritydefaults to0. The higher its value, the earlier the task will be performed, relative to other pending tasks.*pargs and **kwargs – any additional positional arguments, and any keyword arguments, are simply passed through to
funcwhen it is called.
- Returns:
An empty list. When
funcis finally called, its output will be inserted into this list. Iffunccauses an exception to be raised, the stack trace information will be wrapped in aDeferredExceptioninstance and returned in the list. The list also serves as a handle by which you canUndefer()a deferred task.
- EventHandler(slot=0)
Decorator version of
SetEventHandler()Examples:
w = Shady.World() @w.EventHandler # overwrites default slot=0 def handler( self, event ): print( 'handler got %s event' % event.type ) @w.EventHandler( slot=1 ) # uses an explicit slot def handler2( self, event ): print( 'handler2 got %s event' % event.type )
- GetDynamic(name)
For dynamic properties, return the actual callable object that generates property values, rather than the current static value.
- Parameters:
name (str) – Name of the property
- Returns:
Callable object responsible for generating values for the named property (or
Noneif there is no such dynamic).
See also:
GetDynamics(),SetDynamic(),ClearDynamics()
- GetDynamics()
Get an ordered list of (name, callable) tuples detailing all the dynamics of this instance.
See also:
GetDynamic(),SetDynamic(),ClearDynamics()
- HandleEvent(event)
This method is called every time an event happens. Its argument
eventis a standardized instance of classEvent, containing details of what happened. The default (superclass) implementation responds whenevent.typeis'key_release'and the released key is either the Q key or the escape key - this causes the window to close (and hence the drawing thread will terminate, if thisWorldis threaded).You can overshadow this method in your
Worldsubclass, or you can replace it on an instance-by-instance basis using the methodSetEventHandler()or the decoratorEventHandler()- for example:def handler( self, event ): print( event ) w.SetEventHandler( handler )
Note that, for each event, it is possible to have more than one handler, occupying different “slots” in the cascade that is applied to each event. By default, the
HandleEventmethod occupies slot 0.
- Inherit(other)
Set the values of all managed properties of this instance to match those of another instance. Only properties common to both objects will be considered. Dynamic property values will be copied as dynamic properties.
- Parameters:
other – instance whose property values will be copied to the properties of
self- Returns:
self
- LinkPropertiesWithMaster(master, *pargs, **kwargs)
-
- Returns:
self
- LookupTable(*pargs, **kwargs)
Creates a
LookupTableinstance usingLookupTable( world=self, ... )
- MakeCanvas(**kwargs)
Create a
canvasstimulus that covers theWorldand thereby allows theWorld’sbackgroundColor,gamma, ‘.ditheringDenominator` and other “atmosphere” parameters to be put into effect.This is called automatically if you say
canvas=Truein yourWorldconstructor call.
- MakePropertiesIndependent(*pargs, **kwargs)
Undoes the effect of
ShareProperties(). Optionally, set the values of the properties after unsharing.Example:
a.ShareProperties( b, c, d, alpha=1, beta=2, gamma=3 ) b.MakePropertiesIndependent( alpha=4 ) # Now `a` and `b` share properties `.beta` and `.gamma`, but # `b.alpha` is independent and already has the new value 4; # by contrast `a`, `c` and `d` still share all three properties. c.MakePropertiesIndependent( 'beta', 'gamma' ) # Now `c` does not share anything except `.alpha`, although the # property values themselves have not yet been changed. c.Set( beta=c, gamma=c ) # a syntactic shorthand for the same operation as in the previous # line
- Returns:
self
- Patch(**kwargs)
A convenience wrapper around the
Stimulus()method, for creating patches of solid color (supplypp=1for oval,pp=-1for rectangular).
- Place(xp, yp=None, worldCoordinates=True, polar=False)
Convert 2-D normalized coordinates (relative to the instance, -1 to +1 in each dimension), into 2-D pixel coordinates, either relative to the
World’s currentanchor, or relative to theWorld’s bottom left corner irrespective ofanchor.Input coordinates may be given as one scalar argument, two scalar arguments, or one argument that is a sequence of two numbers. Depending on the
polarargument, these will be interpreted asx, yCartesian coordinates (where, ifyomitted, it defaults toy=x) ortheta, rpolar coordinates (where, ifris omitted, it defaults tor=1).- Parameters:
worldCoordinates (bool) – If
True, return pixel coordinates relative to theWorld’s ownanchorposition. IfFalse, return pixel coordinates relative to theWorld’s bottom left corner irrespective of itsanchor.polar (bool) – If
True, input coordinates are interpreted as an angle (in degrees) and an optional radius (0 denoting the center, 1 denoting the edge).
Examples:
instance.Place( [ -1, 1 ] ) # top left corner instance.Place( -1, 1 ) # likewise, top left corner instance.Place( 90, polar=True ) # middle of top edge (radius 1 assumed) instance.Place( [ 90, 0.5 ], polar=True ) # halfway between center and top instance.Place( 90, 0.5, polar=True ) # likewise, halfway between center and top
- Prepare(**kwargs)
This method is called after the
Worldis initialized and the shader programs are set up, but before the first frame is actually rendered. It is carried out in the same thread as initialization and rendering.In the
Worldbase class, this method does nothing. However, if you create a subclass ofWorld, you can overshadow this method. It is then a good place to perform initialStimuluscreation and other configuration specific to your particular application. You can use any prototype you like for the method, as long as it has aselfargument.When you first construct the
World, any keyword arguments that are not recognized by the constructor will be automatically passed through toPrepare().
- ReportVersions(outputType='print', importAll=False)
This method calls the global function
ReportVersionswith theWorldinstance as its first argument.
- Run()
If the
Worldwas created withthreaded=Trueand is already rendering, then this method does nothing except sleep in the current thread until theWorldhas finished. If theWorldwas not created threaded, then this method is required to actually execute its main rendering loop. Either way, the method does not return until theWorldcloses.
- RunDeferred(func, *pargs, **kwargs)
Defer()a function, then wait for it to run, and then return the output. NB: you’ll wait forever if theWorldis not running…Note that you do not need to do this for most
Worldmethods: they have already been wrapped so that they run deferred when necessary and appropriate.
- Set(**kwargs)
Set the values of multiple managed properties in one call. An error will be raised if you try to set the value of a non-existent, or non-managed, property.
- Returns:
self
Example:
instance.Set( rotation=90, color=(0, 0, 1), contrast=0.5 )
- SetAnimationCallback(callback)
Bind the callable object
callbackas the instance’s animation callback. Each object, whether it is aWorldor aStimulus, may optionally have a single animation callback which is called on every frame. If thecallbackargument isNone, any existing callback is removed.The animation callback is installed as the attribute
self.Animate. By default, this attribute isNone.The prototype for an animation callback can be
callback(self, t)or justcallback(t)(if it’s the latter then you can, alternatively, simply assign it asself.Animate = callback).Example:
def animate( self, t ): print( t ) my_world = Shady.World().SetAnimationCallback( animate )
There is also a decorator version of the same operation, simply called
AnimationCallback():stim = my_world.Stimulus() @stim.AnimationCallback def Animate( self, t ): print( t )
- SetBitCombiningMode(mode, verticalGrouping='iso')
This method supports high-dynamic-range rendering on specialized vision-science hardware—see documentation for the
bitCombiningModeproperty for full details. Callingw.SetBitCombiningMode(mode)is the same as simply assigningw.bitCombiningMode = mode. The only difference is that, whenmode=2(sacrificing horizontal resolution to achieve 16-bit-per- channel full-color rendering), the method allows you to specify separately whether vertical resolution should also be sacrificed. Shady’s default behavior is to throw away vertical resolution at the same time, so that logical pixels remain physically square, as follows:w.SetBitCombiningMode( mode=2, verticalGrouping=2 )
However you can override this, changing the aspect ratio of your pixels and retaining full vertical resolution, as follows:
w.SetBitCombiningMode( mode=2, verticalGrouping=1 )
- SetDynamic(name, func, order=-1, canonicalized=False)
Associate a “dynamic” (i.e. a function that can be called repeatedly to set an attribute) with the name of an attribute.
For example:
foo.Set( 'bar', lambda t: t ** 2 )
This will set
foo.bartot ** 2every time the methodfoo._RunDynamics( t )is called (this call will happen automatically from the API user’s point of view, in the object’s infrastructure implementation).A dynamic can be attached to any attribute name. If the
barattribute happens to be aManagedPropertyorManagedShortcut, then it will also automatically support “dynamic value assignment”, i.e. you can do:foo.bar = lambda t: t ** 2
as a syntactic shorthand for
SetDynamic()—the setter will detect the fact that the value is callable, and divert it to the register of dynamics rather than assigning it directly (so the actual static value you get from queryingfoo.barwill not immediately change).- Parameters:
name (str) – name of the attribute
func – callable object, or
Noneto remove any dynamic that may already be associated withnameorder (int, float) – optional numeric ordering key that allows you to control the serial order in which dynamics are evaluated
canonicalized (bool) – for internal use only.
ManagedPropertyandManagedShortcutdescriptors can have multiple aliases. The default settings,canonicalized=Falsesays thatnamehsa not necessarily been translated to the descriptor’s canonical name, so this should be attempted
- Returns:
self
See also:
GetDynamic(),GetDynamics(),ClearDynamics()
- SetEventHandler(handler, slot=0)
Bind the callable
handleras part of the instance’s cascade of event handlers. Theslotargument determines the serial order in which handlers are run on each event (negative numbers before positive). IfhandlerisNone, any handler currently occupying the specified slot is removed.By default, the class’s
HandleEvent()method is registered in slot 0.The prototype for an event handler can be
handler(self, event)or justhandler(event). If the handler returns anything that evaluates toTruein the boolean sense, that’s the signal to abort the cascade of handlers for the event in question (i.e. skip the handlers in higher-numbered slots, this time around).Example:
def handler( self, event ): print( event ) w = Shady.World().SetEventHandler( handler, slot=-1 )
There is also a decorator version of the same operation, simply called
EventHandler():w = Shady.World() @w.EventHandler( slot=-1 ) def handler( self, event ): print( event )
- SetLUT(value)
Sets or unsets a
LookupTablefor aWorldorStimulus. (ForWorld`s, this will only be effective to the extent that the `World’satmosphereproperties are shared withStimulusinstances—for example, the canvas.)Calling this method is the functional equivalent of setting the
lutproperty:stim.SetLUT( value ) # These are equivalent stim.lut = value #
Setting a look-up table disables automatic linearization via
gammaand automatic dynamic-range enhancement viaditheringDenominator, and allows you to take direct control of these issues (although only for one dimension of luminance per pixel: using a look-up table is a form of indexed-color rendering).See the
Shady.Documentation.PreciseControlOfLuminancedocstring or Gamma Correction, Dynamic Range Enhancement, and the Canvas for more details.- Parameters:
value (None, str, list, numpy.ndarray, LookupTable) – A pre-existing
LookupTableinstance may be used here. Alternatively, any valid constructor argument for aLookupTablemay be used, and the instance will be constructed implicitly. That means you can use:a
numpy.ndarrayof integers inn-by-3 orm-by-n-by-3 arrangement, ora list of lists that can be implicitly converted into such an array by
numpy, orthe filename of a
npyornpzfile that contains such an array (under the variable namelutin the latter case) to be loaded byShady.Linearization.LoadLUT(), orthe filename of a
pngfile containing the look-up table entries as RGB pixel values in column-first order, again to be loaded byShady.Linearization.LoadLUT().
Finally you have the option of setting
None, to disable the usage of look-up tables.- Returns:
A
LookupTableinstance.
- SetSwapInterval(value)
By default, Shady attempts to update the screen on every physical frame the display hardware can produce. This corresponds to a “swap interval” of 1 and on a typical modern LCD display this usually means 60 frames per second. If you set the swap interval to 2, updates will happen on every second frame (hence typically 30 fps) allowing you more time to perform computations between frames.
To synchronize frames with the hardware at all, Shady relies on the “vertical synch” option which may have to be enabled explicitly in the control panel of your graphics card driver. Without synchronization, you may observe “tearing” artifacts.
The ability to change the swap interval is hit-and-miss, and back-end- and platform-dependent. This call may have no effect.
Share the underlying array storage of the named managed properties with other objects, so that a change to one affects all. Optionally, set the values at the same time. Calling syntax is flexible - the following examples all take certain property arrays associated with instance
aand share them with instancesb,candd:a.ShareProperties( 'gamma noiseAmplitude backgroundColor', b, c, d ) a.ShareProperties( ['gamma', 'noiseAmplitude', 'backgroundColor'], [b, c], d ) a.ShareProperties( b, c, d, gamma=-1, noiseAmplitude=0.01, backgroundColor=0.5 ) # sets values at the same time
A similar effect can be obtained via
b.LinkPropertiesWithMaster( a, ... )—although there you are limited to one sharee at a time—and a syntactic shorthand for this is to pretend you are assigning the master object instance itself to the target property:b.gamma = a
Undo with
MakePropertiesIndependent()(orb.gamma = b)- Returns:
self
- Sine(**kwargs)
A convenience wrapper around the
Stimulus()method, for creating a functionally-generated sine-wave patch, with the linearization and dynamic-range enhancement parameters (“atmosphere” parameters) yoked to those of theWorldby default.
- Tick()
Wait until after the next frame has been rendered. (Will have no effect, and return immediately, if your are calling this from the same thread in which your
Worldruns.)
- Undefer(target_container)
Cancels a pending task that has been scheduled by
Defer() `to run at the end of the next frame. Its input argument is the output argument of `Defer().
- Wait()
Wait until after the next frame has been rendered. (Will have no effect, and return immediately, if your are calling this from the same thread in which your
Worldruns.)
- WaitFor(condition)
This function blocks the current thread until a specified
conditionbecomesTrue. Theconditionwill be checked repeatedly in between 1-millisecond sleeps. It can be one of two things:a callable (function) which returns
Trueto signal that the wait is over - e.g.:stim.WaitFor( lambda: stim.y < 0 )
a string that names a dynamic attribute belonging to the current instance. In this case, the wait ends when there is no longer a dynamic attached the the property or shortcut in question. A dynamic may be removed due to explicit action of another thread in your program, or explicit action in this instance’s
AnimationCallback(or indeed any instance’sAnimationCallback). Alternatively, a dynamic may automatically remove itself, by raising aStopIterationexception (theFunctionobject returned byShady.Dynamics.Transitionis an example of something that does this):stim.scaling = Shady.Transition( stim.scaling, 2, duration=5 ) # the stimulus will now double in size over the course of 5 sec stim.WaitFor( 'scaling' ) # wait until it's finished
All of this assumes that you are operating in a different thread from the
World—if you callWaitForfrom inside one of theWorldorStimuluscallbacks, then it will simply sleep indefinitely because nothing will get the chance to change.
- anchor
This is a managed property. It is a pair of numbers specifying where, in normalized coordinates within the rendering area of the window, pixel coordinate (0,0) should be considered to be for Stimulus positioning. An origin of [-1,-1] means the bottom left corner; [0,0] means the center; [+1,+1] means the top right corner. Translations resulting from a change in
anchorare automatically rounded down to an integer number of pixels, to avoidanchorbecoming an unexpected source of interpolation artifacts.
- property atmosphere
This property actually encompasses multiple managed properties, all related to linearization and dynamic-range enhancement.
If you query this property, you will get a
dictof the relevant property names and values. You can also assign such a dictionary to it.More usefully, you can use it to link all the properties between instances in one go:
stim.atmosphere = world # hard-links all the "atmosphere" properties # at once
For more information, see the
Shady.Documentation.PreciseControlOfLuminancedocstring or click here.
- ax_n
This is a managed shortcut. It is a shortcut for
anchor[0]
- ay_n
This is a managed shortcut. It is a shortcut for
anchor[1]
- backgroundColor
This is a managed property. It is a triplet of numbers, each in the range 0 to 1, corresponding to red, green and blue channels. It specifies the
backgroundColorof the background canvas Stimulus, if present (theWorldneeds to be constructed with thecanvas=True, or you otherwise need to callMakeCanvas()). When a canvas is created, this property of theWorldis automatically linked to the corresponding property of the canvasStimulusinstance; if there is no canvas then this property is unused, although you may wish to link it explicitly to other stimuli withShareProperties()orLinkPropertiesWithMaster().Default value:
[0.5, 0.5, 0.5]Canonical name:
backgroundColor- Subscripting shortcuts:
bgredis a shortcut forbackgroundColor[0]bggreenis a shortcut forbackgroundColor[1]bgblueis a shortcut forbackgroundColor[2]
- bg
bgis an alias forbackgroundColor
- bgblue
This is a managed shortcut. It is a shortcut for
backgroundColor[2]
- bgcolor
bgcoloris an alias forbackgroundColor
- bggreen
This is a managed shortcut. It is a shortcut for
backgroundColor[1]
- bgred
This is a managed shortcut. It is a shortcut for
backgroundColor[0]
- property bitCombiningMode
This non-managed property allows high-dynamic-range rendering on specialized vision-science hardware. It can be set to:
- 0, or equivalently
'C24': denotes standard 24-bit full-color mode (8 bits per channel, with dithering by default).
- 1, or equivalently
'M16’ or'monoPlusPlus': denotes 16-bit monochrome reinterpretation of frame-buffer contents (each pixel’s red channel is the more-significant byte, and its green channel is the less-signficiant byte, of a 16 bit value). As with look-up tables, Shady reads just the red channel to determine the monochrome target value. Dithering is disabled.
- 2, or equivalently
'C48'or'colorPlusPlus': denotes 48-bit color mode in which horizontal resolution is sacrificed. Dithering is disabled. Each pixel in the frame buffer is paired with its horizontal neighbor, and together they specify a 16-bit-per-channel value for the corresponding yoked pair of physical pixels. Shady also throws away vertical resolution at the same time, so that you can continue working with square pixels and sane geometry—if you do not want this, then the
SetBitCombiningMode()method allows more control.
Values 3 and 4 are also reserved for debugging C48 mode (they will not generate correct C48 stimuli).
- 0, or equivalently
- blue
This is a managed shortcut. It is a shortcut for
clearColor[2]
- bluegamma
This is a managed shortcut. It is a shortcut for
gamma[2]
- bluenoise
This is a managed shortcut. It is a shortcut for
noiseAmplitude[2]
- clearColor
This is a managed property. It is a triplet of numbers in the range 0 to 1. It specifies the color of the empty screen. Note that these values are never linearized or dithered. For more precise control over the background, construct your
Worldwith the argumentcanvas=Trueand then you can manipulatebackgroundColor,gamma, ‘.ditheringDenominator’ andnoiseAmplitude.Default value: varies according to
BackEnd()settings- Subscripting shortcuts:
redis a shortcut forclearColor[0]greenis a shortcut forclearColor[1]blueis a shortcut forclearColor[2]
- dd
ddis an alias forditheringDenominator
- ditheringDenominator
This is a managed property. It is a floating-point number. It should be 0 or negative to disable dithering, or otherwise equal to the maximum DAC value (255 for most video cards). It specifies the
ditheringDenominatorfor the background canvas Stimulus, if present (theWorldneeds to be constructed with thecanvas=True, or you otherwise need to callMakeCanvas()). When a canvas is created, this property of theWorldis automatically linked to the corresponding property of the canvasStimulusinstance; if there is no canvas then this property is unused, although you may wish to link it explicitly to other stimuli withShareProperties()orLinkPropertiesWithMaster().Default value: dithering enabled (value determined automatically)
Canonical name:
ditheringDenominatorOther aliases:
dd
- property fakeFrameRate
By default, with
fakeFrameRateequal toNone, aWorldwill try to update itself at the frame rate of the display hardware (though of couse it may end up being slower if you are doing too much computation between frames, or if there are other tasks that are using too many CPU or GPU resources). The time argumenttthat gets passed into animation callbacks and dynamic property evaluations will reflect the real wall-time at which each frame is drawn.However, if you set
fakeFrameRateto a positive value, now frames can take as long as they like in real time, and thetargument will reflect the theoretical amount of time passed based on the number of frames completed, assuming the specified frame rate. This allows you to run animations in slower-than-real time. One of the main applications would be for capturing stills or movies ofWorldanimation (the capture operation itself tends to be slow).If you do not fully understand the explanation above, do not change this property. It should be left as
Nonewhenever you want to display time-accurate animation (which should be the case under nearly all circumstances).
- gamma
This is a managed property. It is a triplet of numbers, each in the range 0 to 1, corresponding to red, green and blue channels. It specifies the
gammaof the background canvas Stimulus, if present (theWorldneeds to be constructed with thecanvas=True, or you otherwise need to callMakeCanvas()). When a canvas is created, this property of theWorldis automatically linked to the corresponding property of the canvasStimulusinstance; if there is no canvas then this property is unused, although you may wish to link it explicitly to other stimuli withShareProperties()orLinkPropertiesWithMaster().gamma = 1is linear;gamma = -1gives you the sRGB gamma profile (a piecewise function visually very similar togamma = 2.2)
- green
This is a managed shortcut. It is a shortcut for
clearColor[1]
- greengamma
This is a managed shortcut. It is a shortcut for
gamma[1]
- greennoise
This is a managed shortcut. It is a shortcut for
noiseAmplitude[1]
- height
This is a managed shortcut. It is a shortcut for
size[1]
- property lut
The value of this property will either be
None, or an instance ofLookupTable. Assigning to this property is equivalent to calling theSetLUT()method—so you can assign any of the valid argument types accepted by that function. AssigningNonedisables look-up.
- noise
noiseis an alias fornoiseAmplitude
- noiseAmplitude
This is a managed property. It is a triplet of floating-point numbers corresponding to red, green and blue channels. It specifies the
noiseAmplitudefor the background canvas Stimulus, if present (theWorldneeds to be constructed with thecanvas=True, or you otherwise need to callMakeCanvas()). When a canvas is created, this property of theWorldis automatically linked to the corresponding property of the canvasStimulusinstance; if there is no canvas then this property is unused, although you may wish to link it explicitly to other stimuli withShareProperties()orLinkPropertiesWithMaster().Default value:
[0.0, 0.0, 0.0]Canonical name:
noiseAmplitudeOther aliases:
noise- Subscripting shortcuts:
rednoiseis a shortcut fornoiseAmplitude[0]greennoiseis a shortcut fornoiseAmplitude[1]bluenoiseis a shortcut fornoiseAmplitude[2]
- outOfRangeAlpha
This is a managed property. It is a number in the range 0 to 1. It specifies the
outOfRangeAlphafor the background canvas Stimulus, if present (theWorldneeds to be constructed with thecanvas=True, or you otherwise need to callMakeCanvas()). When a canvas is created, this property of theWorldis automatically linked to the corresponding property of the canvasStimulusinstance; if there is no canvas then this property is unused, although you may wish to link it explicitly to other stimuli withShareProperties()orLinkPropertiesWithMaster().Default value:
1.0
- outOfRangeColor
This is a managed property. It is a triplet of numbers, each in the range 0 to 1, corresponding to red, green and blue channels. It specifies the
outOfRangeColorfor the background canvas Stimulus, if present (theWorldneeds to be constructed with thecanvas=True, or you otherwise need to callMakeCanvas()). When a canvas is created, this property of theWorldis automatically linked to the corresponding property of the canvasStimulusinstance; if there is no canvas then this property is unused, although you may wish to link it explicitly to other stimuli withShareProperties()orLinkPropertiesWithMaster().Default value:
[1.0, 0.0, 1.0]
- pixelGrouping
Developer note on pixelGrouping: Explicit rounding, in the shader, to the nearest screen pixel location, is disabled by default. However you can see the tiny rounding errors this creates if you create, for example, a signal function that hits exactly 0 at multiple places on top of a background value of 0.5, such as:
Shady.AddCustomSignalFunction(''' float Tartan(vec2 p) { p = mod(p, 2.0); return 0.25 * (p.x - p.y); } ''') w=Shady.World(fullScreenMode=0,bitCombiningMode=1);s=w.Stimulus(sigfunc=Shady.SIGFUNC.Tartan)
Compare this under
w.pixelGrouping = 0withw.pixelGrouping = 1but be aware that (a) the differences are tiny, rounding to values 1/65535th apart and only visible because of the red-green split, (b) pixel rounding is not computationally trivial on the GPU - it requires a per-fragment matrix multiplication.You can change the default with
Shady.World.SetDefault( pixelGrouping=1 )- then this setting will be respected automatically whenever you change tow.bitCombiningMode=0orw.bitCombiningMode=1.
- red
This is a managed shortcut. It is a shortcut for
clearColor[0]
- redgamma
This is a managed shortcut. It is a shortcut for
gamma[0]
- rednoise
This is a managed shortcut. It is a shortcut for
noiseAmplitude[0]
- size
This is a managed property. It is a pair of integers denoting the width and height of the
Worldin pixels. Do not attempt to change these values - it will not alter the size of the window and may have unexpected side effects.
- t
tis an alias fortimeInSeconds
- timeInSeconds
This is a managed property. It is a floating-point scalar value indicating the time in seconds since the
Worldstarted rendering.Default value:
0.0Canonical name:
timeInSecondsOther aliases:
t
- visible
This is a managed property. It is a scalar boolean value indicating whether or not the
Worldshould be visible or not. On Windows the transition from visible to invisible and back is reasonably instantaneous. On the Mac you may have to endure the minimize/restore animation (although this is backend-dependent).
- width
This is a managed shortcut. It is a shortcut for
size[0]
The Stimulus Class
- class Shady.Stimulus(world, source=None, name=None, page=None, multipage=False, debugTiming=None, **kwargs)
Bases:
LinkGLA
Stimulusis an entity that is drawn automatically within its parentWorldon every frame. It has a number of properties whose values govern its appearance independent of other stimuli.- Parameters:
world (World) – The required first argument is a
Worldinstance. To make this more readable you can alternatively call theStimulusconstructor as aWorldmethod:w = World( ... ) s = w.Stimulus( source, ... )
source (str, list, numpy.ndarray, None) – The second argument is the
sourceof the carrier texture. This may be omitted (or equivalently set toNone) if your stimulus is just a blank patch, or if its carrier signal is defined purely by a function in the shader (see thesignalFunctionproperty). Alternativelysourcemay be a string denoting an image filename or glob pattern for image filenames, anumpyarray specifying texture data explicitly, or a list of strings and/ornumpyarrays - seeLoadTexture()for details.name (str) – This is a string that will identify this
Stimulusin the containerw.stimuliof theWorldto which it belongs. To ensure uniqueness of the names in thisdict, you may include a single numeric printf-style pattern in the name (the defaultname, for example, is'stim%02d').page (int) – You may optionally initialize the
pageproperty here.multipage (bool) – If you set this to
True, multiple image frames will loaded using theLoadPages()method: this transfers each frame to the graphics card as a separate texture, which you switch between using thepageproperty.By contrast, if you leave it at the default value
False, multiple image frames are handled by concatenating them horizontally into a single texture, and you switch between them using theframeproperty, which indirectly manipulatescarrierTranslation.You may need to use
multipage=Truefor animated images that have a large width and/or high number of frames, because the normal concatenation method may lead to the texture exceeding the maximum allowable width.**kwargs – Managed property values can also be specified as optional keyword arguments during construction—for example:
s = w.Stimulus( ..., foregroundColor=[1, 0, 0], ... )
The
width,heightand/orsizearguments (all shortcuts/aliases into theenvelopeSizemanaged property) are worth mentioning specifically: these can be used to specify the dimensions of the envelope in pixels. For texture stimuli these can usually be omitted, since usually they will be dictated by the dimensions of the underlyingsourcematerial. However, they can be specified explicitly if you want to crop or repeat an image texture. Note that you should specify dimensions in the same units as the underlying texture (i.e. unscaled pixels). If you want to change the physical size of the rendered stimulus by magnifying or shrinking the texture, manipulate theenvelopeScalingproperty either directly, or indirectly viascaledSize(but remember this will produce interpolation artifacts).
- classmethod AddCustomUniform(name=None, defaultValue=None, **kwargs)
Modifies the class (
WorldorStimulus) so that it possesses one or more new managed properties, whose values are then accessible from inside the fragment shader. This must be performed beforeWorldconstruction.Example:
Shady.World.AddCustomUniform( 'spam', [1,2,3] ) Shady.Stimulus.AddCustomUniform( eggs=4, beans=[5,6] )
Either syntax can be used in either class. The keyword-argument syntax has the advantage of being able to define multiple new properties in one call.
The default values you supply dictate whether the new property is 1-, 2-, 3- or 4-dimensional. For a 1-dimensional property, the type of your default value also determines whether the property gets defined as an integer or floating-point variable. (2-, 3- or 4- dimensional properties are always re-cast as floating-point).
The corresponding uniform variables are then automatically made available in the fragment shader code, with the first letter of the property name getting capitalized and a ‘u’ prepended. So, as a consequence of the two lines in the example above, the modified shader would then contain these definitions:
uniform vec3 uSpam; uniform int uEggs; uniform vec2 uBeans;
…all of which is useless unless you actually write some custom shader functions that access the new variables. You might use the new variables in your own custom signal-function, modulation-function, windowing-function or color-transformation snippets.
- classmethod Properties(includeShortcuts=False)
Return a list of all managed properties of this class. (Class method)
- Parameters:
includeShortcuts – Determines whether
ManagedShortcutinstances should be included (True) or not (False; default) along withManagedPropertyinstances.- Returns:
A list of
ManagedProperty(and optionally alsoManagedShortcut) descriptor instances.
- classmethod SetDefault(**kwargs)
Affects the class. Sets the default values of named properties. In instances of the class created subsequently, managed properties will have the new default values.
Example:
cls.SetDefault( color=(1,0,0), rotation=90 )
- AnimationCallback(func=None)
Decorator version of
SetAnimationCallback()Examples:
w = Shady.World() @w.AnimationCallback def anim( self, t ): print( t )
- BoundingBox(worldCoordinates=False)
This method returns the bounding box of the
Stimulus, in pixels.- Parameters:
worldCoordinates (bool) – If
True, then theleftandbottomcoordinates are computed relative to theWorld’sanchor. IfFalse, then[0,0]is considered to be the bottom-left corner of theWorld, regardless of itsanchor.- Returns:
[left, bottom], [width, height]pixel coordinates for theStimulus.
- Capture(pil=False, saveas='', normalize='auto')
This captures the pixel data from a particular
Stimulus. Note that it accomplishes this simply by callingWorld.Capture()with the appropriate bounding box. Note, therefore, that if other stimuli overlap this one, the capture will contain image data composited from all of them.- Parameters:
pil (bool) – If
True, and ifPILorpillowis installed, return the image data as aPIL.Image.Imageinstance. IfFalse, return the data as anumpyarray.saveas (str) – If
PILorpillowis installed, you can use this argument to specify an optional filename for immediately saving the image data.normalize (bool or ‘auto’) – If
False, return raw RGBA values as integers. IfTrue, return floating-point values normalized in the range 0 to 1, and furthermore undo the effects of the currentbitCombiningModeif any. If'auto', the default isFalseexcept when all the following conditions are met:numpyis installed,pilisFalse, andself.bitCombiningModeis non-zero.
- Returns:
Either a
numpy.ndarrayor aPIL.Image.Imageinstance, depending on thepilargument.
- ClearDynamics()
Remove all property dynamics from the instance.
See also:
GetDynamic(),GetDynamics(),SetDynamic()
- Enter(**props)
If a
Stimulusinstance has previously left the stage withLeave(), theEnter()method allows it to come back.You may simultaneously change its properties, using keyword arguments.
- GetDynamic(name)
For dynamic properties, return the actual callable object that generates property values, rather than the current static value.
- Parameters:
name (str) – Name of the property
- Returns:
Callable object responsible for generating values for the named property (or
Noneif there is no such dynamic).
See also:
GetDynamics(),SetDynamic(),ClearDynamics()
- GetDynamics()
Get an ordered list of (name, callable) tuples detailing all the dynamics of this instance.
See also:
GetDynamic(),SetDynamic(),ClearDynamics()
- Inherit(other)
Set the values of all managed properties of this instance to match those of another instance. Only properties common to both objects will be considered. Dynamic property values will be copied as dynamic properties.
- Parameters:
other – instance whose property values will be copied to the properties of
self- Returns:
self
- Leave(deferAfterAdditionalFrames=0)
If a
Stimulusinstancestimis made invisible withstim.visible=False, it is not rendered on screen. However, it is still a member of thestimulidictionary of theWorldto which it belongs, and itsAnimationCallback(if any), and any dynamics attached to its individual properties, are still evaluated on every frame.On the other hand, you tell a
Stimulusinstance toLeave()the stage entirely, it is removed from thestimulidictionary of itsWorld, it is not rendered (regardless of itsvisiblesetting), and none of its callbacks and dynamics are called—not until you tell it toEnter()again.- Returns:
the
Stimulusinstance itself.
- LinkPropertiesWithMaster(master, *pargs, **kwargs)
-
- Returns:
self
- LinkTextureWithMaster(master)
This is a wrapper around
LinkPropertiesWithMaster()that allowsStimulusinstances to share a texture—it shares thetextureID,textureSlotNumberanduseTexturemanaged properties.
- LoadPages(sources, keys=0, updateEnvelopeSize=True, page=0, **kwargs)
This method prepares a
Stimulusinstance for animation using thepagemechanism (rather than the defaultframemechanism). It loads multiple textures in multiple pages, indexed by the specifiedkeys(or by integers starting atkeys, ifkeysis an integer). Subsequently, you can switch between pages by setting thepageproperty or equivalently calling theSwitchTo()method.This method is called when constructing a
Stimulusinstance with themultipageconstructor option. It can also be called explicitly, which is especially useful if you want to re-use texture buffers that have already been allocated on the graphics card, for new stimulus content.
- LoadSubTexture(source, x=0, y=0)
This is similar to
LoadTexture()in its interpretation of thesourceargument. The difference is that theStimulusmust already have an existing texture, and the new source is pasted over the old one (or over part of it, depending on the new source’s size).xandyare pixel coordinates relative to the existing texture’s lower-left corner. They specify the position of the lower-left corner of the incoming piece of the texture.
- LoadTexture(source, updateEnvelopeSize=True, useTexture=True)
Loads texture data from
sourceand associates it with this Stimulus.- Parameters:
source – the source of the carrier texture data. This may be:
omitted or set to
Noneif there is no texture (just a constant carrier signal, or one defined by a function in the shader)a string (possibly including glob characters
'*'and/or'?') denoting one or more image files to be used as animation framesa
numpyarray specifying the pixel values of a texture image, in which case:source.dtypemust be one of:numpy.dtype('uint8'): 8-bit pixel values in the range 0 to 255numpy.dtype('float32'): pixel value in the range 0.0 to 1.0numpy.dtype('float64'): pixel value in the range 0.0 to 1.0 (will be converted to float32 automatically)
source.shapemust be one of:[height, width]: LUMINANCE image[height, width, 1]: LUMINANCE image[height, width, 2]: LUMINANCE_ALPHA image[height, width, 3]: RGB image[height, width, 4]: RGBA image
a
listortuplecontaining filenames and/ornumpyarrays as above, to be used as multiple frames
updateEnvelopeSize (bool) – whether or not to update the envelope size to match the dimensions of the new texture
useTexture (bool) – new value for the
useTextureproperty attribute that enables or disables the use of this texture
- MakePropertiesIndependent(*pargs, **kwargs)
Undoes the effect of
ShareProperties(). Optionally, set the values of the properties after unsharing.Example:
a.ShareProperties( b, c, d, alpha=1, beta=2, gamma=3 ) b.MakePropertiesIndependent( alpha=4 ) # Now `a` and `b` share properties `.beta` and `.gamma`, but # `b.alpha` is independent and already has the new value 4; # by contrast `a`, `c` and `d` still share all three properties. c.MakePropertiesIndependent( 'beta', 'gamma' ) # Now `c` does not share anything except `.alpha`, although the # property values themselves have not yet been changed. c.Set( beta=c, gamma=c ) # a syntactic shorthand for the same operation as in the previous # line
- Returns:
self
- NewPage(source, key=None, updateEnvelopeSize=True, **kwargs)
Create a new page from the specified
source. A page is a bundle of properties that determine texture, envelope size, and (viadrawModeandpoints) envelope shape.Note that this can be automated, to load multiple sources as multiple pages, either by specifying
multipage=Truewhen you construct theStimulusinstance, or by explicitly callingLoadPages().- Parameters:
source – Any valid input to
LoadTexture(), includingNone.key – By default, a new page is unlabelled, but if you specify a
keyhere,SavePage( key )will be called automatically to store and label the new texture settings. This will enable you toSwitchTo()this page in future.**kwargs – Additional keyword arguments can be used to set property values at the same time, if you want. (NB: you can set any property at all this way, but remember that not all properties get paged in and out—apart from the ones whose values get inferred from
sourceautomatically, the others that are most meaningful here aredrawModeandpoints)
See also:
page,SavePage(),SwitchTo()andLoadPages()
- Place(xp, yp=None, worldCoordinates=True, polar=False)
Convert 2-D normalized coordinates (relative to the instance, -1 to +1 in each dimension), into 2-D pixel coordinates, either relative to the
World’s currentanchor, or relative to theWorld’s bottom left corner irrespective ofanchor.Input coordinates may be given as one scalar argument, two scalar arguments, or one argument that is a sequence of two numbers. Depending on the
polarargument, these will be interpreted asx, yCartesian coordinates (where, ifyomitted, it defaults toy=x) ortheta, rpolar coordinates (where, ifris omitted, it defaults tor=1).- Parameters:
worldCoordinates (bool) – If
True, return pixel coordinates relative to theWorld’s ownanchorposition. IfFalse, return pixel coordinates relative to theWorld’s bottom left corner irrespective of itsanchor.polar (bool) – If
True, input coordinates are interpreted as an angle (in degrees) and an optional radius (0 denoting the center, 1 denoting the edge).
Examples:
instance.Place( [ -1, 1 ] ) # top left corner instance.Place( -1, 1 ) # likewise, top left corner instance.Place( 90, polar=True ) # middle of top edge (radius 1 assumed) instance.Place( [ 90, 0.5 ], polar=True ) # halfway between center and top instance.Place( 90, 0.5, polar=True ) # likewise, halfway between center and top
- ResetClock(other=None)
A
Stimulusmay have callback functions that are called on every frame—for example, a function that you have registered as itsAnimationCallback, or functions that you assign to its managed properties (dynamic value assignment). In all cases, the argument that is passed to these callbacks on each frame ist, time in seconds. By default, thistis the same as theWorld’st, i.e. the number of seconds have elapsed since theWorldbegan rendering. However, if you wish, you can alter thet0from which eachStimulusinstance’s clock counts:stim.ResetClock() # resets the clock to 0 stim.ResetClock( otherStim ) # synchronizes with `otherStim`
- SavePage(key)
Save the current “page” (a bundle of properties determining texture, envelope size and envelope shape) in the dictionary
self.pagesunder the specifiedkey.See also:
page,NewPage(), andSwitchTo()
- Set(**kwargs)
Set the values of multiple managed properties in one call. An error will be raised if you try to set the value of a non-existent, or non-managed, property.
- Returns:
self
Example:
instance.Set( rotation=90, color=(0, 0, 1), contrast=0.5 )
- SetAnimationCallback(callback)
Bind the callable object
callbackas the instance’s animation callback. Each object, whether it is aWorldor aStimulus, may optionally have a single animation callback which is called on every frame. If thecallbackargument isNone, any existing callback is removed.The animation callback is installed as the attribute
self.Animate. By default, this attribute isNone.The prototype for an animation callback can be
callback(self, t)or justcallback(t)(if it’s the latter then you can, alternatively, simply assign it asself.Animate = callback).Example:
def animate( self, t ): print( t ) my_world = Shady.World().SetAnimationCallback( animate )
There is also a decorator version of the same operation, simply called
AnimationCallback():stim = my_world.Stimulus() @stim.AnimationCallback def Animate( self, t ): print( t )
- SetDynamic(name, func, order=-1, canonicalized=False)
Associate a “dynamic” (i.e. a function that can be called repeatedly to set an attribute) with the name of an attribute.
For example:
foo.Set( 'bar', lambda t: t ** 2 )
This will set
foo.bartot ** 2every time the methodfoo._RunDynamics( t )is called (this call will happen automatically from the API user’s point of view, in the object’s infrastructure implementation).A dynamic can be attached to any attribute name. If the
barattribute happens to be aManagedPropertyorManagedShortcut, then it will also automatically support “dynamic value assignment”, i.e. you can do:foo.bar = lambda t: t ** 2
as a syntactic shorthand for
SetDynamic()—the setter will detect the fact that the value is callable, and divert it to the register of dynamics rather than assigning it directly (so the actual static value you get from queryingfoo.barwill not immediately change).- Parameters:
name (str) – name of the attribute
func – callable object, or
Noneto remove any dynamic that may already be associated withnameorder (int, float) – optional numeric ordering key that allows you to control the serial order in which dynamics are evaluated
canonicalized (bool) – for internal use only.
ManagedPropertyandManagedShortcutdescriptors can have multiple aliases. The default settings,canonicalized=Falsesays thatnamehsa not necessarily been translated to the descriptor’s canonical name, so this should be attempted
- Returns:
self
See also:
GetDynamic(),GetDynamics(),ClearDynamics()
- SetLUT(value)
Sets or unsets a
LookupTablefor aWorldorStimulus. (ForWorld`s, this will only be effective to the extent that the `World’satmosphereproperties are shared withStimulusinstances—for example, the canvas.)Calling this method is the functional equivalent of setting the
lutproperty:stim.SetLUT( value ) # These are equivalent stim.lut = value #
Setting a look-up table disables automatic linearization via
gammaand automatic dynamic-range enhancement viaditheringDenominator, and allows you to take direct control of these issues (although only for one dimension of luminance per pixel: using a look-up table is a form of indexed-color rendering).See the
Shady.Documentation.PreciseControlOfLuminancedocstring or Gamma Correction, Dynamic Range Enhancement, and the Canvas for more details.- Parameters:
value (None, str, list, numpy.ndarray, LookupTable) – A pre-existing
LookupTableinstance may be used here. Alternatively, any valid constructor argument for aLookupTablemay be used, and the instance will be constructed implicitly. That means you can use:a
numpy.ndarrayof integers inn-by-3 orm-by-n-by-3 arrangement, ora list of lists that can be implicitly converted into such an array by
numpy, orthe filename of a
npyornpzfile that contains such an array (under the variable namelutin the latter case) to be loaded byShady.Linearization.LoadLUT(), orthe filename of a
pngfile containing the look-up table entries as RGB pixel values in column-first order, again to be loaded byShady.Linearization.LoadLUT().
Finally you have the option of setting
None, to disable the usage of look-up tables.- Returns:
A
LookupTableinstance.
Share the underlying array storage of the named managed properties with other objects, so that a change to one affects all. Optionally, set the values at the same time. Calling syntax is flexible - the following examples all take certain property arrays associated with instance
aand share them with instancesb,candd:a.ShareProperties( 'gamma noiseAmplitude backgroundColor', b, c, d ) a.ShareProperties( ['gamma', 'noiseAmplitude', 'backgroundColor'], [b, c], d ) a.ShareProperties( b, c, d, gamma=-1, noiseAmplitude=0.01, backgroundColor=0.5 ) # sets values at the same time
A similar effect can be obtained via
b.LinkPropertiesWithMaster( a, ... )—although there you are limited to one sharee at a time—and a syntactic shorthand for this is to pretend you are assigning the master object instance itself to the target property:b.gamma = a
Undo with
MakePropertiesIndependent()(orb.gamma = b)- Returns:
self
This is a wrapper around
ShareProperties()that allowsStimulusinstances to share a texture—it shares thetextureID,textureSlotNumber,textureSizeanduseTexturemanaged properties.
- SwitchTo(key)
Switch to the “page” associated with the given
key. A page is a bundle of properties that determine texture, envelope size and envelope shape. Thekeyargument must be one of the keys in the dictionaryself.pages. Note that if the current settings have not been stored (viaSavePage(), via the explicit specification of a key duringNewPage(), or via the automated loop ofNewPage()calls provided byLoadPages()) then this method will cause the current settings to be lost.See also:
page,NewPage(),LoadPages()andSavePage()
- WaitFor(condition)
This function blocks the current thread until a specified
conditionbecomesTrue. Theconditionwill be checked repeatedly in between 1-millisecond sleeps. It can be one of two things:a callable (function) which returns
Trueto signal that the wait is over - e.g.:stim.WaitFor( lambda: stim.y < 0 )
a string that names a dynamic attribute belonging to the current instance. In this case, the wait ends when there is no longer a dynamic attached the the property or shortcut in question. A dynamic may be removed due to explicit action of another thread in your program, or explicit action in this instance’s
AnimationCallback(or indeed any instance’sAnimationCallback). Alternatively, a dynamic may automatically remove itself, by raising aStopIterationexception (theFunctionobject returned byShady.Dynamics.Transitionis an example of something that does this):stim.scaling = Shady.Transition( stim.scaling, 2, duration=5 ) # the stimulus will now double in size over the course of 5 sec stim.WaitFor( 'scaling' ) # wait until it's finished
All of this assumes that you are operating in a different thread from the
World—if you callWaitForfrom inside one of theWorldorStimuluscallbacks, then it will simply sleep indefinitely because nothing will get the chance to change.
- addb
This is a managed shortcut. It is a shortcut for
offset[2]
- addg
This is a managed shortcut. It is a shortcut for
offset[1]
- addr
This is a managed shortcut. It is a shortcut for
offset[0]
- alpha
This is a managed property. It is a floating-point number from 0 to 1. It specifies the opacity of the
Stimulusas a whole. Note that with psychophysical stimuli you should always ensurealpha== 1, and manipulatebackgroundColorandnormalizedContrastinstead: this is because alpha-blending is carried out by the graphics card AFTER our linearization (via thegammaproperty or via a look-up table) is applied. Therefore a blended result will no longer be linearized.
- anchor
This is a managed property. It is a sequence of two floating-point numbers expressed in normalized coordinates (from -1 to +1). It denotes where, on the surface of the envelope, the anchor point will be. This anchor point is the point whose coordinates are manipulated directly by the other properties, and it also serves as the origin of any scaling and rotation of the envelope. The default value is
[0.0, 0.0]denoting the center, whereas[-1.0, -1.0]would be the bottom left corner.The translation caused by changes to
anchoris always rounded down to an integer number of pixels, to avoid it becoming an unforeseen cause of interpolation artifacts.
- angle
angleis an alias forenvelopeRotation
- property aspect
Non-managed property that affects the behavior of
scaledWidthandscaledHeightmanipulations. The value may be aNone, the string'fixed', or a floating-point number.Assigning a floating-point number to
scaledAspectRatiowill immediately reduce either the horizontal or the vertical component ofenvelopeScalingas necessary to achieve the target aspect ratio.Once the value is set to something other than
None, future manipulation of either thescaledWidthproperty or thescaledHeightproperty will cause the other property to be adjusted simultaneously, to maintain the target aspect ratio. If the value is'fixed', then the target value is simply “whatever it was before you made the manipulation”.This prospective control only applies to the
scaled*properties, however—if you directly manipulateenvelopeSizeorenvelopeScaling, thescaledAspectRatiosetting will not be automatically reasserted.
- property atmosphere
This property actually encompasses multiple managed properties, all related to linearization and dynamic-range enhancement.
If you query this property, you will get a
dictof the relevant property names and values. You can also assign such a dictionary to it.More usefully, you can use it to link all the properties between instances in one go:
stim.atmosphere = world # hard-links all the "atmosphere" properties # at once
For more information, see the
Shady.Documentation.PreciseControlOfLuminancedocstring or click here.
- ax_n
This is a managed shortcut. It is a shortcut for
anchor[0]
- ay_n
This is a managed shortcut. It is a shortcut for
anchor[1]
- backgroundAlpha
This is a managed property. It is a floating-point number from 0 to 1, indicating the opacity at locations where the signal has been attenuated away completely (by windowing via
plateauProportion, by a custommodulationFunction, or by manipulation of overallnormalizedContrast).For psychophysical stimuli, ensure
backgroundAlphais 1.0 and manipulatebackgroundColorinstead: although alpha can be used for windowing in this way, alpha-blending is applied post- linearization so the result will not be well linearized, except in very fragile special cases.Default value:
1.0Canonical name:
backgroundAlphaOther aliases:
bgalpha
- backgroundColor
This is a managed property. It is a triplet of numbers, each in the range 0 to 1, corresponding to red, green and blue channels. It specifies the color at locations in which the carrier signal (texture and/or foreground color and/or functionally generated carrier signal) has been attenuated away completely (by contrast scaling, windowing, or custom contrast modulation pattern).
Default value:
[0.5, 0.5, 0.5]Canonical name:
backgroundColor- Subscripting shortcuts:
bgredis a shortcut forbackgroundColor[0]bggreenis a shortcut forbackgroundColor[1]bgblueis a shortcut forbackgroundColor[2]
- bg
bgis an alias forbackgroundColor
- bgalpha
bgalphais an alias forbackgroundAlpha
- bgblue
This is a managed shortcut. It is a shortcut for
backgroundColor[2]
- bgcolor
bgcoloris an alias forbackgroundColor
- bggreen
This is a managed shortcut. It is a shortcut for
backgroundColor[1]
- bgred
This is a managed shortcut. It is a shortcut for
backgroundColor[0]
- blue
This is a managed shortcut. It is a shortcut for
color[2]
- bluegamma
This is a managed shortcut. It is a shortcut for
gamma[2]
- bluenoise
This is a managed shortcut. It is a shortcut for
noiseAmplitude[2]
- carrierRotation
This is a managed property. It is a scalar number, expressed in degrees. The carrier will be rotated counter-clockwise by this number of degrees around the center of the envelope. Note that if your rotation values is not divisible by 90, this will introduce interpolation artifacts into stimuli that use textures. (Unlike
envelopeRotation, however, this will not compromise pure functionally-generated stimuli.)Default value:
0.0Canonical name:
carrierRotationOther aliases:
cr
- carrierScaling
This is a managed property. It is a sequence of two floating-point numbers denoting horizontal and vertical scaling factors. The carrier will be magnified by these factors relative to an origin the center of the envelope. Note that scaling values != 1.0 will introduce interpolation artifacts into stimuli that use textures (but unlike
envelopeScaling, this will not compromise pure functionally-generated stimuli).Default value:
[1.0, 1.0]Canonical name:
carrierScaling- Subscripting shortcuts:
cxscaleis a shortcut forcarrierScaling[0]cyscaleis a shortcut forcarrierScaling[1]
- carrierTranslation
This is a managed property. It is a sequence of two numbers, expressed in pixels, corresponding to x and y dimensions. It shifts the carrier (texture stimulus and/or shader function) relative to the envelope. Note that non-integer translation values will introduce interpolation artifacts into stimuli that use textures (but unlike
envelopeTranslation, this should not compromise pure functionally-generated stimuli).Default value:
[0.0, 0.0]- Subscripting shortcuts:
cxis a shortcut forcarrierTranslation[0]cyis a shortcut forcarrierTranslation[1]
- color
This is a managed property. It is a triplet of numbers, each in the range 0 to 1, corresponding to red, green and blue channels. Values may also be negative, in which case no colorization is applied in the corresponding channel.
Where non-negative, foreground color plays slightly different roles depending on other parameters:
If the
Stimulususes a texture, the pixel values from the texture are tinted via multiplication with thecolorvalues.If the
Stimulususes asignalFunctionthen the signal is also multiplied by thecolorbefore being added.If there is no texture and no
signalFunction, the carrier image consists of just the specified uniform solidcolor. TheStimuluscolor may still be attenuated towards thebackgroundColor—uniformly by settingnormalizedContrast< 1.0, and/or as a function of space by settingplateauProportion>= 0.0or by using amodulationFunction).
- colorTransformation
This is a managed property. It is an integer specifying the index of a shader-side color transformation function. If it is set to 0, no special color transformation is performed (but the standard
gammatransformation can still be independently applied).Further values may be supported if you add support for them yourself using
AddCustomColorTransformation().In the shader, the color transformation function takes one input argument (a
vec4containing pre-linearization RGBA values) and return a transformedvec4. The return value will then be passed on to the standardgammalinearization step, if used.See also:
gammaDefault value:
0
- contrast
contrastis an alias fornormalizedContrast
- cr
cris an alias forcarrierRotation
- cscale
cscaleis an alias forcarrierScaling
- cscaling
cscalingis an alias forcarrierScaling
- cx
This is a managed shortcut. It is a shortcut for
carrierTranslation[0]
- cxscale
This is a managed shortcut. It is a shortcut for
carrierScaling[0]
- cy
This is a managed shortcut. It is a shortcut for
carrierTranslation[1]
- cyscale
This is a managed shortcut. It is a shortcut for
carrierScaling[1]
- dd
ddis an alias forditheringDenominator
- depthPlane
depthPlaneis an alias forz
- ditheringDenominator
This is a managed property. It is a floating-point number. It should be 0 or negative to disable dithering, or otherwise equal to the maximum DAC value (255 for most video cards). It allows implementation of the “noisy-bit” dithering approach (Allard & Faubert, 2008) for increasing effective dynamic range.
This is distinct from the
noiseAmplitudeproperty, which specifies noise that is (a) applied pre-gamma-correction, (b) can be scaled differently in different color channels, but (c) is otherwise perfectly correlated across color channels. Noisy-bit dithering, on the other hand (a) is applied post-gamma-correction, (b) has the same amplitude in all color channels but (c) is indepdent in each color channel.Note that, like gamma-correction, noisy-bit dithering is disabled for stimuli that use a
lutDefault value: dithering enabled (value determined automatically)
Canonical name:
ditheringDenominatorOther aliases:
dd
- drawMode
This is a managed property. It is an integer that selects between different drawing behaviors. The different values are given meaningful names in the namespace
DRAWMODE, whose documentation also explains the behavior of the different draw modes.Default value:
1
- envelopeOrigin
This is a managed property. It is a triplet of numbers, expressed in pixels, denoting the starting-point, in the coordinate system of the parent
World, of the offsetsenvelopeTranslation(which is composed ofxandy) and depth coordinatez. The actual rendered position of the anchor point ofStimulusswill be:[ int(s.x) + s.ox, int(s.y) + s.oy, s.z + s.oz ]
relative to the
World’s ownorigin.You can manipulate
envelopeOriginexclusively and leaveenvelopeTranslationat 0, as an alternative way of specifyingStimulusposition. This is the way to go if you prefer to work in 3D floating-point coordinates instead of 2D integers: unlikeenvelopeTranslation, this property gives you the opportunity to represent non-integer coordinate values. With that flexibility comes a caveat: non-whole-number values ofoxandoymay result in artifacts in any kind ofStimulus(textured or not) due to linear interpolation during rendering. You may therefore wish to take care to round any values you assign, if you choose to use this property. If you exclusively useenvelopeTranslationinstead, this pitfall is avoided (as you can see in the formula above, its componentsxandyare rounded down to integer values when they are applied).Note also that for all stimuli, you should ensure that the total depth coordinate,
s.z + s.oz, is in the range ( -1, +1 ].Default value:
[0.0, 0.0, 0.0]- Subscripting shortcuts:
oxis a shortcut forenvelopeOrigin[0]oyis a shortcut forenvelopeOrigin[1]ozis a shortcut forenvelopeOrigin[2]
- envelopePosition
envelopePositionis an alias forenvelopeTranslation
- envelopeRotation
This is a managed property. It is a scalar number, expressed in degrees. The envelope will be rotated counter-clockwise by this number of degrees around its
anchor. Note that such transformations of the envelope (except at multiples of 90 degrees) will introduce small artifacts into any stimulus, due to linear interpolation.Default value:
0.0Canonical name:
envelopeRotationOther aliases:
angleorientationrotation
- envelopeScaling
This is a managed property. It is a sequence of two floating-point numbers denoting horizontal and vertical scaling factors. The actual rendered size, in pixels, of the scaled
Stimulusswill bes.envelopeScaling * s.envelopeSizeNote that such transformations of the envelope will introduce small artifacts into any stimulus, due to linear interpolation.Default value:
[1.0, 1.0]Canonical name:
envelopeScaling- Subscripting shortcuts:
xscalingis a shortcut forenvelopeScaling[0]yscalingis a shortcut forenvelopeScaling[1]
- envelopeSize
This is a managed property. It is a sequence of two numbers denoting the unscaled width and height of the envelope (i.e. width and height in texel units). Change these numbers if, for example, you want to crop or repeat a texture, or to load new differently-shaped texture (the easiest way to do the latter is to call
LoadTexture()method with argumentupdateEnvelopeSize=True). To change the size of the envelope by stretching the image content to fit, manipulateenvelopeScalingorscaledSizeinstead.Default value:
[200, 200]Canonical name:
envelopeSizeOther aliases:
size- Subscripting shortcuts:
widthis a shortcut forenvelopeSize[0]heightis a shortcut forenvelopeSize[1]
- envelopeTranslation
This is a managed property. It is a pair of numbers, expressed in pixels. It dictates the two- dimensional coordinates of the
Stimuluslocation within the drawing area. The values are rounded down to integer values when they are applied, to avoid artifacts that might otherwise be introduced inadvertently due to linear interpolation during rendering.See also:
envelopeOriginDefault value:
[0.0, 0.0]Canonical name:
envelopeTranslationOther aliases:
envelopePositionpospositionxy- Subscripting shortcuts:
xis a shortcut forenvelopeTranslation[0]yis a shortcut forenvelopeTranslation[1]
- foregroundColor
foregroundColoris an alias forcolor
- property frame
This non-managed property is an integer denoting the index of the current frame of a multi-frame stimulus. Note that frames are concatenated horizontally in the underlying carrier texture, so a change in
frameis actually achieved by manipulatingcx, otherwise known ascarrierTranslation[0].
- gamma
This is a managed property. It is a triplet of values denoting the screen gamma that should be corrected-for in each of the red, green and blue channels. A gamma value of 1 corresponds to the assumption that your screen is already linear. Setting gamma values other than 1 is an alternative to using a pre-linearized lookup-table or
lut.Any value less than or equal to 0.0 is interpreted to denote the sRGB function, which is a standard piecewise function that follows the
gamma=2.2curve quite closely (although the exponent it uses is actually slightly higher).
- green
This is a managed shortcut. It is a shortcut for
color[1]
- greengamma
This is a managed shortcut. It is a shortcut for
gamma[1]
- greennoise
This is a managed shortcut. It is a shortcut for
noiseAmplitude[1]
- height
This is a managed shortcut. It is a shortcut for
envelopeSize[1]
- property linearMagnification
This property governs the interpolation behavior applied when a textured
Stimulusis enlarged (i.e. when itsenvelopeScalingorcarrierScalingare greater than 1).If
True(default), interpolate pixel values linearly when enlarged.If
False, take the “nearest pixel” method when enlarged.
- property lut
The value of this property will either be
None, or an instance ofLookupTable. Assigning to this property is equivalent to calling theSetLUT()method—so you can assign any of the valid argument types accepted by that function. AssigningNonedisables look-up.
- moda
modais an alias formodulationDepth
- modd
moddis an alias formodulationDepth
- modf
modfis an alias formodulationFrequency
- modfunc
modfuncis an alias formodulationFunction
- modo
modois an alias formodulationOrientation
- modp
modpis an alias formodulationPhase
- modulationAmplitude
modulationAmplitudeis an alias formodulationDepth
- modulationDepth
This is a managed shortcut. It is a shortcut for
modulationParameters[0](amplitude, i.e. modulation depth, from 0 to 1)Canonical name:
modulationDepthOther aliases:
modamoddmodulationAmplitude
- modulationFrequency
This is a managed shortcut. It is a shortcut for
modulationParameters[1](frequency in cycles/pixel)Canonical name:
modulationFrequencyOther aliases:
modf
- modulationFunction
This is a managed property. It is an integer specifying the index of a shader-side contrast modulation function. If it is left at 0, no function is used: the stimulus contrast is then dependent only on the overall
normalizedContrastand on the window applied according toplateauProportion.A value of 1 (which can also be referenced as the constant
MODFUNC.SinewaveModulation) corresponds to the one and only shader- side modulation function that we provide out of the box, namelySinewaveModulationwhich performs sinusoidal contrast modulation. The parameters of this modulation pattern are determined by themodulationParametersproperty.Further values, and hence further functions, may be supported if you add them yourself using
AddCustomModulationFunction().In the shader, the return value of a modulation function is a
float. This return value is used as a multiplier for stimulus contrast.See also:
modulationParameters,signalFunction,signalParameters,windowingFunctionDefault value:
0Canonical name:
modulationFunctionOther aliases:
modfunc
- modulationOrientation
This is a managed shortcut. It is a shortcut for
modulationParameters[2](orientation in degrees)Canonical name:
modulationOrientationOther aliases:
modo
- modulationParameters
This is a managed property. It is a 4-element vector that can be used to pass parameters to the shader-side contrast-modulation function chosen by
modulationFunction.If
modulationFunctionis left at its default value of 0, these four values are ignored. For the one built-in shader modulation function (modulationFunction=1corresponding to the shader functionSinewaveModulation), the values are interpreted as depth, frequency, orientation and phase of the desired sinusoidal modulation pattern.If you’re adding your own custom shader function via
AddCustomModulationFunction(), your implementation of that function may choose to ignore or reinterpret this property as you wish. If you choose to use it, your shader code can access it as the uniformvec4variableuModulationParameters.See also:
modulationFunction,signalFunction,signalParametersDefault value:
[0.0, 0.005, 0.0, 90.0]- Subscripting shortcuts:
modulationDepthis a shortcut formodulationParameters[0](amplitude, i.e. modulation depth, from 0 to 1)modulationFrequencyis a shortcut formodulationParameters[1](frequency in cycles/pixel)modulationOrientationis a shortcut formodulationParameters[2](orientation in degrees)modulationPhaseis a shortcut formodulationParameters[3](phase in degrees)
- modulationPhase
This is a managed shortcut. It is a shortcut for
modulationParameters[3](phase in degrees)Canonical name:
modulationPhaseOther aliases:
modp
- property nFrames
Read-only non-managed property that returns the width of each frame, if the texture pixel data is divided up horizontally into multiple frames.
- noise
noiseis an alias fornoiseAmplitude
- noiseAmplitude
This is a managed property. It is a triplet of floating-point numbers corresponding to red, green and blue channels. Negative values lead to uniform noise in the range
[s.noiseAmplitude[i], -s.noiseAmplitude[i]]. Positive values lead to Gaussian noise with standard deviation equal to thenoiseAmplitudevalue.The noise specified in this way is applied before gamma-correction, and is monochromatic (i.e. perfectly correlated across color channels, though it may have different amplitudes in each channel). It is particularly useful for applying very-low-amplitude noise prior to look-up in a high-dynamic-range bit-stealing look-up table. It can also be useful at higher amplitudes, to create visible noise effects.
It is not to be confused with noisy-bit dithering, which is applied post-gamma-correction (and only when a look-up table is not used), and which is controlled independently by the
ditheringDenominatorproperty.Default value:
[0.0, 0.0, 0.0]Canonical name:
noiseAmplitudeOther aliases:
noise- Subscripting shortcuts:
rednoiseis a shortcut fornoiseAmplitude[0]greennoiseis a shortcut fornoiseAmplitude[1]bluenoiseis a shortcut fornoiseAmplitude[2]
- normalizedContrast
This is a managed property. It is a scalar floating-point value in the range 0.0 to 1.0 which scales the overall contrast of the
Stimulus. At a contrast of 0, theStimulusis reduced to itsbackgroundColor.Default value:
1.0Canonical name:
normalizedContrastOther aliases:
contrast
- offset
This is a managed property. It is a triplet of numbers, each in the range 0.0 to 1.0, corresponding to red, green and blue channels. This is added uniformly to all pixel values before they are scaled by
normalizedContrastor by windowing (viaplateauProportionandwindowingFunction) and/or custom modulation (viamodulationFunction).
- orientation
orientationis an alias forenvelopeRotation
- outOfRangeAlpha
This is a managed property. It is a floating-point number from 0 to 1. It specifies the color that should be used for pixels whose values go out of range. A negative value disables this feature (the alpha value of an out-of- range pixel is left unchanged).
Default value:
1.0
- outOfRangeColor
This is a managed property. It is a triplet of numbers, each in the range 0 to 1, corresponding to red, green and blue channels. It specifies the color that should be used for pixels whose values go out of range. A negative value means “do not flag out-of-range values in this color channel” (values are merely clipped in the range 0 to 1 in that case).
Default value:
[1.0, 0.0, 1.0]
- ox
This is a managed shortcut. It is a shortcut for
envelopeOrigin[0]
- oy
This is a managed shortcut. It is a shortcut for
envelopeOrigin[1]
- oz
This is a managed shortcut. It is a shortcut for
envelopeOrigin[2]
- property page
A
Stimulusmay optionally have more than one “page”. A page is a label attached to a particular set of property values that determine texture, envelope size and envelope shape.A page may have any hashable label—integers and strings are usually the most meaningful. The
pageproperty allows you to query the label of the current page, or switch to a different page according to its label. It is not a managed property, but it does support dynamic value assignment.See also:
LoadPages(),NewPage(),SavePage(), andSwitchTo()
- penThickness
This is a managed property. It is a scalar floating-point value that determines the width, in pixels, of of lines and points drawn when you set
drawModetoDRAWMODE.POINTS,DRAWMODE.LINES,DRAWMODE.LINE_STRIPorDRAWMODE.LINE_LOOP. Implementation is driver-dependent however: many graphics cards seem to consider line-thickness to be a legacy feature and have dropped support for it (for lines, but maybe not for points) in their pure modern-OpenGL contexts.Default value:
1.0
- plateauProportion
This is a managed property. It is sequence of two floating-point values corresponding to the x and y dimensions.
A negative value indicates that no windowing is to be performed in the corresponding dimension.
A value in the range [0, 1] causes windowing to occur: with the default (raised cosine)
windowingFunction, aplateauProportionof 0 gives a Hann window, 1 gives a boxcar window, and intermediate values combine the specified amount of constant plateau with a raised- cosine falloff to the edge of the envelope (i.e., a Tukey window).A non-zero plateau proportion can also be combined with other (custom self-written)
windowingFunctionimplementations.Note that this means [1, 1] gives a circular or elliptical envelope with sharp edges, in contrast to [-1, -1] which gives a square or rectangular envelope.
Default value:
[-1.0, -1.0]Canonical name:
plateauProportionOther aliases:
pp- Subscripting shortcuts:
ppxis a shortcut forplateauProportion[0]ppyis a shortcut forplateauProportion[1]
- property points
This is a view into the
Stimulusinstance’s optional array of coordinates. If you do not have the third-party packagenumpyinstalled, then this is fairly limited (although you can assign a list of alternating x and y coordinates to it, you will not be able to do any array arithmetic operations with it, which is where its power lies). Withnumpy, yourpointswill appear as ann-by-2 array of coordinates (you can also view the same data as a sequence of complex numbers, by accessing aspointsComplex). These coordinates are not used in the defaultdrawMode, which isDRAWMODE.QUAD. To learn how other draw modes use the coordinates, see the documentation for theDRAWMODEnamespace.Assignment to
pointsis interchangeable with assignment topointsComplex—in either case, the input can be a sequence ofncomplex numbers OR ann-by-2 array of real-valued coordinates. Under the hood, assignment topointschanges the content of the managed propertypointsXYand also adjusts the managed propertynPointsThe coordinate system of the
pointsis always in pixels relative to the bottom-left corner of theStimulusbounding-box—i.e. the bottom-left corner of the rectangle you would see if you were to switch theStimulusback todrawMode=Shady.DRAWMODE.QUAD. TheWorld.anchor,Stimulus.position,Stimulus.anchorandStimulus.sizedetermine where this local origin actually lies on screen, but thepointsthemselves are expressed independently of these, and points defined outside the bounding-box (e.g. with negative coordinates) still get drawn.
- property pointsComplex
This is a view into the
Stimulusinstance’s optional array of coordinates. The same data are also accessible aspoints. The only difference is that when you ask forpointsComplex, the data are interpreted as a sequence of complex numbers (requires the third-party packagenumpy).Assignment to
pointsComplexis interchangeable with assignment topoints—in either case, the input can be a sequence ofncomplex numbers OR ann-by-2 array of real-valued coordinates.
- pos
posis an alias forenvelopeTranslation
- position
positionis an alias forenvelopeTranslation
- pp
ppis an alias forplateauProportion
- ppx
This is a managed shortcut. It is a shortcut for
plateauProportion[0]
- ppy
This is a managed shortcut. It is a shortcut for
plateauProportion[1]
- red
This is a managed shortcut. It is a shortcut for
color[0]
- redgamma
This is a managed shortcut. It is a shortcut for
gamma[0]
- rednoise
This is a managed shortcut. It is a shortcut for
noiseAmplitude[0]
- rotation
rotationis an alias forenvelopeRotation
- scale
scaleis an alias forenvelopeScaling
- property scaledAspectRatio
Non-managed property that affects the behavior of
scaledWidthandscaledHeightmanipulations. The value may be aNone, the string'fixed', or a floating-point number.Assigning a floating-point number to
scaledAspectRatiowill immediately reduce either the horizontal or the vertical component ofenvelopeScalingas necessary to achieve the target aspect ratio.Once the value is set to something other than
None, future manipulation of either thescaledWidthproperty or thescaledHeightproperty will cause the other property to be adjusted simultaneously, to maintain the target aspect ratio. If the value is'fixed', then the target value is simply “whatever it was before you made the manipulation”.This prospective control only applies to the
scaled*properties, however—if you directly manipulateenvelopeSizeorenvelopeScaling, thescaledAspectRatiosetting will not be automatically reasserted.
- property scaledHeight
Non-managed property that reflects the product of
envelopeSize[1]andenvelopeScaling[1]. Assigning to this property will changeenvelopeScaling[1]accordingly. Dynamic value assignment is supported.If the
scaledAspectRatioproperty is either'fixed'or a numeric value, then the value ofscaledWidthwill simultaneously be adjusted to ensure aspect ratio is preserved. IfscaledAspectRatioisNone, thenscaledWidthwill not be adjusted.
- property scaledSize
Non-managed property that reflects the product of
envelopeSizeandenvelopeScaling. Assigning to this property will changeenvelopeScalingaccordingly. Dynamic value assignment is supported. Note that you can also addressscaledWidthandscaledHeightseparately if you wish.If the
scaledAspectRatioproperty is eitherNoneor'fixed', then the explicitly-specifiedscaledSizevalue will be respected exactly. However, if you have previously set the value ofscaledAspectRatioto a numeric constant, then the requestedscaledSizevalues may be adjusted (one of them will be reduced) if necessary to preserve that aspect ratio.
- property scaledWidth
Non-managed property that reflects the product of
envelopeSize[0]andenvelopeScaling[0]. Assigning to this property will changeenvelopeScaling[0]accordingly. Dynamic value assignment is supported.If the
scaledAspectRatioproperty is either'fixed'or a numeric value, then the value ofscaledHeightwill simultaneously be adjusted to ensure aspect ratio is preserved. IfscaledAspectRatioisNone, thenscaledHeightwill not be adjusted.
- scaling
scalingis an alias forenvelopeScaling
- siga
sigais an alias forsignalAmplitude
- sigf
sigfis an alias forsignalFrequency
- sigfunc
sigfuncis an alias forsignalFunction
- signalAmplitude
This is a managed shortcut. It is a shortcut for
signalParameters[0](amplitude from 0 to 1)Canonical name:
signalAmplitudeOther aliases:
siga
- signalFrequency
This is a managed shortcut. It is a shortcut for
signalParameters[1](frequency in cycles/pixel)Canonical name:
signalFrequencyOther aliases:
sigf
- signalFunction
This is a managed property. It is an integer specifying the index of a shader-side signal function. If it is left at 0, no function is used: the carrier content is then dependent purely on the texture, if any, or is blank if no texture was specified. A value of 1 (which can also be referenced as the constant
SIGFUNC.SinewaveSignal) corresponds to the one and only shader-side signal function that we provide out of the box, namelySinewaveSignalwhich generates a sinusoid. The parameters of the sinusoid are determined by thesignalParametersproperty.Further values, and hence further functions, may be supported if you add them yourself using
AddCustomSignalFunction().In the shader, the return value of a signal functions is either a
vec3or afloat. This return value gets multiplied by thecolorof theStimulus, and added to itsbackgroundColor(and/or its texture, if any). Ifcoloris negative (i.e. disabled, as it is by default) then the function output is multiplied byvec3(1.0, 1.0, 1.0).See also:
signalParameters,modulationFunction,modulationParameters,windowingFunctionDefault value:
0Canonical name:
signalFunctionOther aliases:
sigfunc
- signalOrientation
This is a managed shortcut. It is a shortcut for
signalParameters[2](orientation in degrees)Canonical name:
signalOrientationOther aliases:
sigo
- signalParameters
This is a managed property. It is a 4-element vector that can be used to pass parameters to the shader-side carrier-signal-generating function chosen by
signalFunction. IfsignalFunctionis left at its default value of 0, thesignalParametersare ignored. For the one built-in shader signal function (signalFunction=1corresponding to the shader functionSinewaveSignal), these parameters are interpreted as amplitude, frequency, orientation and phase of the sinusoidal pattern. Signal functions are additive to your background and/or texture, so if you have no texture and a background color of, for example, 0.3 or 0.7, a sinewave amplitude greater than 0.3 will go out of range at full contrast. (Beware also the additive effect of noise, if yournoiseAmplitudeis not 0.)If you’re adding your own custom shader function via
AddCustomSignalFunction(), your implementation of that function may choose to ignore or reinterpret this property as you wish. If you choose to use it, your shader code can access it as the uniformvec4variableuSignalParameters.See also:
signalFunction,modulationFunction,modulationParametersDefault value:
[1.0, 0.05, 0.0, 0.0]- Subscripting shortcuts:
signalAmplitudeis a shortcut forsignalParameters[0](amplitude from 0 to 1)signalFrequencyis a shortcut forsignalParameters[1](frequency in cycles/pixel)signalOrientationis a shortcut forsignalParameters[2](orientation in degrees)signalPhaseis a shortcut forsignalParameters[3](phase in degrees)
- signalPhase
This is a managed shortcut. It is a shortcut for
signalParameters[3](phase in degrees)Canonical name:
signalPhaseOther aliases:
sigp
- sigo
sigois an alias forsignalOrientation
- sigp
sigpis an alias forsignalPhase
- size
sizeis an alias forenvelopeSize
- smoothing
This is a managed property. It is an integer value that determines whether lines, dots and polygons should be drawn with or without smoothing. The results are unfortunately unpredictable as they vary according to your graphics card and drivers. Example: with
DRAWMODE.POINTS, settingsmoothing=1causes the dots to be round rather than square—but with some graphics drivers, they will remain square regardless (to guarantee round dots, it’s better to draw tiny many-sided polygons). A value of 0 means no smoothing. A value of 1 means points and lines should be smoothed. A value of 2 means lines, points and polygons are smoothed (note that polygon smoothing causes diagonal “crack” artifacts on many graphics cards/drivers, so this option is not enabled by default).Default value:
1
- property text
To use the
textproperty of theStimulusclass, you must first explicitlyimport Shady.Text(seeShady.Textfor documentation on this property).
- textureChannels
This is a managed property. It is an integer value denoting whether the texture has 1, 2, 3 or 4 channels. If there is no texture, the value is -1. You should consider this property read-only—do not change the value by hand.
Default value:
-1
- textureSize
This is a managed property. It is a pair of values denoting the width and height of the texture data, in pixels. If there is no texture, both values are -1. You should consider this property read-only—do not change the values by hand.
Default value:
[-1, -1]
- useTexture
This is a managed property. It is a boolean value. The default value is
Trueif a texture has been specified, and this causes pixel values to be drawn from the texture specified by the constructor argumentsource(or thesourceargument to a subsequentNewPage()orLoadTexture()call). IfuseTextureis set toFalse, the pixel values are determined bybackgroundColorand/orforegroundColor(as well asoffset,normalizedContrast, and any windowing and shader-sidesignalFunctionormodulationFunction).Default value:
1
- property video
To use the
videoproperty of theStimulusclass, you must first explicitlyimport Shady.Video(seeShady.Videofor documentation on this property).
- visible
This is a managed property. It is a boolean value that determines whether the
Stimulusis rendered or not.
- width
This is a managed shortcut. It is a shortcut for
envelopeSize[0]
- windowFunction
windowFunctionis an alias forwindowingFunction
- windowingFunction
This is a managed property. It is an integer specifying the index of a shader-side windowing function. If it is set to 0 (or if the
plateauProportionproperty is negative), no spatial windowing is used.The default value of 1 (which can also be referenced as the constant
WINFUNC.Hann) corresponds to the one and only shader-side windowing function that we provide out of the box, namelyHann, which causes contrast to fall off according to a raised cosine function of radial distance.Further values, and hence further functions, may be supported if you add them yourself using
AddCustomWindowingFunction().In the shader, the windowing function takes one input argument (a
floatwhose value will range from 0 at peak of the window to 1 at the edge) and return afloat. This return value is used as a multiplier for stimulus contrast.See also:
signalFunction,modulationFunctionDefault value:
1Canonical name:
windowingFunctionOther aliases:
windowFunctionwinfunc
- winfunc
winfuncis an alias forwindowingFunction
- x
This is a managed shortcut. It is a shortcut for
envelopeTranslation[0]
- xscaling
This is a managed shortcut. It is a shortcut for
envelopeScaling[0]
- xy
xyis an alias forenvelopeTranslation
- y
This is a managed shortcut. It is a shortcut for
envelopeTranslation[1]
- yscaling
This is a managed shortcut. It is a shortcut for
envelopeScaling[1]
- z
This is a managed property. It is a floating-point number that determines the depth plane of the
Stimulus. The convention is that negative values put you closer to the camera, and positive further away; also, you must ensure -1 <= z <= +1. Since the projection is orthographic, the value is purely used for depth-sorting of stimuli: therefore, settingzto a non-integer value will not cause interpolation artifacts.Default value:
0.0Canonical name:
zOther aliases:
depthdepthPlane
Global Functions and Constants
- Shady.AddCustomSignalFunction(code)
Defines a new signal function in the fragment shader.
Must be called, before construction of your
World. Thecodeargument is a (usually triple-quoted multi-line) string containing the complete definition of a function in GLSL.The protoype for the function may be one of the following:
float MySignalFunction( vec2 xy ) { ... } vec3 MySignalFunction( vec2 xy ) { ... }
where
xyare coordinates measured in pixels relative to the center of the stimulus. Obviously we’re usingMySignalFunctionhere as a placeholder—use your own descriptive name for the new function. Your function mustreturneither a floating-point signal value, or three-dimensional (red, green, blue) signal value. If non-negative values have been supplied in aStimulusinstance’scolorproperty, your signal function will get multiplied by these. Then, any desired contrast modulation and windowing will be applied. Then, the result will be added to thebackgroundColor.Your new function can be applied to a
Stimulusinstancestimas follows:stim.signalFunction = Shady.SIGFUNC.MySignalFunction
If you want to parameterize your new function further, you can use the existing
uniform vec4 uSignalParametersvariable, which is linked to theStimulus.signalParametersproperty. You can also define your own additional properties/uniform variables with theAddCustomUniform()class method.
- Shady.AddCustomModulationFunction(code)
Defines a new contrast-modulation function in the fragment shader.
Must be called before construction of your
World. Thecodeargument is a (usually triple-quoted multi-line) string containing the complete definition of a function in GLSL.The protoype for the function must be:
float MyModulationFunction( vec2 xy ) { ... }
where
xyare coordinates measured in pixels relative to the center of the stimulus. Obviously we’re usingMyModulationFunctionhere as a placeholder—use your own descriptive name for the new function. Your function mustreturna floating-point contrast multiplier.Your new function can be applied to a
Stimulusinstancestimas follows:stim.modulationFunction = Shady.MODFUNC.MyModulationFunction
If you want to parameterize your new function further, you can use the existing
uniform vec4 uModulationParametersvariable, which is linked to theStimulus.modulationParametersproperty. You can also define your own additional properties/uniform variables with theAddCustomUniform()class method.
- Shady.AddCustomWindowingFunction(code)
Defines a new spatial windowing function in the fragment shader.
Must be called before construction of your
World. Thecodeargument is a (usually triple-quoted multi-line) string containing the complete definition of a function in GLSL.The protoype for the function must be:
float MyWindowingFunction( float r ) { ... }
where the domain of
rif from 0 (in the center of theStimulus, or indeed anywhere on its plateau if it has one) to 1 (at outer edge of the largest oval that fits in theStimulusbounding box). Obviously we’re usingMyWindowingFunctionhere as a placeholder— use your own descriptive name for the new function. Your function mustreturna floating-point contrast multiplier.Your new function can be applied to a
Stimulusinstancestimas follows (bearing in mind that a negativeplateauProportionvalue disables windowing entirely):stim.windowingFunction = Shady.WINFUNC.MyWindowingFunction stim.plateauProportion = 0
If you want to parameterize your new function further, you can define your own additional properties/uniform variables with the
AddCustomUniform()class method.
- Shady.AddCustomColorTransformation(code)
Defines a new color transformation function in the fragment shader.
Must be called before construction of your
World. Thecodeargument is a (usually triple-quoted multi-line) string containing the complete definition of a function in GLSL.The protoype for the function must be:
vec4 MyColorTransformation( vec4 color ) { ... }
where the input and output arguments are both RGBA vectors in the domain [0, 1]. The custom transformation step is applied to the pixel color immediately before standard
gammalinearization, if any.Your new function can be applied to a
Stimulusinstancestimas follows:stim.colorTransformation = Shady.COLORTRANS.MyColorTransformation
If you want to parameterize your new function further, you can define your own additional properties/uniform variables with the
AddCustomUniform()class method.
- Shady.BackEnd(windowing=None, acceleration=None)
Globally specify the back-end windowing and rendering systems that future
Worldinstances should use.- Parameters:
windowing – specifies the windowing system. Possible values are as follows:
'default':use the ShaDyLib dynamic library if available, else fall back on pyglet.
'shadylib','accel', or'glfw':use the ShaDyLib dynamic library (windowing is handled via the GLFW library from http://glfw.org ).
'pyglet':use pyglet (a third-party package that you will need to install separately if you want to use this option)
'pygame':use pygame (a third-party package that you will need to install separately if you want to use this option)
acceleration – specifies the rendering implementation, i.e. whether to use the ShaDyLib dynamic library (and if so, whether to use the “development” copy of ShaDyLib in cases where you have the entire Shady repository including the C++ sources for ShaDyLib) or whether to fall back on Python code for rendering (not recommended). Possible values are:
None:leave things as they were (default).
False:disable ShaDyLib and fall back on the
pygletorPyOpenGLcode in thePyEnginesubmodule (this option is not recommended for time-critical presentation).True:if ShaDyLib is already imported, leave things as they are; if not, import either version of ShaDyLib or die trying. Prefer the development version, if available. Print the outcome.
'bundled':silently import the bundled version of ShaDyLib from the Shady.accel sub-package, or die trying.
'devel':silently import the development version of ShaDyLib from
/../accel-src/release/, or die trying.'auto':try to import ShaDyLib. Prefer the development version, if available. Don’t die in the attempt. Whatever happens, print the outcome.
- Returns:
If both input arguments are
None, the name of the current windowing back-end is returned. Otherwise, returnsNone.
- Shady.Screens(pretty_print=False)
Get details of any attached screens using the
Screens()method of whichever windowing backend is enabled.- Parameters:
pretty_print (bool) – determines the type of the return value
- Returns:
If
pretty_printisTrue, returns a human-readable string. Ifpretty_printisFalse, returns adict.
- class Shady.SIGFUNC
This class is an enum container: a namespace of values that can be assigned to the
signalFunctionproperty of aStimulusinstance. Its members are named according to the signal functions available in the shader. The only built-in function isSinewaveSignalwhich has a value of 1. So, when you set thesignalFunctionproperty of aStimulusto 1, theSinewaveSignalfunction is selected in the shader, and when you set it to 0, no signal function is selected.You can define further signal functions, and hence add names and values to this namespace, with
AddCustomSignalFunction.
- class Shady.MODFUNC
This class is an enum container: a namespace of values that can be assigned to the
modulationFunctionproperty of aStimulusinstance. Its members are named according to the modulation functions available in the shader. The only built-in function isSinewaveModulationwhich has a value of 1. So, when you set themodulationFunctionproperty of aStimulusto 1, theSinewaveModulationfunction is selected in the shader, and when you set it to 0, no modulation function is selected.You can define further modulation functions, and hence add names and values to this namespace, with
AddCustomModulationFunction.
- class Shady.WINFUNC
This class is an enum container: a namespace of values that can be assigned to the
windowingFunctionproperty of aStimulusinstance. Its members are named according to the windowing functions available in the shader. The only built-in function isHannwhich has a value of 1. So, when you set thewindowingFunctionproperty of aStimulusto 1, theHannfunction is selected in the shader, and when you set it to 0, no windowing function is selected.You can define further windowing functions, and hence add names and values to this namespace, with
AddCustomWindowingFunction.
- class Shady.COLORTRANS
This class is an enum container: a namespace of values that can be assigned to the
colorTransformationproperty of aStimulusinstance.You can define color transformations, and hence add names and values to this namespace, with
AddCustomColorTransformation.
- class Shady.DRAWMODE
This class is an enum container: a namespace of values that can be assigned to the
drawModeproperty of aStimulusinstance. The defaultdrawModeisDRAWMODE.QUAD: that means that eachStimulusis automatically drawn as a rectangle according to itsenvelopeSize.Other modes rely on the
pointsproperty, which contains a sequence of two-dimensional coordinates:DRAWMODE.POINTSdraws a disconnected dot at each location.DRAWMODE.LINEStakes two locations at a time and connects each pair with a line segment, disconnected from previous or subsequent line segments.DRAWMODE.LINE_STRIPdraws line segments continuously from one location to the next, only taking the pen off the paper if it enounters a NaN coordinate.DRAWMODE.LINE_LOOPis like LINE_STRIP, but the last point in each group is joined back to the first (where a “group” is delimited by NaNs in the sequence of coordinates).DRAWMODE.POLYGONalso connects successive locations continuously, and fills the area bounded by the lines thus drawn (a NaN coordinate is a way to delimit multiple polygons)