MasterScan  Lab_Matlab_control Master Branch
Functions | Variables
DotsUtilities

Functions

isSuccess steps installSnowDots (localFolder, dotsRepo, topsRepo)
 Download and configure Snow Dots and dependencies. More...
 
data benchmarkClientEnsemble (showPlot, iterations, delay)
 Measure timing of dotsClientEnsemble communications. More...
 
data benchmarkDOutPlexon (dOutObject, ensemble, words, intervals)
 Measure intervals between strobed words sent to Plexon. More...
 
lastInterval fetchIntervalPlexon (option)
 Use the Plexon Matalb online client SDK to access strobed word intervals. More...
 
timestampsB delta clockDriftApply (timestampsA, aToB)
 Transform timestamps from one clock to another clock's equivalents. More...
 
aToB clockDriftEstimate (timestampsA, timestampsB)
 Compute drift and offset between two clocks, given coincident timestamps. More...
 
static newData sendNewData (ensemble)
 Send new topsDataLog data to a remote Matlab instance. More...
 
dotsPath dotsRoot ()
 Get the absolute path to the Snow Dots project root. More...
 
didPass dotsRunTests (varargin)
 Invoke Snow Dots unit tests at or below the current folder. More...
 
x y indices makeDisks (xCenter, yCenter, rInner, rOuter, startAngle, sweepAngle, nPieces)
 Calculate x and y vertex positions for one or more disks. More...
 
x y indices makePolygons (xCenter, yCenter, width, height, nSides, isInscribed)
 Calculate x and y vertex positions for one or more polygons. More...
 
string primitiveToString (primitive, charDelimiter)
 Represent a primitive array as a string. More...
 
 xmlIterateNodeAttributes (xNode, attributeAction)
 Execute a function for each of an xml node's attributes. More...
 
 xmlIterateNodes (xNode, nodeAction)
 Execute a function at each node of an xml tree. More...
 

Variables

Property initialFrameCount = 100
 Models the video refresh cycle and predicts MGL frame onset times. More...
 

Detailed Description

Function Documentation

◆ installSnowDots()

isSuccess steps installSnowDots ( localFolder  ,
dotsRepo  ,
topsRepo   
)

Download and configure Snow Dots and dependencies.

Parameters
localFolderwhere to save all the Snow Dots stuff (optional)
dotsRepowhat version of Snow Dots to use (optional)
topsRepowhat version of Tower of Psych to use (optional)

installSnowDots() downloads Snow Dots and a bunch of other projects that Snow Dots depends on. By default it saves everything to a subfolder folder named "SnowDots", in the current folder. localFolder is optional, and can specify a different folder.

By default, downloads the "Version 1" revisions of the Snow Dots and Tower of Psych projects. dotsRepo and topsRepo may specify differnt repository paths. For example, dotsRepo could be something like "http://snow-dots.googlecode.com/svn/trunk".

Here is a list of things that installSnowDots() attempts to download and configure:

  • is Matlab at version 7.6 or greater?
  • is Subbversion installed?
  • download MGL with Subversion (OpenGL support)
  • download Tower of Psych with Subversion (experiment organization)
  • download Snow Dots with Subversion
  • download TCP_UDP_IP Toolbox from Matlab Central File Exchange (Ethernet support)
  • download Matlab xUnit Toolbox from Matlab Central File Exchange (code testing)
  • build several mex functions locally, as needed
  • save all of the above to the Matlab path

installSnowDots() requires the Subversion tool for downloading some projects. Read about Subversion and download it at http://subversion.tigris.org/.

Snow Dots uses object-oriented features of Matlab that were introduced in Matlab version 7.6, also known as 2008a. installSnowDots() checks for this version, or later.

Once everything is downloaded, installSnowDots() tries to add it all to the Matlab path and save the path definition.

installSnowDots() returns true if installation of essential components was successful, or false otherwise. Also returns as a second output a struct array with data about how each step in the installation process went. Each element represents an installation step. The struct has a few fields:

  • function function_handle for the subfunction here in installSnowDots.m that does an installation step
  • isEssential true or false, whether the step is essential for Snow Dots to run
  • status a status code for success of failure of the step (nonzero values mean the step failed)
  • result a string describing the result of the step
Parameters
localFolderwhere to save all the Snow Dots stuff (optional)
dotsRepowhat version of Snow Dots to use (optional)
topsRepowhat version of Tower of Psych to use (optional)

installSnowDots() downloads Snow Dots and a bunch of other projects that Snow Dots depends on. By default it saves everything to a subfolder folder named "SnowDots", in the current folder. localFolder is optional, and can specify a different folder.

By default, downloads the "Version 1" revisions of the Snow Dots and Tower of Psych projects. dotsRepo and topsRepo may specify differnt repository paths. For example, dotsRepo could be something like "http://snow-dots.googlecode.com/svn/trunk".

Here is a list of things that installSnowDots() attempts to download and configure:

  • is Matlab at version 7.6 or greater?
  • is Subversion installed?
  • download MGL with Subversion (OpenGL support)
  • download Tower of Psych with Subversion (experiment organization)
  • download Snow Dots with Subversion
  • download TCP_UDP_IP Toolbox from Matlab Central File Exchange (Ethernet support)
  • download Matlab xUnit Toolbox from Matlab Central File Exchange (code testing)
  • build several mex functions locally, as needed
  • save all of the above to the Matlab path

installSnowDots() requires the Subversion tool for downloading some projects. Read about Subversion and download it at http://subversion.tigris.org/.

Snow Dots uses object-oriented features of Matlab that were introduced in Matlab version 7.6, also known as 2008a. installSnowDots() checks for this version, or later.

Once everything is downloaded, installSnowDots() tries to add it all to the Matlab path and save the path definition.

installSnowDots() returns true if installation of essential components was successful, or false otherwise. Also returns as a second output a struct array with data about how each step in the installation process went. Each element represents an installation step. The struct has a few fields:

  • function function_handle for the subfunction here in installSnowDots.m that does an installation step
  • isEssential true or false, whether the step is essential for Snow Dots to run
  • status a status code for success of failure of the step (nonzero values mean the step failed)
  • result a string describing the result of the step

◆ benchmarkClientEnsemble()

data benchmarkClientEnsemble ( showPlot  ,
iterations  ,
delay   
)

Measure timing of dotsClientEnsemble communications.

Parameters
showPlotwhether or not to plot the timing results
iterationshow many transactions to measure
delaydelay to wait between transactions

benchmarkClientEnsemble() creates a dotsClientEnsemble and performs transactions with a dotsEnsembleServer. The dotsEnsembleServer must be running in another instance of Matlab. This dotsClientEnsemble and the dotsEnsembleServer should expect to use the default network addresses from dotsTheMessenger.

By default, plots the timing results in a new figure. If @showPlot is provided and false, plots nothing. iterations specifies how many transactions to exchange between client and server. The default is 100. delay specifies how long to pause() between transactions, the default is 0.01 seconds.

Returns a struct array with timing data for several parts of each transaction.

◆ benchmarkDOutPlexon()

data benchmarkDOutPlexon ( dOutObject  ,
ensemble  ,
words  ,
intervals   
)

Measure intervals between strobed words sent to Plexon.

Parameters
dOutObjectdotsAllDOutObjects object to send words to Plexon
ensembleensemble object to access Plexon machine
wordsvalues to ouput from dOutObject
intervalsdelays between repetition of each word

dOutObject must be an object that inherits the dotsAllDOutObjects superclass. It will send strobbed digital words to Plexon.

ensemble may be used to access a remote instance of Matlab, where the Plexon Matlab client SDK is running. If provided, ensemble should be connected to a dotsEnsembleServer runnon on the same Matlab instance as the Plexon Matlab client SDK. By default, tries to access the Plexon Matlab client SDK in the local Matlab instance. See fetchIntervalPlexon.m.

words may specify which unique word values to send to Plexon. The default words are 8-bit (0:255). intervals may specify unique delays to wait between pairs of words. The default intervals are linspace(0, 1, 10). The Test

Uses dOutObject to output m x n pairs of strobed words, separated by various delays. m is the number of intervals and n is the number of words. Since a pair of words surrounds each interval, each unique word is output 2*m times.

Outputs each pair of strobed words with the following sequence:

  • uses dOutObject to output the first of a word and gets a "before timestamp"
  • uses mglGetSecs() to get a "before clock time"
  • uses mglWaitSecs() to delay for a given "nominal interval"
  • uses dOutObject to output the last word and gets an "after timestamp"
  • uses mglGetSecs() to get an "after clock time"
  • evaluates the before-after interval as "seen" by the Plexon Matlab client SDK

Each "nominal interval" is be compared to three other measurements of the same interval: the interval between dOutObject timestamps, the interval between mglGetSecs() timestamps, and the interval between Plexon strobbed word timestamps.

The Results

Ideally, all three interval measurements would match the nominal interval. But in practice, each function call takes a finite, random time to complete. Furthermore, the a local clock and plexon clock might count at different rates. So the measured intervals may differ from nominal, and from one another.

benchmarkDOutPlexon() makes three plots to compare interval measurements. The top plot assesses basic agreement among the nominal intervals and the three measured intervals. It's internded as a raw "smell test" of the raw measured intervals: its time scale is coarse and each data point may hide a cluster of data points.

The bottom two plots focus on how well the intervals between dOutObject timestamps agree with the intervals as as "seen" from Plexon.

For the bottom left plot, intervals from dOutObject and Plexon are grouped by nominal interval. The mean of each group is subtracted, so that all the intervals cluster near 0. The mean-subtracted dOutObject and Plexon intervals are plotted against each other. If the measurements from each source agree, all the points will fall near the unity line (i.e. x=y).

For the bottom right plot, intervals from dOutObject and Plexon are each transformed by linear regression into the time frame of mglWaitSecs() (the nominal delay). The residual "jitteriness", not accounterd for by the regression, is plotted. As above, the points should fall along the unity line. See clockDriftEstimate() for more about transforming time values as "seen" from different clocks.

Returns a struct with 5 fields:

  • words the given words, or defaults
  • intervals the given delay intervals, or defaults
  • dOutResiduals m x n matrix of jitter residuals, as "seen" by dOutObject timestamps. m is the number of intervals and n is the number of words
  • plexonResiduals mxn matrix of jitter residuals, as "seen" by Plexon
  • clockResiduals mxn matrix of jitter residuals, as "seen" from mglGetSecs()

◆ fetchIntervalPlexon()

lastInterval fetchIntervalPlexon ( option  )

Use the Plexon Matalb online client SDK to access strobed word intervals.

Parameters
optionoptional string 'init' or 'close' to initalize of close the Plexon connection instead of reading data.

fetchIntervalPlexon() is intended to be invoked via a dotsClientEnsemble, connected to a dotsEnselbleServer which is running on a machine with access to the Plexon Matlab client SDK.

fetchIntervalPlexon() expects to be initialized the first time its called, with option equal to 'init'. It expects to be closed the last time its called, with option equal to 'close'. In between, it expects to be called multiple times with option omitted.

Locates the two most recent strobed word timestamps as seen by Plexon and returns the interval betwen them.

◆ clockDriftApply()

timestampsB delta clockDriftApply ( timestampsA  ,
aToB   
)

Transform timestamps from one clock to another clock's equivalents.

Parameters
timestampsAarray of timestamps for some events, taken with "clock A"
aToBa struct with transformation parameters as returned from clockDriftEstimate()

Uses "drift" and "offset" parameters in aToB to do a linear transform on timestampsA. Returns timestamps for events that were "seen" from clock A, as they might have been "seen" from clock B.

Also returns as a second output the "delta" error estimates (standard deviation) for the returned timestamps, obtained from Matlab's builtin polyval().

See clockDriftEstimate() for estimating the drift and offset between clocks A and B.

◆ clockDriftEstimate()

aToB clockDriftEstimate ( timestampsA  ,
timestampsB   
)

Compute drift and offset between two clocks, given coincident timestamps.

Parameters
timestampsAarray of timestamps for some events, taken with "clock A"
timestampsBarray of timestamps for the same events as timestampsA, taken with "clock B"

timestampsA and timestampsB must be the same size. Both should contain timestamps for a common set of events, so that timestampsA are the event times as "seen" from clock A, and timestampsB are the event times as "seen" from clock B.

Computes parameters for doing a linear transformation from timestampsA into timestampsB, or in general to transform timestamps from clock A into the clock B equivalents. See clockDriftApply() to do the general transformation.

Returns a struct with transformation parameters and information for estimating transformation error as returned from Matlab's polyfit(). The struct has fields:

  • drift the rate at which clocks A and B drift apart over time: how often clock B ticks for each tick of clock A
  • offset the inital absolute difference between clocks A and B: the time at clock B when clock A was at 0.
  • polyMu centering and scaling parameters returned from polyfit()
  • polyInfo struct of error estimation data returned from polyfit()

◆ sendNewData()

static newData sendNewData ( ensemble  )
static

Send new topsDataLog data to a remote Matlab instance.

Parameters
ensembleensemble object connected to a remote Matlab

Gets new data from topsDataLog and sends via the given ensemble to a remote Matlab instance, to be added to that remote topsDataLog.

Returns a struct array of new data that was sent.

◆ dotsRoot()

dotsPath dotsRoot ( )

Get the absolute path to the Snow Dots project root.

◆ dotsRunTests()

didPass dotsRunTests ( varargin  )

Invoke Snow Dots unit tests at or below the current folder.

Parameters
vararginoptional list of parameters to affect test behavior

Runs unit tests for Snow Dots. Searches the current folder and subfolders for files whose names begin or end with "test" or "Test", and executes any Matlab xunit tests they define.

varargin may contain parameter-value pairs which affect test behaviors:

  • (... 'fileFilter', filter, ...) treats filter as a regular expression and limits tests to those files whose names match filter
  • (... 'testSetUp', function, ...) invokes function with feval(), just before each unit test
  • (... 'testTearDown', function, ...) invokes function with feval(), just after each unit test

Other arbitrary parameter-value pairs may be supplied as well. These are treated as global testing data and assigned to the global struct DOTS_TEST_DATA. It's up to individual unit tests to interpret the values contained DOTS_TEST_DATA. For example,

  • (... 'lookSee', delay, ...) assigns delay to DOTS_TEST_DATA.lookSee, which some unit tests use as a hint to allow time for visual inspection of graphics.

Attempts to avoid sequential effects by invoking multiple "clear" statements between test files.

If all unit tests are successful, returns true. If any unit test fails, aborts and returns false.

Here are some examples:

everythingPassed = dotsRunTests();
drawablesPassed = dotsRunTests('fileFilter', 'Drawable', 'lookSee', 2);

◆ makeDisks()

x y indices makeDisks ( xCenter  ,
yCenter  ,
rInner  ,
rOuter  ,
startAngle  ,
sweepAngle  ,
nPieces   
)

Calculate x and y vertex positions for one or more disks.

Parameters
xCenterscalar or array of disk horizontal center positions
yCenterscalar or array of disk vertical center positions
rInnerscalar or array of disk inner radiuses
rOuterscalar or array of disk outer radiuses
startAnglescalar or array of disk angular start locations
sweepAnglescalar or array of disk angular sweep widths
nPiecesthe number of sides for the disk approximation

makeDisks() takes parameters that specify one or more circular disks and computes vertex x and y positions for each disk. It also computes vertex indices which are suitable for drawing all the disks from quad primitives, with counterclockwise winding.

xCenter, yCenter, rInner, and rOuter, may be scalars or arrays. All arrays provided must have the same number of elements. Scalars will be expanded match any arrays. The number of polygons created will match the number of array elements.

Together, xCenter, yCenter, rInner, and rOuter specify two concentric circles with radiuses @rInner and @rOuter. startAngle specifies where around each circle to start drawing a disk. sweepAngle specifies how far around each circle to draw a disk. startAngle and sweepAngle are interpreted as degrees, increasing counterclockwise, with 0 coinciding with the positive x-axis. sweepAngle may omitted, in which case complete disks will be drawn.

nPieces specifies how coarsely or finely to approxomate disk curvature out of flat sides. The larger nPieces, the more sides and the smoother the disks will appear.

Returns x and y positions for one or more disks. The number of rows of x and y will be equal to the number of vertices required to make up each disk, which is nPieces plus 1, times 2. The number of columns of x and y will be equal to the number of disks.

Also returns linear, 1-based indices into x and y, suitable for drawing all disks out of quad primitives. The primitives will share some vertices. The number of rows of indices will be 4. The number of columns of indices will be the number of quads required to cover all disks, which is nPieces times the number of disks.

◆ makePolygons()

x y indices makePolygons ( xCenter  ,
yCenter  ,
width  ,
height  ,
nSides  ,
isInscribed   
)

Calculate x and y vertex positions for one or more polygons.

Parameters
xCenterscalar or array of polygon horizontal center positions
yCenterscalar or array of polygon vertical center positions
widthscalar or array of polygon widths
heightscalar or array of polygon heights
nSidesthe number of sides for the polygons
isInscribedwhether to fit the polygon inside an oval

makePolygons() takes parameters that specify one or more polygons and computes vertex x and y positions for each polygon. It also computes vertex indices which are suitable for drawing all the polygons from triangle primitives, with counterclockwise winding.

xCenter, yCenter, width, and height may be scalars or arrays. All arrays provided must have the same number of elements. Scalars will be expanded match any arrays. The number of polygons created will match the number of array elements.

nSides specifies the type of polygon to create. For example, nSides = 3 creates triangles, nSides = 11 eleven-sided polygons. nSides must be at least 3. If nSides it large, polygons will approximate ovals. All polygons are rotated so that one side is flat on the bottom.

Together, xCenter, yCenter, width, and height specify ovals which are aligned with the x and y axes. By default, polygons are scaled so that each polygon circumscribes its oval. This makes rectangles look right but triangles look very large. If isInscribed is provided and equal to true, each polygon will be inscribed within its oval, instead of circumscribed.

Returns x and y positions for the vertices one or more polygons. The number of rows of x and y will be equal to nSides. The number of columns of x and y will be equal to the number of polygons.

Also returns linear, 1-based indices into x and y, suitable for drawing all polygons out of triangle primitives. The primitives will share some vertices. The number of rows of indices will be 3. The number of columns of indices will be the number of triangles required to cover all polygons, which is nSides minus 2, times the number of polygons.

◆ primitiveToString()

string primitiveToString ( primitive  ,
charDelimiter   
)

Represent a primitive array as a string.

Parameters
primitivea value to convert to string:
  • logical, numeric, char, and cell may be scalar, 1D, or 2D
  • function_handle is scalar by definition
  • struct may only be scalar
charDelimiter,optionalcharacter to substitute for single-quotes in string representations.

Returns a string which represents primitive. Passing the string to Matlab's built-in eval() should reproduce primitive. For numeric primitive, should be faster than num2str(). May be slow for cell or struct primitive.

Attempts to capture the size of primitive by inserting commas and semicolons in to the string representation. Thus, size representation is limited to rows and columns (2D arrays).

Also attempts to capture the types of non-numeric arrays:

  • char rows are quoted verbatim, with optional substitution of single-quotes (helps represent nested strings).
  • logicals are converted to the keywords "true" and "false"
  • function_handles are converted to strings and prepended with "@". Note that function_handles are always scalar.
  • cell array elements are converter recursively and packaged between curly braces.
  • struct fields are converted recursively and packaged in a call to the struct() function.

Numeric types are all treated as doubles–even integers are expanded to decimal notation.

If primitive contains parentheses, ASCII "carriage return" (sprintf('\r') or char(13)) or ASCII "new line" (sprintf('\n') or char(10)) characters, eval() might to fail to reproduce the original primitive.

primitiveToString() is not intended for complex types like objects. primitiveToString() may fail for nested of cell and struct primitive, especially when they contain char elements.

◆ xmlIterateNodeAttributes()

xmlIterateNodeAttributes ( xNode  ,
attributeAction   
)

Execute a function for each of an xml node's attributes.

Parameters
xNodea DOM xml node with attributes
attributeActiona function to execute for each attribute of xNode. Should take xNode and an attribute as the only two arguments.

Used to iterate through all attributes of an xml tree node, using Matlab's built-in DOM xml parser. See "doc xmlread" for details about parsing xml files.

For the given xNode, simply loops through any attributes and invokes attributeAction with xNode and the attribute as the only two arguments.

◆ xmlIterateNodes()

xmlIterateNodes ( xNode  ,
nodeAction   
)

Execute a function at each node of an xml tree.

Parameters
xNodethe DOM node at the top on an xml tree
nodeActiona function to execute at xNode and each of its descendents. Should take a DOM node as the only argument.

Used to iterate through all nodes of an xml tree, using Matlab's built-in DOM xml parser. See "doc xmlread" for details about parsing xml files.

When a node is encountered, invokes nodeAction, with the node as the only argument. Then recursively visits the nodes children and their children, etc. Thus, most of the behavior is left up to nodeAction.

Since nodeAction is executed before trying to visit the next node, xmlIterateNodes is potentially suitable for parsing existing xml trees, or writing new ones on the fly. The only requirement for writing is that nodeAction be smart enough to figure out what to do at each tree level: It should create new nodes in breadth-first order so that xmlIterateNodes can continue parsing in depth-first order.

Variable Documentation

◆ initialFrameCount

Property initialFrameCount = 100

Models the video refresh cycle and predicts MGL frame onset times.

how many frame intervals to measure during initialize()