Routines for handling data structures and analysis
A container class for keeping track of multiple loops/handlers
Useful for generating a single data file from an experiment with many different loops (e.g. interleaved staircases or loops within loops
| Usage : | exp = data.ExperimentHandler(name=”Face Preference”,version=‘0.1.0’) |
|---|---|
| Parameters : |
|
Inform the ExperimentHandler that the run was aborted.
Experiment handler will attempt automatically to save data (even in the event of a crash if possible). So if you quit your script early you may want to tell the Handler not to save out the data files for this run. This is the method that allows you to do that.
Add the data with a given name to the current experiment.
Typically the user does not need to use this function; if you added your data to the loop and had already added the loop to the experiment then the loop will automatically inform the experiment that it has received data.
Multiple data name/value pairs can be added to any given entry of the data file and is considered part of the same entry until the nextEntry() call is made.
e.g.:
#add some data for this trial
exp.addData('resp.rt', 0.8)
exp.addData('resp.key', 'k')
#end of trial - move to next line in data output
exp.nextEntry()
Add a loop such as a TrialHandler or StairHandler Data from this loop will be included in the resulting data files.
Informs the experiment handler that the loop is finished and not to include its values in further entries of the experiment.
This method is called by the loop itself if it ends its iterations, so is not typically needed by the user.
Calling nextEntry indicates to the ExperimentHandler that the current trial has ended and so further addData() calls correspond to the next trial.
Basically just saves a copy of self (with data) to a pickle file.
This can be reloaded if necessary and further analyses carried out.
| Parameters : | fileCollisionMethod: Collision method passed to _handleFileCollision() |
|---|
Saves a long, wide-format text file, with one line representing the attributes and data for a single trial. Suitable for analysis in R and SPSS.
If appendFile=True then the data will be added to the bottom of an existing file. Otherwise, if the file exists already it will be overwritten
If matrixOnly=True then the file will not contain a header row, which can be handy if you want to append data to an existing file of the same format.
Class to handle trial sequencing and data storage.
Calls to .next() will fetch the next trial object given to this handler, according to the method specified (random, sequential, fullRandom). Calls will raise a StopIteration error if trials have finished.
See demo_trialHandler.py
The psydat file format is literally just a pickled copy of the TrialHandler object that saved it. You can open it with:
from psychopy import misc
dat = misc.fromFile(path)
Then you’ll find that dat has the following attributes that
| Parameters : |
nReps: number of repeats for all conditions
|
|---|---|
| Attributes (after creation): | |
.data - a dictionary of numpy arrays, one for each data type stored .trialList - the original list of dicts, specifying the conditions .thisIndex - the index of the current trial in the original conditions list .nTotal - the total number of trials that will be run .nRemaining - the total number of trials remaining .thisN - total trials completed so far .thisRepN - which repeat you are currently on .thisTrialN - which trial number within that repeat .thisTrial - a dictionary giving the parameters of the current trial .finished - True/False for have we finished yet .extraInfo - the dictionary of extra info as given at beginning .origin - the contents of the script or builder experiment that created the handler |
|
Add data for the current trial
Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached
Returns the condition for n trials into the future without advancing the trials.
Attempts to determine the path of the script that created this data file and returns both the path to that script and it’s contents. Useful to store the entire experiment with the data.
If originPath is provided (e.g. from Builder) then this is used otherwise the calling script is the originPath (fine from a standard python script).
Advances to next trial and returns it. Updates attributes; thisTrial, thisTrialN and thisIndex If the trials have ended this method will raise a StopIteration error. This can be handled with code such as:
trials = TrialHandler(.......)
for eachTrial in trials:#automatically stops when done
#do stuff
or:
trials = TrialHandler(.......)
while True: #ie forever
try:
thisTrial = trials.next()
except StopIteration:#we got a StopIteration error
break #break out of the forever loop
#do stuff here for the trial
DEPRECATION WARNING: nextTrial() will be deprecated please use next() instead. jwp: 19/6/06
Exactly like saveAsText() except that the output goes to the screen instead of a file
Save a summary data file in Excel OpenXML format workbook (xlsx) for processing in most spreadsheet packages. This format is compatible with versions of Excel (2007 or greater) and and with OpenOffice (>=3.0).
It has the advantage over the simpler text files (see TrialHandler.saveAsText() ) that data can be stored in multiple named sheets within the file. So you could have a single file named after your experiment and then have one worksheet for each participant. Or you could have one file for each participant and then multiple sheets for repeated sessions etc.
The file extension .xlsx will be added if not given already.
| Parameters : |
|
|---|
Basically just saves a copy of the handler (with data) to a pickle file.
This can be reloaded if necessesary and further analyses carried out.
| Parameters : | fileCollisionMethod: Collision method passed to _handleFileCollision() |
|---|
Write a text file with the data and various chosen stimulus attributes
| Parameters : |
|
|---|
Write a text file with the session, stimulus, and data values from each trial in chronological order.
This ‘wide’ format, as expected by R for creating dataframes, and various other analysis programs, means that some information must be repeated on every row.
In particular, if the trialHandler’s ‘extraInfo’ exists, then each entry in there occurs in every row. In builder, this will include any entries in the ‘Experiment info’ field of the ‘Experiment settings’ dialog. In Coder, this information can be set using something like:
myTrialHandler.extraInfo = {'SubjID':'Joan Smith', 'DOB':1970 Nov 16, 'Group':'Control'}
| Parameters : |
|
|---|
Sets the ExperimentHandler that this handler is attached to
Do NOT attempt to set the experiment using:
trials._exp = myExperiment
because it needs to be performed using the weakref module.
Class to handle smoothly the selection of the next trial and report current values etc. Calls to nextTrial() will fetch the next object given to this handler, according to the method specified.
See demo_trialHandler.py
The staircase will terminate when nTrials AND nReversals have been exceeded. If stepSizes was an array and has been exceeded before nTrials is exceeded then the staircase will continue to reverse
| Parameters : |
|
|---|
Add a 1 or 0 to signify a correct/detected or incorrect/missed trial
This is essential to advance the staircase to a new intensity level!
Supplying an intensity value here indicates that you did not use the recommended intensity in your last trial and the staircase will replace its recorded value with the one you supplied here.
based on current intensity, counter of correct responses and current direction
Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached
Attempts to determine the path of the script that created this data file and returns both the path to that script and it’s contents. Useful to store the entire experiment with the data.
If originPath is provided (e.g. from Builder) then this is used otherwise the calling script is the originPath (fine from a standard python script).
Advances to next trial and returns it. Updates attributes; thisTrial, thisTrialN and thisIndex.
If the trials have ended, calling this method will raise a StopIteration error. This can be handled with code such as:
staircase = StairHandler(.......)
for eachTrial in staircase:#automatically stops when done
#do stuff
or:
staircase = StairHandler(.......)
while True: #ie forever
try:
thisTrial = staircase.next()
except StopIteration:#we got a StopIteration error
break #break out of the forever loop
#do stuff here for the trial
DEPRECATION WARNING: nextTrial() will be deprecated please use next() instead. jwp: 19/6/06
Exactly like saveAsText() except that the output goes to the screen instead of a file
Save a summary data file in Excel OpenXML format workbook (xlsx) for processing in most spreadsheet packages. This format is compatible with versions of Excel (2007 or greater) and and with OpenOffice (>=3.0).
It has the advantage over the simpler text files (see TrialHandler.saveAsText() ) that data can be stored in multiple named sheets within the file. So you could have a single file named after your experiment and then have one worksheet for each participant. Or you could have one file for each participant and then multiple sheets for repeated sessions etc.
The file extension .xlsx will be added if not given already.
The file will contain a set of values specifying the staircase level (‘intensity’) at each reversal, a list of reversal indices (trial numbers), the raw staircase/intensity level on every trial and the corresponding responses of the participant on every trial.
| Parameters : |
|
|---|
Basically just saves a copy of self (with data) to a pickle file.
This can be reloaded if necess and further analyses carried out.
Write a text file with the data
| Parameters : |
|
|---|
Sets the ExperimentHandler that this handler is attached to
Do NOT attempt to set the experiment using:
trials._exp = myExperiment
because it needs to be performed using the weakref module.
A Handler to allow easy interleaved staircase procedures (simple or QUEST).
Parameters for the staircases, as used by the relevant StairHandler or QuestHandler (e.g. the startVal, minVal, maxVal...) should be specified in the conditions list and may vary between each staircase. In particular, the conditions /must/ include the a startVal (because this is a required argument to the above handlers) a label to tag the staircase and a startValSd (only for QUEST staircases). Any parameters not specified in the conditions file will revert to the default for that individual handler.
If you need to custom the behaviour further you may want to look at the recipe on interleavedStairs.
| Params : |
|
|---|
Example usage:
conditions=[
{'label':'low', 'startVal': 0.1, 'ori':45},
{'label':'high','startVal': 0.8, 'ori':45},
{'label':'low', 'startVal': 0.1, 'ori':90},
{'label':'high','startVal': 0.8, 'ori':90},
]
stairs = MultiStairHandler(conditions=conditions, nTrials=50)
for thisIntensity, thisCondition in stairs:
thisOri = thisCondition['ori']
#do something with thisIntensity and thisOri
stairs.addData(correctIncorrect)#this is ESSENTIAL
#save data as multiple formats
stairs.saveDataAsExcel(fileName)#easy to browse
stairs.saveAsPickle(fileName)#contains more info
Add a 1 or 0 to signify a correct/detected or incorrect/missed trial
This is essential to advance the staircase to a new intensity level!
Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached
Attempts to determine the path of the script that created this data file and returns both the path to that script and it’s contents. Useful to store the entire experiment with the data.
If originPath is provided (e.g. from Builder) then this is used otherwise the calling script is the originPath (fine from a standard python script).
Advances to next trial and returns it.
This can be handled with code such as:
staircase = MultiStairHandler(.......)
for eachTrial in staircase:#automatically stops when done
#do stuff here for the trial
or:
staircase = MultiStairHandler(.......)
while True: #ie forever
try:
thisTrial = staircase.next()
except StopIteration:#we got a StopIteration error
break #break out of the forever loop
#do stuff here for the trial
DEPRECATION WARNING: nextTrial() will be deprecated please use next() instead. jwp: 19/6/06
Write the data to the standard output stream
| Parameters : |
|
|---|
Save a summary data file in Excel OpenXML format workbook (xlsx) for processing in most spreadsheet packages. This format is compatible with versions of Excel (2007 or greater) and and with OpenOffice (>=3.0).
It has the advantage over the simpler text files (see TrialHandler.saveAsText() ) that the data from each staircase will be save in the same file, with the sheet name coming from the ‘label’ given in the dictionary of conditions during initialisation of the Handler.
The file extension .xlsx will be added if not given already.
The file will contain a set of values specifying the staircase level (‘intensity’) at each reversal, a list of reversal indices (trial numbers), the raw staircase/intensity level on every trial and the corresponding responses of the participant on every trial.
| Parameters : |
|
|---|
Saves a copy of self (with data) to a pickle file.
This can be reloaded later and further analyses carried out.
Write out text files with the data.
For MultiStairHandler this will output one file for each staircase that was run, with _label added to the fileName that you specify above (label comes from the condition dictionary you specified when you created the Handler).
| Parameters : |
|
|---|
Sets the ExperimentHandler that this handler is attached to
Do NOT attempt to set the experiment using:
trials._exp = myExperiment
because it needs to be performed using the weakref module.
Class that implements the Quest algorithm for quick measurement of psychophysical thresholds.
Uses Andrew Straw’s QUEST, which is a Python port of Denis Pelli’s Matlab code.
Measures threshold using a Weibull psychometric function. Currently, it is not possible to use a different psychometric function.
Threshold ‘t’ is measured on an abstract ‘intensity’ scale, which usually corresponds to log10 contrast.
The Weibull psychometric function:
p2=delta*gamma+(1-delta)*(1-(1-gamma)*exp(-10**(beta*(x2+xThreshold))))
Example:
# setup display/window
...
# create stimulus
stimulus = visual.RadialStim(win=win, tex='sinXsin', size=1, pos=[0,0], units='deg')
...
# create staircase object
# trying to find out the point where subject's response is 50/50
# if wanted to do a 2AFC then the defaults for pThreshold and gamma are good
staircase = data.QuestHandler(staircase._nextIntensity, 0.2, pThreshold=0.63, gamma=0.01,
nTrials=20, minVal=0, maxVal=1)
...
while thisContrast in staircase:
# setup stimulus
stimulus.setContrast(thisContrast)
stimulus.draw()
win.flip()
core.wait(0.5)
# get response
...
# inform QUEST of the response, needed to calculate next level
staircase.addData(thisResp)
...
# can now access 1 of 3 suggested threshold levels
staircase.mean()
staircase.mode()
staircase.quantile() #gets the median
The variable(s) nTrials and/or stopSd must be specified.
beta, delta, and gamma are the parameters of the Weibull psychometric function.
| Parameters : |
|
|---|
Add a 1 or 0 to signify a correct/detected or incorrect/missed trial
Supplying an intensity value here indicates that you did not use the recommended intensity in your last trial and the staircase will replace its recorded value with the one you supplied here.
based on current intensity and counter of correct responses
give the range of the 5-95% confidence interval
Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached
Attempts to determine the path of the script that created this data file and returns both the path to that script and it’s contents. Useful to store the entire experiment with the data.
If originPath is provided (e.g. from Builder) then this is used otherwise the calling script is the originPath (fine from a standard python script).
import some data which wasn’t previously given to the quest algorithm
increase maximum number of trials Updates attribute: nTrials
mean of Quest posterior pdf
mode of Quest posterior pdf
Advances to next trial and returns it. Updates attributes; thisTrial, thisTrialN, thisIndex, finished, intensities
If the trials have ended, calling this method will raise a StopIteration error. This can be handled with code such as:
staircase = QuestHandler(.......)
for eachTrial in staircase:#automatically stops when done
#do stuff
or:
staircase = QuestHandler(.......)
while True: #ie forever
try:
thisTrial = staircase.next()
except StopIteration:#we got a StopIteration error
break #break out of the forever loop
#do stuff here for the trial
DEPRECATION WARNING: nextTrial() will be deprecated please use next() instead. jwp: 19/6/06
Exactly like saveAsText() except that the output goes to the screen instead of a file
quantile of Quest posterior pdf
Save a summary data file in Excel OpenXML format workbook (xlsx) for processing in most spreadsheet packages. This format is compatible with versions of Excel (2007 or greater) and and with OpenOffice (>=3.0).
It has the advantage over the simpler text files (see TrialHandler.saveAsText() ) that data can be stored in multiple named sheets within the file. So you could have a single file named after your experiment and then have one worksheet for each participant. Or you could have one file for each participant and then multiple sheets for repeated sessions etc.
The file extension .xlsx will be added if not given already.
The file will contain a set of values specifying the staircase level (‘intensity’) at each reversal, a list of reversal indices (trial numbers), the raw staircase/intensity level on every trial and the corresponding responses of the participant on every trial.
| Parameters : |
|
|---|
Basically just saves a copy of self (with data) to a pickle file.
This can be reloaded if necess and further analyses carried out.
Write a text file with the data
| Parameters : |
|
|---|
standard deviation of Quest posterior pdf
Sets the ExperimentHandler that this handler is attached to
Do NOT attempt to set the experiment using:
trials._exp = myExperiment
because it needs to be performed using the weakref module.
returns a simulated user response to the next intensity level presented by Quest, need to supply the actual threshold level
Fit a Weibull function (either 2AFC or YN) of the form:
y = chance + (1.0-chance)*(1-exp( -(xx/alpha)**(beta) ))
and with inverse:
x = alpha * (-log((1.0-y)/(1-chance)))**(1.0/beta)
After fitting the function you can evaluate an array of x-values with fit.eval(x), retrieve the inverse of the function with fit.inverse(y) or retrieve the parameters from fit.params (a list with [alpha, beta])
Fit a Logistic function (either 2AFC or YN) of the form:
y = chance + (1-chance)/(1+exp((PSE-xx)*JND))
and with inverse:
x = PSE - log((1-chance)/(yy-chance) - 1)/JND
After fitting the function you can evaluate an array of x-values with fit.eval(x), retrieve the inverse of the function with fit.inverse(y) or retrieve the parameters from fit.params (a list with [PSE, JND])
Fit a Naka-Rushton function of the form:
yy = rMin + (rMax-rMin) * xx**n/(xx**n+c50**n)
After fitting the function you can evaluate an array of x-values with fit.eval(x), retrieve the inverse of the function with fit.inverse(y) or retrieve the parameters from fit.params (a list with [rMin, rMax, c50, n])
Note that this differs from most of the other functions in not using a value for the expected minimum. Rather, it fits this as one of the parameters of the model.
Fit a Cumulative Normal function (aka error function or erf) of the form:
y = chance + (1-chance)*(special.erf(xx*xScale - xShift)/2.0+0.5)
and with inverse:
x = (erfinv((yy-chance)/(1-chance)*2.0-1)+xShift)/xScale
After fitting the function you can evaluate an array of x-values with fit.eval(x), retrieve the inverse of the function with fit.inverse(y) or retrieve the parameters from fit.params (a list with [centre, sd] for the Gaussian distribution forming the cumulative)
NB: Prior to version 1.74 the parameters had different meaning, relating to xShift and slope of the function (similar to 1/sd). Although that is more in with the parameters for the Weibull fit, for instance, it is less in keeping with standard expectations of normal (Gaussian distributions) so in version 1.74.00 the parameters became the [centre,sd] of the normal distribution.
Imports a list of conditions from an .xlsx, .csv, or .pkl file
The output is suitable as an input to TrialHandler trialTypes or to MultiStairHandler as a conditions list.
The file should contain one row per type of trial needed and one column for each parameter that defines the trial type. The first row should give parameter names, which should:
- be unique
- begin with a letter (upper or lower case)
- contain no spaces or other punctuation (underscores are permitted)
Create a psychometric function by binning data from a staircase procedure
usage:
[intensity, meanCorrect, n] = functionFromStaircase(intensities, responses, bins)
Create a list of n bootstrapped resamples of the data
SLOW IMPLEMENTATION (Python for-loop)