All elements

Element objects are all the stimuli as well as functionality (e.g. recording response from subject) that can run in trials. Set element object properties in trial definition tables. [Or in the coding method: Make element objects using <><type><>Object functions, e.g. crossObject, keyPressObject, etc. Then set their properties and input them all to addTrial to define the trial.]

There are many different element object types, e.g. cross, picture, keyPress, portReceiver, etc. See All documentation or type pb at the MATLAB command line for a list with links to documentation for each one. This page documents properties that all element types have.

Input properties all elements have

start
end

Default: start = no start conditions → element doesn't run
Default: end = no end conditions → element must end on its own

Each element runs in a trial, and properties start and end set times or conditions for the element to start/end in the trial. Each of these properties is a further struct. To set a condition, set one of the fields in the table below and omit all the others (or leave them = <cd>[]<cd>). You can also customize a condition, add a delay, set multiple conditions, and more—see further below for options.
.t

Start/End the element at time relative to trial start. Set to a number (sec). 0 = trial start.

.t_sync

Start/End the element at time relative to experiment sync in the trial. Set to a number (sec). Some element must sync the experiment at a trigger in the same trial for this to work—see syncExperiment below.

.duration (end only)

End the element at time relative to its start. Set to a number (sec).

.startOf
.endOf

Start/End the element when another element starts or ends in the trial. Set to a string pointing to an element object by  its variable name and possibly index (visual method: in its object heading / coding method: in the experiment script). Or you can use a string array pointing to multiple elements to listen for when any of them starts. e.g.

<cdsm> "picture"<cdsm>
<cdsm> "pictures(2)"<cdsm>
<cdm>[<cdm><cdsm>"pictures(1)" "pictures(2)"<cdsm><cdm>]<cdm>

Tip: If you have an index in a numeric variable you can use it in an <cdsm>"x"<cdsm> string (but not an <cdsm>'x'<cdsm> string) like this:

<cdsm>"pictures("<cdsm><cdm> + n + <cdm><cdsm>")"<cdsm>

.response
.responseBy

Set field response = <cd>true<cd> to start/end the element at any response from subject recorded by any response handler element in the trial.

Or if there are multiple response handlers in the trial, you can use field responseBy instead to listen for any response recorded by a specific one. Set to a string/string array, like startOf/endOf above.

Note if you want to narrow down what responses or response features (e.g. correct/incorrect) to listen for, you can add field and—see below.

.trigger
.triggerBy

Start/End the element at any trigger registered by any element in the trial. Usage is like response/responseBy above. See also field and below.

Usually when you want to set timing based on a trigger, it's in a scanner experiment and easiest to use t_sync above instead. trigger/triggerBy are more general purpose. They work whether or not an element syncs the experiment in the trial.

.preTrial

If you set field preTrial = <cdm>true<cdm>, the element runs in the pre-trial interval. Only simple static visual elements can do this (e.g. cross elements). Also currently you can only run one element in a pre-trial interval. Note to set pre-trial background color, use trial object property preTrialBackColor.

(End element on its own)

Some elements can end automatically at some point—check Object ends on its own? near the top of the element type documentation. For example, by default a keyPress element ends on its own when it records a response. If an element can end on its own, you don't need to set property end (unless you want it to maybe end earlier).

Examples

element.start.t = 0
element.end.duration = 2

→ start at trial start and run for 2 sec.

element.start.endOf = <cdsm>"movies(1)"<cdsm>

→ start when element movies(1) ends. No end condition is set, so the element needs to be able to end on its own.

Add to a condition – Field and

You can add field and to some conditions (currently response and trigger conditions) to further customize it. Set and to a string that is any MATLAB expression for PsychBench to evaluate during the experiment. The expression must evaluate to <cd>true<cd>/<cd>false<cd>, and the condition will only be met if <cd>true<cd>. If you need multiple lines of code, the string can be the name of a script that makes a variable ans containing <cd>true<cd>/<cd>false<cd>.

An and expression can reference the following variables:

response/responseBy condition:
response
correctResponse
responseScore
responseLatency
n_response

Response and related information. Mostly taken from corresponding record properties of the response handler element that recorded the response. Additionally n_response is response number recorded by the respond handler (1, 2, 3, …). Note if the response handler has recorded multiple responses, these variables contain information for the current one. See below for examples of using these to set response feedback.

trigger/triggerBy condition:
trigger
n_trigger

trigger is trigger value, taken from record property trigger of the element that registered the trigger.
 n_trigger is trigger number registered (1, 2, 3, …). If the element has registered multiple triggers, these variables contains information for the current one.

Examples: Correct/Incorrect response feedback

element.start.response = true
element.start.and = <cdsm>"responseScore = true"<cdsm>

→ start at any response scored <cdm>true<cdm>, typically meaning correct.

element.start.response = true
element.start.and = <cdsm>"responseScore = false"<cdsm>

→ start at any response scored <cdm>false<cdm>, typically meaning incorrect.

Wait from condition – Field timeFrom

You can add field timeFrom = a number (sec) to any condition to tell the element to wait from when the condition is met (including and above if set) to start/end.

Example

element.start.response = true
element.start.timeFrom = 2

→ start 2 sec from any response.

Multiple conditions

You can set more than one start or end condition for an element. If so the element will start/end at whichever one occurs first. To do this, just make start/end a row struct array instead of a single struct. Note additional fields (and, timeFrom, cancel) can have different values for different conditions.

Example: Setting a maximum start time

element.start(1).response = true
element.start(1).timeFrom = 2
element.start(2).t = 10

→ start 2 sec from any response or 10 sec from trial start, whichever occurs first.

Not all elements need to run (Field cancel)

By default each trial simply ends when no elements are left running or scheduled to start (e.g. by a start.t condition). If none of an element's other start conditions occur by then, it just won't run.

Another way for an element to maybe not run is to add field cancel to one of its end conditions. By default an end condition that occurs before or at when the element would start is just ignored. However, if you add end field cancel = <cd>true<cd> then the element will not start anytime at or after when the condition occurs (in addition to ending if it's running when the condition occurs).

Lastly if you just leave start = <cd>[]<cd> for an element, it won't run.

Examples

pic.start.t = 5;
pic.end.response = true;

pic starts 5 sec from trial start and ends at any response.

pic.start.t = 5;
pic.end.response = true;
pic.end.cancel = true;

pic starts 5 sec from trial start and ends at any response. Additionally, if a response is recorded before the element starts (before 5 sec), it won't run.

Synchronizing elements with each other

To synchronize the start or end of different elements, just give them the same start or end condition. This works regardless of element modality (visual, auditory, etc.).

Special timing

Additional special timing options are available in some element types. For example, elements of type sequence can run other elements in an alternating sequence, e.g. in a change blindness experiment. See element type documentation for more information.

Trial timing

By default each trial ends whenever no elements in it are left running or scheduled to start (e.g. by a start.t condition), and the next trial starts after a 0.75 sec interval. This is all you need for most experiments. However, a few trial object properties allow other options: preTrialInterval, start, end. See Trial timing if you need more information.

Timing precision

There are various potential sources of deviation between expected element times and actual times you get during an experiment—finite frame rate, dropped frames, delays when starting/ending on spontaneous conditions (e.g. response and trigger conditions with no wait time), etc. In experiments where precise timing is important, you may need to consider these, in some cases to be aware of them as limitations and in other cases to avoid them by setting things correctly. If precise timing is important, see Timing precision for more information. See also properties startBuffer/endBuffer below.

Debugging timing – pbLog.txt

PsychBench writes pbLog.txt in the MATLAB current folder to log events like elements starting and ending during the experiment. This can be helpful for figuring out mistakes you made in setting element start/end conditions. Note times in this log are approximate. For all other purposes use experiment results output (see Time measurements above).

Time measurements

start/end tell the element when to run. To measure actual times during the experiment, include record properties startTime, endTime, duration, etc. below in experiment results output (property report). Similar record properties are available at the trial and experiment levels.

startBuffer
endBuffer

Defaults: no start/end buffers

Ignore unless you need precise timing.

There are various potential sources of deviation between expected element start/end times and actual times you get during an experiment. One common deviation is delay caused by too much processing that your system needs to do at the time (dropped frames). If this occurs and it matters in your experiment, you may be able to reduce or eliminate it by setting a start or end "buffer" for the element. To do this: Do a test run with element record properties start/endLatencyBufferable in experiment results output. If these properties record a value > 0, try setting startBuffer/endBuffer to a similar or greater value (sec). Note buffering is only possible for start/end conditions that have definite times so PyschBench knows when they are coming ahead of time (t conditions, t_sync or duration conditions > buffer time you want, any condition with a wait time timeFrom > buffer time you want).

Setting a buffer tells PsychBench to begin preparing the element start/end early. It comes at a cost that some processes will pause for the duration of the buffer immediately before the target time, including any display animation in running elements. If nothing is happening, including if target time is at trial start, then this doesn't matter. In other cases you should only set the shortest buffer you need and/or make a tradeoff.

(Note if latencies are mostly 0 except in trial 1, that is a common consequence of MATLAB loading functions into memory on first use. In that case it may be better to just discount the results of trial 1 than set buffers in it.)

For more information on timing precision and frames see Timing precision.

syncExperiment

Default: don't synchronize the experiment at trigger

For use in scanner experiments. Set = <cd>true<cd> to tell the element to synchronize the experiment when it registers a trigger. This allows you to set any element in the trial to start/end at times relative to sync using start/end field t_sync for it. You can also set subsequent trials to start at times relative to sync using trial object property start field t_sync.

Only some elements can register triggers: You can switch any response handler element to register inputs as triggers by setting its property registerTrigger = <cd>true<cd>. A common example is using keyPress elements to receive synchronization signals from a scanner that arrive as keyboard inputs. Some elements that aren’t response handlers can also register triggers, e.g. portSender/Receiver elements.

See also record property syncTime below.

Examples

See scanner demos in <><PsychBench folder><>/docs/demos.

vary

Default: don't vary any properties of the element

Many elements are dynamic by their nature (e.g. movie elements). However, you can also more generally change the value of some element properties in real time when the element is running. Do this by listing it in property vary. Then instead of you setting the target property, PsychBench will vary it on a time-dependent course using any expression you set.

You can only vary properties that are adjustable. Which properties are adjustable depends on the element type—see the top of the property list in the type documentation. If you need to make other properties adjustable, you can edit the element type code—see Element Type Programming Manual.

vary is a further struct that can have the following fields. For unusual cases to vary multiple properties of the element, you can make vary a struct array, e.g. <cd>vary(1).what = <cd> ..., <cd>vary(2).what = <cd>...

.what

A string that is name of an input property to vary. You can also vary part of a property by including further indexes/field names, e.g. <cdsm>"size(2)"<cdsm> would vary the second coordinate in property size . If you vary part of a property, you can set the rest of it directly or leave it at default.

If you want to vary a visual element property that you set in units other than deg using <cdm>{val, <cdm><cdsm>"unit"<cdsm><cdm>}<cdm> form, just target the numeric part of the property here, e.g. <cdsm>"height{1}"<cdsm>.

.setExpr

A string that is any MATLAB expression for PsychBench to evaluate to set the target. The expression can reference a variable t which will contain current time relevant to element start (sec). If you need multiple lines of code, the string can be the name of a script that makes a variable ans containing value to set.

Example

element.vary.what = <cdsm>"position"<cdsm>
element.vary.setExpr = <cdsm>"[-5+mod(2*t, 10) 2*sin(pi*t)]"<cdsm>

→ move a visual element right on a sinusoidal path and wrap around

element.position = {[], <cdsm>"cm"<cdsm>};
element.vary.what = <cdsm>"position{1}"<cdsm>
element.vary.setExpr = <cdsm>"[-5+mod(2*t, 10) 2*sin(pi*t)]"<cdsm>

→ same but in cm instead of deg

staircase

Default: don't staircase any properties of the element

You can use a staircase to set one or more numeric properties of the element by listing them here. Then instead of you setting the target property, PsychBench will set it based on the value of the staircase when the trial containing the element runs. You also need a single staircase object to carry and step the staircase value across trials. The usual approach is to apply the staircase to the same property of a similar stimulus element in each trial.

staircase is a further struct that can have the following fields. You can omit fields (or leave them = <cd>[]<cd>) to leave them at default. For unusual cases to staircase multiple properties of the element, you can make staircase a struct array, e.g. <cd>staircase(1).what = <cd> ..., <cd>staircase(2).what = <cd>...

Note you will get an error during the experiment if a property is staircased to a value that is impossible for it (e.g. a negative value for a property that must be positive). You need to set the parameters here and in the staircase object so this can't happen.

.what

No default

A string that is name of a property to staircase. You can also staircase part of a property by including further indexes/field names, e.g. <cdsm>"size(2)"<cdsm> would staircase the second coordinate in property size . If you staircase part of a property, you can set the rest of it directly or leave it at default. Target must be numeric (not necessarily scalar).

If you want to staircase a visual element property that you set in units other than deg using <cdm>{val, <cdm><cdsm>"unit"<cdsm><cdm>}<cdm> form, just target the numeric part of the property here, e.g. <cdsm>"height{1}"<cdsm>.

.setExpr

Default: set target = staircase value

You can set setExpr to a string that is any MATLAB expression for PsychBench to evaluate to set the target. The expression must reference the variable staircaseVal which will contain the staircase value (a number).

e.g.
Target must be an integer (and staircase value might not be)
→ <cdsm>"round(staircaseVal)"<cdsm>

If you need multiple lines of code, the string can be the name of a script that makes a variable ans containing value to set.

.min
.max

Default: no minimum/maximum target value

You can use these fields to set minimum and/or maximum target values. The staircase won’t step if it would set the target past these limits. min/max can be single numbers to apply to all numbers in target, or numeric arrays with size = size of target. If you target part of a property, min/max applies only to that part.

See also staircase object properties min/max if it’s more convenient to set min/max at the staircase value (before transformation by setExpr above).

.setStaircaseExpr

Default: Don’t update staircase value

If you use setExpr above and the target value the staircase sets (what the subject perceives) may not precisely correspond to the staircase value, use setStaircaseExpr to update the staircase value recorded in the staircase object. e.g. if setExpr = <cdsm>"round(staircaseVal)"<cdsm>, you would use setStaircaseExpr to update to the rounded value. This is important since the recorded staircase value can affect the next staircase value and threshold estimate. Usage is like setExpr except the variable to reference in the expression is targetVal, which will contain the staircased target value.

Examples

See staircase demos in <><PsychBench folder><>/docs/demos.

Input properties all objects have

report
info

Record properties all elements have

PsychBench uses record properties to record information during experiments. You can't set record properties but you can see them in experiment results using input property report.

startTime
endTime
duration
n_startFrame
n_endFrame
startLatencyBufferable
endLatencyBufferable

startTime and endTime record start/end times relative to trial 1 start (sec). If the element presents a stimulus, these generally = stimulus onset/offset times. If the element listens for input from a device, these generally = earliest/latest times input could be received. Note these properties record actual times during the experiment—to set timing, use input properties start/end above.

duration records end time − start time.

n_startFrame and n_endFrame record frame numbers in the trial for the first/last frames the element ran in. They are related to startTime/endTime as start time = first frame start time, end time = last frame end time ( = next frame after that start time). You can use these with trial object record properties frameRates, frameIntervals.

startLatencyBufferable and endLatencyBufferable are estimates of the part of delay from expected start/end time (sec) that might be reducible by setting a buffer in properties startBuffer or endBuffer above. Generally only for experiments where precise timing is important.

For more information on frames and timing precision see Timing precision.

trigger
triggerTime
d_triggerTime
numTriggers

In PsychBench a trigger is a "flag" an element raises that you can set timing from. Most commonly set syncExperiment = <cd>true<cd> above to tell the element to synchronize the experiment at trigger, then set the timing of any element in the trial (element properties start/end field t_sync) and/or subsequent trial timing (trial object property start field t_sync) from sync. Even if you don't set syncExperiment, you can set any element in the trial to start/end from triggers more generally using element properties start/end fields trigger/TriggerBy.

Only some elements can register triggers: You can switch any response handler element to register inputs as triggers by setting its property registerTrigger = <cd>true<cd>. A common example is using keyPress elements to receive synchronization signals from a scanner that arrive as keyboard inputs. Some elements that aren’t response handlers can also register triggers, e.g. portSender/Receiver elements.

If the element registers triggers, these properties record information about them in case useful to see in results:

trigger is a value representing the trigger registered. What trigger values can be depends on element type—see its documentation. They are often numbers.

triggerTime is time the trigger occurred relative to trial 1 start (sec). See also syncTime below.

d_triggerTime is uncertainty in trigger time (sec). Range = ± d_triggerTime. This is > 0 in the common case of an element that checks to receive a trigger once per frame, giving uncertainty = 1/2 the interval between checks (≈ 8 msec at 60 frames/sec with no dropped frames). Otherwise this property reports 0, but note this doesn’t include other sources of uncertainty which may be present in your system. For more information on frames and timing precision see Timing precision.

If the element registers multiple triggers then the properties above become row vectors or cell arrays.

numTriggers is number of triggers registered by the element.

syncTime

If the element syncs the experiment (property syncExperiment above), this records the sync time relative to trial 1 start (sec). This = triggerTime above for the trigger it synced at.