Skip to content

Commit 9aa6737

Browse files
committed
fix _run_trial_loop skipping present_stimulus when SOA < frame duration
Previously, current_trial advanced based on elapsed_time alone. If a single frame took longer than the SOA window, the trial incremented before present_stimulus could fire, silently skipping it. Fix: only advance current_trial when rendering_trial has caught up, guaranteeing every trial fires exactly once regardless of SOA length. Also adds text_color param to show_instructions() (default black, unchanged) and moves the instruction_text % duration substitution into setup() where self.duration lives.
1 parent 322592e commit 9aa6737

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

eegnb/experiments/Experiment.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ def setup(self, instructions=True):
125125

126126
# Show Instruction Screen if not skipped by the user
127127
if instructions:
128+
self.instruction_text = self.instruction_text % self.duration
128129
if not self.show_instructions():
129130
return False
130131

@@ -143,15 +144,16 @@ def setup(self, instructions=True):
143144
)
144145
return True
145146

146-
def show_instructions(self):
147-
"""
147+
def show_instructions(self, text_color=None):
148+
"""
148149
Method that shows the instructions for the specific Experiment
149150
In the usual case it is not overwritten, the instruction text can be overwritten by the specific experiment
150-
No parameters accepted, can be skipped through passing a False while running the Experiment
151-
"""
152151
153-
# Splitting instruction text into lines
154-
self.instruction_text = self.instruction_text % self.duration
152+
Args:
153+
text_color: PsychoPy colour for instruction text. Defaults to black [-1,-1,-1].
154+
"""
155+
if text_color is None:
156+
text_color = [-1, -1, -1]
155157

156158
# Disabling the cursor during display of instructions
157159
self.window.mouseVisible = False
@@ -162,7 +164,7 @@ def show_instructions(self):
162164
# Waiting for the user to press the spacebar or controller button or trigger to start the experiment
163165
while not self._user_input('start'):
164166
# Displaying the instructions on the screen
165-
text = visual.TextStim(win=self.window, text=self.instruction_text, color=[-1, -1, -1])
167+
text = visual.TextStim(win=self.window, text=self.instruction_text, color=text_color)
166168
self._draw(lambda: self.__draw_instructions(text))
167169

168170
# Enabling the cursor again
@@ -286,11 +288,14 @@ def iti_with_jitter():
286288
# Run the trial loop
287289
while (time() - start_time) < duration:
288290
elapsed_time = time() - start_time
289-
290-
# Do not present stimulus until current trial begins(Adhere to inter-trial interval).
291-
if elapsed_time > trial_end_time:
291+
292+
# Advance to next trial only after the previous stimulus has been shown.
293+
# Checking rendering_trial guards against the case where elapsed_time jumps
294+
# past trial_end_time in a single frame (e.g. short SOA relative to frame
295+
# duration), which would otherwise skip present_stimulus entirely.
296+
if elapsed_time > trial_end_time and current_trial == rendering_trial:
292297
current_trial += 1
293-
298+
294299
# Calculate timing for this trial
295300
trial_start_time = elapsed_time + iti_with_jitter()
296301
trial_end_time = trial_start_time + self.soa

0 commit comments

Comments
 (0)