Table Of Contents

Previous topic

psychopy.clock - Clocks and timers

Next topic

Encryption

This Page

Quick links

psychopy.data - functions for storing/saving/analysing data

Routines for handling data structures and analysis

ExperimentHandler

class psychopy.data.ExperimentHandler(name='', version='', extraInfo=None, runtimeInfo=None, originPath=None, savePickle=True, saveWideText=True, dataFileName='', autoLog=True)

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:
name
: a string or unicode

As a useful identifier later

version
: usually a string (e.g. ‘1.1.0’)

To keep track of which version of the experiment was run

extraInfo
: a dictionary

Containing useful information about this run (e.g. {‘participant’:’jwp’,’gender’:’m’,’orientation’:90} )

runtimeInfo
: psychopy.info.RunTimeInfo

Containining information about the system as detected at runtime

originPath
: string or unicode

The path and filename of the originating script/experiment If not provided this will be determined as the path of the calling script.

dataFileName
: string

This is defined in advance and the file will be saved at any point that the handler is removed or discarded (unless .abort() had been called in advance). The handler will attempt to populate the file even in the event of a (not too serious) crash!

savePickle : True (default) or False

saveWideText : True (default) or False

autoLog : True (default) or False

abort()

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.

addData(name, value)

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()
addLoop(loopHandler)

Add a loop such as a TrialHandler or StairHandler Data from this loop will be included in the resulting data files.

loopEnded(loopHandler)

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.

nextEntry()

Calling nextEntry indicates to the ExperimentHandler that the current trial has ended and so further addData() calls correspond to the next trial.

saveAsPickle(fileName, fileCollisionMethod='rename')

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()
saveAsWideText(fileName, delim=None, matrixOnly=False, appendFile=False, encoding='utf-8', fileCollisionMethod='rename')

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.

encoding:
The encoding to use when saving a the file. Defaults to utf-8.
fileCollisionMethod:
Collision method passed to handleFileCollision()

TrialHandler

class psychopy.data.TrialHandler(trialList, nReps, method='random', dataTypes=None, extraInfo=None, seed=None, originPath=None, name='', autoLog=True)

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.tools.filetools import fromFile
dat = fromFile(path)

Then you’ll find that dat has the following attributes that

Parameters:
trialList: a simple list (or flat array) of dictionaries

specifying conditions. This can be imported from an excel/csv file using importConditions()

nReps: number of repeats for all conditions

method: ‘random’, ‘sequential’, or ‘fullRandom’

‘sequential’ obviously presents the conditions in the order they appear in the list. ‘random’ will result in a shuffle of the conditions on each repeat, but all conditions occur once before the second repeat etc. ‘fullRandom’ fully randomises the trials across repeats as well, which means you could potentially run all trials of one condition before any trial of another.

dataTypes: (optional) list of names for data storage.

e.g. [‘corr’,’rt’,’resp’]. If not provided then these will be created as needed during calls to addData()

extraInfo: A dictionary

This will be stored alongside the data and usually describes the experiment and subject ID, date etc.

seed: an integer

If provided then this fixes the random number generator to use the same pattern of trials, by seeding its startpoint

originPath: a string describing the location of the

script / experiment file path. The psydat file format will store a copy of the experiment if possible. If originPath==None is provided here then the TrialHandler will still store a copy of the script where it was created. If OriginPath==-1 then nothing will be stored.

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

addData(thisType, value, position=None)

Add data for the current trial

getEarlierTrial(n=-1)

Returns the condition information from n trials previously. Useful for comparisons in n-back tasks. Returns ‘None’ if trying to access a trial prior to the first.

getExp()

Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached

getFutureTrial(n=1)

Returns the condition for n trials into the future, without advancing the trials. A negative n returns a previous (past) trial. Returns ‘None’ if attempting to go beyond the last trial.

getOriginPathAndFile(originPath=None)

Attempts to determine the path of the script that created this data file and returns both the path to that script and its 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).

next()

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 = data.TrialHandler(.......)
for eachTrial in trials:  # automatically stops when done
    # do stuff

or:

trials = data.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
printAsText(stimOut=None, dataOut=('all_mean', 'all_std', 'all_raw'), delim='\t', matrixOnly=False)

Exactly like saveAsText() except that the output goes to the screen instead of a file

saveAsExcel(fileName, sheetName='rawData', stimOut=None, dataOut=('n', 'all_mean', 'all_std', 'all_raw'), matrixOnly=False, appendFile=True, fileCollisionMethod='rename')

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:
fileName: string

the name of the file to create or append. Can include relative or absolute path

sheetName: string

the name of the worksheet within the file

stimOut: list of strings

the attributes of the trial characteristics to be output. To use this you need to have provided a list of dictionaries specifying to trialList parameter of the TrialHandler and give here the names of strings specifying entries in that dictionary

dataOut: list of strings

specifying the dataType and the analysis to be performed, in the form dataType_analysis. The data can be any of the types that you added using trialHandler.data.add() and the analysis can be either ‘raw’ or most things in the numpy library, including ‘mean’,’std’,’median’,’max’,’min’. e.g. rt_max will give a column of max reaction times across the trials assuming that rt values have been stored. The default values will output the raw, mean and std of all datatypes found.

appendFile: True or False

If False any existing file with this name will be overwritten. If True then a new worksheet will be appended. If a worksheet already exists with that name a number will be added to make it unique.

fileCollisionMethod: string

Collision method passed to handleFileCollision() This is ignored if append is True.

saveAsPickle(fileName, fileCollisionMethod='rename')

Basically just saves a copy of the handler (with data) to a pickle file.

This can be reloaded if necessary and further analyses carried out.

Parameters:fileCollisionMethod: Collision method passed to handleFileCollision()
saveAsText(fileName, stimOut=None, dataOut=('n', 'all_mean', 'all_std', 'all_raw'), delim=None, matrixOnly=False, appendFile=True, summarised=True, fileCollisionMethod='rename', encoding='utf-8')

Write a text file with the data and various chosen stimulus attributes

Parameters:
fileName:
will have .tsv appended and can include path info.
stimOut:
the stimulus attributes to be output. To use this you need to use a list of dictionaries and give here the names of dictionary keys that you want as strings
dataOut:
a list of strings specifying the dataType and the analysis to be performed,in the form dataType_analysis. The data can be any of the types that you added using trialHandler.data.add() and the analysis can be either ‘raw’ or most things in the numpy library, including; ‘mean’,’std’,’median’,’max’,’min’... The default values will output the raw, mean and std of all datatypes found
delim:
allows the user to use a delimiter other than tab (”,” is popular with file extension ”.csv”)
matrixOnly:
outputs the data with no header row or extraInfo attached
appendFile:
will add this output to the end of the specified file if it already exists
fileCollisionMethod:
Collision method passed to handleFileCollision()
encoding:
The encoding to use when saving a the file. Defaults to utf-8.
saveAsWideText(fileName, delim=None, matrixOnly=False, appendFile=True, encoding='utf-8', fileCollisionMethod='rename')

Write a text file with the session, stimulus, and data values from each trial in chronological order. Also, return a pandas.DataFrame containing same information as the file.

That is, unlike ‘saveAsText’ and ‘saveAsExcel’:
  • each row comprises information from only a single trial.
  • no summarizing is done (such as collapsing to produce mean and standard deviation values across trials).

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',
                            'Group': 'Control'}
Parameters:
fileName:

if extension is not specified, ‘.csv’ will be appended if the delimiter is ‘,’, else ‘.tsv’ will be appended. Can include path info.

delim:

allows the user to use a delimiter other than the default tab (”,” is popular with file extension ”.csv”)

matrixOnly:

outputs the data with no header row.

appendFile:

will add this output to the end of the specified file if it already exists.

fileCollisionMethod:

Collision method passed to handleFileCollision()

encoding:

The encoding to use when saving a the file. Defaults to utf-8.

setExp(exp)

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.

StairHandler

class psychopy.data.StairHandler(startVal, nReversals=None, stepSizes=4, nTrials=0, nUp=1, nDown=3, extraInfo=None, method='2AFC', stepType='db', minVal=None, maxVal=None, originPath=None, name='', autoLog=True, **kwargs)

Class to handle smoothly the selection of the next trial and report current values etc. Calls to next() will fetch the next object given to this handler, according to the method specified.

See Demos >> ExperimentalControl >> JND_staircase_exp.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.

nUp and nDown are always considered as 1 until the first reversal is reached. The values entered as arguments are then used.

Parameters:
startVal:

The initial value for the staircase.

nReversals:

The minimum number of reversals permitted. If stepSizes is a list, but the minimum number of reversals to perform, nReversals, is less than the length of this list, PsychoPy will automatically increase the minimum number of reversals and emit a warning.

stepSizes:

The size of steps as a single value or a list (or array). For a single value the step size is fixed. For an array or list the step size will progress to the next entry at each reversal.

nTrials:

The minimum number of trials to be conducted. If the staircase has not reached the required number of reversals then it will continue.

nUp:

The number of ‘incorrect’ (or 0) responses before the staircase level increases.

nDown:

The number of ‘correct’ (or 1) responses before the staircase level decreases.

extraInfo:

A dictionary (typically) that will be stored along with collected data using saveAsPickle() or saveAsText() methods.

stepType:

specifies whether each step will be a jump of the given size in ‘db’, ‘log’ or ‘lin’ units (‘lin’ means this intensity will be added/subtracted)

method:

Not used and may be deprecated in future releases.

stepType: ‘db’, ‘lin’, ‘log’

The type of steps that should be taken each time. ‘lin’ will simply add or subtract that amount each step, ‘db’ and ‘log’ will step by a certain number of decibels or log units (note that this will prevent your value ever reaching zero or less)

minVal: None, or a number

The smallest legal value for the staircase, which can be used to prevent it reaching impossible contrast values, for instance.

maxVal: None, or a number

The largest legal value for the staircase, which can be used to prevent it reaching impossible contrast values, for instance.

Additional keyword arguments will be ignored.

Notes:

The additional keyword arguments **kwargs might for example be passed by the MultiStairHandler, which expects a label keyword for each staircase. These parameters are to be ignored by the StairHandler.

addData(result, intensity=None)

Deprecated since 1.79.00: This function name was ambiguous. Please use one of these instead:

.addResponse(result, intensity) .addOtherData(‘dataName’, value’)
addOtherData(dataName, value)

Add additional data to the handler, to be tracked alongside the result data but not affecting the value of the staircase

addResponse(result, intensity=None)

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.

calculateNextIntensity()

Based on current intensity, counter of correct responses, and current direction.

getExp()

Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached

getOriginPathAndFile(originPath=None)

Attempts to determine the path of the script that created this data file and returns both the path to that script and its 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).

next()

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 = data.StairHandler(.......)
for eachTrial in staircase:  # automatically stops when done
    # do stuff

or:

staircase = data.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
printAsText(stimOut=None, dataOut=('all_mean', 'all_std', 'all_raw'), delim='\t', matrixOnly=False)

Exactly like saveAsText() except that the output goes to the screen instead of a file

saveAsExcel(fileName, sheetName='data', matrixOnly=False, appendFile=True, fileCollisionMethod='rename')

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:
fileName: string

the name of the file to create or append. Can include relative or absolute path

sheetName: string

the name of the worksheet within the file

matrixOnly: True or False

If set to True then only the data itself will be output (no additional info)

appendFile: True or False

If False any existing file with this name will be overwritten. If True then a new worksheet will be appended. If a worksheet already exists with that name a number will be added to make it unique.

fileCollisionMethod: string

Collision method passed to handleFileCollision() This is ignored if append is True.

saveAsPickle(fileName, fileCollisionMethod='rename')

Basically just saves a copy of self (with data) to a pickle file.

This can be reloaded if necess and further analyses carried out.

Parameters:fileCollisionMethod: Collision method passed to handleFileCollision()
saveAsText(fileName, delim=None, matrixOnly=False, fileCollisionMethod='rename', encoding='utf-8')

Write a text file with the data

Parameters:
fileName: a string

The name of the file, including path if needed. The extension .tsv will be added if not included.

delim: a string

the delimitter to be used (e.g. ‘ ‘ for tab-delimitted, ‘,’ for csv files)

matrixOnly: True/False

If True, prevents the output of the extraInfo provided at initialisation.

fileCollisionMethod:

Collision method passed to handleFileCollision()

encoding:

The encoding to use when saving a the file. Defaults to utf-8.

setExp(exp)

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.

MultiStairHandler

class psychopy.data.MultiStairHandler(stairType='simple', method='random', conditions=None, nTrials=50, originPath=None, name='', autoLog=True)

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 Coder - interleave staircases.

Params:
stairType: ‘simple’ or ‘quest’

Use a StairHandler or QuestHandler

method: ‘random’ or ‘sequential’

The stairs are shuffled in each repeat but not randomised more than that (so you can’t have 3 repeats of the same staircase in a row unless it’s the only one still running)

conditions: a list of dictionaries specifying conditions

Can be used to control parameters for the different staicases. Can be imported from an Excel file using psychopy.data.importConditions MUST include keys providing, ‘startVal’, ‘label’ and ‘startValSd’ (QUEST only). The ‘label’ will be used in data file saving so should be unique. See Example Usage below.

nTrials=50

Minimum trials to run (but may take more if the staircase hasn’t also met its minimal reversals. See StairHandler

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 = data.MultiStairHandler(conditions=conditions, nTrials=50)

for thisIntensity, thisCondition in stairs:
    thisOri = thisCondition['ori']

    # do something with thisIntensity and thisOri

    stairs.addResponse(correctIncorrect)  # this is ESSENTIAL

# save data as multiple formats
stairs.saveDataAsExcel(fileName)  # easy to browse
stairs.saveAsPickle(fileName)  # contains more info
addData(result, intensity=None)

Deprecated 1.79.00: It was ambiguous whether you were adding the response (0 or 1) or some other data concerning the trial so there is now a pair of explicit methods:

addResponse(corr,intensity) #some data that alters the next
trial value
addOtherData(‘RT’, reactionTime) #some other data that won’t
control staircase
addOtherData(name, value)

Add some data about the current trial that will not be used to control the staircase(s) such as reaction time data

addResponse(result, intensity=None)

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!

getExp()

Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached

getOriginPathAndFile(originPath=None)

Attempts to determine the path of the script that created this data file and returns both the path to that script and its 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).

next()

Advances to next trial and returns it.

This can be handled with code such as:

staircase = data.MultiStairHandler(.......)
for eachTrial in staircase:  # automatically stops when done
    # do stuff here for the trial

or:

staircase = data.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
printAsText(delim='\t', matrixOnly=False)

Write the data to the standard output stream

Parameters:
delim: a string

the delimitter to be used (e.g. ‘ ‘ for tab-delimitted, ‘,’ for csv files)

matrixOnly: True/False

If True, prevents the output of the extraInfo provided at initialisation.

saveAsExcel(fileName, matrixOnly=False, appendFile=False, fileCollisionMethod='rename')

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:
fileName: string

the name of the file to create or append. Can include relative or absolute path

matrixOnly: True or False

If set to True then only the data itself will be output (no additional info)

appendFile: True or False

If False any existing file with this name will be overwritten. If True then a new worksheet will be appended. If a worksheet already exists with that name a number will be added to make it unique.

fileCollisionMethod: string

Collision method passed to handleFileCollision() This is ignored if append is True.

saveAsPickle(fileName, fileCollisionMethod='rename')

Saves a copy of self (with data) to a pickle file.

This can be reloaded later and further analyses carried out.

Parameters:fileCollisionMethod: Collision method passed to handleFileCollision()
saveAsText(fileName, delim=None, matrixOnly=False, fileCollisionMethod='rename', encoding='utf-8')

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:
fileName: a string

The name of the file, including path if needed. The extension .tsv will be added if not included.

delim: a string

the delimitter to be used (e.g. ‘ ‘ for tab-delimitted, ‘,’ for csv files)

matrixOnly: True/False

If True, prevents the output of the extraInfo provided at initialisation.

fileCollisionMethod:

Collision method passed to handleFileCollision()

encoding:

The encoding to use when saving a the file. Defaults to utf-8.

setExp(exp)

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.

QuestHandler

class psychopy.data.QuestHandler(startVal, startValSd, pThreshold=0.82, nTrials=None, stopInterval=None, method='quantile', beta=3.5, delta=0.01, gamma=0.5, grain=0.01, range=None, extraInfo=None, minVal=None, maxVal=None, staircase=None, originPath=None, name='', autoLog=True, **kwargs)

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:

_e = -10**(beta * (x2 + xThreshold)) p2 = delta * gamma + (1-delta) * (1 - (1 - gamma) * exp(_e))

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.addResponse(thisResp)
...
# can now access 1 of 3 suggested threshold levels
staircase.mean()
staircase.mode()
staircase.quantile(0.5)  # gets the median
Typical values for pThreshold are:
  • 0.82 which is equivalent to a 3 up 1 down standard staircase

  • 0.63 which is equivalent to a 1 up 1 down standard staircase

    (and might want gamma=0.01)

The variable(s) nTrials and/or stopSd must be specified.

beta, delta, and gamma are the parameters of the Weibull psychometric function.

Parameters:
startVal:

Prior threshold estimate or your initial guess threshold.

startValSd:

Standard deviation of your starting guess threshold. Be generous with the sd as QUEST will have trouble finding the true threshold if it’s more than one sd from your initial guess.

pThreshold

Your threshold criterion expressed as probability of response==1. An intensity offset is introduced into the psychometric function so that the threshold (i.e., the midpoint of the table) yields pThreshold.

nTrials: None or a number

The maximum number of trials to be conducted.

stopInterval: None or a number

The minimum 5-95% confidence interval required in the threshold estimate before stopping. If both this and nTrials is specified, whichever happens first will determine when Quest will stop.

method: ‘quantile’, ‘mean’, ‘mode’

The method used to determine the next threshold to test. If you want to get a specific threshold level at the end of your staircasing, please use the quantile, mean, and mode methods directly.

beta: 3.5 or a number

Controls the steepness of the psychometric function.

delta: 0.01 or a number

The fraction of trials on which the observer presses blindly.

gamma: 0.5 or a number

The fraction of trials that will generate response 1 when intensity=-Inf.

grain: 0.01 or a number

The quantization of the internal table.

range: None, or a number

The intensity difference between the largest and smallest intensity that the internal table can store. This interval will be centered on the initial guess tGuess. QUEST assumes that intensities outside of this range have zero prior probability (i.e., they are impossible).

extraInfo:

A dictionary (typically) that will be stored along with collected data using saveAsPickle() or saveAsText() methods.

minVal: None, or a number

The smallest legal value for the staircase, which can be used to prevent it reaching impossible contrast values, for instance.

maxVal: None, or a number

The largest legal value for the staircase, which can be used to prevent it reaching impossible contrast values, for instance.

staircase: None or StairHandler

Can supply a staircase object with intensities and results. Might be useful to give the quest algorithm more information if you have it. You can also call the importData function directly.

Additional keyword arguments will be ignored.

Notes:

The additional keyword arguments **kwargs might for example be passed by the MultiStairHandler, which expects a label keyword for each staircase. These parameters are to be ignored by the StairHandler.

addData(result, intensity=None)

Deprecated since 1.79.00: This function name was ambiguous. Please use one of these instead:

.addResponse(result, intensity) .addOtherData(‘dataName’, value’)
addOtherData(dataName, value)

Add additional data to the handler, to be tracked alongside the result data but not affecting the value of the staircase

addResponse(result, intensity=None)

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.

calculateNextIntensity()

based on current intensity and counter of correct responses

confInterval(getDifference=False)

Return estimate for the 5%–95% confidence interval (CI).

Parameters:
getDifference (bool)

If True, return the width of the confidence interval (95% - 5% percentiles). If False, return an NumPy array with estimates for the 5% and 95% boundaries.

Returns:

scalar or array of length 2.

getExp()

Return the ExperimentHandler that this handler is attached to, if any. Returns None if not attached

getOriginPathAndFile(originPath=None)

Attempts to determine the path of the script that created this data file and returns both the path to that script and its 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).

importData(intensities, results)

import some data which wasn’t previously given to the quest algorithm

incTrials(nNewTrials)

increase maximum number of trials Updates attribute: nTrials

mean()

mean of Quest posterior pdf

mode()

mode of Quest posterior pdf

next()

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 = data.QuestHandler(.......)
for eachTrial in staircase:  # automatically stops when done
    # do stuff

or:

staircase = data.QuestHandler(.......)
while True:  # i.e. 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
printAsText(stimOut=None, dataOut=('all_mean', 'all_std', 'all_raw'), delim='\t', matrixOnly=False)

Exactly like saveAsText() except that the output goes to the screen instead of a file

quantile(p=None)

quantile of Quest posterior pdf

saveAsExcel(fileName, sheetName='data', matrixOnly=False, appendFile=True, fileCollisionMethod='rename')

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:
fileName: string

the name of the file to create or append. Can include relative or absolute path

sheetName: string

the name of the worksheet within the file

matrixOnly: True or False

If set to True then only the data itself will be output (no additional info)

appendFile: True or False

If False any existing file with this name will be overwritten. If True then a new worksheet will be appended. If a worksheet already exists with that name a number will be added to make it unique.

fileCollisionMethod: string

Collision method passed to handleFileCollision() This is ignored if append is True.

saveAsPickle(fileName, fileCollisionMethod='rename')

Basically just saves a copy of self (with data) to a pickle file.

This can be reloaded if necess and further analyses carried out.

Parameters:fileCollisionMethod: Collision method passed to handleFileCollision()
saveAsText(fileName, delim=None, matrixOnly=False, fileCollisionMethod='rename', encoding='utf-8')

Write a text file with the data

Parameters:
fileName: a string

The name of the file, including path if needed. The extension .tsv will be added if not included.

delim: a string

the delimitter to be used (e.g. ‘ ‘ for tab-delimitted, ‘,’ for csv files)

matrixOnly: True/False

If True, prevents the output of the extraInfo provided at initialisation.

fileCollisionMethod:

Collision method passed to handleFileCollision()

encoding:

The encoding to use when saving a the file. Defaults to utf-8.

sd()

standard deviation of Quest posterior pdf

setExp(exp)

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.

simulate(tActual)

returns a simulated user response to the next intensity level presented by Quest, need to supply the actual threshold level

FitWeibull

class psychopy.data.FitWeibull(xx, yy, sems=1.0, guess=None, display=1, expectedMin=0.5)

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])

eval(xx, params=None)

Evaluate xx for the current parameters of the model, or for arbitrary params if these are given.

inverse(yy, params=None)

Evaluate yy for the current parameters of the model, or for arbitrary params if these are given.

FitLogistic

class psychopy.data.FitLogistic(xx, yy, sems=1.0, guess=None, display=1, expectedMin=0.5)

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])

eval(xx, params=None)

Evaluate xx for the current parameters of the model, or for arbitrary params if these are given.

inverse(yy, params=None)

Evaluate yy for the current parameters of the model, or for arbitrary params if these are given.

FitNakaRushton

class psychopy.data.FitNakaRushton(xx, yy, sems=1.0, guess=None, display=1, expectedMin=0.5)

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.

eval(xx, params=None)

Evaluate xx for the current parameters of the model, or for arbitrary params if these are given.

inverse(yy, params=None)

Evaluate yy for the current parameters of the model, or for arbitrary params if these are given.

FitCumNormal

class psychopy.data.FitCumNormal(xx, yy, sems=1.0, guess=None, display=1, expectedMin=0.5)

Fit a Cumulative Normal function (aka error function or erf) of the form:

y = chance + (1-chance)*((special.erf((xx-xShift)/(sqrt(2)*sd))+1)*0.5)

and with inverse:

x = xShift+sqrt(2)*sd*(erfinv(((yy-chance)/(1-chance)-.5)*2))

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.

eval(xx, params=None)

Evaluate xx for the current parameters of the model, or for arbitrary params if these are given.

inverse(yy, params=None)

Evaluate yy for the current parameters of the model, or for arbitrary params if these are given.

importConditions()

psychopy.data.importConditions(fileName, returnFieldNames=False, selection='')

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.

If fileName ends with:

  • .csv: import as a comma-separated-value file

    (header + row x col)

  • .xlsx: import as Excel 2007 (xlsx) files.

    No support for older (.xls) is planned.

  • .pkl: import from a pickle file as list of lists

    (header + row x col)

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)

selection is used to select a subset of condition indices to be used It can be a list/array of indices, a python slice object or a string to be parsed as either option. e.g.:

  • “1,2,4” or [1,2,4] or (1,2,4) are the same
  • “2:5” # 2, 3, 4 (doesn’t include last whole value)
  • “-10:2:” # tenth from last to the last in steps of 2
  • slice(-10, 2, None) # the same as above
  • random(5) * 8 # five random vals 0-8

functionFromStaircase()

psychopy.data.functionFromStaircase(intensities, responses, bins=10)

Create a psychometric function by binning data from a staircase procedure. Although the default is 10 bins Jon now always uses ‘unique’ bins (fewer bins looks pretty but leads to errors in slope estimation)

usage:

intensity, meanCorrect, n = functionFromStaircase(intensities,
                                                  responses, bins)
where:
intensities
are a list (or array) of intensities to be binned
responses
are a list of 0,1 each corresponding to the equivalent intensity value
bins
can be an integer (giving that number of bins) or ‘unique’ (each bin is made from aa data for exactly one intensity value)
intensity
a numpy array of intensity values (where each is the center of an intensity bin)
meanCorrect
a numpy array of mean % correct in each bin
n
a numpy array of number of responses contributing to each mean

bootStraps()

psychopy.data.bootStraps(dat, n=1)

Create a list of n bootstrapped resamples of the data

SLOW IMPLEMENTATION (Python for-loop)

Usage:
out = bootStraps(dat, n=1)
Where:
dat
an NxM or 1xN array (each row is a different condition, each column is a different trial)
n
number of bootstrapped resamples to create
out
  • dim[0]=conditions
  • dim[1]=trials
  • dim[2]=resamples