Example #1
0
def test_weibull():
    #fit to the fake data
    fit = data.FitWeibull(contrasts, responses, display=0, expectedMin=0.5)
    #check threshold is close (maybe not identical because not same function)
    assert thresh-fit.inverse(0.75)<0.01
    #check that inverse works too
    modResps = fit.eval(contrasts)
    invs = fit.inverse(modResps)
    assert numpy.allclose(contrasts,invs), contrasts-invs#inverse should match the forwards function
    #do a plot to check fits look right
    if PLOTTING:
        plotFit(modResps, thresh, 'Weibull (thresh=%.2f, params=%s)' %(fit.inverse(0.75), fit.params))
Example #2
0
def test_weibull():
    #fit to the fake data
    fit = data.FitWeibull(contrasts, responses, display=0, expectedMin=0.5)
    #check threshold is close (maybe not identical because not same function)
    assert thresh - fit.inverse(0.75) < 0.001
    #check that inverse works too
    modelResponses = fit.eval(contrasts)
    invs = fit.inverse(modelResponses)
    assert numpy.allclose(
        contrasts,
        invs), contrasts - invs  #inverse should match the forwards function
    #do a plot to check fits look right
    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 Weibull (thresh=%.2f)' % (fit.inverse(0.75)))
for fileN, thisStair in enumerate(allIntensities):
    # lines.extend(pylab.plot(thisStair))  # uncomment for a legend for files
    # names = files[fileN]
    pylab.plot(thisStair, label=files[fileN])
# pylab.legend()

# get combined data
i, r, n = data.functionFromStaircase(allIntensities,
                                     allResponses,
                                     bins='unique')
combinedInten, combinedResp, combinedN = i, r, n
combinedN = pylab.array(combinedN)  # convert to array so we can do maths

# fit curve
fit = data.FitWeibull(combinedInten,
                      combinedResp,
                      expectedMin=expectedMin,
                      sems=1.0 / combinedN)
smoothInt = pylab.arange(min(combinedInten), max(combinedInten), 0.001)
smoothResp = fit.eval(smoothInt)
thresh = fit.inverse(threshVal)
print(thresh)

# plot curve
pylab.subplot(122)
pylab.plot(smoothInt, smoothResp, 'k-')
pylab.plot([thresh, thresh], [0, threshVal], 'k--')  # vertical dashed line
pylab.plot([0, thresh], [threshVal, threshVal],
           'k--')  # horizontal dashed line
pylab.title('threshold (%.2f) = %0.3f' % (threshVal, thresh))

# plot points
Example #4
0
#plot each staircase
pylab.subplot(121)
lines, names = [],[]
for fileN, thisStair in enumerate(allIntensities):
    #lines.extend(pylab.plot(thisStair))
    #names = files[fileN]
    pylab.plot(thisStair, label=files[fileN])
#pylab.legend()

#get combined data
combinedInten, combinedResp, combinedN = \
             data.functionFromStaircase(allIntensities, allResponses, 'unique')
#fit curve
guess= [num.average(combinedInten), num.average(combinedInten)/5]

fit = data.FitWeibull(combinedInten, combinedResp, guess=guess, expectedMin=0.0)
smoothInt = num.arange(min(combinedInten), max(combinedInten), 0.001)
smoothResp = fit.eval(smoothInt)
thresh = fit.inverse(0.5)
print thresh

#plot curve
pylab.subplot(122)
pylab.plot(smoothInt, smoothResp, '-')
pylab.plot([thresh, thresh],[0,0.5],'--'); pylab.plot([0, thresh],[0.5,0.5],'--')
pylab.title('threshold = %0.3f' %(thresh))
#plot points
pylab.plot(combinedInten, combinedResp, 'o')
pylab.ylim([0,1])

pylab.show()
    staircase.importData( toStaircase(noiseEachTrial,descendingPsycho), np.array(corrEachTrial) )
    printStaircase(staircase, briefTrialUpdate=False, printInternalVal=True, alsoLog=False)

    #Fit and plot data
    descendingPsycho = False
    fit = None
    intensityForCurveFitting = outOfStaircase(staircase.intensities,staircase,descendingPsycho)
    #print('intensityForCurveFitting=',intensityForCurveFitting)
    if descendingPsycho: 
         intensityForCurveFitting = 100-staircase.intensities #because fitWeibull assumes curve is ascending
    #convert from list of trials to probabilities
    combinedInten, combinedResp, combinedN = \
         data.functionFromStaircase(intensityForCurveFitting, staircase.data, bins='unique')
    print('combinedInten=',combinedInten,'combinedResp=',combinedResp)
    try:
        fit = data.FitWeibull(combinedInten, combinedResp, expectedMin=0, sems = 1.0/len(staircase.intensities))
        print('fit=',fit)
    except:
        print("Fit failed.")
    plotDataAndPsychometricCurve(staircase,fit,descendingPsycho,threshVal=0.75)
    pylab.show() #must call this to actually show plot
    
    testNoise = True
    if testNoise: #Test noise
        myWin = visual.Window()
        proportnNoise = 0.9
        noiseFieldWidthPix = 200
        bgColor = [-.7,-.7,-.7] 
    
        (noise,allFieldCoords,numNoiseDots) = createNoise(proportnNoise,myWin,noiseFieldWidthPix, bgColor)
        print("allFieldCoords[0:3]=",allFieldCoords[0:3])
from psychopy import data
import numpy as np
#my data
x = np.array([5.0, 10.0, 20.0, 50.0, 70.0, 80.0, 95.0])
y = np.array([0.4, 0.4, 0.4, 0.57, 1.0, 1.0, 1.0])  #good

expectedMin = 0
try:
    data.FitWeibull(x, y, expectedMin=expectedMin)
    print('Fit succeeded on my 1st dataset')
except:
    print('Fit failed on my 1st dataset')

#my data
x = np.array([5.0, 10.0, 20.0, 50.0, 70.0, 80.0, 95.0])
y = np.array([0.0, 0.0, 0.0, 0.57, 1.0, 1.0,
              1.0])  #bad FIT FAILS. Doesnt seem to like zeros

expectedMin = 0
try:
    data.FitWeibull(x, y, expectedMin=expectedMin)
    print('Fit succeeded on my 2nd dataset')
except:
    print('Fit failed on my 2nd dataset')

#JWP JND_staircase_exp data
x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 12.0, 20.0])
y = np.array([0.4, 0.63, 0.8, 0.92, 1.0, 1.0, 1.0])
expectedMin = 0
try:
    data.FitWeibull(x, y, expectedMin=expectedMin)
Example #7
0
    printStaircase(staircase, descendingPsycho, briefTrialUpdate=True, printInternalVal=True, alsoLog=False)
    #print('staircase.quantile=',round(staircase.quantile(),2),' sd=',round(staircase.sd(),2))
    threshNoise = round(staircase.quantile(),3)
    if descendingPsycho:
        threshNoise = 100- threshNoise
    threshNoise = max( 0, threshNoise ) #e.g. ff get all trials wrong, posterior peaks at a very negative number
    msg= 'Staircase estimate of threshold = ' + str(threshNoise) + ' with sd=' + str(round(staircase.sd(),2))
    logging.info(msg); print(msg)
    myWin.close()
    #Fit and plot data
    fit = None
    try:
        intensityForCurveFitting = staircase.intensities
        if descendingPsycho: 
            intensityForCurveFitting = 100-staircase.intensities #because fitWeibull assumes curve is ascending
        fit = data.FitWeibull(intensityForCurveFitting, staircase.data, expectedMin=1/26., sems = 1.0/len(staircase.intensities))
    except:
        print("Fit failed.")
    plotDataAndPsychometricCurve(staircase,fit,descendingPsycho,threshCriterion)
    #save figure to file
    pylab.savefig(fileName+'.pdf')
    print('The plot has been saved, as '+fileName+'.pdf')
    pylab.show() #must call this to actually show plot
else: #not staircase
    noisePercent = defaultNoiseLevel
    phasesMsg = 'Experiment will have '+str(trials.nTotal)+' trials. Letters will be drawn with superposed noise of' + "{:.2%}".format(defaultNoiseLevel)
    print(phasesMsg); logging.info(phasesMsg)
    
    #myWin= openMyStimWindow();    myWin.flip(); myWin.flip();myWin.flip();myWin.flip()
    nDoneMain =0
    while nDoneMain < trials.nTotal and expStop==False:
Example #8
0
    def run_quest_procedure(self, n_trials=10, start=20, start_sd=10, maxvalue=40, beta=3.5, delta=0.01, gamma=0.01, grain=0.01):

        print("RUNNING QUEST\n" \
              "-------------\n")

        startVal=start
        startValSd=start_sd
        pThreshold=0.75
        nTrials=n_trials
        minVal=0
        maxVal=maxvalue
        beta=beta
        delta=delta
        gamma=gamma
        grain=grain
        method='quantile'
        
        conditions = {
            'startVal': startVal, 'startValSd': startValSd,
            'minVal': 0, 'maxVal': maxVal, 'pThreshold': 0.75, 'gamma': gamma, 'delta': delta,
            'grain': grain, 'method': method, 'nTrials': n_trials,
        }
        self.conditions = [
            dict({'label': 'staircase_1'}.items() + conditions.items()),
            dict({'label': 'staircase_2'}.items() + conditions.items()),
        ]
        self.quest = data.MultiStairHandler(stairType='quest', method='random', conditions=self.conditions)
        t1 = self.quest.staircases[0].mean()
        t2 = self.quest.staircases[1].mean()
        sd1 = self.quest.staircases[0].sd()
        sd2 = self.quest.staircases[1].sd()
        beta1 = contrib.quest.QuestObject.beta(self.quest.staircases[0])
        beta1 = contrib.quest.QuestObject.beta(self.quest.staircases[1])
        
        t_mean = (t1 + t2) / 2
        beta_mean = (beta1 + beta2) / 2 

        fit = data.FitWeibull(t_mean, beta_mean, sems=1/n_trials)

        for n, stim_level in enumerate(self.quest):

            print("Calibration trial {0} / {1}\n" \
                  "Stimulation level = {2}\n" \
                  "-----------------------------".format(n + 1, n_trials, stim_level))

            response = None

            # Repeat if subject doesn't respond
            while response == None:
                trial = ConditioningTrial(self, n, True, max_voltage=stim_level)
                response = trial.run()

            # Add the response
            if response:
                print("Stimulation detected")
            else:
                print("Stimulation not detected")

            if n >= self.config['quest_settings']['n_ignored']:
                self.quest.addResponse(int(response))
                p0 = fit.inverse(0)
                p25 = fit.inverse(.25)
                p50 = fit.inverse(.50)
                p75 = fit.inverse(.75)
                print("1% detection probability level = {0}\n"
                      "25% detection probability level = {1}\n"
                      "50% detection probability level = {2}\n"
                      "75% detection probability level = {3}\n".format(self.quest.quantile(0.01), self.quest.quantile(.25), self.quest.quantile(.5), self.quest.quantile(.75)))


        return p0, p25, p50, p75
Example #9
0
    quantilePctNoise = 100-staircase.quantile() 
#print('staircase quantile (median)=','{:.4f}'.format(staircase.quantile()), end='') #gets the median. Prints as floating point with 4 digits of precision
print('Median of posterior distribution according to QUEST, percent noise=','{:.4f}'.format(quantilePctNoise)) 

if plotFakeDataInstead: #plot standard fake data instead.
    intensities = np.array([5.00, 20.00, 20.00, 20.00, 50.00, 50.00, 50.00, 5.00, 80.00, 80.00, 80.00, 5.00, 95.00, 95.00, 95.00, 74.56, 75.89, 76.94, 77.72, 78.43, 79.05, 79.68, 80.28, 80.87, 81.53, 82.22, 83.05, 84.01, 85.04, 86.09, 87.02, 87.80, 88.47, 89.03, 89.49, 89.88, 90.20, 90.49, 90.74, 90.96, 91.16, 89.97, 90.12, 90.24, 90.37, 90.48, 90.59, 90.69, 90.79, 90.10, 90.18, 90.26, 90.33, 90.40, 90.47, 90.54, 90.60, 90.66, 90.72, 90.28, 90.33, 90.37, 90.42, 90.06, 89.73
    ]) #debug, example data
    corrEachTrial= np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1
    ]) #debug, example data
    staircase.importData( toStaircase(intensities,descendingPsycho), corrEachTrial) 

intensities = outOfStaircase( staircase.intensities, staircase, descendingPsycho ) #inverse log, 100- 
responses = staircase.data

expectedMin = 1.0/26
#fit curve
fit = None
try: 
    intensityForCurveFitting = intensities
    if descendingPsycho: 
        intensityForCurveFitting = 100-intensities #because fitWeibull assumes curve is ascending
    fit = data.FitWeibull(intensityForCurveFitting, responses, expectedMin=expectedMin,  sems = 1.0/len(intensityForCurveFitting))
except:
    print("Fit failed.")
plotDataAndPsychometricCurve(staircase,fit,descendingPsycho,threshCriterion)
#save figure to file
outputFile =  'test_staircase_plot' # os.path.join(dataDir, 'test_staircase_plot')
pylab.savefig(outputFile + '.pdf')
pylab.savefig(outputFile + '.jpg')
pylab.show() #must call this to actually show plot
Example #10
0
#plot each staircase
pylab.subplot(121)
colors = 'brgkcmbrgkcm'
lines, names = [], []
for fileN, thisStair in enumerate(allIntensities):
    #lines.extend(pylab.plot(thisStair))
    #names = files[fileN]
    pylab.plot(thisStair, label=files[fileN])
#pylab.legend()

#get combined data
combinedInten, combinedResp, combinedN = \
             data.functionFromStaircase(allIntensities, allResponses, 5)
#fit curve
fit = data.FitWeibull(combinedInten, combinedResp, guess=[0.2, 0.5])
smoothInt = pylab.arange(min(combinedInten), max(combinedInten), 0.001)
smoothResp = fit.eval(smoothInt)
thresh = fit.inverse(0.8)
print thresh

#plot curve
pylab.subplot(122)
pylab.plot(smoothInt, smoothResp, 'k-')
pylab.plot([thresh, thresh], [0, 0.8], 'k--')
pylab.plot([0, thresh], [0.8, 0.8], 'k--')
pylab.title('threshold = %0.3f' % (thresh))
#plot points
pylab.plot(combinedInten, combinedResp, 'ko')
pylab.ylim([0, 1])