Hey thanks for your reply. The thing is I am completely new to using Psychopy and so I am extremely sorry for not understanding your reply.
Anyway here is the basic code that I have-
# gabor_meridian_keyed_final_vK_PSI_vNoExternal.py
Version using only PsychoPy for Bayesian (Psi) threshold
from psychopy import visual, core, event, monitors, data
import numpy as np
import pandas as pd
import os, random, time
import matplotlib.pyplot as plt
----------------------------
Monitor Configuration
----------------------------
myMonitor = monitors.Monitor(“myMonitor”)
myMonitor.setWidth(34) # screen width in cm
myMonitor.setDistance(57) # viewing distance in cm
myMonitor.setSizePix((1920, 1000)) # resolution
----------------------------
Window Setup
----------------------------
win = visual.Window(
size=(1360, 768),
fullscr=True,
monitor=myMonitor,
color=[0, 0, 0],
units=‘deg’,
allowGUI=False,
waitBlanking=False,
checkTiming=False
)
----------------------------
Stimulus Setup
----------------------------
ecc = 14
fixation = visual.TextStim(win, text=‘+’, color=‘white’, height=0.6)
gabor = visual.GratingStim(
win=win,
mask=‘gauss’,
sf=2,
size=4,
ori=0,
contrast=1.0,
units=‘deg’
)
feedback_correct = visual.TextStim(win, text=‘✓’, color=‘green’, height=0.8)
feedback_wrong = visual.TextStim(win, text=‘✗’, color=‘red’, height=0.8)
----------------------------
Experiment Parameters
----------------------------
spatial_freqs = np.geomspace(1, 20, 8)
orientations = [45, -45]
response_keys = {‘z’: -45, ‘m’: 45}
n_trials = 50
results =
----------------------------
PsiHandler (Bayesian adaptive)
----------------------------
psi_handler = data.PsiHandler(
stimRange=(1, 20), # spatial frequency range
nTrials=n_trials,
threshold=0.625,
slope=3.5,
guessRate=0.5, # 2AFC task
lapseRate=0.02,
startVal=5.0
)
----------------------------
Trial Loop
----------------------------
print(" Starting experiment… Press ESC to quit.\n")
clock = core.Clock()
try:
for trial in range(n_trials):
sf = psi_handler.next()
ori_rel = random.choice(orientations)
ori_abs = 0 + ori_rel
# Horizontal meridian
angle = np.deg2rad(0)
gabor.pos = (ecc \* np.cos(angle), ecc \* np.sin(angle))
gabor.sf = sf
gabor.ori = ori_abs
# Fixation
fixation.draw()
win.flip()
core.wait(0.5)
# Stimulus
gabor.draw()
win.flip()
core.wait(0.25)
# ISI
win.flip()
core.wait(0.5)
# Response
keys = event.waitKeys(keyList=list(response_keys.keys()) + \['escape'\])
if 'escape' in keys:
raise KeyboardInterrupt
pressed_key = keys\[0\]
response_ori = response_keys.get(pressed_key, None)
correct = int(response_ori == ori_rel)
# Feedback
if correct:
feedback_correct.draw()
else:
feedback_wrong.draw()
win.flip()
core.wait(0.3)
# Record data
results.append({
'trial': trial + 1,
'sf': sf,
'ori_rel': ori_rel,
'pressed_key': pressed_key,
'correct': correct
})
psi_handler.addData(correct)
except KeyboardInterrupt:
print(“\n Experiment safely exited by user.\n”)
finally:
win.close()
core.quit()
----------------------------
Save data
----------------------------
df = pd.DataFrame(results)
timestamp = time.strftime(“%Y-%m-%d_%Hh%M.%S”, time.localtime())
filename = f"gabor_PSI_results_{timestamp}.xlsx"
try:
df.to_excel(filename, index=False)
print(f" Data saved to {filename}“)
except PermissionError:
alt_filename = f"gabor_PSI_results_{timestamp}_backup.xlsx”
df.to_excel(alt_filename, index=False)
print(f"️ File was open; saved instead to {alt_filename}")
----------------------------
Plot Bayesian Psi curve (using PsychoPy PsiHandler estimates)
----------------------------
x = np.linspace(1, 20, 100)
y = psi_handler.mean # mean threshold estimate
For a simple plot, we can show the sequence of stimuli & responses
plt.figure()
plt.title(“Bayesian Psi Curve (Estimated Threshold)”)
plt.xlabel(“Trial”)
plt.ylabel(“Spatial Frequency (cpd)”)
plt.plot([r[‘trial’] for r in results], [r[‘sf’] for r in results], ‘o-’, label=‘Stimulus SF’)
plt.axhline(y, color=‘red’, linestyle=‘–’, label=f’Estimated threshold ≈ {y:.2f} cpd’)
plt.legend()
plt.show()
I used AI to draft this code since I have little experience in coding Python. So if you could elaborate how to integrate QUEST code using into this, it would be helpful. I have installed numpy scipy pandas and matplotlib Python libraries of 3.10.4 version of Python since thats what Psychopy uses.
Thank you
Tarun.