QUEST staircase and psychometric function

Hello,

I am wanting to run a QUEST staircase, then fit a psychometric function to detain the 75, 50 and 25% detection thresholds. Has anyone done this? It will need to run in Psychopy and on Pavlovia? I am using a task where participants have to detect a tone in white noise and the QUEST dynamically changes the volume.

I have managed to get the quest working - I was just wondering if the QUEST in PsychoPy is consistent with this code that has been used from a different task outside of psychopy.```
var questlib = require(‘questlib’);

const tGuess = 0.5,
tGuessSd = 0.1,
pThreshold = 0.75,
beta = 3.5,
delta = 0.01,
gamma = 0.01,
grain = 0.001,
range = 20;

const q1 = new questlib.Quest(tGuess + 0.1, tGuessSd, pThreshold, beta, delta, gamma, grain, range);
const q2 = new questlib.Quest(tGuess - 0.1, tGuessSd, pThreshold, beta, delta, gamma, grain, range);

const tTest = q1.quantile();
q1.update(tTest, response);

const tTest2 = q2.quantile();
q2.update(tTest2, response2);

const intensities = questlib.ProcessQuestData(q1, q2).intensities;
const c25 = intensities.c25;


I've also had problems in detaining the thresholds with a psychometric function and wondered if anyone has done this on Psychopy or Pavlovia before?

Thanks

Hi, could you please share how you got the QUEST working to get 75/50/25 detection threshold/excel file? I need to do the same but I get an error saying that the “psychometric function range [0.50 0.99] omits 0.25 threshold” or “0.50 threshold” :frowning:

During the quest I created lists to save the x_data and y_data (intensities and responses).

After the quest I had another routine with the code:

#Define the cumulative Gaussian function
def cumulative_gaussian(x, a, b, c):
return a / (1 + np.exp(-(x - b) / c))

#Fit the psychometric function to the data
try:
params, covariance = curve_fit(cumulative_gaussian, x_data, y_data, p0=[1, np.mean(x_data), 1])

#Print the parameters to check if curve fitting was successful
print(f"Fitted parameters: {params}")

# Generate data for the fitted curve
x_values = np.linspace(min(x_data), max(x_data), 100)
y_values = cumulative_gaussian(x_values, *params)

# Plot the data points and the fitted curve
plt.figure(figsize=(8, 6))
plt.plot(x_data, y_data, 'o', label="Participant Data")
plt.plot(x_values, y_values, '-', label="Fitted Cumulative Gaussian")
plt.xlabel("Stimulus Intensity")
plt.ylabel("Probability of Correct Response")
plt.title("Psychometric Function Fitting")
plt.legend()
plt.grid()

# Function to calculate thresholds 
def find_threshold(prob, params):
    a, b, c = params
    return b - c * np.log((1 / prob) - 1)

# Calculate the 50%, 25%, and 75% thresholds
threshold_50 = find_threshold(0.50, params)
threshold_25 = find_threshold(0.25, params)
threshold_75 = find_threshold(0.75, params)
except RuntimeError as e:
print(“Error during curve fitting:”, e)

#Save the plot as an image file - this saves it as an image so you can view it
plt.savefig(‘psychometric_function_plot.png’, dpi=300)

threshold_50 = float(threshold_50)
threshold_25 = float(threshold_25)
threshold_75 = float(threshold_75)

#Create dictionary
threshold_dict = {
“threshold_50”: threshold_50,
“threshold_25”: threshold_25,
“threshold_75”: threshold_75
}

print(f"Threshold Dictionary: {threshold_dict}")

You could define this at the begin experiment and run as a function after - I’m still playing around improving it so might not be working but hope it helps somewhat

Thank you so much for your help, really appreciated - so just to have it clear, this code is to extract the 50/25/75 thresholds, is that correct? But then, I wonder which threshold did you set up in your excel condition file (“pThreshold” column)? In general, it would be super helpful if you can share the condition file or a screenshot of it, to understand how you got this to work.. Thanks again!

I used 0.75 pThreshold. My Quest finished based on maxTrials (80), I used the Quest to dynamically change the volume, then the psychometric function to obtain the thresholds. I’ll try and find my QUEST conditions file (I’ve changed my study since then). For some reason my QUEST didn’t work until I found someone else’s QUEST example and condition file - I changed the values to what I wanted. Even though I used the same values before it didn’t work.

thank you so much! I am also using that threshold and maxTrials too in order to run it online. Are you also running it online? Re your useful function: thank you! just to check, are you storing the response (y_data) using the key response storing accuracy values (0 or 1)? If you are running it online as well, how are you managing to fit the psychometric curve online (ie run your function online)?

Hi - so that was local. I’ve tried online but there is no way (that I’ve found so far), to fit the psychometric curve.

Still looking for ways to get this to work if anyone has found a solution?