Pavlovia: only download relevant stimuli for participant

Hello, I would like to assign different stimuli to different participants, and only download the relevant ones on the participant’s computer. But Pavlovia seems to always download the whole “resources” folder by default. Is there a way to avoid this and make it only download a subset of stimuli?

Giacomo,

Did you ever sort this problem out? I have reduced the image files in my project from 420 to 210, to save download time but Pavlovia remembers there used to be 420 and insists on downloading the full set, even though it registered that 210 were deleted when I synched with Pavlovia after doing it. That means it didn’t speed up the download at all and I cant see how to get rid of the old files from the Pavlovia server either. There must be a cache somewhere that can be purged.

If you did figure out a solution I would be very pleased to hear about it.

Thanks

I’m afraid we haven’t built a way to vary the files that get delivered on a per-participant basis. We will be looking into options to fetch additional files during the experiment but there are then extra things to worry about like making sure the right files are fully received before they are needed, given the impotance of not suddenly “buffering” while running the study.

@DavidB-UWA your issue sounds like a problem with sync no longer working if you’ve removed files from the project but they are still being sent. When files are pushed to gitlab.pavlovia.org they are then pulled over by run.pavlovia.org using git. Sometimes a merge conflict occurs there (the cause of which we haven’t worked out) and from then on the sync fails. My guess is that your study has had this problem. Could you leave it there for us to investigate but then push the study to a fresh project* so that sync starts working again?

cheers,
Jon

*The safest way to make sure this happens is to duplicate your experiment folder and then, in the new copy, go and delete the hidden folder called .git from inside it, then open the study in PsychoPy and sync as before so that it will ask to create a new project.

I have had success with the following code:

psychoJS.downloadResources([
{ name: (expInfo["participant"] + "s.jpg"), path: ("../faces/" + expInfo["participant"] + "s.jpg") },
{ name: (expInfo["participant"] + ".jpg"), path: ("../faces/" + expInfo["participant"] + ".jpg") }
]);

If you start downloading in the first routine then hopefully the resources will be ready once they have read the instructions and perhaps done some practice trials with predownloaded resources.

Don’t call psychoJS.downloadResources multiple times to download resources.

Instead Create an array of dictionaries, e.g.

stimuli=[];
stimuli.push({name:(filename),path: (filenameWithPath)});
psychoJS.downloadResources(stimuli);

Could you please elaborate on how to create such an array of dictionaries? I am trying to selective load resources based on the participant number, such that I would load, among others, 120 images called (“grating” + expInfo[“participant”] + “_1” + “.png”), (“grating” + expInfo[“participant”] + “_2” + “.png”), (“grating” + expInfo[“participant”] + “_3” + “.png”), etc up to (“grating” + expInfo[“participant”] + “_120” + “.png”).

I’m very unfamiliar with javascript, and would very much appreciate your help coding this!

stimuli=[];
for (var Idx = 1, _pj_a = 120; (Idx <= _pj_a); Idx += 1) {
stimuli.push({name:"grating" + expInfo['participant']+ "_" + Idx + ".png",path: ("gratings/grating" + expInfo['participant']+ "_" + Idx + ".png")});
}
psychoJS.downloadResources(stimuli);

(if the gratings are in a folder called gratings)

Thank you so much for the instant reply, I’ll try it out!

I’m not sure what went wrong, but it starts loading resources and about 1/3 of the way through it throws an error saying ReferenceError: PsychoJS is not defined, which quickly disappears and is followed by SyntaxError: Cannot use import statement outside a module

Here is the code I added to the “begin experiment” tab of my first routine:

event=psychoJS.eventManager;
thisExp=psychoJS.experiment;
win=psychoJS.window;



demoStimuli=[];
for (var Idx = 1, _pj_a = 5; (Idx <= _pj_a); Idx += 1) {
demoStimuli.push({name:"demoPracticeGrating" + expInfo['participant']+ "_" + Idx + ".png",path: ("demoPracticeGrating" + expInfo['participant']+ "_" + Idx + ".png")});
}
psychoJS.downloadResources(demoStimuli);

practiceStimuli=[];
for (var Idx = 1, _pj_a = 120; (Idx <= _pj_a); Idx += 1) {
practiceStimuli.push({name:"practiceGrating" + expInfo['participant']+ "_" + Idx + ".png",path: ("practiceGrating" + expInfo['participant']+ "_" + Idx + ".png")});
}
psychoJS.downloadResources(practiceStimuli);

trialStimuli=[];
for (var Idx = 1, _pj_a = 1200; (Idx <= _pj_a); Idx += 1) {
trialStimuli.push({name:"grating" + expInfo['participant']+ "_" + Idx + ".png",path: ("grating" + expInfo['participant']+ "_" + Idx + ".png")});
}
psychoJS.downloadResources(trialStimuli);

psychoJS.downloadResources([
{ name: ("conMat" + expInfo["participant"] + ".xlsx"), path: ("conMat" + expInfo["participant"] + ".xlsx")},
{ name: ("practiceConMat" + expInfo["participant"] + ".xlsx"), path: ("practiceConMat" + expInfo["participant"] + ".xlsx")}
]);


Array.prototype.append = [].push;
shuffle = util.shuffle;
average = (arr) => (arr.reduce((a, b) => (a + b), 0)) / arr.length;
random = Math.random;
document.body.style.cursor='none';


thisWidth=x_scale*10.57974;
thisHeight=y_scale*10.57974;

What am I doing wrong??

Your error message has PsychoJS with a capital P. Where is that in your code?

One of your loops goes up to 1200 instead of 120

Also, append everything to the stimuli list and then call download resources once. It fails if you have overlapping calls.

Thank you for your suggestions! I can only see a capital P psychoJS in the .js code that’s created automatically, even though I don’t have that spelled that way in any of my code components. Here’s the link to the experiment on gitlab: Sign in · GitLab

The loops are correct, one of them does contain 1200 images.

I appended everything to stimuli, as you suggested, but it’s still crashing - this is the new code:

stimuli=[];

for (var Idx = 1, _pj_a = 5; (Idx <= _pj_a); Idx += 1) {
stimuli.push({name:"demoPracticeGrating" + expInfo['participant']+ "_" + Idx + ".png",path: ("demoPracticeGrating" + expInfo['participant']+ "_" + Idx + ".png")});
}

for (var Idx = 1, _pj_a = 120; (Idx <= _pj_a); Idx += 1) {
stimuli.push({name:"practiceGrating" + expInfo['participant']+ "_" + Idx + ".png",path: ("practiceGrating" + expInfo['participant']+ "_" + Idx + ".png")});
}

for (var Idx = 1, _pj_a = 1200; (Idx <= _pj_a); Idx += 1) {
stimuli.push({name:"grating" + expInfo['participant']+ "_" + Idx + ".png",path: ("grating" + expInfo['participant']+ "_" + Idx + ".png")});
}


stimuli.push([{ name: ("conMat" + expInfo["participant"] + ".xlsx"), path: ("conMat" + expInfo["participant"] + ".xlsx")},
{ name: ("practiceConMat" + expInfo["participant"] + ".xlsx"), path: ("practiceConMat" + expInfo["participant"] + ".xlsx")}]);

psychoJS.downloadResources(stimuli)

This is what appears on the console:

I think that the error might be related to something else.

Thanks for this! I can’t see a solution for that error (or what the mistake is, for that matter), am I missing something?

I think (from what I saw of the other thread) that it might be related to confusion between local and remote piloting of online experiments. How are you testing it?

Actually, I’ve just noticed that you seem to be working in a sub folder. Your experiment is at

https://run.pavlovia.org/mdelrio/tr/html/

so your psyexp file should be in https://gitlab.pavlovia.org/mdelrio/tr/

You should only have one experiment in each folder.

I’m testing it online.

I have seen previously that the html folder is deprecated, but it seemed to be the only way it would work online. If I remove it, it gets stuck initialising.

Some of my experiments still use the html folder. I’ve found that it can be a bit tricky to edit the runtime folder of a live experiment. You could delete the local .git folder and sync to a new repository online.

(the syntax error is because you’re running it from the wrong folder)

If I delete the .git folder and export the html, this is the structure: There’s an experiment folder (tr), with an html folder, all the resources, the psyexp file and the gitignore file. The html folder contains the html index file, the 2 js files and the resources folder, which only contains 2 of the images.
Before I create a new repository, could you confirm this is correct?

That looks fine. However, you could remove html from Experiment Settings / Online to avoid using the html folder.

If you do use the html folder, then you’ll need to add …/ to the path to the resources because the images would be one folder up from the html folder.

It took a while to load, but it’s now html-folder free in a new repository: https://gitlab.pavlovia.org/mdelrio/tempreg

Now it doesn’t seem to load any of the resources though…?

For some reason, it automatically identifies two resource files:

psychoJS.start({
  expName: expName,
  expInfo: expInfo,
  resources: [
    {'name': 'demoPracticeGrating1_1.png', 'path': 'demoPracticeGrating1_1.png'},
    {'name': 'bank-1300155_640.png', 'path': 'bank-1300155_640.png'}
  ]
});

However, it throws the error TypeError: Cannot read property ‘toString’ of undefined, when trying to load demoPracticeGrating1_1.png, so I’m not certain any files are loading correctly.