Experiment running with Psychopy, but not on Pavlovia

URL of experiment: Sign in · GitLab

Description of the problem: I have a problem with running an experiment online via Pavlovia. It’s about a task where subjects have to press combinations of buttons on the keyboard (two at a time). The button presses and times of the button presses are stored for offline analysis.

The task runs perfectly on Psychopy but unfortunately not online via Pavlovia. I tried to change code manually (e.g., setting up a new keyboard, where syntax differs in JS from the automatic translation in Psychopy), but I still do not get this thing running, and I don’t know why. The task does not appear on the screen, and there is no file stored with the results (type and time of keyboard presses).

I would very much appreciate your help because I am stuck here.

Christian
task.psyexp (85.1 KB)

Hello,
What error do you recieve when running the experiment online?
https://workshops.psychopy.org/3days/debuggingOnline.html

I would try remove this code from your text component:

$int(round(30 - t, 3))

I don’t think this is being translated into Javascript through the text component.

You can try adding a code component this way:

# Every frame
countdown_text = str(int(round(30 - t, 3)))
countdown.setText(countdown_text)

Chen

Dear Chen,

thanks for the quick reply.
I tried it but get an error message that ‘countdown’ is not defined.

Instructional Design/PS-I finger sequence task/PS-I finger sequence task/task_lastrun.py", line 1375, in
countdown.setText(countdown_text)
NameError: name ‘countdown’ is not defined

Don’t I have to define the distinct component in the BeginRoutine Tab, and, if so, how?

I also tested if the countdown clock is actually the problem, by removing it, and found that it is not.

There is no error message before starting the experiment, but it just displays the picture with all the combinations of finger presses visualised as small squares. When pressing a combination, e.g., and on the keyboard, the respective square is supposed to change its size, i.e., gets smaller.
However, this does not happen, and no file is written at the end of the experiment.

thank you very much, best,

Christian

Hello,
You don’t need to define the countdown_text at the start of the routine.
You can set it for each frame and leave your text component empty:

# Every Frame:
countdown_text = str(int(round(30 - t, 3)))
countdown.setText(countdown_text)
console.log(countdown_text)

Take a look at a working example here:
task_key.psyexp (29.7 KB)

Is it the same way you have implemented it? Don’t you have the coutndown_text variable used somewhere else?

Chen

Dear Chen,

I successfully implemented it, the clock is now running, by using the first two lines of the code. Thanks a lot!!

However, the task is still not doing what it is supposed to do, namely shrinking the symbols representing the combination of key presses when they are pressed at the same time, and storing the results of key presses and times.

I attached the output when running it on Pavlovia, stating only zeros for types and times of key presses.

best,

Christian

332175_task_2023-08-14_05h41.13.056.csv (1.1 KB)

Hey,
The data seems to be outputted fine on my end:

# Start Routine:
kb = keyboard.Keyboard()

keysWatched = ['a','s','d','f','j','k','l','ö']

keyPressTypes = []
keyPressTimes = []


# Every Frame:
keys_pressed = kb.getKeys(keysWatched, waitRelease=False, clear=True)

for key in keys_pressed: 
    keyPressTypes.append(key.name)
    
for key in keys_pressed: 
    keyPressTimes.append(key.rt)


# End Routine:
thisExp.addData("keyPressTypes", keyPressTypes)
thisExp.addData("keyPressTimes", keyPressTimes)

For the image size, try to use the following instead:

stim.setSize([0.3, 0.3])

Dear Chen,

I tried what you suggested, changing it to var12.setSize instead of var12.size on the “right side” of the code window (JS). See attached. However, it still does not work. The images (var 12 to 78) are not changed by combination of key presses.
862740_task_2023-08-15_14h27.45.132.csv (1.0 KB)

It puzzles me that the output are zeros, for both keyPress types and times, see attached. Might it be that the keys are not distinctly recognized, i.e., that a press is recognized but not that it is from a specific key, e.g., ?

Here comes the updated psychopy file.
task.psyexp (86.5 KB)

Hey,
Is there any reason you use the Both code type?
It’s making it so each window is acting separately. So you have a separate Javascript code and Python code for this code component.
It makes it so your Python code is not being translated to Javascript code:
image

Unless you are typing your Javascript code manually, you should set your code type to Auto->JS

Chen

I used autotranslate and only changed code where autotranslation does not work, e.g., setting up the keyboard in JS.

The every frame code was autotranslated. I just change the setSize according to your suggestion.

Hey,
The following if statement won’t work. You cannot compare arrays in Javascript using the === operator. This is because arrays are objects that are a reference. Only if both references are the same will the statement be true, as the following:

let a = [1, 2, 3];
let b = [1, 2, 3];

a === a; // true
a === b; // false

Compare Arrays in JavaScript - Mastering JS.

So, the following code won’t work:

if (((keys_pressed === ["a", "s"]) || (keys_pressed === ["s", "a"]))) {
    var_12.setSize([0.3, 0.3]);
}

You can fix it by changing it for the following:

if (
  (keys_pressed[0] === "a" && keys_pressed[1] === "s") ||
  (keys_pressed[0] === "s" && keys_pressed[1] === "a")
) {
  var_12.setSize([0.3, 0.3]);
}

Or, even better:

if (keys_pressed.includes('a') && keys_pressed.includes('s')) {
    var_12.setSize([0.03, 0.03]);
}

Chen

Hi Chen, great, thank you very much.
I’ve tried both of your suggestions. The former one works kind of (see below), the second one not (here, the program stops at “initialising”).

Concerning the former one:
now the size of a respective stimulus changes (smaller) when I combine two key presses, that’s very good! Unfortunately, however, the key presses and times of the key presses are still not stored in the .csv file (see attachment).

Further, it seems as if the timing of two key presses have to be highly temporally precise in order to succeed. Would it be possible to set up a longer time frame (e.g., 150 ms) during which both keys have to be pressed in order to get the size of the stimulus smaller? Right now, the time frame is quite small, set by the refresh rate of the monitor, right?

best

Christian

task2.psyexp (82.5 KB)
141967_task2_2023-08-15_17h50.06.182.csv (568 Bytes)

Hi,

I spent some more time on it and wonder if it is this part of the code in the every frame tab which cause the problem of having just 0s in the results file?
keys_pressed = psychoJS.eventManager.getKeys(keysWatched, {“waitRelease”: false, “clear”: false});

for (var key, _pj_c = 0, _pj_a = keys_pressed, _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
key = _pj_a[_pj_c];
keyPressTypes.push(key.name);
}

for (var key, _pj_c = 0, _pj_a = keys_pressed, _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
key = _pj_a[_pj_c];
keyPressTimes.push(key.rt);
}

The number of 0s (count) in the file corresponds to the number of times (count) I press keys during the trial. However, instead of getting the types of keys I pressed (e.g., ) and the reaction times from trial onset there are just these 0s.

best,

Christian

Hey,
I wonder about one thing that I couldn’t find the answer for, why did you write key.name and key.rt?
I tried playing with your code and and it doesn’t look like those attributes exists.


keys_pressed = kb.getKeys(keysWatched, waitRelease=False, clear=True)

the kb.getKeys() returns an array of strings, not a dict/class.
https://psychopy.org/api/hardware/keyboard.html#psychopy.hardware.keyboard.KeyPress

So, instead of pusing key.name, you can simply push key.
Instead of pushing key.rt, you can push globalClock.getTime()

Let me know if it helped,
Chen

Did you refer to the attributes of the keyboard?
It’s possible you mixed the keyboard itself and the keyboard.getKeys function.

See the following:

Dear Chen,

success! Now the key types and times are stores. Thank you so much, Chen!!!

I realise that I already took a significant amount of your time, but may you allow me two final questions?

The first one concerns the timing of the button presses. Two buttons have to be pressed in combination, and stimuli are only changed if the two buttons are pressed at more or less the same time, checked at the screen refresh rate of 60 Hz (temporal window of 16.6 ms). This is quite challenging. Would it be possible to allow for a larger temporal window, say 100 ms. Two buttons pressed during that (100 ms) time window will change the stimulus?

The second one concerns the repetition of trials. Subjects need to repeat this trial 5 times. I tried to loop this routine. The problem here is that stimuli that were changed during the first run keep changed at the start of the second run. However, I want all stimuli to be unchanged at the beginning of the second run, i.e., a reset of these stimuli at the end of the first run. How is this possible?

best regards,

Christian

task3.psyexp (166.4 KB)

Hey,
About your first concern, this is indeed a little tricky, and I don’t have a quick solution for you. I will have to think about it.
I would suggest creating a new thread with this specific problem, so if someone else has a solution, it will be easier for him to notice your question (because it’s in this long thread, it’s very easy to miss).

About the second concern.
All your components should receive their original sizes back.
If you refer to variables you changed during the first iteration, you can reset them at the start of the routine. Simply reset the variables in the Beging Routine tab.
If you could be more specific about the elements that are changing on the second loop, it could help.

Chen

Dear Chen,

you are right, I will create a new thread just for this question.

Concerning the resetting of the variables: i) all the stimuli need to be displayed in its original size, and the countdown clock needs to be reset. Further, results (key presses and times of key presses) have to be saved in a new line in the same document.

Do I have to reset each of these items selectively, or is there a possibility to reset all of the stimuli at once?

thanks, best,

Christian