Self-paced reading: how to make fixation stop automatically

Hi all,

I am working on a self-paced reading experiment with comprehension questions after each sentence (which is starting to come together now), but there are two things that I can’t seem to work out.

First of all, I would like to have a fixation cross ‘+’ before each sentence, but I want this cross to last for 2 seconds and then automatically disappear. Now, it is needed to press the space bar in order to make the cross disappear. I tried to change the duration of the trial text into 2 seconds, and I also tried to make a separate fixation routine, but both without success.

The second problem is that I would like to add the text “press ‘j’ for yes, ‘f’ for now” below each comprehension question, but it doesn’t work to simply type the text into the question routine (called ‘qs’). I get the following error:

Python syntax error in field ‘text’

Does anybody have a solution for these problems?

Thanks in advance!

Here is my experiment:
spr.psyexp (31.5 KB)

Hello @Emma_B ,
For the fixation cross I am confused about exactly what you tried. If you want it to appear for 2 seconds then you can just set stop point of all components in that trial component to 2 seconds. So in the text description window fill in 2s for the stop field. If you have tried this and it doesn’t work I am thinking it would be because of the code component you have running on each frame, which seems like you basically built your own keyboard component which might be interfering with the automatic stopping that should happen in PsychoPy. Try deleting or commenting out this code in the each frame window, setting the stop time at 2s and seeing if that does it.

For the second problem, this is an easy fix. You can’t add additional constant text to a text component by just typing it in because the $ indicates you are inputting a variable. There are many ways to get around this:

  1. Define the text field as the combination of 2 strings, the variable question and your written text, this would look like:
    $Question + "\n press 'j' for yes, press 'f' for no"
    The \n controls the line spacing
    2.You could also just make another text component that has this constant text, and adjust the spacing on it to be below the variable text

Hope this helps!

Hello @Bobby_Thomas,

Thanks for you reply, the second problem is now solved!

I am not sure how to fix the first problem though. I think you are right about the code component interfering with the automatic stopping.

while continueRoutine:
kb = event.getKeys(timeStamped=True)
if len(kb) > 0:
if ‘space’ in kb[0]:

Because of this code, the program always needs the space bar to be pressed in order to continue to the next frame. I just do not want this to happen for the first frame (when the fixation cross is in the frame). Do you know how to fix this?

Thanks again!

Yes, it seems like you should just remove this code from the routine that presents the fixation cross. I’m unclear why you want this code component in the routine that presents the fixation cross in the first place? That code seems like it only serves a purpose when you want the user to hit space to end the routine, which shouldn’t be an issue since the fixation cross is in its own routine.
I feel like I might be missing something about what you are trying to achieve. From the experiment you posted it seems like an iteration of a loop should start with a 2s fixation cross (which can be its own routine), and then moves to a routine to show the question text (which lasts until the user inputs an answer using the keyboard), is there some other function you are trying to make work that I am missing?

“From the experiment you posted it seems like an iteration of a loop should start with a 2s fixation cross (which can be its own routine), and then moves to a routine to show the question text (which lasts until the user inputs an answer using the keyboard)”

That is right. I already tried to make a separate routine for the fixation, but then I still have the problem that the space bar needs to be pressed to make the first word of the sentence appear on the screen.

The main reason that added the code component is that is makes a data file in which the reading time for each word is added. I did not write this code myself, but found it in another discussion:

For clarification, this is what I have now for the trial loops:

  1. a fixation for 2 seconds
  2. a sentence, presented word by word, but starting with “…”, which I want to get rid of
  3. a comprehension question

So, I would like to get rid of the “…” and directly see the first word of the sentence after the fixation cross.

Updated file:
spr.psyexp (38.3 KB)

Oh ok, I think I understand now.
It should be as simple as executing the code to pop the word list and set this word as the text one time at the beginning of the routine.
Try editing the code in Begin Routine to:
word_list = Sentence.split()
word_list.reverse() # switch the order
rtList = []
event.clearEvents()

nextWord = word_list.pop()
text.setText(nextWord)

As you can see it just involves adding in these last two lines. Essentially what this change is doing is making it so that at the start of the routine the code to produce a word is run 1 time, so that the first word should appear on screen. Then the code in each frame takes over and this should continue to redefine text whenever space is hit on the routine.
Hope that helps and let me know if that works

Yes, that works! Thank you so much!

1 Like

Wait, there is still a problem. Now, the reading time for the first word is not added to the data file…

Ok, I looked into dvbridges example a bit more, and that project was built to have subjects start the routine and remove the fixation cross by pressing space, and it seems like you do not want that to happen for your project.
If you want to stick with having the word starting on the screen without them having to press space, then you essentially need to define the first response time in RTList as 0, since that is the time when the first word appears on that trial. Hopefully, by doing this, the rest of his code should automatically adjust to this change. In trialing this I would try to make your response times to the different words very obvious (some words take a long time to respond to, others very short), so that you can ensure the recorded times match up to the words they were presented on.
So try editing the begin routine code to:

trialClock = core.Clock()
trialClock.reset
word_list = Sentence.split()
word_list.reverse() # switch the order
rtList = []
event.clearEvents()

nextWord = word_list.pop()
text.setText(nextWord)
rtList.append(trialClock.getTime())

If that doesn’t work I might be out of ideas.

Thank you so much for all your help!! With this code, reading times for all words are added to the data file, so that’s great. The only problem is that the reading time for the first word of each sentence is not resetted to 0 for some reason (it keeps adding up for the whole experiment). Do you by any chance know how to fix that? If not, it’s no problem, I will stick with pressing the space bar after the fixation cross :slight_smile:

I think that is because I am still very much learning PsychoPy and gave you some code that doesn’t actually reset the clock.
Try changing the second line to

trialClock.reset()

Hopefully that should help. I think without the parentheses it wasn’t actually reseting the trial clock each time through the loop.
Happy to help keep debugging this as needed since the main issue seems to be fixed.

Thanks for your help! This unfortunately does not reset the clock either…

Well you could try and figure out how to get trialClock to reset each trial, or a less precise fix would be to just do
rtList.append(0)
which would set the start time to 0 on each trial (this shouldn’t affect measurements by too much, but depending on how precise your study needs to be this might not be an ideal solution)