Personal E-Prime knowledge base of one experimental psychology PhD student, or, what I’ve found useful to know during my learning experience with E-Prime… If you find something that is wrong or want to add more tips, please absolutely do that (in the comments below)!
Contents:
- Basic work with context attributes and variables in E-Basic inline scripts
- How to run experiments on multiple computers (without the full E-Prime suite)?
- How to adjust a script on a subject station without E-Studio?
- How to read & export collected data (.edat2) without E-DataAid?
- How to easily output just some values during the experiment?
- How to create a staircase procedure in E-Prime?
- How to send markers/triggers from E-Prime to EEG or other device (without any code)?
- How to design displays with flexible position values?
- More resources
Basic work with context attributes and variables in E-Basic inline scripts
You probably won’t get far beyond very simple experiments without using these.. This might not be the most precise picture, but should be useful for beginners (who are at least somewhat familiar with the basics of E-Prime).
Variables
E-Basic (a VB-based language used in E-Prime) variables are variables like in many other programming languages. You can define new ones in the User tab of Script (ALT+5) by the Dim keyword, and you can later work with them in the code in various ways. They can be of many types, like Integer or String, but can also be complex objects, with many properties and methods (associated functions) to work with them. One of the most useful object types is Summation, which serves as a container for storing numeric values and computing some statistics on these stored values. A simple example:
'User tab of Script: Dim DetectionACC As Summation 'Define new variable 'Inline code, useful to place it as the first item in your experiment: Set DetectionACC = New Summation 'Initialize the variable (make it empty and ready to use) 'Inline object, after a response: DetectionACC.AddObservation StimulusSlide.ACC 'Add a new value to the container, in this case accuracy property of a response to a Slide object which was displayed before, which can be one for a correct or zero for incorrect response 'Inline object, end of experiment, e.g.: Debug.Print DetectionACC.Mean 'Print a mean of all the values in the container, in our case the mean accuracy
Context attributes
Context attributes are simply said a special type of variables that can hold string and numeric values and are accessible using special ways as described below. Their advantage is mainly that they can be used not just inside inline code, but directly in the graphical interface. You can create them by adding columns in a List and you can read them by simply writing their name in square brackets in some text-field.
For example, it is useful to define stimulus picture file names as context variables, because then you just change the filename at only one place (the first inline script).
- Specify the filename of an image as a context attribute using the square brackets. Here [ImgTop] will specify the name of an image that will be displayed at the top location.
- We want to vary from trial to trial what picture will be displayed here. Instead of a specific file we only enter a name of a context attribute [ImgTop]. We set the possible values of this attribute through a List object, where we create a column with the same name as this attribute, and inside the rows of this columns enter what values that this attribute will have on the various trials (each line of the table corresponds to one or more trials):
- On some trials the [ImgTop] attribute will be a neutral item, on some trials it will be a target item. Both items are represented by a different picture. These two pictures occur many times here so it would be impractical to write directly the file name inside this List table. Instead, we define two more context variables, [Target] and [Neutral]. We assign real file name values to them in an Inline script with the c.SetAttrib function (it is useful to place this inline script as the first object in the experiment):
c.SetAttrib "Target", "target1.bmp"
As you can see, you can read the context attributes in the graphical interface using the square brackets. You can also read them via code with the c.GetAttrib function. For example here we want to define different response keys for different subject groups:
c.SetAttrib "FirstResponseKey", "c" c.SetAttrib "SecondResponseKey", "m" If CStr(c.GetAttrib("Group")) = "2" Then c.SetAttrib "FirstResponseKey", "m" c.SetAttrib "SecondResponseKey", "c" End If
Note that the method for reading the attributes has a different syntax than the one for writing values to it:
WhatIRead = c.GetAttrib("NameOfAttribute") c.SetAttrib "NameOfAttribute", WhatIWrite
How to run experiments on multiple computers (without the full E-Prime suite)?
You are likely to have only a one or a similarly limited number of licenses for E-Studio and the whole E-Prime suite, but you want to run your experiments on multiple computers. How to do that?
Your license allows you to install several (around 25) so called Subject stations, which is exactly what we want here: It includes only E-Run, the component of E-Prime that allows you to run compiled E-Basic script .ebs2 files. But it does not allow you to change the script (no E-Studio) or export the collected data into some sensible format (no E-DataAid). Actually, both of these thing are sort-of possible even without the full E-Prime suite, more on this later! To install Subject stations, simply run the E-Prime installation file on the given computers, select that you want only the Subject station, and enter in the license details.
How to adjust a script on a subject station without E-Studio?
You cannot directly edit the compiled .ebs2 script, but you can make your experiment adjustable in various ways via various parameters. The easiest way is to define “startup info parameters” (basically, context attributes) in the properties of your experiment (CTRL+E) for which the experimenter/participant will be prompted at the start of the experiment:
But maybe you want to create many of these parameters, which will not vary across participants, but will remain the same for the given computer. Or you want to be able to easily send your experiment’s parameters to someone else. Or you don’t want your participant to see you entering the values, etc. For these purposes it is handy to use a separate XML file that can hold many parameters and settings of your experiment. One example is the number of trials, screen resolution, refresh rate or font size, which could be nice to adjust e.g. if you send your experiment to a different lab which has computers with different screens, etc. You can set any context variable that you use in your script in this way.
To create or change this startupInfo file, go to: Top menu bar – Edit – Experiment… (CTRL+E). On Startup Info tab check “Load values from external..” and click on “Edit Local Values”.
This opens an editor, where you can set built-in properties (e.g. Display.XRes) or create new attributes (e.g. LetterSize here, to set font size of stimuli). The editor is quite easy to use. Save the file so that it has the same name as your script, and extension .startupInfo.
You can open this editor from Windows Start menu as well:
And importantly, you can easily edit this file e.g. in a Notepad on the target computer:
You can use the variables (context attributes) that you define in the startup file in typical ways:
Or using c.GetAttrib(“LetterSize”) in inline scripts.
How to read & export collected data (.edat2) without E-DataAid?
When I collect data on subject stations, I have to copy the .edat2 files to the computer with the full E-Prime suite, merge it in E-Merge, and export it using E-DataAid in some sensible format, e.g. tab-delimited (.csv). It has happened to me several times that I wasn’t able to do this, because the only PC with E-DataAid was occupied, and at any rate, it was a lot of running to and fro, so I thought about a way to become independent of E-DataAid. You can notice E-Run creates another output file (.txt, can be opened by E-Recovery to convert it into .edat2). It contains the same data as .edat2 file, but is stored as plain text. I.e., it is possible to read it by a parser, that can convert it into an e.g. tab-delimited file. I wanted to write my own parser, but found out there is an existing one for R, called rprime, which is perfect, because R is the best tool for data analysis anyway:-) You can download the project and read how to use it here. I had to build the package myself and took me some time to learn to use it well, but overall it is simple, so if you need some help, feel free to contact me. Now there seems to be a finished package that you can easily install: install.packages(“rprime”).
Example of R script that was sufficient in my case to load the .txt file and covert it into a .csv (it might differ in your case, depending on e.g. how your experiment is structured into levels, you will surely figure out how to make it work):
library(rprime) datapath <- "D:/Experiments/SomeExperiment/data/" Files <- list.files(datapath, pattern = ".txt") # convert all .txt files in the given folder for (i in 1:length(Files)){ dataname <- Files[i] filename <- paste(datapath, dataname, sep="") elog <- read_eprime(filename) elist <- FrameList(elog) level2 <- keep_levels(elist, 2) edf <- to_data_frame(level2) write.table(edf, file=paste0(datapath, "tsv_", dataname), quote=FALSE, sep="\t") }
But you might want a simpler solution and/or do not need to export all the logged data. In that case have a look especially at the custom logger solution in the next section:
How to easily output just some values during the experiment?
Sometimes you don’t want to export all your data to find out something of interest, like the error rate of your participant or the threshold outcome of a staircase procedure. There are several ways how to output such a value.
- If you are running the experiment via E-Studio, you can print it to debug console, e.g., I want to know the mean accuracy (DetectionACC is a Summation object, see above):
Debug.Print DetectionACC.Mean
- If you run the experiment at a subject station, you can print the value on screen inside a TextDisplay or other object, using an Inline script placed before the output TextDisplay, e.g. (EndFB is the name of the TextDisplay object):
EndFB.Text = "Accuracy=" & CStr(CLng(DetectionACC.Mean*100))
- Or, if you want to save the output value or don’t want the participant to see it, you can write it into a file. If it is just a few values, the easiest way can be to use the StartupInfo file (see above), which can not only store values that are input to the experiment, but can store outputs as well. You can use such a code inside an Inline script:
Rte.StartupInfo.Local.SetProperty "SCAcc", CLng(DetectionACC.Mean*100)
You can then open the file using Notepad (and see that the accuracy was 84 % in this case):
- You can also create a custom log file and append multiple lines into it, e.g. selected info for each trial. For example here we create a file named according to the subject and session numbers, e.g. 12-1-Staircase.dat, and write some info into it. (This Inline object is placed inside a Procedure inside a List, therefore performs a write operation on each trial. Modified from Hairston and Maldjian, see below.)
Open c.GetAttrib("Subject") & "-" & c.GetAttrib("Session") & "-" & "log.dat" For Append As #1 Print #1, c.GetAttrib("Subject") & chr(9) & c.GetAttrib("Session") & chr(9) & TrialNum & chr(9) & Response.RT Close
How to create a staircase procedure in E-Prime?
Previous section leads me to the following problem: Creating a staircase procedure that can find a threshold value for some stimulus (e.g., duration of a display, loudness of a sound..). I have found a nice basic solution by Hairston and Maldjian and further worked on it to allow the kind of adaptive staircase procedures as described in the nice paper Garcı́a-Pérez, M. A. (1998). Forced-choice staircases with fixed step sizes: asymptotic and small-sample properties. Vision research, 38(12), 1861-1881. I have generalized it to allow combining various up-down rules with step-up/step-down ratios (e.g. I am using a 3-down/1-up rule with a 3/4 delta-down/delta-up ratio to achieve ca. 84% accuracy; it works very well), and fixed what I think was an error in determining the occurrence of a reversal in sequences longer than 1. It is quite likely the original authors have made some improvements on their code before they published it, but I wasn’t able to get my hands on the new code. If you are interested in my solution, I have uploaded the staircase code with some basic explanation to GitHub.
How to send markers/triggers from E-Prime to EEG or other device (without any code)?
If you want to record EEG during your behavioral experiment and want to later know at what times in the EEG recording experimental events occurred (e.g. to create ERPs), you need to send trigger signals to the EEG device from E-Prime at specified times. In older versions of E-Prime you needed to do this via Inline scripts. In new version you can use the graphical interface to do it! In many object, like the TextDisplay or a Slide there is a new tab in the object properties, called Task Events. Here you can define signals that should be sent when various events (display onset, keypress, etc.) occur.
In my case I wanted to send a certain value (a byte, i.e. a number between 0 and 255) to an EEG device via parallel port (LPT) at the time of the onset of the stimulus. Therefore I added a new OnsetTime event to the Slide object which presents my stimulus display, with these parameters: delay kept as 0 (send the trigger exactly at the onset time), as a Task I selected a parallel port device (defined in experiment properties, see picture below), action is to write a byte (because that’s what our EEG recording software wants), DisplayTrigger is the value to be sent, which is defined as a context attribute elsewhere (as a good programming practice, to be able to change it easily), data type is Byte.
It works the same way for response events, e.g., Keyboard.Press events. Or (I had a reason for this once), you can create a dummy (empty) TextDisplay object which will be displayed for e.g. 20ms right after the response had been made, and send the trigger using OnsetTime events.
An important thing to note is that here one has to set the signal value, keep it for a short time, and then set it back to zero, because it is the change of the signal value from zero to something that is important. For this you need to add the same event again, and change the Delay and Custom (signal) values. I set the signal to zero after 10 ms, because that is twice the recommended minimum duration for my sampling rate of 500 Hz in our EEG recording software manual. But it can be even longer (e.g. 50 ms), to make sure it is long enough to be registered by your software. You can read more about this in the E-Prime New Features Reference Guide, which I recommend, as well as the basic User Guide, or here.
Here is how I defined the parallel port device, but you can use a general Port device, and set it using the address of your port (how to determine it is described in the resources linked below, but often it is &H378).
More on this topic and on doing these things by inline code, here, here, here, etc..
How to design displays with flexible position values?
In (e.g.) vision science you often need to design search displays with many items. Maybe your locations stay fixed and you only change the items that are displayed at these locations. Maybe you vary the locations from trial to trial completely. In either case, it is a good idea to define the locations
- as relative values (in percentages) to make your script work with different screen resolutions (although percentage values are not as precise as pixel values..), and
- not as fixed values but as variables (defined in an in-line script or an external file) so that you can easily change them.
However, if you do this, you will likely see a mess in your E-Studio: all the (e.g.) Image items on your (e.g.) Slide object will overlap in the center and it will be difficult to change their properties (you can use the dropdown box for that).
Useful practice is thus to write the positions like this: [contextAttribute]:defaultPercentage%, e.g. [loc6x]:30%. The part after the colon specifies the default location, if we don’t know the variable value, e.g. when displaying the slide object in the E-Studio.
It all then looks nicely:
BTW, if you need to create displays with many concentric, equally spaced items (like the one below), I have a nice Matlab script for computing the location values, feel free to contact me.
More resources
Depending on your level of expertise, you can read portions of the basic Users Guide, from which I recommend reading chapter on Critical Timing, and the New Features Reference Guide. The official website has a lot of info as well, there is a support forum and you can find many other resources online (in google it helps to write “e-prime” in quotation marks;-))
Other useful resources that I’ve stumbled upon..
Many more tips at the official website: https://www.pstnet.com/eprimelegFAQ.cfm
Examples of experiments: http://step.psy.cmu.edu/scripts-plus/
Very nice tips and tricks in this blog post! I really needed to find out how to do the staircase part. Thank you!
Thanks for your nice comment, Freddy! Glad you found it interesting. If you want the code for the staircase procedure, feel free to contact me at ohavlicek / at / gmail / dot / com. I had a look at your blog, it looks really interesting!
Hi, great post! Would really appreciate it if you could share the code for the staircase procedure. Thank you!
Thank you for sharing. very useful. I am trying to linked between experiments. Such that variables defined randomly in Exp 1, could be save with a unique participant’s identifier and then upload and used in a different experiment. any ideas?
Hi Pia, thanks for your question;-) If I understand it well, you want to save some variables from Experiment1 (like what I describe in the section “How to easily output just some values during the experiment?”) and then use those values as startup info values in a second experiment? Well, the simplest solution I see is to do it manually, just enter the saved values into the startup dialog windows (like subject number etc). Unless it is a large amount of values per participant, that should suffice. Or is your situation different?
Thank you for the reply,we prefer not to do it manually because we have about 20 variables which we want to export form one experiment to the other.
Participants provides names of 5 people they know, which are randomly assigned to shapes – so that is already 10… than we have additional 10 coordinates which we obtain in one study and want to use in another. We tried to save variables to Startupinfo but failed. maybe we move to matlab?
I see.. I would also try Startupinfo, saving the variables from one experiment into the startupinfo file, then storing the file in another folder, one for each participant, and then use those saved files for the second experiment, renaming the files and making sure the variables in the second experiment have the same names.. Or you can use a more sophisticated E-Basic code for reading and writing text files, that way you might have only one file.. If you switch to Matlab (Psychtoolbox?) you’ll also have to solve how to write and read text files, right?