Commit 25dc3da8 by Laura Rodríguez

17 jun

parent 657966b4
......@@ -103,7 +103,7 @@ def calibrate_tobii(self):
# ============ TEST PRO/NOGO ======================
# ============ TEST PS/NOGO ======================
def run_pro_nogo_test(self):
pygame.init()
......@@ -283,7 +283,7 @@ def run_pro_nogo_test(self):
print("Resultados guardados en 'gonogo_results.xlsx'.")
# ============ TEST PR/AS ===================
# ============ TEST PS/AS ===================
def run_pr_as_test(self):
......@@ -353,6 +353,7 @@ def run_pr_as_test(self):
max_blocks = 30
results = []
try:
self.tracker.start_recording()
for block in range(max_blocks):
trials = ['PS', 'AS']
fixation_duration = random.choice([1000, 2000, 3000]) # milisegundos
......@@ -367,7 +368,7 @@ def run_pr_as_test(self):
# Mostrar cruz de fijación
self.disp.fill(fixscreen)
self.disp.show()
libtime.pause(random.randint(750, 1250))
#libtime.pause(random.randint(750, 1250))
libtime.pause(fixation_duration) # Usamos la duración fija del bloque
# # Esperar que el usuario presione espacio
......@@ -382,7 +383,6 @@ def run_pr_as_test(self):
time.sleep(0.2)
self.tracker.start_recording()
# Mostrar señal central de color
self.disp.fill(signal_screens[trialtype])
......@@ -416,7 +416,6 @@ def run_pr_as_test(self):
latency = (t1 - t0) / 1000
self.tracker.stop_recording()
# midpoint = SCREEN_WIDTH / 2
# margin = 100
......@@ -444,6 +443,7 @@ def run_pr_as_test(self):
results.append([trialnr, trialtype, targetside, endpos, round(latency, 3), correct])
self.tracker.stop_recording()
except KeyboardInterrupt:
print("Test interrumpido por el usuario con la tecla 'E'.")
finally:
......@@ -655,35 +655,23 @@ def open_results_file():
# ============ TEST BATERIA ===================
def run_bateria_test(self):
import pygame
from random import choice
from pygaze import libscreen, liblog
from pygaze.keyboard import Keyboard
import constants
from pygaze.display import Display
from pygaze.eyetracker import EyeTracker
pygame.init()
while True:
self.disp = libscreen.Display(bgcolor=(0, 0, 0)) # Abrir pantalla
# self.test_window.disp = self.disp
self.disp = libscreen.Display(bgcolor=(0, 0, 0))#abro display de nuevo
# self.tracker = eyetracker.EyeTracker(self.disp)
log = liblog.Logfile()
log.write(["trialnr", "trialtype", "targetside", "gaze_endpos", "latency", "correct"])
kb = Keyboard()
tracker = EyeTracker(self.disp)
# Constantes
SCREEN_WIDTH, SCREEN_HEIGHT = constants.DISPSIZE
CENTER = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
TARGET_OFFSET = 382
left_pos = (CENTER[0] - TARGET_OFFSET, CENTER[1])
right_pos = (CENTER[0] + TARGET_OFFSET, CENTER[1])
center = CENTER
arrow_length = 100
arrow_color = (255, 255, 255)
n_trials = 5
# Pantalla de instrucciones
blackscreen = libscreen.Screen()
blackscreen.clear(colour=(0, 0, 0))
inscreen = libscreen.Screen()
inscreen.clear(colour=(0, 0, 0))
ins_text = (
......@@ -694,7 +682,31 @@ def run_bateria_test(self):
"Pulsa ESPACIO para comenzar la prueba.\n"
"Pulsa E para salir."
)
time.sleep(0.7)
inscreen.draw_text(text=ins_text, fontsize=30, pos=CENTER, colour=(255, 255, 255), center=True)
fixscreen = libscreen.Screen()
fixscreen.clear(colour=(0, 0, 0))
fixscreen.draw_fixation(fixtype='cross', diameter=57, pos=CENTER, colour=(255, 255, 255))
signal_screens = {
'PS': libscreen.Screen(),
'AS': libscreen.Screen(),
'NoGo': libscreen.Screen()
}
for key, color in [('PS', (0, 255, 0)), ('AS', (255, 0, 0)), ('NoGo', (255, 165, 0))]:
signal_screens[key].clear(colour=(0, 0, 0))
signal_screens[key].draw_circle(pos=CENTER, r=38, fill=True, colour=color)
feedbackscreens = {
1: libscreen.Screen(),
0: libscreen.Screen()
}
feedbackscreens[1].clear(colour=(0, 0, 0))
feedbackscreens[1].draw_text(text='Correcto', fontsize=30, pos=CENTER, colour=(0, 255, 0), center=True)
feedbackscreens[0].clear(colour=(0, 0, 0))
feedbackscreens[0].draw_text(text='Incorrecto', fontsize=30, pos=CENTER, colour=(255, 0, 0), center=True)
self.disp.fill(inscreen)
self.disp.show()
......@@ -707,102 +719,143 @@ def run_bateria_test(self):
elif event.key == pygame.K_e:
pygame.quit()
return
total_trials = 5
results = []
try:
trials = ['PS', 'AS', 'NoGo'] * 2 # Para asegurar que haya variedad
random.shuffle(trials)
selected_trials = trials[:total_trials]
screen = libscreen.Screen()
for trialnr, trialtype in enumerate(selected_trials, start=1):
def wait_with_exit(seconds):
start = pygame.time.get_ticks()
while (pygame.time.get_ticks() - start) < seconds * 1000:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_e:
pygame.quit()
exit()
for trial in range(n_trials):
# Mensaje previo
screen.clear(colour=(0, 0, 0))
screen.draw_text(f"Trial {trial + 1} de {n_trials}\nPulsa E para salir o espera para comenzar...",
fontsize=30, colour=(255, 255, 255))
self.disp.fill(screen)
raise KeyboardInterrupt
# Mostrar cruz de fijación
self.disp.fill(fixscreen)
self.disp.show()
wait_with_exit(2.0)
libtime.pause(random.randint(750, 1250))
# Esperar que el usuario presione espacio
# waiting = True
# while waiting:
# for event in pygame.event.get():
# if event.type == pygame.KEYDOWN:
# if event.key == pygame.K_SPACE:
# waiting = False
# elif event.key == pygame.K_e:
# raise KeyboardInterrupt
# Dirección y condición
direction = choice(["left", "right"])
condition = choice(["pro", "anti", "nogo"])
time.sleep(0.2)
if condition == "pro":
central_color = (0, 255, 0)
elif condition == "anti":
central_color = (255, 0, 0)
else:
central_color = (255, 165, 0)
self.tracker.start_recording()
# Estímulo central
screen.clear(colour=(0, 0, 0))
screen.draw_circle(colour=central_color, pos=center, r=28, fill=True)
self.disp.fill(screen)
# Mostrar señal central de color
self.disp.fill(signal_screens[trialtype])
self.disp.show()
wait_with_exit(1.0)
time.sleep(0.8)
# Flechas y círculos
screen.clear(colour=(0, 0, 0))
screen.draw_circle(colour=central_color, pos=center, r=28, fill=True)
self.disp.fill(blackscreen)
self.disp.show()
time.sleep(0.2)
if direction == "left":
big_circle_pos = left_pos
small_circle_pos = right_pos
else:
big_circle_pos = right_pos
small_circle_pos = left_pos
screen.draw_circle(colour=(255, 255, 255), pos=big_circle_pos, r=52, fill=True)
screen.draw_circle(colour=(255, 255, 255), pos=small_circle_pos, r=38, fill=True)
# Dibujar flecha
if condition != "nogo":
arrow_dir = direction if condition == "pro" else ("left" if direction == "right" else "right")
if arrow_dir == "right":
end = (center[0] + arrow_length, center[1])
screen.draw_line(colour=arrow_color, spos=center, epos=end, pw=6)
screen.draw_line(colour=arrow_color, spos=end, epos=(end[0] - 30, end[1] - 30), pw=6)
screen.draw_line(colour=arrow_color, spos=end, epos=(end[0] - 30, end[1] + 30), pw=6)
else:
end = (center[0] - arrow_length, center[1])
screen.draw_line(colour=arrow_color, spos=center, epos=end, pw=6)
screen.draw_line(colour=arrow_color, spos=end, epos=(end[0] + 30, end[1] - 30), pw=6)
screen.draw_line(colour=arrow_color, spos=end, epos=(end[0] + 30, end[1] + 30), pw=6)
targetside = random.choice(['left', 'right'])
target_pos = left_pos if targetside == 'left' else right_pos
nontarget_pos = right_pos if targetside == 'left' else left_pos
# Mostrar flecha de dirección según la condición (PS, AS, NoGo)
arrow_screen = libscreen.Screen()
arrow_screen.clear(colour=(0, 0, 0))
# Mostrar y grabar
self.disp.fill(screen)
tracker.start_recording()
tracker.log("TRIAL_%d_COND_%s_DIR_%s" % (trial + 1, condition.upper(), direction.upper()))
arrow_offset = 100 # desplazamiento vertical para colocar la flecha por encima
arrow_color = (255, 255, 255)
if trialtype == 'PS':
arrow_pos = target_pos
elif trialtype == 'AS':
arrow_pos = nontarget_pos
else: # NoGo
arrow_pos = CENTER
arrow_pos_above = (arrow_pos[0], arrow_pos[1] - arrow_offset)
arrow_screen.draw_text(text='↑', fontsize=60, pos=arrow_pos_above, colour=arrow_color, center=True)
self.disp.fill(arrow_screen)
self.disp.show()
wait_with_exit(1.5)
tracker.stop_recording()
time.sleep(0.8)
dualstim_screen = libscreen.Screen()
dualstim_screen.clear(colour=(0, 0, 0))
dualstim_screen.draw_circle(pos=nontarget_pos, r=28, fill=True, colour=(255, 255, 255))
dualstim_screen.draw_circle(pos=target_pos, r=38, fill=True, colour=(255, 255, 255))
dualstim_screen.draw_circle(pos=target_pos, r=32, fill=True, colour=(0, 0, 0))
dualstim_screen.draw_circle(pos=target_pos, r=28, fill=True, colour=(255, 255, 255))
# Cruz entre trials
screen.clear(colour=(0, 0, 0))
screen.draw_text("+", fontsize=40)
self.disp.fill(screen)
self.disp.fill(dualstim_screen)
self.disp.show()
wait_with_exit(0.8)
# Preguntar si repetir
screen.clear(colour=(0, 0, 0))
screen.draw_text("Test completado. ¿Quieres volver a intentarlo?\n\nPulsa S para repetir o N para salir.",
fontsize=30, colour=(255, 255, 255))
self.disp.fill(screen)
t0 = pygame.time.get_ticks()
self.tracker.log(f"target {targetside}")
# try:
t1, startpos = self.tracker.wait_for_saccade_start()
endtime, startpos, endpos = self.tracker.wait_for_saccade_end()
latency = (t1 - t0) / 1000
self.tracker.stop_recording()
# midpoint = SCREEN_WIDTH / 2
# margin = 100
# endpos=None
if trialtype == 'PS':
correct = int(
(targetside == 'left' and endpos[0] <= constants.DISPSIZE[0] / 2) or
(targetside == 'right' and endpos[0] >= constants.DISPSIZE[0] / 2)
)
print(correct)
elif trialtype == 'AS':
correct = int(
(targetside == 'left' and endpos[0] >= constants.DISPSIZE[0] / 2) or
(targetside == 'right' and endpos[0] <= constants.DISPSIZE[0] / 2)
)
print(correct)
elif trialtype == 'NoGo':
# En NoGo siempre se considera incorrecto
try:
t1, startpos = self.tracker.wait_for_saccade_start(latency=200)
endtime, _, endpos = self.tracker.wait_for_saccade_end()
latency = (t1 - t0) / 1000
print("Incorrecto - Sacada detectada")
except Exception:
latency = 0
endpos = None
print("Incorrecto - No se detectó sacada")
correct = 0
self.disp.fill(feedbackscreens[correct])
self.disp.show()
while True:
key, _ = kb.get_key(keylist=['s', 'n', 'e'])
if key == 's':
break # vuelve al inicio del while True
elif key in ['n', 'e']:
pygame.quit()
return
time.sleep(0.5)
results.append([trialnr, trialtype, targetside, endpos, round(latency, 3), correct])
except KeyboardInterrupt:
print("Test interrumpido por el usuario con la tecla 'E'.")
finally:
log.close()
self.tracker.close()
self.disp.close()
print("Test Go/NoGo finalizado.")
df = pd.DataFrame(results, columns=["trialnr", "trialtype", "targetside", "gaze_endpos", "latency", "correct"])
df.to_excel("gonogo_results.xlsx", index=False)
print("Resultados guardados en 'gonogo_results.xlsx'.")
# ============ INTERFAZ PYQT ===================
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment