brainbox.behavior.pyschofit

The psychofit toolbox contains tools to fit two-alternative psychometric data. The fitting is done using maximal likelihood estimation: one assumes that the responses of the subject are given by a binomial distribution whose mean is given by the psychometric function. The data can be expressed in fraction correct (from .5 to 1) or in fraction of one specific choice (from 0 to 1). To fit them you can use these functions:

weibull50 - Weibull function from 0.5 to 1, with lapse rate weibull - Weibull function from 0 to 1, with lapse rate erf_psycho - erf function from 0 to 1, with lapse rate erf_psycho_2gammas - erf function from 0 to 1, with two lapse rates

Functions in the toolbox are:

mle_fit_psycho - Maximumum likelihood fit of psychometric function neg_likelihood - Negative likelihood of a psychometric function

For more info, see:

Examples - Examples of use of psychofit toolbox

Matteo Carandini, 2000-2015

Functions

erf_psycho

erf function from 0 to 1, with lapse rate.

erf_psycho_2gammas

erf function from 0 to 1, with two lapse rates.

mle_fit_psycho

Maximumum likelihood fit of psychometric function. :param data: 3 x n matrix where first row corresponds to stim levels, the second to number of trials for each stim level (int), the third to proportion correct / proportion rightward (float between 0 and 1) :param P_model: The psychometric function. Possibilities include ‘weibull’ (DEFAULT), ‘weibull50’, ‘erf_psycho’ and ‘erf_psycho_2gammas’ :param parstart: Non-zero starting parameters, used to try to avoid local minima. The parameters are [threshold, slope, gamma], or if using the ‘erf_psycho_2gammas’ model append a second gamma value. Recommended to use a value > 1. If None, some reasonable defaults are used. :param parmin: Minimum parameter values. If None, some reasonable defaults are used :param parmax: Maximum parameter values. If None, some reasonable defaults are used :param nfits: The number of fits.

neg_likelihood

Negative likelihood of a psychometric function. :param pars: Model parameters [threshold, slope, gamma], or if using the ‘erf_psycho_2gammas’ model append a second gamma value. :param data: 3 x n matrix where first row corresponds to stim levels, the second to number of trials for each stim level (int), the third to proportion correct / proportion rightward (float between 0 and 1) :param P_model: The psychometric function. Possibilities include ‘weibull’ (DEFAULT), ‘weibull50’, ‘erf_psycho’ and ‘erf_psycho_2gammas’ :param parmin: Minimum bound for parameters. If None, some reasonable defaults are used :param parmax: Maximum bound for parameters. If None, some reasonable defaults are used.

weibull

Weibull function from 0 to 1, with lapse rate.

weibull50

Weibull function from 0.5 to 1, with lapse rate.

mle_fit_psycho(data, P_model='weibull', parstart=None, parmin=None, parmax=None, nfits=5)[source]

Maximumum likelihood fit of psychometric function. :param data: 3 x n matrix where first row corresponds to stim levels,

the second to number of trials for each stim level (int), the third to proportion correct / proportion rightward (float between 0 and 1)

Parameters
  • P_model – The psychometric function. Possibilities include ‘weibull’ (DEFAULT), ‘weibull50’, ‘erf_psycho’ and ‘erf_psycho_2gammas’

  • parstart – Non-zero starting parameters, used to try to avoid local minima. The parameters are [threshold, slope, gamma], or if using the ‘erf_psycho_2gammas’ model append a second gamma value. Recommended to use a value > 1. If None, some reasonable defaults are used.

  • parmin – Minimum parameter values. If None, some reasonable defaults are used

  • parmax – Maximum parameter values. If None, some reasonable defaults are used

  • nfits – The number of fits

Returns

The parameters from the best of the fits L: The likelihood of the best fit

Return type

pars

Raises
  • TypeError – data must be a list or numpy array

  • ValueError – data must be m by 3 matrix

Examples

Below we fit a Weibull function to some data: >>> import numpy as np >>> import matplotlib.pyplot as plt >>> cc = np.array([-8., -6., -4., -2., 0., 2., 4., 6., 8.]) # contrasts >>> nn = np.full((9,), 10) # number of trials at each contrast >>> pp = np.array([5., 8., 20., 41., 54., 59., 79., 92., 96])/100 # proportion “rightward” >>> pars, L = mle_fit_psycho(np.vstack((cc, nn, pp)), ‘erf_psycho’) >>> plt.plot(cc, pp, ‘bo’, mfc=’b’) >>> plt.plot(np.arange(-8, 8, 0.1), erf_psycho(pars, np.arange(-8, 8, 0.1)), ‘-b’)

Information:

1999-11 FH wrote it 2000-01 MC cleaned it up 2000-04 MC took care of the 50% case 2009-12 MC replaced fmins with fminsearch 2010-02 MC, AZ added nfits 2013-02 MC+MD fixed bug with dealing with NaNs 2018-08 MW ported to Python

neg_likelihood(pars, data, P_model='weibull', parmin=None, parmax=None)[source]

Negative likelihood of a psychometric function. :param pars: Model parameters [threshold, slope, gamma], or if

using the ‘erf_psycho_2gammas’ model append a second gamma value.

Parameters
  • data – 3 x n matrix where first row corresponds to stim levels, the second to number of trials for each stim level (int), the third to proportion correct / proportion rightward (float between 0 and 1)

  • P_model – The psychometric function. Possibilities include ‘weibull’ (DEFAULT), ‘weibull50’, ‘erf_psycho’ and ‘erf_psycho_2gammas’

  • parmin – Minimum bound for parameters. If None, some reasonable defaults are used

  • parmax – Maximum bound for parameters. If None, some reasonable defaults are used

Returns

The likelihood of the parameters. The equation is:
  • sum(nn.*(pp.*log10(P_model)+(1-pp).*log10(1-P_model)))

See the the appendix of Watson, A.B. (1979). Probability summation over time. Vision Res 19, 515-522.

Return type

ll

Raises
  • ValueError – invalid model, options are “weibull”, “weibull50”, “erf_psycho” and “erf_psycho_2gammas”

  • TypeError – data must be a list or numpy array

  • ValueError data must be m by 3 matrix

Information:

1999-11 FH wrote it 2000-01 MC cleaned it up 2000-07 MC made it indep of Weibull and added parmin and parmax 2018-08 MW ported to Python

weibull(pars, xx)[source]

Weibull function from 0 to 1, with lapse rate. :param pars: Model parameters [alpha, beta, gamma]. :param xx: vector of stim levels.

Returns

A vector of length xx

Raises
  • ValueError – pars must be of length 3

  • TypeError – pars must be list-like or numpy array

Information:

1999-11 FH wrote it 2000-01 MC cleaned it up 2018-08 MW ported to Python

weibull50(pars, xx)[source]

Weibull function from 0.5 to 1, with lapse rate. :param pars: Model parameters [alpha, beta, gamma]. :param xx: vector of stim levels.

Returns

A vector of length xx

Raises
  • ValueError – pars must be of length 3

  • TypeError – pars must be list-like or numpy array

Information:

2000-04 MC wrote it 2018-08 MW ported to Python

erf_psycho(pars, xx)[source]

erf function from 0 to 1, with lapse rate. :param pars: Model parameters [bias, slope, lapse]. :param xx: vector of stim levels.

Returns

A vector of length xx

Return type

ff

Examples

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> xx = np.arange(-50, 50)
>>> ff = erf_psycho(np.array([-10., 10., 0.1]), xx)
>>> plt.plot(xx, ff)
Raises
  • ValueError – pars must be of length 3

  • TypeError – pars must be a list or numpy array

Information:

2000 MC wrote it 2018-08 MW ported to Python

erf_psycho_2gammas(pars, xx)[source]

erf function from 0 to 1, with two lapse rates. :param pars: Model parameters [bias, slope, gamma]. :param xx: vector of stim levels (%)

Returns

A vector of length xx

Return type

ff

Examples

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> xx = np.arange(-50, 50)
>>> ff = erf_psycho_2gammas(np.array([-10., 10., 0.2, 0.]), xx)
>>> plt.plot(xx, ff)
Raises
  • ValueError – pars must be of length 4

  • TypeError – pars must be list-like or numpy array

Information:

2000 MC wrote it 2018-08 MW ported to Python