E-Prime notes: Difference between revisions

From Helpful
Jump to navigation Jump to search
 
(15 intermediate revisions by the same user not shown)
Line 46: Line 46:
: and writing to file formats readable by something office or statistics software (seems to all be [[TSV]] variants{{verify}})
: and writing to file formats readable by something office or statistics software (seems to all be [[TSV]] variants{{verify}})


===How E-Prime thinks about how you should build experiments===
===Turning your experiment idea into a working experiment (a.k.a. how E-prime thinks)===
 
====Parts of the E-Studio interface====
 
https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_01_Introduction.html
 
 
The left is the '''Toolbox''' of things you ''could'' add
 
 
The middle is the '''Experiment explorer''', mostly used to showing the overall '''structure''' of things you ''have'' added
: and the properties of the selected item (which you can get in a somewhat more organized popup via the property pages entry, or the property icon in the workspace once opened)
 
 
The right is the '''workspace''' that lets you edit the currently selected thing in the structure view.
: note that these things
 
 
 
 
(Text and audio - probably enter in that order)
 
 
 
To the more technically inclined:
* it likes hierarchical structure
 
 
* you put stimuli detail into Lists
 
: randomization/counterbalancing of stimuli is handled in Lists
 
 
* lists call into procedures
: how simple you keep that, or how complex you make that, is up to you
 
* procedures include presentation
 
 
* the thing that presents a stimulus also records the response
 
 
To the less technically inclined:
* the tutorials and videos are pretty decent, if a little verbose
 
 




Line 249: Line 294:




====Lists and Procedures (for experiment phases, trials, timelines)====
=====Responses to objects=====
<!--
{{stub}}


It helps to grasp how E-prime thinks about Procedures and Lists, because they determine the flow of the entire experiment.
'''Input Devices, Input Masks, and Echoes'''


The '''Input Masks''' area within an Object's ''Duration/Input'' tab
defines which devices it will respond to, and how.




''Procedures''
"Once enabled, a device maintains its own Response Option settings as a mask on the device. Selection of a device in the Device(s) field will display the options for the mask in the Response Options. "
* are a sequence of events
: that are ''usually'' made to correspond to a single trial done in a single way
: so usually consist of at least simple sequence like 'present fixation, present stimulus, record response'
: even if more complex, it is a good idea to keep it in a single sequence


* one procedure will also create a single row in the eventual data file


https://support.pstnet.com/hc/en-us/articles/115011298368


Because you probably want some variation in which procedures should be run, and some control over that,
Lists aren't just data but also the things that control what procedures get run.




''Lists'' tell E-prime ''what'' to present (and in what order - more on that later).
Whatever Object presents the stimulus will also be used to records the response to that stimulus.
: For very simple cases this may be a lone TextDisplay, ImageDisplay, etc.
: For more complex cases, this may be a Slide containing multiple things


Lists let you store all data related to trial item. When a List item is chosen (again, we'll get to that),
it invokes the listed Procedure (required), to do one trial's worth of present-and-record.


Go to that Object, and find (right-click) ''Properties -> "Duration/Input"''


Since you can get the presentation to pick up column values from the currently-presenting item[https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_04_Lists_Procedures_Attributes.html], you can control various things about the presentation by altering that list.
You will find fields controlling


The Stroop test is a favourite introduction of this, and how in some cases you can do everything you need from just one Procedure -- because without this, you might need to create a lot of variant Procedures.
* what kind of thing to record - what '''device(s)''' to accept input from
:: most commonly response box, keyboard, mouse, but
:: ...but possibly also
::: joysticks/gamepads (mostly for buttons, x-y is only polled?)
::: and anything you can manage to connect via hardware ports, or network input
::: audio recording (though many experiments are desiged to not do this, largely because it's a complex sort of data to deal with afterwards)
::: '''Button''' device [https://support.pstnet.com/hc/en-us/articles/360011374693] lets you look for specific behaviour (like hover, long press, double-click) from Keyboard, Mouse, Joystick (though not Port, response box, etc.{{verify}})
:::: and in theory can be used to unify responses from multiple types of input (but this is rarely necessary)


* '''Allowable''' - what input from that device to consider a valid response at all
:: lets you ignore accidental input
:: Because hardware has specifically named buttons you may want to use here, you may care to read [https://support.pstnet.com/hc/en-us/articles/360049191374 valid values for different hardware]


What else do people store in Lists?
* '''Correct''' - what the correct response is
:: yes, you can always score people from their output.  This field is primarily useful if you do during-the-experiment scoring that you show to the participant
:: the value will often (like the stimulus) have to be picked from a list column


Anything you have use of now or later, and ''might'' vary between stimuli now or later.
* How fast to give up on a user, and move on
: details to how to present something
:: which you may want for reaction-time experiments
: the dependent variable (a.k.a. condition) - which you are probably just handing along to yourself once you get to processing
: both of the above at the same time, e.g. color_word and font_color in the Stroop task
: correct_answer if you want to present scoring along the way








'''What else can you do with Lists and procedures?'''
'''More timing-related details'''


A single stimulis presentation may be finised by a timer, and/or by a response before that time.


E-Prime likes to lay things out '''hierarchically''',
* If you set a Duration and no input, it will be presented for that long
and various examples add List-and-Procedure combo a layer higher than the present-the-trials one.  
:: e.g. useful for fixation
:: (Duration seems to default to 1sec for new objects)


* When you set input ''and'' a Duration, people have only so long to respond


This may do nothing more than make it easier to add another ''phase'' of your experiment later.
* if you set input and no Duration, the thing will be presented until a (allowable) response
And until you do, does absolutely nothing (the largest difference is probably that that phase number will get logged).


'phase' is used loosely here.
* '''Time Limit''' - for how long to accept input
Maybe it's a completely different experiment.
:: a fixed time may be longer than the procedure we're running or cross into feedback time
But also, if you want "first do something about family, then do something about animals" you will find it easier to implement by creating two distinct stimuli lists than by thinking about how you would get E-prime to select things from ''one'' mixed list.
:: (end of proc) may cross into feedback time
:: (until feedback) will stop if you follow it up with a Feedback object in the Procedure - but if there is none, will act as (infinite)
:: (infinite)
:: so generally use (until feedback) if you have feedback, (end of proc) if you don't?
:: what do multiple responses do?




(Time Limit relation's to Duration?)




'''About about picking and ordering?'''


This is where E-prime shoved a lot of different things into one place.


Say, the default List behaviour is to sequentially work down the list,
----
which is e.g. great when you're using it to structure parts of your experiment.


When presenting stimuli, though, you probably don't want bias from ordering effects,
======Sound responses======
so want to present things randomly.
Or, as [[counterbalancing]] points out, maybe not ''quite'' randomly.


There is '''SoundIn'''[https://support.pstnet.com/hc/en-us/articles/115010679768] (recorded as WAV), but as an individual object it is effectively exclusive with e.g. presentation{{verify}},
so it may well be more convenient to start recording earlier, e.g. using a SlideSoundIn on a Slide {{verify}}






There is a '''Voice Key''', which is the Chronos responding to any sound on ''its'' sound input
: that input is not related to whatever SoundIn is recording from
:: unless you set that to Chronos
:: and, if you did ''not'' set that to chronos, may still be the same if you physically connect the microphone to both your recording device and chronos input




'''I'm looking in List properties, and have a question'''
: which in theory is a great way to record the start of a response by sound amplitude alone,
: ...at a configurable amplitude


: but in practice will just respond to anything loud enough ('um', tapping foot, whatnot) and you ''will not know afterwards'' what that was. So if you care about the timing of a real response, record the audio and use your judgment.


...yes, a List is more of a table than a list.
====Presenting multiple things in sequence====
<!--
You generally do not want to put in the stimuli to present manually - it is too much work, and does not give you the randomness you want to remove ordering effects.


In this table,
So you will usually want to do loops, of doing the same ''sort'' of presentation,
: rows are called '''levels'''
but with different stimuli each time.
:: when organizing stimuli, rows are likely to contain one each
:: but tables are useful beyond that


: columns are called '''attributes'''


Presumably both to avoid the ambiguous word 'variable'.
In E-prime,
* you make a procedure that that handles an individual presentation
* you make it automatic via lists
-->




'''Cycle''' - seems to be about sampling
====Lists and Procedures (for experiment phases, trials, timelines)====
 
<!--


It helps to grasp how E-prime thinks about Procedures and Lists, because they determine the flow of the entire experiment.






''Procedures''
* are a sequence of events
: that are ''usually'' made to correspond to a single trial done in a single way
: so usually consist of at least simple sequence like 'present fixation, present stimulus, record response'
: even if more complex, it is a good idea to keep it in a single sequence


* one procedure will also create a single row in the eventual data file




Lists have three fixed columns:
Because you probably want some variation in which procedures should be run, and some control over that,
* Weight - how often to present this {{verify}}
Lists aren't just data but also the things that control what procedures get run.
* Nested - nested list
 
* Procedure - will be called - oftne to present this stimulus


''Lists'' tell E-prime ''what'' to present (and in what order - more on that later).


And any amount of custom columns, but will often have things like
Lists let you store all data related to trial item. When a List item is chosen (again, we'll get to that),
* stimulus (e.g. text,  
it invokes the listed Procedure (required), to do one trial's worth of present-and-record.
* condition (something for code to select on)
* correct  ()
* presentation details (e.g. if you have an column like align, color, objects could use [align], [color]




Since you can get the presentation to pick up column values from the currently-presenting item[https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_04_Lists_Procedures_Attributes.html], you can control various things about the presentation by altering that list.


List properties include
The Stroop test is a favourite introduction of this, and how in some cases you can do everything you need from just one Procedure -- because without this, you might need to create a lot of variant Procedures.
* Load method
:: '''Embedded''' in the experiment
:: you can also load them from a '''file''' (txt, xml{{verify}})
:: or generate them from a '''script'''




* Order
What else do people store in Lists?
:: Sequential (default) - ordered as in the list
:: Random - without replacement, everything gets presented at most once (relation to weight?{{verify}})
:: Random with replacement -
:: Counterbalance
:: Offset - sequential but with offset
:: Permutation - all possible orders
:: Interactive


Anything you have use of now or later, and ''might'' vary between stimuli now or later.
: details to how to present something
: the dependent variable (a.k.a. condition) - which you are probably just handing along to yourself once you get to processing
: both of the above at the same time, e.g. color_word and font_color in the Stroop task
: correct_answer if you want to present scoring along the way








'''Procedure''' objects are mostly about the things an experiment should do, and the order it should do them in.
'''What else can you do with Lists and procedures?'''
Particularly useful to specify ''how'' something should be shown




Lists are more about
E-Prime likes to lay things out '''hierarchically''',
and various examples add List-and-Procedure combo a layer higher than the present-the-trials one.




A procedure doesn't directly call another, because you often want to work in a configurable way
This may do nothing more than make it easier to add another ''phase'' of your experiment later.
And until you do, does absolutely nothing (the largest difference is probably that that phase number will get logged).


'phase' is used loosely here.
Maybe it's a completely different experiment.
But also, if you want "first do something about family, then do something about animals" you will find it easier to implement by creating two distinct stimuli lists than by thinking about how you would get E-prime to select things from ''one'' mixed list.








'''About about picking and ordering?'''


You could, for example, have
This is where E-prime shoved a lot of different things into one place.
* a TrialProc that basically handles one stimulus presentation and response


* a SessionProc that
Say, the default List behaviour is to sequentially work down the list,
** decides which stimuli to present, what order to present them in,  
which is e.g. great when you're using it to structure parts of your experiment.
** loops over that an and calls TrialProc for each


When presenting stimuli, though, you probably don't want bias from ordering effects,
so want to present things randomly.
Or, as [[counterbalancing]] points out, maybe not ''quite'' randomly.




'''A List can call a Procedure for each item''',
and will basically have that row to allows its [columns] to be used in scripting and object properties.








It's fairly usual to have one overall StimulusList, with ''everything'' about a stimulus
'''I'm looking in List properties, and have a question'''
: what to present, description,  correct response, whatever
-->


====Scripting====


<!--
...yes, a List is more of a table than a list.
It is suggested that whenever you have the choice to do something in an E-Prime object or in InLine scripting,
to do it via the E-Prime object,


In this table,
: rows are called '''levels'''
:: when organizing stimuli, rows are likely to contain one each
:: but tables are useful beyond that


Not because scripting is bad. It is more flexible, but for exactly the same reason it is so much easier to get yourself into trouble.
: columns are called '''attributes'''


But the fact that E-Prime objects cannot be altered much, or only in specific ways,
Presumably both to avoid the ambiguous word 'variable'.
means that is is easier to know what the expected behaviour is.




You start programming, and every quirk of behaviour is on you.
'''Cycle''' - seems to be about sampling


You can absolutely process keypresses yourself, but may not want to if you do not understand what terms like 'concurrent event loops' mean.
Maybe some copy-pasting gets you exactly what you want -- and maybe it means it is broken in ways that only the nearest nearest programmer will understand.


Which is why, if the E-Prime object can be wrangled to do it, that's probably better.


-->


====Reactions====


<!--
'''Basics'''


E-Prime is primarily set up to measure
: the interval between
:: an object onset (when something started showing/playing) and
:: a condition being met




That condition
Lists have three fixed columns:
* is ''usually'' "you started pressing a key"
* Weight - how often to present this {{verify}}
* can also be did you click the mouse (on a specific area of the screen) [https://support.pstnet.com/hc/en-us/articles/115001800567]
* Nested - nested list
-->
* Procedure - will be called - oftne to present this stimulus


<!--
'''Optionally'''


Independently, it has some built-in logic that lets it
And any amount of custom columns, but will often have things like
* react only to specific 'correct' responses
* stimulus (e.g. text,
* condition (something for code to select on)
* correct   ()
* presentation details (e.g. if you have an column like align, color, objects could use [align], [color]


* ''count'' those correct-versus-incorrect responses.
: This is only relevant if you care to ''show'' that score to participants during the experiment, which is rarely necessary.
-->


<!--
'''More creative '''


An InLine script can also
List properties include
* ask for any other single value to be recorded in the data file (basically, SetAttribute)
* Load method
: and do that repeatedly (not always the best way of doing what you want, mind)
:: '''Embedded''' in the experiment
:: you can also load them from a '''file''' (txt, xml{{verify}})
:: or generate them from a '''script'''


* interact with input objects, abusing it any other way you like (as long as you can interrogate the specific interactions), e.g.
** "total amount you held down a key"
** track mouse coordinates [https://support.pstnet.com/hc/en-us/articles/115001909088] -- but note that this is often means "we'll be recording the latest coordinates before we moved on"
** do things like draw on screen live, then save the screen as a file before moving on [https://support.pstnet.com/hc/en-us/articles/1500004775682-Draw-with-mouse-or-finger-37346]
-->


===Some practical aspects to experiment design===
* Order
 
:: Sequential (default) - ordered as in the list
====Stimuli and responses====
:: Random - without replacement, everything gets presented at most once (relation to weight?{{verify}})
 
:: Random with replacement -
<!--
:: Counterbalance
:: Offset - sequential but with offset
:: Permutation - all possible orders
:: Interactive


Keyboards themselves report both when you press a key down, and when you release it.




E-prime by default only records the key-down, because
* most uses don't require seeing both
* key-down is the earlier event of the two




...but you can change that via Keyboard properties &rarr; Keyboard tab &rarr; Collection mode.
'''Procedure''' objects are mostly about the things an experiment should do, and the order it should do them in.
Chronos, SRBox, Mouse and possible others can also be configured to register both.  
Particularly useful to specify ''how'' something should be shown
Note that if you do, you also need to alter the correct/accepted field for each, because now you probably now need to accept ''both'' (or they'll still be ignores). See the [https://support.pstnet.com/hc/en-us/articles/360049191374 Key naming scheme].




Note that any object that accepts {ANY} will still exclude release events - for that you will want {ANY}{-ANY}
Lists are more about
: this is usually quite sane, in that the moment you switch your keyboard input from "Presses" to "Pressed and releases" you would have to check ''every'' keyboard interaction
:: because "hey what if key-down moved to the next object and releasing it was the input to that next object" would more often be a bug than what you actually intended




A procedure doesn't directly call another, because you often want to work in a configurable way


When all you want to do with a response is record it and move to the next stimulus (input based and/or timeout),
it is usually simplest to use the object that presents stimuli to record the response.
{{comment|(In the simple demos, and some simpler experiments, that would be a TextDisplay object, in more complex presentation that might be a Slide with multiple things on it)}}.


In simpler cases this is all handled in the '''Duration/Input tab'''. Sometimes you may want some extra handling via Task Events




If you want more complex logic to your responses,
I've seen people put an InLine script directly after the stimulus object, but this can be severe trickery.
The example I'm using at presents a stimulus, ''immediately'' moves on, and counts on the InLine to hold up


...and I'm looking at that because it sometimes freezes.


You could, for example, have
* a TrialProc that basically handles one stimulus presentation and response


* a SessionProc that
** decides which stimuli to present, what order to present them in,
** loops over that an and calls TrialProc for each






'''A List can call a Procedure for each item''',
and will basically have that row to allows its [columns] to be used in scripting and object properties.




Duration/Input tab, roughly in order from most to least touched:


* Device(s)
:: you can add any input Device that was added to the experiment


* Allowable - the name of reponses to react to at all
It's fairly usual to have one overall StimulusList, with ''everything'' about a stimulus
[https://support.pstnet.com/hc/en-us/articles/360049191374 Key naming scheme].
: what to present, description,  correct response, whatever
-->


* Correct
====Scripting====
: generally picks up a field from the list row
: only really used if you want E-Prime to report statistics while running


<!--
It is suggested that whenever you have the choice to do something in an E-Prime object or in InLine scripting,
to do it via the E-Prime object,




Not because scripting is bad. It is more flexible, but for exactly the same reason it is so much easier to get yourself into trouble.


But the fact that E-Prime objects cannot be altered much, or only in specific ways,
means that is is easier to know what the expected behaviour is.




You start programming, and every quirk of behaviour is on you.


Timing Mode - [[#Timing Mode|see below]]
You can absolutely process keypresses yourself, but may not want to if you do not understand what terms like 'concurrent event loops' mean.
Maybe some copy-pasting gets you exactly what you want -- and maybe it means it is broken in ways that only the nearest nearest programmer will understand.


Data Logging
Which is why, if the E-Prime object can be wrangled to do it, that's probably better.


-->


* Advanced
====Reactions====
** Max Count - allows recording of multiple responses, even [https://support.pstnet.com/hc/en-us/articles/115001812847 string input]
** Termination Response seems intended to help with the last, e.g. letting you use {ENTER} to end such input
** Flush Input Buffer - if someone mashed, it will forget all but the first key


<!--
'''Basics'''


E-Prime is primarily set up to measure
: the interval between
:: an object onset (when something started showing/playing) and
:: a condition being met


OnsetTime
: when the stimulus presentation began
: milliseconds since experiment start


OnsetDelay
That condition
: difference between planned onset and actual onset
* is ''usually'' "you started pressing a key"
: in milliseconds
* can also be did you click the mouse (on a specific area of the screen) [https://support.pstnet.com/hc/en-us/articles/115001800567]
-->


DurationError
<!--
: difference between planned duration and actual duration
'''Optionally'''
: in milliseconds
 
Independently, it has some built-in logic that lets it
* react only to specific 'correct' responses
 
* ''count'' those correct-versus-incorrect responses.
: This is only relevant if you care to ''show'' that score to participants during the experiment, which is rarely necessary.
-->


OnsetToOnset
<!--
: difference between two object's OnsetTimes
'''More creative '''
: in milliseconds


An InLine script can also
* ask for any other single value to be recorded in the data file (basically, SetAttribute)
: and do that repeatedly (not always the best way of doing what you want, mind)


* interact with input objects, abusing it any other way you like (as long as you can interrogate the specific interactions), e.g.
** "total amount you held down a key"
** track mouse coordinates [https://support.pstnet.com/hc/en-us/articles/115001909088] -- but note that this is often means "we'll be recording the latest coordinates before we moved on"
** do things like draw on screen live, then save the screen as a file before moving on [https://support.pstnet.com/hc/en-us/articles/1500004775682-Draw-with-mouse-or-finger-37346]
-->
-->


====Naming objects====
===Some practical aspects to experiment design===


Try to rename new objects to something descriptive.
====Introduction and tutorials====


Future you,
* [https://support.pstnet.com/hc/en-us/articles/115002175188 OVERVIEW: Experiment Design Using E-Studio]
the person who processes the data (often you),
other people,
and your lab assistants who are your helpdesk will thank you,
and it usually makes any scripting clearer and easier to debug as well.


* [https://support.pstnet.com/hc/en-us/articles/360006911093 E-STUDIO: E-Studio Interface]


If you do or ''will'' do any scripting, do this earlier rather than later,
because changing it later will invalidate existing references in scripts ().
{{comment|(Other E-objects ''should'' be fine because they follow renames, but don't blindly assume that)}}


====Drawing, and display size====
====Stimuli and responses====


* There is a "Match Desktop Resolution at Runtime" (in the Display device settings)
<!--
: which that tends to look crisp on monitors no matter if their native resolution is different from the one you designed on


Keyboards themselves report both when you press a key down, and when you release it.


* E-prime seems to ''default'' to 1024x768 fullscreen,
: It will look a little low-resolution (and some things may look rescaled/blurry)
:: because while that resolution should be supported by roughly everything,
:: it's also lower than most monitors have been for two decades.
: this is presumably done because drawing positions will be consistent without thinking about the next point


E-prime by default only records the key-down, because
* most uses don't require seeing both
* key-down is the earlier event of the two


* PST recommend using percentage positions rather than pixels, as this will display more similarly regardless of what monitor resolution you run it on,
: rather than
:: seem to shift to the top left when run on higher resolutions than where you designed it
:: or, more rarely, seem to go off-screen to the right when run on lower resolutions


...but you can change that via Keyboard properties &rarr; Keyboard tab &rarr; Collection mode.
Chronos, SRBox, Mouse and possible others can also be configured to register both.
Note that if you do, you also need to alter the correct/accepted field for each, because now you probably now need to accept ''both'' (or they'll still be ignores). See the [https://support.pstnet.com/hc/en-us/articles/360049191374 Key naming scheme].


It will ''not'' save you if you decided to e.g. extend your desktop onto another monitor
: (because to windows, this is indistinguisable from a 3840x1080 monitor)


====Thinking about what to log====
Note that any object that accepts {ANY} will still exclude release events - for that you will want {ANY}{-ANY}
: this is usually quite sane, in that the moment you switch your keyboard input from "Presses" to "Pressed and releases" you would have to check ''every'' keyboard interaction
:: because "hey what if key-down moved to the next object and releasing it was the input to that next object" would more often be a bug than what you actually intended
 


By default, E-prime already logs more than you typically care about,
and it is willing to log a lot more.


When all you want to do with a response is record it and move to the next stimulus (input based and/or timeout),
it is usually simplest to use the object that presents stimuli to record the response.
{{comment|(In the simple demos, and some simpler experiments, that would be a TextDisplay object, in more complex presentation that might be a Slide with multiple things on it)}}.


It duplicates everything that ''might possibly change'' with any event, so it seems to ''start'' at fifty columns or so, and you rarely care about more than about five once you're done.
In simpler cases this is all handled in the '''Duration/Input tab'''. Sometimes you may want some extra handling via Task Events


This is a little spammy.


That said, the flat structure is easy to process with simpler tools
If you want more complex logic to your responses,  
: it's a decent solution once you do start altering things during a run via scripting
I've seen people put an InLine script directly after the stimulus object, but this can be severe trickery.
: space is very cheap these days
The example I'm using at presents a stimulus, ''immediately'' moves on, and counts on the InLine to hold up


...and I'm looking at that because it sometimes freezes.




====Other hints====


https://pstnet.com/9-common-mistakes-in-e-prime3/


===More technical===


<!--
A lot of experiments can be done with procedures and lists handling the interactions,
and when this fits, this may probe to be relatively little work.




You do have a fairly full programming language at your disposal, though,
Duration/Input tab, roughly in order from most to least touched:
so can make things as complex as you want.


However, keep in mind that generating stimuli as you go might cause slow drawing
* Device(s)
that limit timing accuracy. In general, try to prepare stimuli beforehand.
:: you can add any input Device that was added to the experiment
-->


* Allowable - the name of reponses to react to at all
[https://support.pstnet.com/hc/en-us/articles/360049191374 Key naming scheme].


* Correct
: generally picks up a field from the list row
: only really used if you want E-Prime to report statistics while running


=====Task Events=====


<!--
A set of rules of 'if this event happens, run this task'


(It also groups tasks things into some categories, where E-Basic has ~240 separate methods)


Events include
buttons,
other hardware input
incorrect response,
...




Generally, procedures keep things very controlled,
so the most structural reason to use this may be to integrate with external hardware?


Timing Mode - [[#Timing Mode|see below]]


Data Logging


* [https://support.pstnet.com/hc/en-us/articles/115015199548 E-STUDIO: Using Task Events]


* [https://support.pstnet.com/hc/en-us/articles/115015040608 E-STUDIO: Configuring Task Events]
* Advanced
-->
** Max Count - allows recording of multiple responses, even [https://support.pstnet.com/hc/en-us/articles/115001812847 string input]
** Termination Response seems intended to help with the last, e.g. letting you use {ENTER} to end such input
** Flush Input Buffer - if someone mashed, it will forget all but the first key
 


====InputMasks====


<!--
OnsetTime
: when the stimulus presentation began
: milliseconds since experiment start


An InputMask seems to represent a specific input device, masked by things like what input is considered at all, and for how long to listen to it {{verify}}
OnsetDelay
: difference between planned onset and actual onset
: in milliseconds


DurationError
: difference between planned duration and actual duration
: in milliseconds


Each Object may have one or more InputMasks - normally configured via the duration/Input tab, and via [https://pstnet.com/ecr/E-Objects/RteRunnableInputObject.InputMasks-Property.htm RteRunnableInputObject.InputMasks] if you're.
OnsetToOnset
: difference between two object's OnsetTimes
: in milliseconds


Scripting can also read multiple ''.Responses'' from the object's InputMasks, if you need to do distinct things per presentation.


-->


https://support.pstnet.com/hc/en-us/articles/229366267-E-BASIC-The-Terminate-and-Timeout-methods-for-InputMask-and-InputMaskManager-17219-
====Naming objects====


Try to rename new objects to something descriptive.


Time Limit
Future you,
* {{inlinecode|(same as duration)}} - often means
the person who processes the data (often you),
:: except when you do Inline-after-object trickery
other people,  
* {{inlinecode|(end of proc)}} the Procedure terminates the Input Mask when it completes.
and your lab assistants who are your helpdesk will thank you,
* {{inlinecode|(until feedback)}} - refers to a FeedbackDisplay, not a user reaction, so if you do not have one it will actually act like (infinite)
and it usually makes any scripting clearer and easier to debug as well.
* {{inlinecode|(infinite)}}
:: (can you still stop it via code?)
* number    (milliseconds)




If you do or ''will'' do any scripting, do this earlier rather than later,
because changing it later will invalidate existing references in scripts ().
{{comment|(Other E-objects ''should'' be fine because they follow renames, but don't blindly assume that)}}


====Drawing, and display size====


* There is a "Match Desktop Resolution at Runtime" (in the Display device settings)
: which that tends to look crisp on monitors no matter if their native resolution is different from the one you designed on




* E-prime seems to ''default'' to 1024x768 fullscreen,
: It will look a little low-resolution (and some things may look rescaled/blurry)
:: because while that resolution should be supported by roughly everything,
:: it's also lower than most monitors have been for two decades.
: this is presumably done because drawing positions will be consistent without thinking about the next point




An [https://pstnet.com/ecr/E-Objects/RteRunnableInputObject-Object.htm RteRunnableInputObject] will have
* PST recommend using percentage positions rather than pixels, as this will display more similarly regardless of what monitor resolution you run it on,
* {{inlinecode|.InputMasks}} - an InputMaskManager object that lets you control what to listen for. You typically do this via the UI.
: rather than
* {{inlinecode|.PendingInputMasks}} -  
:: seem to shift to the top left when run on higher resolutions than where you designed it
:: or, more rarely, seem to go off-screen to the right when run on lower resolutions




Dim theResponseObject As RteRunnableInputObject
It will ''not'' save you if you decided to e.g. extend your desktop onto another monitor
Set theResponseObject = CRteRunnableInputObject(Rte.GetObject("PresentStimulus"))
: (because to windows, this is indistinguisable from a 3840x1080 monitor)


theResponseObject.InputMasks.Responses
====Thinking about what to log====


By default, E-prime already logs more than you typically care about,
and it is willing to log a lot more.




It duplicates everything that ''might possibly change'' with any event, so it seems to ''start'' at fifty columns or so, and you rarely care about more than about five once you're done.


theResponseObject.InputMasks.Responses.Count
This is a little spammy.  


That said, the flat structure is easy to process with simpler tools
: it's a decent solution once you do start altering things during a run via scripting
: space is very cheap these days


Procedure.ProcessPendingInputMasks




====Testing experiments in different ways====


https://support.pstnet.com/hc/en-us/articles/115011298368
Before starting an experiment, test that all buttons, sound input, sound output, etc. works as expected.


https://support.pstnet.com/hc/en-us/articles/360020940774-INFO-Procedure-ProcessPendingInputMasks-19271-


https://support.pstnet.com/hc/en-us/articles/229354507-INFO-InputMask-items-appear-gray-to-indicate-the-state-17235-


''''Quick Start'' helps run ''parts'' of your whole experiment in isolation
[https://support.pstnet.com/hc/en-us/articles/360006834514]


There are ways in which this differs from running the experiment fully.


-->
Generally few, but it can be worth testing it the slow and full way before moving on to really using it.


====Scripting (more details)====


<!--


E-Run's '''Test Mode''' [https://support.pstnet.com/hc/en-us/articles/360006834394] runs through an experiment quickly, automatically giving answers.
It is meant to test that it will record what you think it will.


General advice: avoid scripting until you use it.


There are some things you can only do with scripting.
There are also ''problems'' unique to scripting.




Scripting object [https://support.pstnet.com/hc/en-us/articles/360011218993]
While developing, you may like windowed mode[https://support.pstnet.com/hc/en-us/articles/360011287174] rather than the default full-screen while testing interaction
* you can draw on the canvas via scripting (...not directly)


* Summation Object
: "Summation objects are used to collect a series of observations. From this collection, various summary measures may be determined, such as the minimum or maximum value in the collection, the number of observations, and various statistical measures, such as the mean, standard deviation, or variance of the observations within the collection. For example, in order to determine overall accuracy in a block of trials, a Summation object may be used to keep track of the individual observations, and to calculate the desired measure from the total collection."




* Debug Object
: The Debug object encapsulates a set of useful debugging mechanisms. The Debug.Print command sends a string to the Debug tab in the Output window at run-time, which is helpful when verifying sampling sequences or timing presentation of an object. The Debug commands may be used when developing or testing a new program. See article SCRIPTING: Steps for Writing E-Prime Script [22880] for further debugging information






'''"What is c.SetAttrib"?'''
====Going to the final setup====


There is the concept of a Context object, objects that particularly scripting can refer to, mostly for logging data.
Keep in mind that when you move from design to data collection,
you are probably moving from your own PC to a lab PC,
which may have a slightly different setup.


There appears to be
* a global Context
* an object-specific context c {{verify}}
:: if you SetAttr, it will turn up logged for that list item in the .edat file


It is a good idea to run the entire thing once to check it is doing what you expect.


If you want scripting to report multiple things about
If you tweak any settings, you probably want to save that copy with a clear indication of
"this is a copy that works in the lab" - at least, if you are likely.


...and since you can also GetAttrib, you can also use it for
state you want react to,  alter stimuli presentation during the experiment




See also:
Some last minute things to think about:
* https://pstnet.com/ecr/E-Objects/Context.SetAttrib-Method.htm
* https://pstnet.com/ecr/E-Objects/Context-Object.htm


* it may have distinct sound cards, e.g. for quality recording
: run your experiment once to check that it is doing what you expect
: ''particularly'' if you record audio


* it probably has two monitors
: one for you, one for just the subject
: PCs are usually set up to consider that the main/first display, so that E-Run will go there by default


* the monitor resolution may differ
: not generally an issue - you may prefer a little rescaling over repositioning {{verify}}


* E-Studio does not seem overly clever at dealing with multiple response boxes
: You may need to explicitly tell it which you expect input from


====Other hints====
{{stub}}


'''"User script"''' under experiment mainly for globals




'''InLine''' objects [https://support.pstnet.com/hc/en-us/articles/115011962348]
https://pstnet.com/9-common-mistakes-in-e-prime3/
: for more precise control




'''"Full script"''' is the generated everything, and read-only.


"Match desktop resolution"


'''PackageCall Object''' [https://support.pstnet.com/hc/en-us/articles/115011986608]
===More technical control===
: to share code between experiments
: created with [https://support.pstnet.com/hc/en-us/articles/115000902588 PackageFile Editor]
 
-->


====Debugging====
<!--
<!--
A lot of experiments can be done with procedures and lists handling the interactions,
and when this fits, this may probe to be relatively little work.


You do have a fairly full programming language at your disposal, though,
so can make things as complex as you want.
However, keep in mind that generating stimuli as you go might cause slow drawing
that limit timing accuracy. In general, try to prepare stimuli beforehand.
-->




https://support.pstnet.com/hc/en-us/articles/115000902728-SCRIPTING-Debugging-22913-


=====Task Events=====


<!--
A set of rules of 'if this event happens, run this task'


-->
(It also groups tasks things into some categories, where E-Basic has ~240 separate methods)


===Exiting early===
Events include
buttons,
other hardware input
incorrect response,
...




'''''By the experimenter'''''
Generally, procedures keep things very controlled,
so the most structural reason to use this may be to integrate with external hardware?




{{keyhold|Ctrl}}{{keyhold|Alt}}{{key|Backspace}}
: seems to stop after currently running object{{verify}}
: ''will'' produce an {{inlinecode|.edat}} file - that is almost certainly incomplete, but that's to be expected
: because of the flexibility of this environment, 'after the current object' might sometimes have side effects, sometimes even including some that prevent exit{{verify}}
: https://support.pstnet.com/hc/en-us/articles/360019591114


{{keyhold|Ctrl}}{{keyhold|Alt}}{{key|Shift}}
* [https://support.pstnet.com/hc/en-us/articles/115015199548 E-STUDIO: Using Task Events]
: stop ''now'' - treat this as an emergency,
: useful while debugging but not when doing actual experiments, because...
: Will '''not''' generate a {{inlinecode|.edat}} file
: https://support.pstnet.com/hc/en-us/articles/115000902848


The data seems to be written to disk as an experiment goes on (in a .txt file),
* [https://support.pstnet.com/hc/en-us/articles/115015040608 E-STUDIO: Configuring Task Events]
so even when an edat file is not generated (clean exit, usually happens at the very end),
-->
you can use the E-Recovery program to read that written-as-it-went .txt file, and generate a .edat file (that will be incomplete because you stopped the experiment) -- but this is considered an emergency provision, and you should not count on this in regular use.


====InputMasks====


{{comment|(Note that if an experiment is frozen, these two or others will not work)}}
<!--


An InputMask seems to represent a specific input device, masked by things like what input is considered at all, and for how long to listen to it {{verify}}




'''''By the experiment'''''
Each Object may have one or more InputMasks - normally configured via the duration/Input tab, and via [https://pstnet.com/ecr/E-Objects/RteRunnableInputObject.InputMasks-Property.htm RteRunnableInputObject.InputMasks] if you're.


You can have your code do a call to {{inlinecode|Terminate()}} on the current list, which means "skip the rest of this specific list" (and thereby all Procs it implies).
Scripting can also read multiple ''.Responses'' from the object's InputMasks, if you need to do distinct things per presentation.
 
This may be the most controlled way to for you to  
: know and/or control exactly what is being skipped
: and to have some end-of-experiment cleanup still happen.


...but you'ld first need a clear reason to do so.


https://support.pstnet.com/hc/en-us/articles/229366267-E-BASIC-The-Terminate-and-Timeout-methods-for-InputMask-and-InputMaskManager-17219-




You could do that in an otherwise regular keyboard response by adding  a special key that does that.
Time Limit
* {{inlinecode|(same as duration)}} - often means
:: except when you do Inline-after-object trickery
* {{inlinecode|(end of proc)}} the Procedure terminates the Input Mask when it completes.
* {{inlinecode|(until feedback)}} - refers to a FeedbackDisplay, not a user reaction, so if you do not have one it will actually act like (infinite)
* {{inlinecode|(infinite)}}
:: (can you still stop it via code?)
* number    (milliseconds)


For example, in the standard NestedList example, you might add an Inline at the end of TrialProc that does:
<syntaxhighlight lang="vb">
if StrComp(Stimulus.RESP, "T", 1) = 0 Then
    TrialList.Terminate
    BlockList.Terminate
End If
</syntaxhighlight>




...a little awkward in that you would also need to include T (or whatever it is) into all your allowed responses, and consider what that actual value is - here we used a capital T so that people would probably need to hit Shift-t, which is less likely to happen accidentally.


...and that last detail can be avoided with the following:
E-Prime will listen to the {{keyhold|Ctrl}}{{key|Shift}} combination and will set internal state so that {{inlinecode|GetUserBreakState()}} returns true.
It does nothing else - you still need to check GetUserBreakState yourself ''and'' do your own informed "this is how to most gracefully stop this specific experiment" ''based'' on that. In the same example that might be:
<syntaxhighlight lang="vb">
If GetUserBreakState() Then
TrialList.Terminate
BlockList.Terminate
End If
</syntaxhighlight>


There is also a {{inlinecode|SetUserBreakState()}}, which would lead to the same clean exist, though you generally wouldn't need to unless you have both the Ctrl-Shift and some additional code-level reasons to exit the same way.


https://support.pstnet.com/hc/en-us/articles/115002035608




<!--
An [https://pstnet.com/ecr/E-Objects/RteRunnableInputObject-Object.htm RteRunnableInputObject] will have
Note that in experiments with multiple phases, there are probably according lists, so similar logic can be used to move on to the next phase of an experiment. You may want to avoid this breakstate stuff so that that is done ''only'' based on the conditions you care about.
* {{inlinecode|.InputMasks}} - an InputMaskManager object that lets you control what to listen for. You typically do this via the UI.
* {{inlinecode|.PendingInputMasks}} -
 


{{comment|(If you wanted "move on to the next section of the experiment after 10 minutes, regardless of how many answers you got done exactly" (or various other reasons), you might want to ''avoid'' this breakstate stuff)}}
Dim theResponseObject As RteRunnableInputObject
-->
Set theResponseObject = CRteRunnableInputObject(Rte.GetObject("PresentStimulus"))
<!--
Or, if you like to debug this,
If GetUserBreakState() Then
c.SetAttrib "UserBreak", "Yes"
Else
c.SetAttrib "UserBreak", "No"
End If


-->
theResponseObject.InputMasks.Responses


===When things go wrong===




====Freezes====


{{stub}}
theResponseObject.InputMasks.Responses.Count




'''What to do when freezes make interaction impossible'''
Procedure.ProcessPendingInputMasks


While {{keyhold|Ctrl}}{{keyhold|Alt}}{{keyhold|shift}} asks E-prime to immediately stop, but if the process itself has become entirely unresponsive (hanging, frozen, whatever you want to call it) for any reason, it seems your only resort is to end the process.


Probably using [[Task Manager]].


E-prime wants to run fullscreen (and seems to have always-on-top behaviour as well), so...
https://support.pstnet.com/hc/en-us/articles/115011298368
: if using a single monitor, even if you can switch to another program (like task manager), you won't see it.


: on multiple-monitor setups,
https://support.pstnet.com/hc/en-us/articles/360020940774-INFO-Procedure-ProcessPendingInputMasks-19271-
:: alt-Tab should get you a cursor back to do things on the other desktop, and/or 
:: and {{keyhold|Ctrl}}{{keyhold|Shift}}{{key|Esc}} gives you a task manager {{comment|(Ctrl-Alt-Del and then choosing Task Manager amounts to the same)}}
::: If that seems to do nothing it's probably on the same monitor as E-prime being drawn under it. Press {{keyhold|⊞ Win}} and arrow keys, this should move it between monitors. (if you pressed other things inbetween, press Ctrl-Shift-Esc again before the win-arrow thing)


https://support.pstnet.com/hc/en-us/articles/229354507-INFO-InputMask-items-appear-gray-to-indicate-the-state-17235-




You can run it in [https://support.pstnet.com/hc/en-us/articles/360011287174 windowed mode] rather than fullscreen which is less controlling -- but PST seems to consider this a debug thing only because it also gives less control of timing?{{verify}} and even gets things wrong?


-->


====Scripting (more details)====


<!--




General advice: avoid scripting until you use it.


'''running from the network / loading resources from the network'''
There are some things you can only do with scripting.
There are also ''problems'' unique to scripting.


At universities it is not unusual for your profile to be on the network.


And loading files over the network will often take longer than local disk. At best, this makes timing more precarious (E-Prime does do certain pre-loading, but it's not exactly guaranteed).
Scripting object [https://support.pstnet.com/hc/en-us/articles/360011218993]
* you can draw on the canvas via scripting (...not directly)


You generally want to run things from local disk {{comment|(local SSD is preferable over local platter disk)}},
* Summation Object
if only to avoid these potential delays.  
: "Summation objects are used to collect a series of observations. From this collection, various summary measures may be determined, such as the minimum or maximum value in the collection, the number of observations, and various statistical measures, such as the mean, standard deviation, or variance of the observations within the collection. For example, in order to determine overall accuracy in a block of trials, a Summation object may be used to keep track of the individual observations, and to calculate the desired measure from the total collection."


While this should rarely cause freezes, they have been observed.


* Debug Object
: The Debug object encapsulates a set of useful debugging mechanisms. The Debug.Print command sends a string to the Debug tab in the Output window at run-time, which is helpful when verifying sampling sequences or timing presentation of an object. The Debug commands may be used when developing or testing a new program. See article SCRIPTING: Steps for Writing E-Prime Script [22880] for further debugging information




Display busy?


https://support.pstnet.com/hc/en-us/articles/360055529993-BUG-FIX-Freezing-may-occur-on-E-Prime-Go-runs-using-Windows-10-1903-or-1909-36052-
'''"What is c.SetAttrib"?'''


There is the concept of a Context object, objects that particularly scripting can refer to, mostly for logging data.


There appears to be
* a global Context
* an object-specific context c {{verify}}
:: if you SetAttr, it will turn up logged for that list item in the .edat file


'''antivirus/antimalware scanner'''


A scanner will generally delay IO a little.
If you want scripting to report multiple things about
 
...and since you can also GetAttrib, you can also use it for
state you want react to,  alter stimuli presentation during the experiment


On network profiles and/or initial logins, whatever loading happens within the first few minutes may occupy the disk and/or a CPU core for the first minutes. If you have the time before a participant, you might consider waiting for that to calm down (Task Manager's graphs dip to near-zero).


See also:
* https://pstnet.com/ecr/E-Objects/Context.SetAttrib-Method.htm
* https://pstnet.com/ecr/E-Objects/Context-Object.htm






'''Older experiments, newer changes'''


For example, if using E-Prime 3, apparently using the outdated MsgBox(statement) instead of the newer DisplayDevice.MsgBox(statement) can cause this[https://researchwiki.solo.universiteitleiden.nl/xwiki/wiki/researchwiki.solo.universiteitleiden.nl/view/Software/E-Prime/#HUsingTwoScreens][https://support.pstnet.com/hc/en-us/articles/360008221873 ]




'''"User script"''' under experiment mainly for globals




'''InLine''' objects [https://support.pstnet.com/hc/en-us/articles/115011962348]
: for more precise control




'''"Full script"''' is the generated everything, and read-only.




'''PackageCall Object''' [https://support.pstnet.com/hc/en-us/articles/115011986608]
: to share code between experiments
: created with [https://support.pstnet.com/hc/en-us/articles/115000902588 PackageFile Editor]


There are other interactions you may be using, implicitly or not, that may block.
-->


Say, you are synchornize timing via SNTP (E-Prime can do this itself, see Experiment properties &rarr; Timing tab [https://support.pstnet.com/hc/en-us/articles/360008105174-TIMING-E-Prime-SNTP-Realtime-Clock-19471-]). I don't know what happens when that server doesn't seem to like the frequent connections, and aside from a warning in a config file, it doesn't seem all that documented.
====Debugging====
<!--






https://support.pstnet.com/hc/en-us/articles/115000902728-SCRIPTING-Debugging-22913-




Line 967: Line 1,028:
-->
-->


====Hardware unresponsive after freezes====
===Exiting early===
 


''Possibly'' some subsystem or hardware got into a weird state, but windows is pretty good about that these days,
'''''By the experimenter'''''
so there often is some leftover process.
You could try to stop that with with task manager.
Logging out and back in may be simpler to do though might take a little longer.


The other simple-but-takes longer is to shut down and restart the computer.
Most times this will still be faster than diagnosing.


{{keyhold|Ctrl}}{{keyhold|Alt}}{{key|Backspace}}
: seems to stop after currently running object{{verify}}
: ''will'' produce an {{inlinecode|.edat}} file - that is almost certainly incomplete, but that's to be expected
: because of the flexibility of this environment, 'after the current object' might sometimes have side effects, sometimes even including some that prevent exit{{verify}}
: https://support.pstnet.com/hc/en-us/articles/360019591114


https://support.pstnet.com/hc/en-us/articles/360009483794-BUG-FIX-E-Prime-hangs-on-the-first-screen-of-an-experiment-run-27780-
{{keyhold|Ctrl}}{{keyhold|Alt}}{{key|Shift}}
: stop ''now'' - treat this as an emergency,
: useful while debugging but not when doing actual experiments, because...
: Will '''not''' generate a {{inlinecode|.edat}} file
: https://support.pstnet.com/hc/en-us/articles/115000902848


The data seems to be written to disk as an experiment goes on (in a .txt file),
so even when an edat file is not generated (clean exit, usually happens at the very end),
you can use the E-Recovery program to read that written-as-it-went .txt file, and generate a .edat file (that will be incomplete because you stopped the experiment) -- but this is considered an emergency provision, and you should not count on this in regular use.




====Graphics glitches under load====
{{comment|(Note that if an experiment is frozen, these two or others will not work)}}


===When timing matters===
{{stub}}


<!--
When you ask people whether they want millisecond timing, they will say yes, more precision is more better.


'''''By the experiment'''''


That said, there are a lot of things that aren't precise to that to start with.
You can have your code do a call to {{inlinecode|Terminate()}} on the current list, which means "skip the rest of this specific list" (and thereby all Procs it implies).


Say you play a sound file and measure a response to that.
This may be the most controlled way to for you to
: know and/or control exactly what is being skipped
: and to have some end-of-experiment cleanup still happen.


...if there are a few milliseconds at the start of that file, all responses will be late by that amount of silence.
...but you'ld first need a clear reason to do so.
And that is, generally, not a problem.


In particular if you ''compare'' reaction times, it doesn't really matter if precisely 5 milliseconds are added to ''all'' figure - the difference will be just as pronounced and precise (just a little less accurate to a true value).




If you ''do'' want millisecond accuracy, you must reconsidere ''everything'' you do.  
You could do that in an otherwise regular keyboard response by adding  a special key that does that.  
-->


For example, in the standard NestedList example, you might add an Inline at the end of TrialProc that does:
<syntaxhighlight lang="vb">
if StrComp(Stimulus.RESP, "T", 1) = 0 Then
    TrialList.Terminate
    BlockList.Terminate
End If
</syntaxhighlight>


=====Thinking about timing in experiment design=====


<!--
...a little awkward in that you would also need to include T (or whatever it is) into all your allowed responses, and consider what that actual value is - here we used a capital T so that people would probably need to hit Shift-t, which is less likely to happen accidentally.
'''Do you care if the person ''or'' the machine happens to take a little longer ''between'' individual tasks?'''


'''Do you care that that might add up, add a little to the total time taken?'''
...and that last detail can be avoided with the following:
E-Prime will listen to the {{keyhold|Ctrl}}{{key|Shift}} combination and will set internal state so that {{inlinecode|GetUserBreakState()}} returns true.
It does nothing else - you still need to check GetUserBreakState yourself ''and'' do your own informed "this is how to most gracefully stop this specific experiment" ''based'' on that. In the same example that might be:
<syntaxhighlight lang="vb">
If GetUserBreakState() Then
TrialList.Terminate
BlockList.Terminate
End If
</syntaxhighlight>


If the answer to both is no, your life stays relatively simple.
There is also a {{inlinecode|SetUserBreakState()}}, which would lead to the same clean exist, though you generally wouldn't need to unless you have both the Ctrl-Shift and some additional code-level reasons to exit the same way.


Reasons you might not care:
https://support.pstnet.com/hc/en-us/articles/115002035608
* each task is self-contained - e.g. you have a series of questions where you time the answer, but time taken ''between'' the question-answer pairs doesn't matter.


Reasons you might care
* your 20 minute experiment might each take a few minutes longer, and that messes with your participant schedule for the day


Alleviation
<!--
* Schedule each of your participants with some time to spare. You probably want that anyway.
Note that in experiments with multiple phases, there are probably according lists, so similar logic can be used to move on to the next phase of an experiment. You may want to avoid this breakstate stuff so that that is done ''only'' based on the conditions you care about.


{{comment|(If you wanted "move on to the next section of the experiment after 10 minutes, regardless of how many answers you got done exactly" (or various other reasons), you might want to ''avoid'' this breakstate stuff)}}
-->
<!--
Or, if you like to debug this,
If GetUserBreakState() Then
c.SetAttrib "UserBreak", "Yes"
Else
c.SetAttrib "UserBreak", "No"
End If


-->


'''Do you care if the machine happens to be late presenting a stimulus?'''
===When things go wrong===
 
Say, if you told it to display an image ''now'', or play a sound ''now'', and it actually takes 30ms for it to fetch and decode it to start presenting it.
 
Video is a known culprit, and can take longer than that.
 


Reasons you may care
* If our response timing is relative to when we ''wanted'' it to be there, not when it actually is, then your response time by an unknown, variable amount


Reasons you may not coare
====Freezes====
* video is usually about giving someone complex information to parse, not precise timing of events within that video


Alleviation:
{{stub}}
* PreRelease goes a long way for images and sound
:: less so for video{{verify}} but as mentioned
:: see also [https://support.pstnet.com/hc/en-us/articles/229355007-TIMING-Using-PreRelease-to-Maintain-Millisecond-Timing-17760- TIMING: Using PreRelease to Maintain Millisecond Timing [17760] ]




'''What to do when freezes make interaction impossible'''


'''Do you care if the machine happens to present the stimulus a little shorter or longer?'''
While {{keyhold|Ctrl}}{{keyhold|Alt}}{{keyhold|shift}} asks E-prime to immediately stop, but if the process itself has become entirely unresponsive (hanging, frozen, whatever you want to call it) for any reason, it seems your only resort is to end the process.


See the section about monitors, but roughly speaking, on a typical 60Hz monitor, you can only change what appears on screen every 16ms.
Probably using [[Task Manager]].


When timing is aware of the monitor, and knows exactly when next image flip appears,
E-prime wants to run fullscreen (and seems to have always-on-top behaviour as well), so...
then it can plan that start time exactly, and time from then precisely.
: if using a single monitor, even if you can switch to another program (like task manager), you won't see it.


The time of future image flips are still set in stone, though.
: on multiple-monitor setups,  
:: alt-Tab should get you a cursor back to do things on the other desktop, and/or 
:: and {{keyhold|Ctrl}}{{keyhold|Shift}}{{key|Esc}} gives you a task manager {{comment|(Ctrl-Alt-Del and then choosing Task Manager amounts to the same)}}
::: If that seems to do nothing it's probably on the same monitor as E-prime being drawn under it. Press {{keyhold|⊞ Win}} and arrow keys, this should move it between monitors. (if you pressed other things inbetween, press Ctrl-Shift-Esc again before the win-arrow thing)


{{comment|(native apps can do this to decent accuracy. Browser experiments... less so. TODO: tests) (does DirectX actually tell you, or are we basing this on something like timing of blocking buffer flip calls and assumption of no drift?)}}


Reasons you might not care:
* it's a presentation while also accepting a response (e.g. stroop task)
: as long as you know when the start of presentation was, timing relative to it is easy
: (timeout is there only to deal with non-response)


Reasons you might care:
You can run it in [https://support.pstnet.com/hc/en-us/articles/360011287174 windowed mode] rather than fullscreen which is less controlling -- but PST seems to consider this a debug thing only because it also gives less control of timing?{{verify}} and even gets things wrong?
* Your protocol tells you you must present stimulus for e.g. 1000ms, to the millisecond
: a lot of numbers we consider round happen to divide well in 60Hz (1000ms is 60 frames, 800ms is 48, 750ms is 45), but some other numbers will not, and will be show for a handful of milliseconds longer


Alleviations:
* For visuals, [[#On_RefreshAlignment|RefreshAlignment]] helps the ''average'' time be your target (even if for individuals it's still longer or shorter)






'''Do you care if the machine happens to take a little longer ''between'' stimuli belonging to the same presentation?'''


'''Do you care that that might add up?'''


Say you are shown four stimuli in sequence, one second each, and then have a single timed answer (e.g. a memory task), and for some reason or other (e.g. loading on the fly), the presentation took 4.2 seconds total.
'''running from the network / loading resources from the network'''


Reasons you might not care
At universities it is not unusual for your profile to be on the network.
* if it's a memory task, chances are this does not invalidate anything.


Reasons you might care
And loading files over the network will often take longer than local disk. At best, this makes timing more precarious (E-Prime does do certain pre-loading, but it's not exactly guaranteed).  
* If you have external devices that you cannot control precisely, e.g. an MRI you can only tell it "4 seconds after presentation start, measure for one second", then the same situation will cut off data collection.


You generally want to run things from local disk {{comment|(local SSD is preferable over local platter disk)}},
if only to avoid these potential delays.


While this should rarely cause freezes, they have been observed.




'''Do you have a separate device that you cannot control to very precise timing'''


Separate devices have unique problems, and unique solutions.
Display busy?


For example, in EEG experiments you have a fairly fast signal recorder anyway, so it's not unusual to feed extra markers in time, "I did a thing exactly now", to the EEG recorder (largely because that puts all information and timing in one place, meaning you don't have to join those later, so makes your analysis a lot easier).
https://support.pstnet.com/hc/en-us/articles/360055529993-BUG-FIX-Freezing-may-occur-on-E-Prime-Go-runs-using-Windows-10-1903-or-1909-36052-






----
'''antivirus/antimalware scanner'''


'''Most of the above are not ''necessarily'' a problem'''
A scanner will generally delay IO a little.


As already pointed, out, '''if''' delays do not change how well we can pinpoint the start of anything,
On network profiles and/or initial logins, whatever loading happens within the first few minutes may occupy the disk and/or a CPU core for the first minutes. If you have the time before a participant, you might consider waiting for that to calm down (Task Manager's graphs dip to near-zero).
then this does not affect precision,
only how long the overall experiment takes.


A little more specifically: Even if the start of a stimulus is later than you thought,
: timing from the start of that stimulus presentations is usually still well defined
: and for the same reason the length of a stimulus on screen is still well defined and typically very controllable






'''When you need to start thinking harder'''
'''Older experiments, newer changes'''


A number of issues can be addressed afterwards (particular where it turns out E-prime logged the start of presentation), but in some cases it's much better to avoiding them in first place.
For example, if using E-Prime 3, apparently using the outdated MsgBox(statement) instead of the newer DisplayDevice.MsgBox(statement) can cause this[https://researchwiki.solo.universiteitleiden.nl/xwiki/wiki/researchwiki.solo.universiteitleiden.nl/view/Software/E-Prime/#HUsingTwoScreens][https://support.pstnet.com/hc/en-us/articles/360008221873 ]


The "doesn't affect precision" may not be true
* for video ''if'' it is presented more latency
:: that said, a lot of tasks with video are 'watch a video, report what you saw' - the watching is not timed, the response may be


* for audio if it is presented with more latency
: this is actually an unnecessarily complex topic




* if the mode is set to




-->


====Diving deeper====


=====On PreRelease=====


<!--
There are other interactions you may be using, implicitly or not, that may block.


'''Doing everything seprately'''
Say, you are synchornize timing via SNTP (E-Prime can do this itself, see Experiment properties &rarr; Timing tab [https://support.pstnet.com/hc/en-us/articles/360008105174-TIMING-E-Prime-SNTP-Realtime-Clock-19471-]). I don't know what happens when that server doesn't seem to like the frequent connections, and aside from a warning in a config file, it doesn't seem all that documented.


Stimuli presentation can be entirely sequential. Do one, get done, start the next.


Any preparation required for presentation would ''have'' to happen when the object starts to be shown - meaning the ''actual'' time it is seen/heard is late by however long that preparation still took.


Because preparation would have to happen ''between'' presentations.




: upsides:
:: the stimulus presentation can never accidentally get interrupted by work
: limitations:
:: preparation takes time, so putting it between presentations makes the experiment a 'little'' longer (by the accumulated preparation time, which shouldn't be much  more than 30ms per stimulus)
:: a sequence of stimuli that follows a longer-term schedule won't be as regular as you may sometimes want (but this is somewhat rare)


-->


====Hardware unresponsive after freezes====


''Possibly'' some subsystem or hardware got into a weird state, but windows is pretty good about that these days,
so there often is some leftover process.
You could try to stop that with with task manager.
Logging out and back in may be simpler to do though might take a little longer.


The other simple-but-takes longer is to shut down and restart the computer.
Most times this will still be faster than diagnosing.


'''Can we get those down near 0ms (also making presentation schedule to be strictly regular)?'''


Yes, with some footnotes.
https://support.pstnet.com/hc/en-us/articles/360009483794-BUG-FIX-E-Prime-hangs-on-the-first-screen-of-an-experiment-run-27780-




First, to do this, E-Prime separates the acts of
* "get the stimulus ready" (e.g. load from disk, decode)
* "present the simulus"


for context, most stimulus preparation is some busywork at the beginning, and then a second or so of very little to do.
====Graphics glitches under load====


If, once idle, you can prepare the work for the next object, then that busywork is done
after the work for the current object, and before the next object needs it.


===Issues and Errors===


You can also tell it to preparation during the previous stimulus presentation ('''PreRelease''')
: upsides
:: timing of a sequence can be done on a more regular schedule
: downsides
:: might affect the last bit of the previous stimulus presentation{{verify}}
:: still not guaranteed, just usually okay




=====Multiple sound cards=====


Presenting on multiple sound cards is not particularly possible to do with accuracy (this is not really PST's fault, though ''some'' sort of provisions for this would have been nice).




'''How much does this really matter?'''


====="unable to find sound capture device"=====


In terms of time spent:
=====''Device Name:'' Sound; Unable to play=====
: text should be negligible
: loading images should often be no more than up to 30ms{{verify}} (reading stuff from disk, decoding it)
: loading sound should be assumed to take up to 30ms{{verify}} (reading stuff from disk, decoding it)
: loading video is... a bit of a wildcard.
:: just don't expect accurate timing around video.




Seems to mean it can't open a specific sound card.


In terms of your experiment, no prerelease


''Will'' affect
Could mean it's trying to open the system one in exclusive mode?
* it often does the length of the overall experiment
I don't see a way to ask for a specific device.
:: because it keeps on adding a few dozen milliseconds




Often ''won't'' affect
* length of individual stimulus presentation


* response times of stimuli
:: in that because that is relative to when it ''did'' get presented.


=====There is a 3rd party driver installation issue=====


Lack of prerelease It only causes issues when
Usually actually means "License not found"
* multiple stimuli could not be synchronized{{verify}}
* you have external hardware on a timer that you ''cannot'' adapt later. Think MRI machine or such.


(this doesn't matter in a lot of experiments, but can)






=====Video=====


'''what it means, a little more technically'''
E-prime does not preload video.
Expect it to not be presented with very precise timing.


The PreRelease of an object is the amount of time (in ms) that E-Prime will take during the execution of that object, to setup/preload the ''next'' object.
This is often fine enough, in that video is often used in a "''what'' did you see" (or how did what you see correlate with what you heard), more than a "''when precisely''" did you see it. But yeah, it's a bit of a known issue.


'''PreRelease''' is a property of objects
: actually the maximum number of milliseconds to spend on a next presentation)
:: defaults to (same as duration) since E-Prime 2?{{verify}}
:: (making it shorter than refresh rate is unlikely to help much. A few dozen ms may be enough for most cases, though, and setting it to more ''usually'' has no more effect)
:: When an object just needs to load, this is fine. When an object has a dynamic nature (e.g. InLine)


Video may stutter.
Trying to ensure it's read from local disk, preferably SSD, may lessen that.




Stuttering has been known to cause audio buffer issues.
Complain to PST, I suppose?


'''Setting PreLoad to '(same as duration)' ''' {{comment|(introduced in, and default since, E-Prime 2[https://support.pstnet.com/hc/en-us/articles/360020318414-TIMING-PreRelease-defaults-changed-to-promote-better-timing-accuracy-17936-])}}
===When timing matters===
{{stub}}


...amounts to mean "Hi object, once you're done processing your own thing, start doing the ''setup'' of the next one"
<!--
When you ask people whether they want millisecond timing, they will say yes, more precision is more better.




That said, there are a lot of things that aren't precise to that to start with.


'''Setting PreLoad to 0'''
Say you play a sound file and measure a response to that.


...is equivalent that "start preparing when the schedule says you should be showing" described above.
...if there are a few milliseconds at the start of that file, all responses will be late by that amount of silence.
And that is, generally, not a problem.


In particular if you ''compare'' reaction times, it doesn't really matter if precisely 5 milliseconds are added to ''all'' figure - the difference will be just as pronounced and precise (just a little less accurate to a true value).




'''Setting Preload to a specific number'''
If you ''do'' want millisecond accuracy, you must reconsidere ''everything'' you do.
-->


A preload of a specific number is "(that amount) before the end of presentation, start setup of the next"
: For example, if you have a text with 3000ms and 500ms preload, it will start working 2500ms into the text object presentation.
: a very small preload (e.g. <20ms) might not always be enough time for the setup to be done in time
: a large enough preload (e.g. above 500ms, ballpark) may have no additional effect, because most things ''are'' done faster than that


=====Thinking about timing in experiment design=====


<!--
'''Do you care if the person ''or'' the machine happens to take a little longer ''between'' individual tasks?'''


Notes:
'''Do you care that that might add up, add a little to the total time taken?'''
* In most cases, (same as duration) means things will be prepared in time


If the answer to both is no, your life stays relatively simple.


* it seems that for InLine scripts, preload is run time
Reasons you might not care:
: that means that if
* each task is self-contained - e.g. you have a series of questions where you time the answer, but time taken ''between'' the question-answer pairs doesn't matter.  
:: the timing of that InLine matters, it will start too soon
:: the InLine needs to respond to a reaction before, it may be too soon
: ...so you often want the object before such an inline to have PreLoad set to 0


* something similar goes for FeedBack (for the 'may be before the last response' reasons{{verify}})
Reasons you might care
* your 20 minute experiment might each take a few minutes longer, and that messes with your participant schedule for the day


* something similar goes for Package Call (for 'we can't know exactly what it will do at this time' reasons{{verify}})
Alleviation
* Schedule each of your participants with some time to spare. You probably want that anyway.


* something similar goes for the last object in a procedure (?)


* when timing is critical, think hard about PreRelease


'''Do you care if the machine happens to be late presenting a stimulus?'''


Say, if you told it to display an image ''now'', or play a sound ''now'', and it actually takes 30ms for it to fetch and decode it to start presenting it.


Video is a known culprit, and can take longer than that.


'''Are there downsides?'''


Yup.
Reasons you may care
* If our response timing is relative to when we ''wanted'' it to be there, not when it actually is, then your response time by an unknown, variable amount


Reasons you may not coare
* video is usually about giving someone complex information to parse, not precise timing of events within that video


''it can silently cause other things to behave incorrectly''
Alleviation:
* PreRelease goes a long way for images and sound
:: less so for video{{verify}} but as mentioned
:: see also [https://support.pstnet.com/hc/en-us/articles/229355007-TIMING-Using-PreRelease-to-Maintain-Millisecond-Timing-17760- TIMING: Using PreRelease to Maintain Millisecond Timing [17760] ]


PreRelease is a clever hack, but a hack all the same.


Ideally, it will only start the Load of objects, which should not lead to its presentation.


However, this distinction is fuzzy for some kinds of objects.
'''Do you care if the machine happens to present the stimulus a little shorter or longer?'''
It should not be used when the next thing is
* a Feedback object
* an InLine object
* a Package Call


I have also seen it cause sound recording to fail (but have not diagnosed why).
See the section about monitors, but roughly speaking, on a typical 60Hz monitor, you can only change what appears on screen every 16ms.


Maybe also be wary of slides with multiple objects, some of which are recording?
When timing is aware of the monitor, and knows exactly when next image flip appears,
then it can plan that start time exactly, and time from then precisely.


The time of future image flips are still set in stone, though.


{{comment|(native apps can do this to decent accuracy. Browser experiments... less so. TODO: tests) (does DirectX actually tell you, or are we basing this on something like timing of blocking buffer flip calls and assumption of no drift?)}}


''No guarantees''
Reasons you might not care:
* it's a presentation while also accepting a response (e.g. stroop task)
: as long as you know when the start of presentation was, timing relative to it is easy
: (timeout is there only to deal with non-response)


PreRelease only says that preparation will start earlier, it still cannot guarantees the preparation ''will'' have happened already.
Reasons you might care:
* Your protocol tells you you must present stimulus for e.g. 1000ms, to the millisecond
: a lot of numbers we consider round happen to divide well in 60Hz (1000ms is 60 frames, 800ms is 48, 750ms is 45), but some other numbers will not, and will be show for a handful of milliseconds longer
 
Alleviations:
* For visuals, [[#On_RefreshAlignment|RefreshAlignment]] helps the ''average'' time be your target (even if for individuals it's still longer or shorter)


Around long audio, it may not manage.


I'm not sure it even ''tries'' with video, because this is a component external to it.


'''Do you care if the machine happens to take a little longer ''between'' stimuli belonging to the same presentation?'''


For images and short sounds it's fine most of the time, though, and it ''will' record how much late it was,
'''Do you care that that might add up?'''
but when the onset timing is ''absolutely critical'', more attention to this is is important.


Say you are shown four stimuli in sequence, one second each, and then have a single timed answer (e.g. a memory task), and for some reason or other (e.g. loading on the fly), the presentation took 4.2 seconds total.


Reasons you might not care
* if it's a memory task, chances are this does not invalidate anything.


Reasons you might care
* If you have external devices that you cannot control precisely, e.g. an MRI you can only tell it "4 seconds after presentation start, measure for one second", then the same situation will cut off data collection.








---
'''Do you have a separate device that you cannot control to very precise timing'''


"[...] the median duration is longer than the specified duration time, is most strongly
Separate devices have unique problems, and unique solutions.  
influenced by the time required for stimulus preparation, [...]"


For example, in EEG experiments you have a fairly fast signal recorder anyway, so it's not unusual to feed extra markers in time, "I did a thing exactly now", to the EEG recorder (largely because that puts all information and timing in one place, meaning you don't have to join those later, so makes your analysis a lot easier).




Keep in mind that even after preparing (in the below diagram: '''Setup'''/'''preparation'''{{verify}}),
a fully prepared stimulus may be on your monitor a little later (in the below diagram: '''Sync'''{{verify}})


----
----


'''Most of the above are not ''necessarily'' a problem'''


There is also the question of what do do after the planned end of a stimulus, and the planned start of the next.  
As already pointed, out, '''if''' delays do not change how well we can pinpoint the start of anything,
then this does not affect precision,
only how long the overall experiment takes.


Remove the thing? Leave it there?
A little more specifically: Even if the start of a stimulus is later than you thought,
: timing from the start of that stimulus presentations is usually still well defined
: and for the same reason the length of a stimulus on screen is still well defined and typically very controllable




[[File:E-prime timing.png|thumb|500px]]


'''Setup'''/'''preparation''' - the work to be done before something can be drawn/listened to/etc.
'''When you need to start thinking harder'''


A number of issues can be addressed afterwards (particular where it turns out E-prime logged the start of presentation), but in some cases it's much better to avoiding them in first place.


Perhaps most importantly,
The "doesn't affect precision" may not be true
* E-prime does not do all setup before an experiment starts
* for video ''if'' it is presented more latency
:: ...presumably because it couldn't guarantee this can always be done
:: that said, a lot of tasks with video are 'watch a video, report what you saw' - the watching is not timed, the response may be
:: ...and fundamentally can't when things can be interactive{{verify}}


* It does it just before presentation starts
* for audio if it is presented with more latency
: this is actually an unnecessarily complex topic




* if the mode is set to


'''Sync''' -


'''TargetOnsetTime'''
-->


'''OnsetDelay''' = OnsetTime - TargetOnsetTime
====Diving deeper====
: i.e. the time between planned/scheduled target onset time, and actual onset time


'''StartTime''' -
=====On PreRelease=====


'''StopTime''' -  
<!--


'''OnsetTime''' - milliseconds from the start of the experiment to when onset action begins
'''Doing everything seprately'''
: (for visual items, when draw commands happen; for SoundOut, when playback begins, etc.)


'''ActionTime''' -
Stimuli presentation can be entirely sequential. Do one, get done, start the next.


'''ActionDelay''' = ActionTime - OnsetTime
Any preparation required for presentation would ''have'' to happen when the object starts to be shown - meaning the ''actual'' time it is seen/heard is late by however long that preparation still took.
: (ideally there should be &le;1ms difference?)


Because preparation would have to happen ''between'' presentations.


'''OffsetTime''' - milliseconds from the start of the experiment to when offset action (e.g. drawing on screen) begins


'''OffsetDelay''' -
: upsides:
:: the stimulus presentation can never accidentally get interrupted by work
: limitations:
:: preparation takes time, so putting it between presentations makes the experiment a 'little'' longer (by the accumulated preparation time, which shouldn't be much  more than 30ms per stimulus)
:: a sequence of stimuli that follows a longer-term schedule won't be as regular as you may sometimes want (but this is somewhat rare)


'''OffsetDelay''' = OffsetTime - TargetOffsetTime


execution duration? = OffsetTime - OnsetTime


'''FinishTime''' -
: generally there should be &le;1ms difference between FinishTime and OffsetTime


'''DurationError''' - OffsetTime + PreRelease - OnsetTime - Duration
: difference between the actual duration and intended duration


'''OnsetToOnset''' - The ''actual'' duration something is on-screen may be OnsetTime to the next thing's OnsetTime
'''Can we get those down near 0ms (also making presentation schedule to be strictly regular)?'''
: (because the logged Duration in the log is the ''requested'' duration (as configured))
: the best metric for how long an object was visible


(note: various of those you'll only see around TimeAudit)
Yes, with some footnotes.




First, to do this, E-Prime separates the acts of
* "get the stimulus ready" (e.g. load from disk, decode)
* "present the simulus"


for context, most stimulus preparation is some busywork at the beginning, and then a second or so of very little to do.


If, once idle, you can prepare the work for the next object, then that busywork is done
after the work for the current object, and before the next object needs it.




You can also tell it to preparation during the previous stimulus presentation ('''PreRelease''')
: upsides
:: timing of a sequence can be done on a more regular schedule
: downsides
:: might affect the last bit of the previous stimulus presentation{{verify}}
:: still not guaranteed, just usually okay




https://researchwiki.solo.universiteitleiden.nl/xwiki/wiki/researchwiki.solo.universiteitleiden.nl/view/Software/E-Prime/


https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_03_Duration_Termination_Pre-Release.html


-->


=====Generate PreRun=====
'''How much does this really matter?'''


Generate PreRun (Object's Common tab) controls ''when'' external resources are loaded.


In terms of time spent:
: text should be negligible
: loading images should often be no more than up to 30ms{{verify}} (reading stuff from disk, decoding it)
: loading sound should be assumed to take up to 30ms{{verify}} (reading stuff from disk, decoding it)
: loading video is... a bit of a wildcard.
:: just don't expect accurate timing around video.


BeforeObjectRun - loads right before execution (see also PreRelease)


TopOfProcedure - loads at the beginning of the procedure, before any of its objects.


In terms of your experiment, no prerelease


E-Prime 2 defaulted to TopOfProcedure
''Will'' affect
* it often does the length of the overall experiment
:: because it keeps on adding a few dozen milliseconds


E-Prime 3 defaults to BeforeObjectRun


Often ''won't'' affect
* length of individual stimulus presentation


In an "avoid doing things at the last minute because that may delay things" way, TopOfProcedure is preferable.
* response times of stimuli
:: in that because that is relative to when it ''did'' get presented.


In a "that makes it sort of out of order, so if you are doing interesting scripting it may not do what you want" way,
e.g. want to control what it should load in the procedure e.g. via c.SetAttrib,
that won't work ''because'' that load already happened earlier.
It seems E-Prime 3 defaults BeforeObjectRun to avoid this particular confusion, at the cost of onset delays (which usually don't matter)


=====On RefreshAlignment=====
Lack of prerelease It only causes issues when
* multiple stimuli could not be synchronized{{verify}}
* you have external hardware on a timer that you ''cannot'' adapt later. Think MRI machine or such.


<!--
(this doesn't matter in a lot of experiments, but can)




Consider that the Duration ''may'' not be an exact multiple of the screen time.




For a round-numbered example, say we actually had a 100Hz monitor, for nicer round numbers of 10ms intervals.
'''what it means, a little more technically'''


Say we asked for a 202ms Duration. Or a 207ms Duration.
The PreRelease of an object is the amount of time (in ms) that E-Prime will take during the execution of that object, to setup/preload the ''next'' object.


'''PreRelease''' is a property of objects
: actually the maximum number of milliseconds to spend on a next presentation)
:: defaults to (same as duration) since E-Prime 2?{{verify}}
:: (making it shorter than refresh rate is unlikely to help much. A few dozen ms may be enough for most cases, though, and setting it to more ''usually'' has no more effect)
:: When an object just needs to load, this is fine. When an object has a dynamic nature (e.g. InLine)


If our logic is 'we aim to take it off-screen the next refresh after the target time', the duration will just always be 210 both both examples,
and it would always be on screen longer than requested.  By 8 and 3ms, respectively.


If we could aim for closest, it would be always shorter (200) for the 202 example, but would be always longer (210) for e.g. 206.




If we wanted to get that Duration closer ''on average'', then there is some extra trickery.
'''Setting PreLoad to '(same as duration)' ''' {{comment|(introduced in, and default since, E-Prime 2[https://support.pstnet.com/hc/en-us/articles/360020318414-TIMING-PreRelease-defaults-changed-to-promote-better-timing-accuracy-17936-])}}
It's not perfect, but it's better.


Basically, you tell E-Prime to schedule to take it off a frame ''earlier'' some of the time - whenever that's fairly soon.
...amounts to mean "Hi object, once you're done processing your own thing, start doing the ''setup'' of the next one"






But also, if we didn't syncr
'''Setting PreLoad to 0'''


...is equivalent that "start preparing when the schedule says you should be showing" described above.


---




Assume our own timing isn't perfectly in sync with the monitor frames.
'''Setting Preload to a specific number'''


That makes the numbers messier (every now and then it would be much less), but it would still be always positive, and still tend towards ''roughly'' 8ms{{verify}} longer on average.
A preload of a specific number is "(that amount) before the end of presentation, start setup of the next"
: For example, if you have a text with 3000ms and 500ms preload, it will start working 2500ms into the text object presentation.
: a very small preload (e.g. <20ms) might not always be enough time for the setup to be done in time
: a large enough preload (e.g. above 500ms, ballpark) may have no additional effect, because most things ''are'' done faster than that




[[File:Refresh alignment.png|thumb|right|400px]]
Now consider being able to say "if schedulingwise it turns out you have the opportunity to put the next thing on screen 5ms ''earlier'' than planned, that's also fine".  Now, scheduling would become a mix of
: &lt; 10 ms late
: &le; 5 ms early


We still know when we started putting things on screen, that doesn't change.
Notes:
* In most cases, (same as duration) means things will be prepared in time


The average duration is now ''less'' than 8ms.  Not zero, but closer to it.


* it seems that for InLine scripts, preload is run time
: that means that if
:: the timing of that InLine matters, it will start too soon
:: the InLine needs to respond to a reaction before, it may be too soon
: ...so you often want the object before such an inline to have PreLoad set to 0


Refresh Alignment can be intuited as how much of an object's Duration time can be sacrificed in order to do that.
* something similar goes for FeedBack (for the 'may be before the last response' reasons{{verify}})


Or, from a wider view, it lets you spread the error around objects better, making for better timing on average{{verify}}
* something similar goes for Package Call (for 'we can't know exactly what it will do at this time' reasons{{verify}})


* something similar goes for the last object in a procedure (?)


As a setting, Refresh Alignment is a percentage - of the refresh rate, so e.g. for 60Hz, 25% means it schedules it a frame early if that is less than (0.25 * 1/60&#x2248;) 4.2ms earlier{{verify}}. Defaults to 25% so that's what it actually means for many screens.
* when timing is critical, think hard about PreRelease








Also, consider that ''if'' there are related stimuli for which the timing must be precise, then you may care to do some careful planning.
'''Are there downsides?'''
: the screen is essentially the slowest device so you probably want to time things relative to the frame things start showing, and not e.g. show things relative to when you trigger a sound.


 
Yup.
If you only care about the ''length'' of the stimulus on screen, this doesn't matter - it starts whenever it starts and we start counting from there.




An object's 'Onset Sync' defaults to 'vertical blank', basically meaning "wait until the next frame being shown" (will not doing so potentially do screen tearing?).
''it can silently cause other things to behave incorrectly''


PreRelease is a clever hack, but a hack all the same.


Ideally, it will only start the Load of objects, which should not lead to its presentation.


In theory this means things are on the screen late compared to when you started to care about a stimulus,
However, this distinction is fuzzy for some kinds of objects.
but this is not an issue for presentation of visual stimuli, because you can make the start of the frame the start of whatever timer.
It should not be used when the next thing is
* a Feedback object
* an InLine object
* a Package Call
 
I have also seen it cause sound recording to fail (but have not diagnosed why).


Maybe also be wary of slides with multiple objects, some of which are recording?


The shorter the presentation duration, the more it can matter to make it a multiple of the refresh rate.




'''Onset Sync''' - typically vertical sync
''No guarantees''


'''Offset Sync''' - typically none, but practically still vertical sync because it will coincide with the onset of the new object
PreRelease only says that preparation will start earlier, it still cannot guarantees the preparation ''will'' have happened already.


Around long audio, it may not manage.


-->
I'm not sure it even ''tries'' with video, because this is a component external to it.


=====Timing Mode (property of an object in a procedure)=====
{{stub}}


[[File:E-prime timing modes.png|thumb|550px]]
For images and short sounds it's fine most of the time, though, and it ''will' record how much late it was,
but when the onset timing is ''absolutely critical'', more attention to this is is important.


'''Event''' - keep on-screen for '''at least''' as long as Duration - timed from the start of ''presentation'' <!-- onset? -->
: If there was delay in preparation, that will not affect the presentation time, which implies it will make the entire experiment take a little longer




'''Cumulative''' - timed from start of ''attempt'' to present, so '''stops no later than initially planned''', regardless of whether the start was delayed
:: this may shorten the presentation, but would help the experiment take exactly as long as planned




'''Custom''' - ?


---
"[...] the median duration is longer than the specified duration time, is most strongly
influenced by the time required for stimulus preparation, [...]"




Practically,
* in terms of response time
:: response time is measure from the start of presentation{{verify}} so "how fast you respond to a thing" measurement is not really affected
:: yes, 'cumulative' can chops off some amount of milliseconds at the end that people could respond in -- but generally your duration is long enough that 'at the last possible milliseconds' should be outliers anyway. 
:: It would matter to things that are ''planned'' to be very brief, and little else.


* when you have external devices
Keep in mind that even after preparing (in the below diagram: '''Setup'''/'''preparation'''{{verify}}),
: consider you have an fMRI machine that samples for exactly 60 seconds, in which you do 12 5-second questions.
a fully prepared stimulus may be on your monitor a little later (in the below diagram: '''Sync'''{{verify}})
:: Event's delays might mean it turns off in the middle of the last question
:: Cumulative might start presenting each a ''little'' late, but it is a lot simpler to know that that delay, and match response data to fMRI data


* As [[#PreRelease|PreRelease]] is enabled by default, these scheduling issues are ideally uncommon in ''either'' Event and Cumulative
----


=====Audio playback and recording timing=====


<!--
There is also the question of what do do after the planned end of a stimulus, and the planned start of the next.  
See the section below.


Remove the thing? Leave it there?


If you only need to ''compare'' response time this matters much less,
but if the absolute value matters, and matters to more precision than a dozen milliseconds, this is important.


[[File:E-prime timing.png|thumb|500px]]


You control relatively little of this in E-Prime.  
'''Setup'''/'''preparation''' - the work to be done before something can be drawn/listened to/etc.




Mostly the Sound API - the configuration of Devices &rarr; sound
Perhaps most importantly,
* ASIO
* E-prime does not do all setup before an experiment starts
: best choice when you have ASIO hardware (mostly external mic / sound cards)
:: ...presumably because it couldn't guarantee this can always be done
: ...but only work son devices that specifically support it -- including most external audio interfaces, and excluding most internal sound cards.
:: ...and fundamentally can't when things can be interactive{{verify}}
: assume no better than 5ms


* It does it just before presentation starts


* CoreAudio
: the best choice for ''generic'' (non-ASIO) sound hardware (arguably better than DirectX)
: assume no better than 10ms


* DirectX
: The remark of "Use of DirectSound for machines running Windows Vista, Window 7 (or later) is not recommended for paradigms that require sound latencies under 30ms."[https://support.pstnet.com/hc/en-us/articles/229363067-AV-Editing-the-SoundDevice-API-for-DirectSound-ASIO-CoreAudio-or-Chronos-18865-] isn't because DirectX got worse, it's because CoreAudio exists since then and can do better, so DirectX became more of a fallback
: assume no better than 30ms (and it might be more)


* Chronos
'''Sync''' -
: the chronos box can prepare by loading, and can in theory start playback within 1ms
: (it's not that generic hardware couldn't be designed to do that, it's that it ''isn't'' because roughly nothing else in the world needs it)


'''TargetOnsetTime'''


Notes:
'''OnsetDelay''' = OnsetTime - TargetOnsetTime
* I've had problems with E-Prime creating loud-noise issues (stuck ringbuffer sound), specifically when set to CoreAudio
: i.e. the time between planned/scheduled target onset time, and actual onset time
: presumably this is because of buffer-size reasons, but E-Prime offers no control? (maybe ASIO4All)
: Switch to ASIO when you can, DirectX when you must


'''StartTime''' -


-->
'''StopTime''' -  


====When you have separate devices you do not control precisely====
'''OnsetTime''' - milliseconds from the start of the experiment to when onset action begins
: (for visual items, when draw commands happen; for SoundOut, when playback begins, etc.)


====Experiment Advisor Reports====
'''ActionTime''' -


<!--
'''ActionDelay''' = ActionTime - OnsetTime
: (ideally there should be &le;1ms difference?)


'''"Duration not divisible by refresh rate"'''


If you set unusual and/or very short durations, chances are something's going to be on screen for half a second shorter or longer - on an 60Hz monitor ''on average'' off by 8ms or so.  
'''OffsetTime''' - milliseconds from the start of the experiment to when offset action (e.g. drawing on screen) begins
: whole seconds are fine
:: on 60Hz, multiples of 0.1s are fine (6 frames)
:: on 75Hz, multiples of 0.2s are fine (15 frames)


For longer stimuli, a handful of extra milliseconds won't make the world of difference.
'''OffsetDelay''' -
For very short presentations, you may well care.


'''OffsetDelay''' = OffsetTime - TargetOffsetTime


'''"The 'Sound' device is using the DirectSound API on Windows Vista or later which typically cannot achieve latency values under 30ms. ..."'''
execution duration? = OffsetTime - OnsetTime


DirectSound is an older API, that may be a little less likely to cause trouble, but sounds may come out more than 30ms later than planned.
'''FinishTime''' -
CoreAudio can be expected to push that down 10ms but this varies.
: generally there should be &le;1ms difference between FinishTime and OffsetTime
ASIO is surer to push it under 10ms.
a Chronos device, if you have one, can do certain thing to the millisecond{{verify}}


'''DurationError''' - OffsetTime + PreRelease - OnsetTime - Duration
: difference between the actual duration and intended duration


'''OnsetToOnset''' - The ''actual'' duration something is on-screen may be OnsetTime to the next thing's OnsetTime
: (because the logged Duration in the log is the ''requested'' duration (as configured))
: the best metric for how long an object was visible
(note: various of those you'll only see around TimeAudit)




'''"The display adapter of the machine is set to clone or mirror mode."'''


Under such a configuration it is impossible to know/determine when exactly each monitor's refresh rate is.






'''"Procedure ends with pending InputMask"'''




https://researchwiki.solo.universiteitleiden.nl/xwiki/wiki/researchwiki.solo.universiteitleiden.nl/view/Software/E-Prime/


https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_03_Duration_Termination_Pre-Release.html


'''"The 'Display' DisplayDevice has the "Match desktop resolution at runtime" property "'''
-->


The further explanation isn't clear to me, but I assume E-Prime has more control over the graphics process in full-screen mode,
=====Generate PreRun=====
and apparently better timing (and performance?) as a result.


https://support.pstnet.com/hc/en-us/articles/360008184434
Generate PreRun (Object's Common tab) controls ''when'' external resources are loaded.


Outside of the timing-crucual part, sure, but when exactly?




BeforeObjectRun - loads right before execution (see also PreRelease)


'''"Non-Visual object using OnsetSync or OffsetSync"'''
TopOfProcedure - loads at the beginning of the procedure, before any of its objects.


"A non-visual object (SoundOut, SoundIn, Wait) has either of its OnsetSync or OffsetSync properties set to (vertical blank) which is usually unnecessary unless syncing with external equipment."


E-Prime 2 defaulted to TopOfProcedure


E-Prime 3 defaults to BeforeObjectRun




In an "avoid doing things at the last minute because that may delay things" way, TopOfProcedure is preferable.


In a "that makes it sort of out of order, so if you are doing interesting scripting it may not do what you want" way,
e.g. want to control what it should load in the procedure e.g. via c.SetAttrib,
that won't work ''because'' that load already happened earlier.
It seems E-Prime 3 defaults BeforeObjectRun to avoid this particular confusion, at the cost of onset delays (which usually don't matter)




https://support.pstnet.com/hc/en-us/articles/360019927114
<!--
GeneratePreRun, GeneratePostRun
-->
-->


==Unsorted==
https://support.pstnet.com/hc/en-us/articles/115000902428-TIMING-Timing-of-E-Objects-22852-
 
=====On RefreshAlignment=====
 
<!--
 
 
Consider that the Duration ''may'' not be an exact multiple of the screen time.


===What is this ebLCase and ebUCase stuff?===


For example
For a round-numbered example, say we actually had a 100Hz monitor, for nicer round numbers of 10ms intervals.
ebLCase_s
ebUCase_s
are constants for strings s and S


So
Say we asked for a 202ms Duration. Or a 207ms Duration.
Const attrib_weight = ebUCase_W & ebLCase_e & ebLCase_i & ebLCase_g & ebLCase_h & ebLCase_t
is basically the string "Weight"


Why is it done like that?


https://support.pstnet.com/hc/en-us/articles/360019773853-E-BASIC-List-generates-Const-for-all-Attribute-names-17973
If our logic is 'we aim to take it off-screen the next refresh after the target time', the duration will just always be 210 both both examples,
and it would always be on screen longer than requested. By 8 and 3ms, respectively.


...iono.
If we could aim for closest, it would be always shorter (200) for the 202 example, but would be always longer (210) for e.g. 206.
 
 
If we wanted to get that Duration closer ''on average'', then there is some extra trickery.
It's not perfect, but it's better.
 
Basically, you tell E-Prime to schedule to take it off a frame ''earlier'' some of the time - whenever that's fairly soon.
 
 
 
But also, if we didn't syncr
 
 
---
 
 
Assume our own timing isn't perfectly in sync with the monitor frames.
 
That makes the numbers messier (every now and then it would be much less), but it would still be always positive, and still tend towards ''roughly'' 8ms{{verify}} longer on average.
 
 
[[File:Refresh alignment.png|thumb|right|400px]]
Now consider being able to say "if schedulingwise it turns out you have the opportunity to put the next thing on screen 5ms ''earlier'' than planned, that's also fine".  Now, scheduling would become a mix of
: &lt; 10 ms late
: &le; 5 ms early
 
We still know when we started putting things on screen, that doesn't change.
 
The average duration is now ''less'' than 8ms.  Not zero, but closer to it.
 
 
Refresh Alignment can be intuited as how much of an object's Duration time can be sacrificed in order to do that.
 
Or, from a wider view, it lets you spread the error around objects better, making for better timing on average{{verify}}
 
 
As a setting, Refresh Alignment is a percentage - of the refresh rate, so e.g. for 60Hz, 25% means it schedules it a frame early if that is less than (0.25 * 1/60&#x2248;) 4.2ms earlier{{verify}}. Defaults to 25% so that's what it actually means for many screens.
 
 
 
 
Also, consider that ''if'' there are related stimuli for which the timing must be precise, then you may care to do some careful planning.
: the screen is essentially the slowest device so you probably want to time things relative to the frame things start showing, and not e.g. show things relative to when you trigger a sound.
 
 
If you only care about the ''length'' of the stimulus on screen, this doesn't matter - it starts whenever it starts and we start counting from there.
 
 
An object's 'Onset Sync' defaults to 'vertical blank', basically meaning "wait until the next frame being shown" (will not doing so potentially do screen tearing?).
 
 
 
In theory this means things are on the screen late compared to when you started to care about a stimulus,
but this is not an issue for presentation of visual stimuli, because you can make the start of the frame the start of whatever timer.
 
 
The shorter the presentation duration, the more it can matter to make it a multiple of the refresh rate.
 
 
'''Onset Sync''' - typically vertical sync
 
'''Offset Sync''' - typically none, but practically still vertical sync because it will coincide with the onset of the new object
 
 
-->
 
=====Timing Mode (property of an object in a procedure)=====
{{stub}}
 
[[File:E-prime timing modes.png|thumb|550px]]
 
'''Event''' - keep on-screen for '''at least''' as long as Duration - timed from the start of ''presentation'' <!-- onset? -->
: If there was delay in preparation, that will not affect the presentation time, which implies it will make the entire experiment take a little longer
 
 
'''Cumulative''' - timed from start of ''attempt'' to present, so '''stops no later than initially planned''', regardless of whether the start was delayed
:: this may shorten the presentation, but would help the experiment take exactly as long as planned
 
 
'''Custom''' - ?
 
 
 
Practically,
* in terms of response time
:: response time is measure from the start of presentation{{verify}} so "how fast you respond to a thing" measurement is not really affected
:: yes, 'cumulative' can chops off some amount of milliseconds at the end that people could respond in -- but generally your duration is long enough that 'at the last possible milliseconds' should be outliers anyway. 
:: It would matter to things that are ''planned'' to be very brief, and little else.
 
* when you have external devices
: consider you have an fMRI machine that samples for exactly 60 seconds, in which you do 12 5-second questions.
:: Event's delays might mean it turns off in the middle of the last question
:: Cumulative might start presenting each a ''little'' late, but it is a lot simpler to know that that delay, and match response data to fMRI data
 
* As [[#PreRelease|PreRelease]] is enabled by default, these scheduling issues are ideally uncommon in ''either'' Event and Cumulative
 
=====Audio playback and recording timing=====
 
<!--
See the section below.
 
 
If you only need to ''compare'' response time this matters much less,
but if the absolute value matters, and matters to more precision than a dozen milliseconds, this is important.
 
 
You control relatively little of this in E-Prime.
 
 
Mostly the Sound API - the configuration of Devices &rarr; sound
* ASIO
: best choice when you have ASIO hardware (mostly external mic / sound cards)
: ...but only work son devices that specifically support it -- including most external audio interfaces, and excluding most internal sound cards.
: assume no better than 5ms
 
 
* CoreAudio
: the best choice for ''generic'' (non-ASIO) sound hardware (arguably better than DirectX)
: assume no better than 10ms
 
* DirectX
: The remark of "Use of DirectSound for machines running Windows Vista, Window 7 (or later) is not recommended for paradigms that require sound latencies under 30ms."[https://support.pstnet.com/hc/en-us/articles/229363067-AV-Editing-the-SoundDevice-API-for-DirectSound-ASIO-CoreAudio-or-Chronos-18865-] isn't because DirectX got worse, it's because CoreAudio exists since then and can do better, so DirectX became more of a fallback
: assume no better than 30ms (and it might be more)
 
* Chronos
: the chronos box can prepare by loading, and can in theory start playback within 1ms
: (it's not that generic hardware couldn't be designed to do that, it's that it ''isn't'' because roughly nothing else in the world needs it)
 
 
Notes:
* I've had problems with E-Prime creating loud-noise issues (stuck ringbuffer sound), specifically when set to CoreAudio
: presumably this is because of buffer-size reasons, but E-Prime offers no control? (maybe ASIO4All)
: Switch to ASIO when you can, DirectX when you must
 
 
-->
 
====When you have separate devices you do not control precisely====
 
====Experiment Advisor Reports====
 
<!--
 
'''"Duration not divisible by refresh rate"'''
 
If you set unusual and/or very short durations, chances are something's going to be on screen for half a second shorter or longer - on an 60Hz monitor ''on average'' off by 8ms or so.
: whole seconds are fine
:: on 60Hz, multiples of 0.1s are fine (6 frames)
:: on 75Hz, multiples of 0.2s are fine (15 frames)
 
For longer stimuli, a handful of extra milliseconds won't make the world of difference.
For very short presentations, you may well care.
 
 
'''"The 'Sound' device is using the DirectSound API on Windows Vista or later which typically cannot achieve latency values under 30ms. ..."'''
 
DirectSound is an older API, that may be a little less likely to cause trouble, but sounds may come out more than 30ms later than planned.
CoreAudio can be expected to push that down 10ms but this varies.
ASIO is surer to push it under 10ms.
a Chronos device, if you have one, can do certain thing to the millisecond{{verify}}
 
 
 
 
'''"The display adapter of the machine is set to clone or mirror mode."'''
 
Under such a configuration it is impossible to know/determine when exactly each monitor's refresh rate is.
 
 
 
'''"Procedure ends with pending InputMask"'''
 
 
 
 
'''"The 'Display' DisplayDevice has the "Match desktop resolution at runtime" property "'''
 
The further explanation isn't clear to me, but I assume E-Prime has more control over the graphics process in full-screen mode,
and apparently better timing (and performance?) as a result.
 
https://support.pstnet.com/hc/en-us/articles/360008184434
 
 
 
 
'''"Non-Visual object using OnsetSync or OffsetSync"'''
 
"A non-visual object (SoundOut, SoundIn, Wait) has either of its OnsetSync or OffsetSync properties set to (vertical blank) which is usually unnecessary unless syncing with external equipment."
 
 
 
 
 
 
 
https://support.pstnet.com/hc/en-us/articles/360019927114
-->
 
==Unsorted==
 
===What is this ebLCase and ebUCase stuff?===
 
For example
ebLCase_s
ebUCase_s
are constants for strings s and S
 
So
Const attrib_weight = ebUCase_W & ebLCase_e & ebLCase_i & ebLCase_g & ebLCase_h & ebLCase_t
is basically the string "Weight"
 
Why is it done like that?
 
https://support.pstnet.com/hc/en-us/articles/360019773853-E-BASIC-List-generates-Const-for-all-Attribute-names-17973
 
...iono.




https://pstnet.com/ecr/EBM/Constants.htm
https://pstnet.com/ecr/EBM/Constants.htm
===Timing tests===
====Testing timing====
<!--
[https://www.youtube.com/watch?v=-Gv-qDPO5Ew E-Prime 3.0 Live Stream: Auditing E-Prime]
https://youtu.be/-Gv-qDPO5Ew?t=1034  suggests inline affects onset of following object
=====ClockBinTest=====
Seems to test whether e.g. waiting waits for as long as it expects?
This seems to just test the Windows timekeeping API,
which is useful as a validation of other tests,
but seemingly not necessary beyond that.
Preferably run it for a long time to ensure there is no variation.
{{verify}}
=====ChronosTimingTest=====
Given the setup
* Chronos box's Digital Out 1 wired to Digital In 1
:: ...by default, you can modify that if convenient in your setup
What it does:
* at OnsetTime, sends a signal out over Chronos Digital 1
* records how fast the response is received
For Chronos boxes, the response is expected to be &le;1ms ([https://support.pstnet.com/hc/en-us/articles/115003716908 often around 0.3ms, though with a moderate stdev, but still well described as "typically under 1ms"])
Again, this seems to just be a QA test of the chronos box, and ''maybe'' the USB subsystem,
more of a "is there something weird with my hardware" test than anythign else?
https://support.pstnet.com/hc/en-us/articles/360044883253-TIMING-Verifying-your-Clock-and-Timing-in-E-Prime-34371-
=====Display Timing test=====
Photo sensor
https://youtu.be/-Gv-qDPO5Ew?t=2333
=====Testing other input devices=====
[https://youtu.be/-Gv-qDPO5Ew?t=173 3min]
-> BlackBox ToolKit as verification with third party hardware
[https://youtu.be/-Gv-qDPO5Ew?t=190 3m10]
Test 1:
* Chronos
: IO expander to
* SR Box
: header
* Mouse test:
: BBTK clicks modified mouse via transistor
* Keyboard test:
: BBTK clicks modified keyboard via transistor
=====Chronos test=====
=====Sound onset latency test=====
https://youtu.be/-Gv-qDPO5Ew?t=1894
ChronosSoundLatency
BBTK-only (no Chronos)
Send bit high and send sound - it sees how much later one is compared to the other.
=====Display tests=====
-->
<!--
====Unsorted====
Scriptable
* User script window - your custom parts (editable)
* full script window - the result of all configured parts, and your script  (not editable) [https://support.pstnet.com/hc/en-us/articles/115003291787]
Output window[https://support.pstnet.com/hc/en-us/articles/115003291907]
* for generation
Experiment Explorer [https://support.pstnet.com/hc/en-us/articles/115004291547]
: for overview of experiment design
----
Easing visual design
https://support.pstnet.com/hc/en-us/articles/115004936088
https://support.pstnet.com/hc/en-us/articles/360011449873
Hint: If you have customized properties, copying objects may save time.
----
Glossary
'''E-Objects''' - the parts of an experiment you work with in the structure view, procedural timelines, and workspace [https://support.pstnet.com/hc/en-us/articles/360006911153]
: there are
'''E-Basic''' is an OO scripting language
'''E-prime go''' - seems to be a service letting you transport/sharing data more easily
Experiment Advisor [https://support.pstnet.com/hc/en-us/articles/360011268134]
: suggests dewsign/timing issues
[https://support.pstnet.com/hc/en-us/articles/360026123314 E-Prime for Beginners]
----
'''Colors'''
You can generally use color names (seem to be the HTML set?)
AliceBlue
and R,G,B triples:
240,248,255
In code, that's
Color.AliceBlue
Color("AliceBlue")
Color("240,248,255")
You can also alter an existing Color object's .Red, .Green, and .Blue
----
Install requires admin privileges  https://support.pstnet.com/hc/en-us/articles/360051016594
'''File extensions''' [https://support.pstnet.com/hc/en-us/articles/229354727]
.es3 - experiment design
.ebs3 - E-basic script
.edat - experiment data
.epk3
<!--
E-prime 2  &  E-prime 3
E-prime 2 pro / not?
  - unless you're sure you want that, you don't
because it makes your experiment design openable only in pro versions from then on?
-->

Latest revision as of 16:52, 21 June 2024

Notes related to setting up behavioural experiments and such.
Experiment design
Hardware and timing
Experiment building - on timing · on online experiments · on counterbalancing
E-Prime notes · PsychoPy notes · Experiment builder notes · Gorilla notes · PsychToolbox notes · OpenSesame notes · DMDX notes



E-prime lets you do a good amount of things with just its drag and drop GUI style designer and built-in elements.

You can add scripting (Visual Basic) if you need to (though it is discouraged to have complex code, also for timing reasons).


Given it is paid-for and pricy software, with its own also-pricy hardware (Chronos) if you want better response latency, you may want to look at alternatives both in software and hardware (but to be fair, Chronos does a few things other hardware may not).


What

Parts of the overall software

E-Studio - creating an experiment

You could also do test runs from here, or even real runs
though you might prefer E-Run
because can run that on more computers for cheaper
and for details like that you can't accidentally alter the experiment


E-Run -

when you want to run an experiment, you can run it from E-studio (it will compile it to an .ebs file(verify)), but...
E-Run is a simpler environment that only runs an experiment, with fewer moving parts for you to touch and break
(also the licensing to run (and only run) things on many machines can be cheaper(verify))
creates a .txt log and, (only) if ended gracefully, an .edat file


E-Recovery [1]

when an experiment is broken off abrubtly (see #Exiting_early), it has not generated its final data file, but it will have written the ongoing data. E-Recovery converts the latter into a typically-incomplete .edat file


E-Merge - [2]

Generally, you have one .edat output file for each subject (or session).
This merges them into one .emrg

E-DataAid - helps deal with the collective output of experiments (so practically often .emrg, though it also opens .edat)

including some Excel-like analysis
and writing to file formats readable by something office or statistics software (seems to all be TSV variants(verify))

Turning your experiment idea into a working experiment (a.k.a. how E-prime thinks)

Parts of the E-Studio interface

https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_01_Introduction.html


The left is the Toolbox of things you could add


The middle is the Experiment explorer, mostly used to showing the overall structure of things you have added

and the properties of the selected item (which you can get in a somewhat more organized popup via the property pages entry, or the property icon in the workspace once opened)


The right is the workspace that lets you edit the currently selected thing in the structure view.

note that these things



(Text and audio - probably enter in that order)


To the more technically inclined:

  • it likes hierarchical structure


  • you put stimuli detail into Lists
randomization/counterbalancing of stimuli is handled in Lists


  • lists call into procedures
how simple you keep that, or how complex you make that, is up to you
  • procedures include presentation


  • the thing that presents a stimulus also records the response


To the less technically inclined:

  • the tutorials and videos are pretty decent, if a little verbose



Devices (presentation and input)

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


The Experiment object's properties has a Devices tab that lists the devices that objects and code can actively manipulate. (usually added on a need basis, in part because each may introduce some configuration for you to think about)


The defaults include Display, Keyboard, Mouse, Sound, which covers a lot of practical uses. and don't need to add any until you interact with specific hardware, and you only sometimes wish to tweak settings.

Button and Script are there for slightly more complex reasons, that you don't need to understand initially.



useful settings include e.g. resolution, refresh


  • Sound - playback/output only
lets you configure a sound API (CoreAudio/WASAPI, DirectSound, ASIO, Chronos) but not which sound card (except ASIO?) -- presumably whatever is the default or is current? (in the case of DS/CA controlled by windows?)
assume DirectSound has 30ms latency (=how late it is with playing back sound); CoreAudio may be around 5..10ms but if you need to be sure, measure it
  • SoundCapture
even fewer settings (than the playback) - just rate and channels
Presumably follows the Sound config?(verify)


  • Keyboard
note: assume USB keyboards have ~15ms latency
also, if you would press extremely regularly you would still get variation in recorded timing, because the schedule in which it polls the keyboard is unrelated to what you are doing (and cannot be synchronized)
  • Mouse
note: assume mice might have ~15ms latency(verify)
  • Joystick
note: assume joystick input might have ~15ms latency(verify)
  • Chronos
more precise button presses
more precise sound playback
  • SRBox - Chronos Box's predecessor
  • Serial, Parallel (hardware ports)
you can generally assume serial ports can react under 2ms. Some are better, some are worse.
  • Socket (network)
probably mostly used for remote control
  • Script -
apparently there to give you control of specific timing?(verify)
always there


Touchscreens and stylus input are not supported. They are supported only in that OSes will typically emulate mice, but assume this is more latency. Multitouch is not supported, by implication of mice not doing that. [4]



Monitor resolution
Multiple monitors

Objects

Overall structure


Procedure - an ordered timeline of objects to handle [5]

jumps can change order
can't jump into other procedures (though you can nest them in timelines?)

List[6] -

intended to organize (trial) data used within the experiment
e.g. independent variables (called 'attributes', to avoid confusion with variables as in code) and their levels
Interactive Lists allows control over order while testing [7]


Wait [8] - amount of time

Label [9] - target of Jump (which other objects and scripting can do)


Presentation of simple things (in sequence)

'TextDisplay[10]

ImageDisplay[11]

MovieDisplay [12]

can specify start and end time/frame

Notes:

  • For supported formats for audio and movie, see [13]
video uses ffmpeg so should easily support at least DivX, XVid, MPEG-1, MPEG-2, MPEG-4, H-264, WMV




Presenting complex things (combined / parallel)


Slide[14] -

where the above handful stimuli-like things are one-on-a-screen things that help keep simple experiments simple ("show text, ask for response")
...Slide seems to largely exists to have lets you present multiple concurrent stimuli, with one collective Input/Duration

SlideState [15]

where a Slide is a toolbox object you can put in a procedure, a SlideState lets you split one Slide into multiple presentable things - e.g. useful to have one step in a procedure be able to present alternative stimuli
Any Slide starts with a single SlideState
One way to use these is to have a slide's ActiveState be based on a list column, e.g. [PresentState]


(SlideState) sub-objects [16] refers to things you can put into a Slide / SlideState

The kind of things you can put on here overlaps lot of the toolbox one-on-a-screen things (consider SlideText[17], SlideImage[18])
but also has things that mainly make sense in combination (consider SlideButton[19], SlideChoice[20], SlideSlider[21]),
and/or that may work a little different in combination (consider SlideSoundOut[22], SlideSoundIn[23], SlideMovie[24])
Each of these can still have their own Input/Duration but this is generally not advisable in that there are various interactions you could set up that make no sense and will do weird things)
seem to be meant to structure both stimuli presentation, and thereby also structure of collected data (verify)


FeedbackDisplay [25]

is mostly just a pre-made Slide with three/four SlideStates (Correct, Incorrect, NoResponse, Pending (?))
special-cased to present feedback based on the input from another object
the last response, plus some of its own processing to allow showing statistics from previous reponses



Other objects that exist


InLine[26] -

user-written script, run at a point in a Procedure
compare to
User Script (run only at startup(verify), and a fixed part of Experiment)
https://andysbrainbook.readthedocs.io/en/latest/E-Prime/E-Prime_ShortCourse/EP_08_InlineObjects.html


Experiment - fixed, single parent of everything [27]

General, Notes - record things like author name, version, notes
Startup Info - what things to ask for and log - defaults to subject and session number, you can add more
Data File - by default, a log is written per experiment+subject+session
Devices - which devices this experiment is configured to use -- see #Presentation_output_and_response_input_devices
Experiment Advisor - helps alert various timing issues
in design (during generation)
while running


PackageCall[28]

meant for code shared by (and constant between) experiments
you may never use/need these, they may be part of how your lab works
e.g. to have "start up EEG device" be something only a lab technician has to make, and experimenters need only use
the packages they call into (.epk3) need to be registered with the experiment, so you still need to set that up


Responses to objects
This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Input Devices, Input Masks, and Echoes

The Input Masks area within an Object's Duration/Input tab defines which devices it will respond to, and how.


"Once enabled, a device maintains its own Response Option settings as a mask on the device. Selection of a device in the Device(s) field will display the options for the mask in the Response Options. "


https://support.pstnet.com/hc/en-us/articles/115011298368


Whatever Object presents the stimulus will also be used to records the response to that stimulus.

For very simple cases this may be a lone TextDisplay, ImageDisplay, etc.
For more complex cases, this may be a Slide containing multiple things


Go to that Object, and find (right-click) Properties -> "Duration/Input"

You will find fields controlling

  • what kind of thing to record - what device(s) to accept input from
most commonly response box, keyboard, mouse, but
...but possibly also
joysticks/gamepads (mostly for buttons, x-y is only polled?)
and anything you can manage to connect via hardware ports, or network input
audio recording (though many experiments are desiged to not do this, largely because it's a complex sort of data to deal with afterwards)
Button device [29] lets you look for specific behaviour (like hover, long press, double-click) from Keyboard, Mouse, Joystick (though not Port, response box, etc.(verify))
and in theory can be used to unify responses from multiple types of input (but this is rarely necessary)
  • Allowable - what input from that device to consider a valid response at all
lets you ignore accidental input
Because hardware has specifically named buttons you may want to use here, you may care to read valid values for different hardware
  • Correct - what the correct response is
yes, you can always score people from their output. This field is primarily useful if you do during-the-experiment scoring that you show to the participant
the value will often (like the stimulus) have to be picked from a list column
  • How fast to give up on a user, and move on
which you may want for reaction-time experiments



More timing-related details

A single stimulis presentation may be finised by a timer, and/or by a response before that time.

  • If you set a Duration and no input, it will be presented for that long
e.g. useful for fixation
(Duration seems to default to 1sec for new objects)
  • When you set input and a Duration, people have only so long to respond
  • if you set input and no Duration, the thing will be presented until a (allowable) response
  • Time Limit - for how long to accept input
a fixed time may be longer than the procedure we're running or cross into feedback time
(end of proc) may cross into feedback time
(until feedback) will stop if you follow it up with a Feedback object in the Procedure - but if there is none, will act as (infinite)
(infinite)
so generally use (until feedback) if you have feedback, (end of proc) if you don't?
what do multiple responses do?


(Time Limit relation's to Duration?)




Sound responses

There is SoundIn[30] (recorded as WAV), but as an individual object it is effectively exclusive with e.g. presentation(verify), so it may well be more convenient to start recording earlier, e.g. using a SlideSoundIn on a Slide (verify)


There is a Voice Key, which is the Chronos responding to any sound on its sound input

that input is not related to whatever SoundIn is recording from
unless you set that to Chronos
and, if you did not set that to chronos, may still be the same if you physically connect the microphone to both your recording device and chronos input


which in theory is a great way to record the start of a response by sound amplitude alone,
...at a configurable amplitude
but in practice will just respond to anything loud enough ('um', tapping foot, whatnot) and you will not know afterwards what that was. So if you care about the timing of a real response, record the audio and use your judgment.

Presenting multiple things in sequence

Lists and Procedures (for experiment phases, trials, timelines)

Scripting

Reactions

Some practical aspects to experiment design

Introduction and tutorials


Stimuli and responses

Naming objects

Try to rename new objects to something descriptive.

Future you, the person who processes the data (often you), other people, and your lab assistants who are your helpdesk will thank you, and it usually makes any scripting clearer and easier to debug as well.


If you do or will do any scripting, do this earlier rather than later, because changing it later will invalidate existing references in scripts (). (Other E-objects should be fine because they follow renames, but don't blindly assume that)

Drawing, and display size

  • There is a "Match Desktop Resolution at Runtime" (in the Display device settings)
which that tends to look crisp on monitors no matter if their native resolution is different from the one you designed on


  • E-prime seems to default to 1024x768 fullscreen,
It will look a little low-resolution (and some things may look rescaled/blurry)
because while that resolution should be supported by roughly everything,
it's also lower than most monitors have been for two decades.
this is presumably done because drawing positions will be consistent without thinking about the next point


  • PST recommend using percentage positions rather than pixels, as this will display more similarly regardless of what monitor resolution you run it on,
rather than
seem to shift to the top left when run on higher resolutions than where you designed it
or, more rarely, seem to go off-screen to the right when run on lower resolutions


It will not save you if you decided to e.g. extend your desktop onto another monitor

(because to windows, this is indistinguisable from a 3840x1080 monitor)

Thinking about what to log

By default, E-prime already logs more than you typically care about, and it is willing to log a lot more.


It duplicates everything that might possibly change with any event, so it seems to start at fifty columns or so, and you rarely care about more than about five once you're done.

This is a little spammy.

That said, the flat structure is easy to process with simpler tools

it's a decent solution once you do start altering things during a run via scripting
space is very cheap these days


Testing experiments in different ways

Before starting an experiment, test that all buttons, sound input, sound output, etc. works as expected.


''Quick Start helps run parts of your whole experiment in isolation [31]

There are ways in which this differs from running the experiment fully.

Generally few, but it can be worth testing it the slow and full way before moving on to really using it.


E-Run's Test Mode [32] runs through an experiment quickly, automatically giving answers. It is meant to test that it will record what you think it will.



While developing, you may like windowed mode[33] rather than the default full-screen while testing interaction




Going to the final setup

Keep in mind that when you move from design to data collection, you are probably moving from your own PC to a lab PC, which may have a slightly different setup.


It is a good idea to run the entire thing once to check it is doing what you expect.

If you tweak any settings, you probably want to save that copy with a clear indication of "this is a copy that works in the lab" - at least, if you are likely.


Some last minute things to think about:

  • it may have distinct sound cards, e.g. for quality recording
run your experiment once to check that it is doing what you expect
particularly if you record audio
  • it probably has two monitors
one for you, one for just the subject
PCs are usually set up to consider that the main/first display, so that E-Run will go there by default
  • the monitor resolution may differ
not generally an issue - you may prefer a little rescaling over repositioning (verify)
  • E-Studio does not seem overly clever at dealing with multiple response boxes
You may need to explicitly tell it which you expect input from

Other hints

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


https://pstnet.com/9-common-mistakes-in-e-prime3/


"Match desktop resolution"

More technical control

Task Events

InputMasks

Scripting (more details)

Debugging

Exiting early

By the experimenter


CtrlAltBackspace

seems to stop after currently running object(verify)
will produce an .edat file - that is almost certainly incomplete, but that's to be expected
because of the flexibility of this environment, 'after the current object' might sometimes have side effects, sometimes even including some that prevent exit(verify)
https://support.pstnet.com/hc/en-us/articles/360019591114

CtrlAltShift

stop now - treat this as an emergency,
useful while debugging but not when doing actual experiments, because...
Will not generate a .edat file
https://support.pstnet.com/hc/en-us/articles/115000902848

The data seems to be written to disk as an experiment goes on (in a .txt file), so even when an edat file is not generated (clean exit, usually happens at the very end), you can use the E-Recovery program to read that written-as-it-went .txt file, and generate a .edat file (that will be incomplete because you stopped the experiment) -- but this is considered an emergency provision, and you should not count on this in regular use.


(Note that if an experiment is frozen, these two or others will not work)


By the experiment

You can have your code do a call to Terminate() on the current list, which means "skip the rest of this specific list" (and thereby all Procs it implies).

This may be the most controlled way to for you to

know and/or control exactly what is being skipped
and to have some end-of-experiment cleanup still happen.

...but you'ld first need a clear reason to do so.


You could do that in an otherwise regular keyboard response by adding a special key that does that.

For example, in the standard NestedList example, you might add an Inline at the end of TrialProc that does:

if StrComp(Stimulus.RESP, "T", 1) = 0 Then
    TrialList.Terminate
    BlockList.Terminate
End If


...a little awkward in that you would also need to include T (or whatever it is) into all your allowed responses, and consider what that actual value is - here we used a capital T so that people would probably need to hit Shift-t, which is less likely to happen accidentally.

...and that last detail can be avoided with the following: E-Prime will listen to the CtrlShift combination and will set internal state so that GetUserBreakState() returns true. It does nothing else - you still need to check GetUserBreakState yourself and do your own informed "this is how to most gracefully stop this specific experiment" based on that. In the same example that might be:

If GetUserBreakState() Then
	TrialList.Terminate
	BlockList.Terminate
End If

There is also a SetUserBreakState(), which would lead to the same clean exist, though you generally wouldn't need to unless you have both the Ctrl-Shift and some additional code-level reasons to exit the same way.

https://support.pstnet.com/hc/en-us/articles/115002035608


When things go wrong

Freezes

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


What to do when freezes make interaction impossible

While CtrlAltshift asks E-prime to immediately stop, but if the process itself has become entirely unresponsive (hanging, frozen, whatever you want to call it) for any reason, it seems your only resort is to end the process.

Probably using Task Manager.

E-prime wants to run fullscreen (and seems to have always-on-top behaviour as well), so...

if using a single monitor, even if you can switch to another program (like task manager), you won't see it.
on multiple-monitor setups,
alt-Tab should get you a cursor back to do things on the other desktop, and/or
and CtrlShiftEsc gives you a task manager (Ctrl-Alt-Del and then choosing Task Manager amounts to the same)
If that seems to do nothing it's probably on the same monitor as E-prime being drawn under it. Press ⊞ Win and arrow keys, this should move it between monitors. (if you pressed other things inbetween, press Ctrl-Shift-Esc again before the win-arrow thing)


You can run it in windowed mode rather than fullscreen which is less controlling -- but PST seems to consider this a debug thing only because it also gives less control of timing?(verify) and even gets things wrong?




running from the network / loading resources from the network

At universities it is not unusual for your profile to be on the network.

And loading files over the network will often take longer than local disk. At best, this makes timing more precarious (E-Prime does do certain pre-loading, but it's not exactly guaranteed).

You generally want to run things from local disk (local SSD is preferable over local platter disk), if only to avoid these potential delays.

While this should rarely cause freezes, they have been observed.


Display busy?

https://support.pstnet.com/hc/en-us/articles/360055529993-BUG-FIX-Freezing-may-occur-on-E-Prime-Go-runs-using-Windows-10-1903-or-1909-36052-


antivirus/antimalware scanner

A scanner will generally delay IO a little.

On network profiles and/or initial logins, whatever loading happens within the first few minutes may occupy the disk and/or a CPU core for the first minutes. If you have the time before a participant, you might consider waiting for that to calm down (Task Manager's graphs dip to near-zero).



Older experiments, newer changes

For example, if using E-Prime 3, apparently using the outdated MsgBox(statement) instead of the newer DisplayDevice.MsgBox(statement) can cause this[34][35]





There are other interactions you may be using, implicitly or not, that may block.

Say, you are synchornize timing via SNTP (E-Prime can do this itself, see Experiment properties → Timing tab [36]). I don't know what happens when that server doesn't seem to like the frequent connections, and aside from a warning in a config file, it doesn't seem all that documented.




-->

Hardware unresponsive after freezes

Possibly some subsystem or hardware got into a weird state, but windows is pretty good about that these days, so there often is some leftover process. You could try to stop that with with task manager. Logging out and back in may be simpler to do though might take a little longer.

The other simple-but-takes longer is to shut down and restart the computer. Most times this will still be faster than diagnosing.


https://support.pstnet.com/hc/en-us/articles/360009483794-BUG-FIX-E-Prime-hangs-on-the-first-screen-of-an-experiment-run-27780-


Graphics glitches under load

Issues and Errors

Multiple sound cards

Presenting on multiple sound cards is not particularly possible to do with accuracy (this is not really PST's fault, though some sort of provisions for this would have been nice).


"unable to find sound capture device"
Device Name: Sound; Unable to play

Seems to mean it can't open a specific sound card.


Could mean it's trying to open the system one in exclusive mode? I don't see a way to ask for a specific device.



There is a 3rd party driver installation issue

Usually actually means "License not found"



Video

E-prime does not preload video. Expect it to not be presented with very precise timing.

This is often fine enough, in that video is often used in a "what did you see" (or how did what you see correlate with what you heard), more than a "when precisely" did you see it. But yeah, it's a bit of a known issue.


Video may stutter. Trying to ensure it's read from local disk, preferably SSD, may lessen that.


Stuttering has been known to cause audio buffer issues. Complain to PST, I suppose?

When timing matters

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


Thinking about timing in experiment design

Diving deeper

On PreRelease
Generate PreRun

Generate PreRun (Object's Common tab) controls when external resources are loaded.

Outside of the timing-crucual part, sure, but when exactly?


BeforeObjectRun - loads right before execution (see also PreRelease)

TopOfProcedure - loads at the beginning of the procedure, before any of its objects.


E-Prime 2 defaulted to TopOfProcedure

E-Prime 3 defaults to BeforeObjectRun


In an "avoid doing things at the last minute because that may delay things" way, TopOfProcedure is preferable.

In a "that makes it sort of out of order, so if you are doing interesting scripting it may not do what you want" way, e.g. want to control what it should load in the procedure e.g. via c.SetAttrib, that won't work because that load already happened earlier. It seems E-Prime 3 defaults BeforeObjectRun to avoid this particular confusion, at the cost of onset delays (which usually don't matter)


https://support.pstnet.com/hc/en-us/articles/115000902428-TIMING-Timing-of-E-Objects-22852-

On RefreshAlignment
Timing Mode (property of an object in a procedure)
This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Event - keep on-screen for at least as long as Duration - timed from the start of presentation

If there was delay in preparation, that will not affect the presentation time, which implies it will make the entire experiment take a little longer


Cumulative - timed from start of attempt to present, so stops no later than initially planned, regardless of whether the start was delayed

this may shorten the presentation, but would help the experiment take exactly as long as planned


Custom - ?


Practically,

  • in terms of response time
response time is measure from the start of presentation(verify) so "how fast you respond to a thing" measurement is not really affected
yes, 'cumulative' can chops off some amount of milliseconds at the end that people could respond in -- but generally your duration is long enough that 'at the last possible milliseconds' should be outliers anyway.
It would matter to things that are planned to be very brief, and little else.
  • when you have external devices
consider you have an fMRI machine that samples for exactly 60 seconds, in which you do 12 5-second questions.
Event's delays might mean it turns off in the middle of the last question
Cumulative might start presenting each a little late, but it is a lot simpler to know that that delay, and match response data to fMRI data
  • As PreRelease is enabled by default, these scheduling issues are ideally uncommon in either Event and Cumulative
Audio playback and recording timing

When you have separate devices you do not control precisely

Experiment Advisor Reports

Unsorted

What is this ebLCase and ebUCase stuff?

For example

ebLCase_s
ebUCase_s

are constants for strings s and S

So

Const attrib_weight = ebUCase_W & ebLCase_e & ebLCase_i & ebLCase_g & ebLCase_h & ebLCase_t

is basically the string "Weight"

Why is it done like that?

https://support.pstnet.com/hc/en-us/articles/360019773853-E-BASIC-List-generates-Const-for-all-Attribute-names-17973

...iono.


https://pstnet.com/ecr/EBM/Constants.htm


Timing tests

Testing timing