Beispiel #1
0
def test_fitCumNorm():
    #the data are actually from a cum norm so this should be exact
    fit = data.FitCumNormal(contrasts, responses, display=0, expectedMin=0.5)
    assert numpy.allclose([thresh,sd], fit.params)
    modResps = fit.eval(contrasts)
    #check that inverse works too
    invs = fit.inverse(responses)
    assert numpy.allclose(contrasts,invs)#inverse should match the forwards function
    #plot if needed
    if PLOTTING:
        plotFit(modResps, thresh, 'CumulativeNormal (thresh=%.2f, params=%s)' %(fit.inverse(0.75), fit.params))
Beispiel #2
0
def test_fitCumNorm():
    #the data are actually from a cum norm so this should be exact
    fit = data.FitCumNormal(contrasts, responses, display=0, expectedMin=0.5)
    assert numpy.allclose([thresh, sd], fit.params)
    #check that inverse works too
    invs = fit.inverse(responses)
    assert numpy.allclose(contrasts,
                          invs)  #inverse should match the forwards function
    #plot if needed
    if PLOTTING:
        pylab.figure(1)
        pylab.plot(contrasts, responses, 'o')
        pylab.plot(contrasts, fit.eval(contrasts))
        pylab.plot([0, thresh], [0.75, 0.75], '--b')  #horiz
        pylab.plot([thresh, thresh], [0., 0.75], '--b')  #vert
        pylab.title('Fitting CumulativeNormal')
Beispiel #3
0
from psychopy import data

x = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
y = [0.1, 0.2, 0.5, 0.7, 0.9, 0.8]

myFunc = data.FitCumNormal(xx=x, yy=y, expectedMin=0)
#myFunc2 = data.FitFunction('logistYN',xx=x,yy=y)
print myFunc.eval(x)
print myFunc.params
print myFunc.inverse(myFunc.eval(x))
"""
[ 0.09031101  0.26949287  0.46916508  0.64717069  0.78403421  0.87766973]
[ 0.1  0.2  0.3  0.4  0.5  0.6]"""
Beispiel #4
0
    def fitpf(self):

        from psychopy import data
        import pylab
        import matplotlib.pyplot as plt

        dfs, _ = self.sumxrl()
        allIntensities = dfs.groupby(level=0)['all_intensities'].apply(
            np.hstack)
        allResponses = dfs.groupby(level=0)['all_responses'].apply(np.hstack)

        ntrial = dfs.groupby(level=0)['ntrial'].sum().unique()
        num = int(len(allIntensities) / 2)
        colorcodes = np.repeat(color4plot(num), 2, axis=0)

        # curve fitting and plotting for each condition
        fig, axes = plt.subplots(4, 4, figsize=(16, 10))
        fig.suptitle(self.sub)
        thresh = []
        for idx, label in enumerate(allResponses.index):
            intensities = abs(allIntensities[label])
            responses = allResponses[label]

            # bin data and fit to PF
            combinedInten, combinedResp, combinedN = data.functionFromStaircase(
                intensities, responses,
                bins='unique')  # optimal: bins='unique'
            fit = data.FitCumNormal(combinedInten,
                                    combinedResp,
                                    guess=None,
                                    expectedMin=0.5)  # cumulative Gaussian
            # fit = data.FitLogistic(combinedInten, combinedResp, guess=None)  # logistic
            # fit = data.FitWeibull(combinedInten, combinedResp, guess=[3, 0.5], display=1, expectedMin=0.5)  #< --- somehow errors
            thresh.append(fit.inverse(0.76))  # threshold
            print(label + ': % 0.3f' % fit.ssq)
            # plot
            ax = axes.flatten()[idx]
            fontsize = 8
            ax.plot(combinedInten,
                    combinedResp,
                    'o',
                    fillstyle='none',
                    color='grey',
                    alpha=.5,
                    markersize=5)  # plot combined data points
            # ax.plot(intensities, responses, 'o', color='grey', alpha=.5, markersize=3)  # plot all data points
            # smoothInt = pylab.arange(min(combinedInten), max(combinedInten), 0.1)  # x for fitted curve
            # smoothResp = fit.eval(smoothInt)  # y for fitted curve
            smoothResp = pylab.arange(0.5, 1, 0.02)
            smoothInt = fit.inverse(smoothResp)
            ax.plot(smoothInt, smoothResp, '-',
                    color=colorcodes[idx])  # plot fitted curve
            ax.plot([thresh[idx], thresh[idx]], [0, 0.76], '--', color='grey')
            ax.plot([0, thresh[idx]], [0.76, 0.76], '--', color='grey')
            ax.set_title(label + ' ' + 'threshold = %0.3f' % thresh[idx],
                         fontsize=fontsize)
            ax.set_ylim([0.5, 1])
            ax.set_xlim([0, 6])
            ax.tick_params(axis='both', which='major', labelsize=fontsize - 2)

        plt.setp(axes[-1, :], xlabel='hue angle')
        plt.setp(axes[:, 0], ylabel='correctness')

        plt.savefig('pilot_data_fig/' + self.sub + '_' +
                    self.xstr(self.sel_par) + '_' + self.xstr(self.sel_ses) +
                    '_' + str(ntrial) + 'trl' + '.pdf')
        plt.show()

        return allResponses, thresh
Beispiel #5
0
def fitData(stairs, percent):

    allIntensities, allResponses = [], []
    for s in stairs.staircases:
        allIntensities.append(s.intensities)
        allResponses.append(s.data)

    for s in stairs.staircases:
        print "Mean for condition ", s.condition['label'], "=", average(
            s.reversalIntensities), "std=", std(s.reversalIntensities)

    #plot each condition
    pylab.subplot(221)
    #for stairNumber, thisStair in enumerate(allIntensities):
    pylab.plot(allIntensities[0],
               'o-',
               label=stairs.staircases[0].condition['label'])
    pylab.xlabel('Trials')
    pylab.ylabel('Speed [cm/s]')
    pylab.legend()

    # Get combined data
    combinedInten, combinedResp, combinedN = data.functionFromStaircase(
        allIntensities, allResponses, 10)

    # Fit curve - in this case using a Weibull function
    fit = data.FitFunction('weibullTAFC',
                           combinedInten,
                           combinedResp,
                           guess=None)
    #fit = data.FitCumNormal(combinedInten,combinedResp)
    intensitiesDomainInterp = pylab.arange(min(allIntensities[0]),
                                           max(allIntensities[0]), 0.01)
    smoothResponses = fit.eval(intensitiesDomainInterp)
    thresh = fit.inverse(percent)

    #Plot fitted curve
    pylab.subplot(222)
    pylab.axis(xmin=min(allIntensities[0]), xmax=max(allIntensities[0]))
    pylab.xlabel('Speed [cm/s]')
    pylab.ylabel('Probability')
    pylab.plot(intensitiesDomainInterp, smoothResponses, '-')
    pylab.plot([thresh, thresh], [0, percent], '--')
    pylab.plot([0, thresh], [percent, percent], '--')
    pylab.title('Threshold at ' + str(percent) + '= %0.3f' % (thresh))
    # Plot points
    pylab.plot(combinedInten, combinedResp, 'o')
    pylab.ylim([0, 1])

    # SECOND CONDITION, the plots are in a second row, under
    pylab.subplot(223)
    #for stairNumber, thisStair in enumerate(allIntensities):
    pylab.plot(allIntensities[1],
               'o-',
               label=stairs.staircases[1].condition['label'])
    pylab.xlabel('Trials')
    pylab.ylabel('Speed [cm/s]')
    pylab.legend()

    # Get combined data
    combinedInten, combinedResp, combinedN = data.functionFromStaircase(
        allIntensities[1], allResponses[1], 10)

    #fit curve - in this case using a Weibull function
    #fit = data.FitFunction('weibullTAFC',combinedInten, combinedResp, guess=None)
    fit = data.FitCumNormal(combinedInten, combinedResp)

    intensitiesDomainInterp = pylab.arange(min(allIntensities[1]),
                                           max(allIntensities[1]), 0.01)
    smoothResponses = fit.eval(intensitiesDomainInterp)

    thresh = fit.inverse(percent)
    #print "Threshold at " + str(percent) +"% with Cumulative Normal= ",thresh

    #Plot fitted curve
    pylab.subplot(224)
    pylab.axis(xmin=min(allIntensities[1]), xmax=max(allIntensities[1]))
    pylab.xlabel('Speed [cm/s]')
    pylab.ylabel('Probability')
    pylab.plot(intensitiesDomainInterp, smoothResponses, '-')
    pylab.plot([thresh, thresh], [0, percent], '--')
    pylab.plot([0, thresh], [percent, percent], '--')
    pylab.title('Threshold at ' + str(percent) + '= %0.3f' % (thresh))
    # Plot points
    pylab.plot(combinedInten, combinedResp, 'o')
    pylab.ylim([0, 1])

    pylab.show()