Forum Replies Created
-
AuthorPosts
-
Jeremy
KeymasterHi Daiwen,
Please feel free to send the experiment link to support@pcibex.net if you feel more comfortable sharing it privately
The random blank image issue might have difference sources. One is, you might have different groups in your CSV file and only some rows have invalid references, resulting in the error showing only when you run the experiment in that group—if you have an early
SetCounter
command, simply refreshing the page could be enough to switch group. Another explanation would be that the server hosting the images refuses to serve some of them in certain conditions (eg. repeated requests over a short time window)The error message “ERROR: There must be some items in the running order!” appears when there is a syntax error in your script that prevents it from creating the
items
variable (or when you simply don’t create any items, but you said that’s not your case). Simply refreshing a functional experiment should not make the error message appear, unless you edit the script in the meantime to introduce syntax errors. One explanation I could imagine is the farm maintains multiple parallel copies of your script and randomly serves one that does contain a syntax error. Maybe try to save a backup of your script (that you know to be functional), delete the script file from your project and recreate it using the backup, and see whether the problem persistsJeremy
Jeremy
KeymasterHi,
I’m glad you found a solution by yourself. You can use
getVar("myvar")._element.value
in a pure-javascript environment to retrieve the current value of the Var element, eg.getVar("mytextvariable1").set( v => v+getVar("mytextvariable2")._element.value )
Jeremy
Jeremy
KeymasterHi Kavita,
Any modification to a project will trigger an automatic save: changing the project title isn’t necessary by any means (although it does constitute, indeed, a modification to the project)
The browser you use also should not make a difference. This is a farm-internal problem, and the only workaround I have found so far is to delete the faulty file from the project (after saving a backup) and recreate it, to prevent the farm from maintaining parallel copies (reference)
Jeremy
September 19, 2022 at 5:06 pm in reply to: .avi file for eyetracking data experiment for chrome #8417Jeremy
KeymasterHi,
AVI files are indeed generally not supported by the
video
element across browsers. The most compatible video format seems to be H.264 (MP4)Jeremy
Jeremy
KeymasterHello,
Apologies for the late reply: I was away from the office for the past two weeks and only catching up with messages now.
it goes to the first video before the middle one. It just shows black screen with play button that u cannot press play and it is stuck at that canvas with the black screen.
This happens when the referenced video is not found: the Video element is printed with its interface, but because no stream can be found, clicking the play button just won’t do anything (since there’s no stream to play). Your script waits until the video has fully played (
getVideo("image1").wait("first")
) before it reaches the line to print the next Image element (newImage("image2", row.middle_picture_s_video)
) which is why the trial is stuck with a blank screen: the video will never have fully played so the script will be stuck on that line (getVideo("image1").wait("first")
)I’m afraid I cannot help more at this point, since the script at https://farm.pcibex.net/r/OFgwcs/ does not match the one from your most recent message, and the URLs referenced in the various
PreloadZip
commands are no longer validNote that you will see a preloading screen (“please wait 1 min”) as long as your experiment uses multimedia objects (images, videos, audios) that take a long time to preload or simply fail to preload (as in the case just mentioned, where no video stream can be found). This is not a bug, it is a feature
Jeremy
September 1, 2022 at 1:50 pm in reply to: difficulties calling getTextInput on elements within the same trial and reg exp #8385Jeremy
KeymasterHi Kavita,
I think those errors came from a previous version of the script, maybe the latest changes failed to be saved when you tested the experiment. When I test the experiment at the link you provided, I see no errors, and same thing if I create a new project and paste the code from your message. Everything behaves as expected, namely clicks on the buttons only validate the
wait
commands if the referenced TextInput element have some text in themAlso, would you recommend putting all GJT items into the experiment trial rather than creating a number of separate GJT items as separate trials?
This is entirely your call, but what I would recommend is try to find some recurring pattern and avoid manually typing repeating commands. For example, if you decide to create separate trials, you could list the details of each trial in a table (say, gjt.csv) and use
Template
, eg:Template( "gjt.csv" , newTrial("experiment", defaultText.center().print() , newText("Instructions", "You will now read a sentence in English and need to judge whether you think the sentence is grammatically correct or not. Here you are not interested in the content or words or punctuation, just the form. After you decide whether the sentence is ungrammatical or not, please indicate for ungrammatical sentences how you would fix them so that they become grammatical.") , newText("Example", "For example, if you read the sentence The cat chased mouse, you would click on the Ungrammatical button and then type a correction into the box: the mouse.") , newText("D1", row.sentence ).bold() // assuming you list the sentences in a column named 'sentence' in gjt.csv , newText("instructions2", "Please type G if you think the above sentence is grammatically correct, U if you think it is not grammatically correct or DK if you don't know:") , defaultTextInput.center().lines(0).size(600,50).log().print() , newTextInput("d1GJT", "") , newText("CorrectionInstruction", "If you think the sentence above is ungrammatical, please fix the grammar mistake by typing the correct form in the box below:") , newTextInput("correctionD1","") , newText("NextPage", "Once you have answered the above questions please click Next below to go to the next question.") , newButton("nextQ", "Next Question") .print() .wait(getTextInput("d1GJT").test.text(/.+/) ) ) )
Jeremy
Jeremy
KeymasterHi,
This is a little tricky indeed, since ideally you’d like to pre-associate each video with a trial based on its running order, so that the first video starts preloading before the second video and so forth, but the running order is randomized
One trick would consist in randomizing the table itself (the one that contains the stim details for the trials) rather than randomizing the trials in the
Sequence
, so that you outputnewTrial
s generated from the randomized table, but with the video references taken from another, non-randomized tableSay you have two CSV files in your project, one named “stims.csv” and one name “videos.csv” (the latter only lists video references in the order in which they are supposed to play). Then you can do something like this:
// we will store the stim details in an array named 'trials' (which we will randomize) var trials = [] // fill 'trials' with each row from stims.csv Template( "stims.csv", row => [ trials.push(row) ] ) // we will successively retrieve each row from 'trials' in 'row' var row // generate trials from video.csv, where row_w points to each of its lines Template( "videos.csv", row_v => newTrial( "trial" , fisherYates(trials), // randomize the array 'trials' row = trials.pop() // move the last entry of 'trials' into 'row' , // write your trial as usual, with 'row' pointing to a random line from 'stims.csv' newText( row.Sentence ).print() , newText( row.Question ).print() , newScale(7).print().wait() , // row_v points to each lines in videos.csv in a non-randomized order newVideo(row_v.Video).print().play().wait() ) )
NB: you might see errors about not finding a column named
_promises
, you can safely ignore those specific errors (they come from the linerow = trials.pop()
which is not very standard syntax)Let me know if you have questions
Jeremy
August 31, 2022 at 2:35 pm in reply to: does the Results file take awhile to update? a few other questions too! #8381Jeremy
KeymasterHi Kavita,
If you haven’t already, I recommend that you read the Basic tutorial and then continue with the Advanced tutorial. The latter explains in section 9.5 that by default results are sent to the server after all trials have completed, and that you can use
SendResults
to send them earlierIf you look at the “Sequence” tab of the debugger when you test your experiment at the demonstration link, you’ll see that you have a total of three trials: the first is labeled “intro”, the second “end” and there is a third trial labeled “null” automatically inserted at the end of the sequence, which is of type “__SendResults__”. The code of the trial labeled “end” finishes with this line
newButton().wait()
, which makes the script wait for a click on the Button element before moving on, but since it is never printed on the page (in the absence of aprint
instruction) it will effectively just prevent the participant from moving on to the next trial. Because that last trial is never executed, and because there was noSendResults
up to that point, the results are just never sent to the serverThe results are sent to separate sets whether you take the experiment at the demonstration link or at the data-collection link. This way, you can test your experiment at the demonstration link, or share it with non-participants (eg. collaborators or reviewers) and not have the results of those runs “pollute” the results that you are actually interested in, the ones from real participants who take your experiment at the data-collection link
Also, I was wondering if there are any examples of trials containing simple untimed grammaticality judgment tests with buttons placed side by side for grammatical, ungrammatical and not sure and with the possibility of entering text indicating corrections below the buttons in one trial (displayed on one screen)?
I don’t think there currently is any publicly available example project of that sort, but this is something that the tutorials were written to help readers code themselves. Section 5.1.2 explains how to manipulate the visual layout so as to align items horizontally, for example (using a Canvas element), and Section 11.2 introduces the TextInput element, which lets the participant freely type in text. Section 9.1 illustrates how you can use a Selector element to keep track of which of several elements (eg. Button elements) was clicked on
If one has multiple questions on one screen (ex. a few textInput and button click items), like one would see in a questionnaire for example, and one simply has .log() under each newTextItem and newButton object in a given trial, would all that info be written to the results file as soon as the trial is over?
The command
log
will add one or several lines to the results file for each element on which it is called (button.log
,textinput.log
). The lines are added to the results as soon as the trial ends, but as explained above, the results are only sent when all the trials have completed, or when an earlySendResults
trial is executedLastly, what does this code I found on one of the documentation files do? what is the ID sent here?
.log( “ID” , GetURLParameter(“id”) ) // Append the “ID” URL parameter to each result lineWhen called after the closing parenthesis of
newTrial()
, thelog
command adds one column to every result line of that trial, where the first parameter oflog
is the new column’s name, and the second parameter is the value. The commandGetURLParameter
retrieves a value from the URL:GetURLParameter("id")
will look forid=VALUE
after?
in the URL and will returnVALUE
. So if the link to your experiment ends with?id=JaneDoe
then.log( "ID" , GetURLParameter("id") )
will add a column to every line of the corresponding trial containingJaneDoe
1. is the Sequence() command at the start necessary?
The two
Sequence
commands in your code are commented out (they are preceded by//
) which means that, as far as the script is concerned, they are just not there. Yet, your experiment can run, which goes to show that it is not necessary to include aSequence
command to run an experiment. In its absence, trials are run in the order in which they are written in the script (top-down). However, inserting your firstSequence
command back in (by removing the preceding//
) would include aSendResults
trial before the trial labeled “end”, which would effectively send the results to the serverif I want to update the progress bar after each trial, should I simply change the last line to the following: .setOption(“countsForProgressBar”, true)?
The progress bar is updated after each trial by default. Adding
.setOption("countsForProgressBar", false)
(as on the closing parenthesis ofnewTrial("end", /* ... */)
in the code you posted) will make the corresponding trial not count for the progress bar. The code that you posted only defines two trials (the one labeled “intro” and the one labeled “end”) but the second one has that line, so there really is only one trial that counts for the progress bar. As a result, at the very beginning of the experiment, the progress bar is empty (no trial is over yet) and after the “intro” trial is over, all the trials that count for the progress bar have ended, so the progress bar is full. If you remove.setOption("countsForProgressBar", false)
then the progress bar will be only half-full when you reach the trial labeled “end”, and will never be completely full, since there is no way for the participant to complete that last trialNB: the Scripts folder of your project at https://farm.pcibex.net/r/Hjdxdc/ contains many js and css files that should not be there (mostly duplicates of the files found in the Aesthetics and Modules folders). I recommend that you click the checkbox to the left of “filter…” under “Scripts” to select all the files, scroll down to main.js to uncheck its own checkbox, and proceed to delete all the selected files (ie. all the files except main.js) by clicking on the trash can icon to the right of “filter…”
Jeremy
August 29, 2022 at 1:47 pm in reply to: How to go automatically from one iamge to next within a row or from one row to #8378Jeremy
KeymasterThe general idea for what you describe could be implemented like this:
newImage("image1", row.main_picture).print(), // Show the image newTimer("displayTime1", 1000).start().wait(), // Wait 1000ms getImage("image1").remove(), // Remove the image newTimer("gap", 400).start().wait() // Wait 400ms , getEyeTracker("tracker").calibrate(5) // Calibrate , newImage("image2", "Neutral.jpg").print(), // Show the image newAudio("audio", row.wav_file).play().wait(), // Play the audio and wait until playback is over getImage("image2").remove(), // Remove the image getTimer("gap").start().wait() // Wait 400ms , newImage("image3", row.end_picture), // Show the image newTimer("displayTime2", 700).start().wait(), // Wait 700ms getImage("image3").remove() // Remove the image
Jeremy
Jeremy
KeymasterHi Pegah,
I currently see 28 submissions for your project. The most recent one was received today (August 29) at 12:42 UTC, so it seems that submissions are actively coming in
Jeremy
August 29, 2022 at 12:21 pm in reply to: How to go automatically from one iamge to next within a row or from one row to #8374Jeremy
KeymasterHi,
Do you mean that each picture should be displayed for 400ms before automatically disappearing, and being replaced with the next picture? What about the middle one, with audio playback: should it also remain on the screen for just 400ms regardless of audio playback, or should it remain on the screen for the whole duration of the audio?
In any case, as long as you have
wait
on a Key element, the script will not move on to the next lines until the participant presses a key. If instead of waiting for a keypress, you want to wait for some time to elapse, then you need to wait for a Timer element instead. For example, you could replace the linenewKey("space", " ").wait(),
withnewTimer("displayTime", 400).start().wait(),
and the first image would remain on the page for 400ms before being removed (because the next command,getImage("image1").remove()
, will only be executed once thewait
command on the Timer element has been completed)Note that if you remove the line
newKey("space", " ").wait(),
then you no longer create a Key element named “space” in your trial, and therefore any future reference to it (getKey("space")
) will consequently result in a reference error (but I presume that you would replace all those Key references anyway, if you want everything to move on automatically rather than upon keypress)Jeremy
August 26, 2022 at 4:05 pm in reply to: Allowing participants to exit and come back to an experiment #8370Jeremy
KeymasterHi,
Unfortunately PCIbex does not offer that function out of the box, so you will need to code it yourself if you want to implement it. There are two main directions you can go, considering that you are running the experiment on your own server: A. store the participant’s progress somewhere on the server and assign them a corresponding unique login ID, or B. generate an encrypted token when they leave that contains the progress information, so you don’t have to store anything on the server’s side
In either case, you would need to be able to restore the experiment the way you want it, including the order of the trials, which maybe you will have randomized, depending on your design. In addition, you might want to store the value of some variables, if you set those during runtime and future trials depend on them (eg. global Var elements)
In any case, this is not a trivial task, and I can only give you general pointers at this point
Jeremy
Jeremy
KeymasterHi,
I am not sure how to answer your question. What does your code currently look like? Are you using native controllers? If so, are you inserting them inside a PennController trial (
newTrial( /* ... */ newController
) or are you using native-Ibex syntax (items = [ [ // ...
)?The code from my previous message is just an example: it generates one (unlabeled) trial where you can read a self-paced sentence once or twice before finishing the trial. You can start a new empty project on the farm and paste the code in the editor just below
PennController.ResetPrefix()
to try itJeremy
Jeremy
Keymasterhow does one know what to put into script to indiviualize it? is just through the documentation provided and sheer practicing skills?
That’s what the tutorial is for: it’s a detailed, step-by-step explanation of the concepts and mechanisms of the script that you can arrange to build your experimental design from scratch. Most experiments are composed of displaying some content on the page and waiting for a timeout or some interaction with the page. The tutorial explains how to display and remove text (
newText
/getText
) and images (newImage
/getImage
) on the page, how to play and stop audio files (newAudio
/getAudio
), how to wait for a given duration (newTimer
/getTimer
) and how to listen to keypresses (newKey
/getKey
) or clicks (newSelector
/getSelector
). Those constitute the vast majority of the building blocks required by almost all experiments. The documentation also lists the existing element types in a dedicated section so you can learn more about how to use them, and maybe look for some that you need in a project but were not familiar with yet (eg. the DropDown element to display drop-down lists)The How-to guides then detail how to go on about frequent, more complex aspects of designing an experiment with PCIbex
Finally, with sufficient knowledge of the script and its mechanisms, reading the code of other experiments helps you discover new ways of implementing various features, without necessarily needing any further documentation
Jeremy
Jeremy
KeymasterIf you haven’t done so yet, I recommend that you read and follow along the Basic tutorial, and then continue with the Advanced tutorial. They are meant to provide you with enough skills that, by the end, you should be able to recreate the project from my previous message, for example
Once you feel comfortable with that, you can read the guide on how to collect eye-tracking data to learn how to incorporate the EyeTracker element in your project
Now, regarding your specific questions:
Do you have example code for the example above?
If you mean this example, you can click on the text “Click here to edit a copy in the PCIbex Farm.” in the top bar to open a copy of the project in the PCIbex Farm, where you will be able to see and edit its code
since its an eyetrackign study. I cant have next button, i think it needs to automatic
It is possible, and even recommended, to have buttons in an eyetracking study. For example, asking participants to click on a button placed at the center of the page before starting a trial is a good way to drag their gaze to the center of the screen
I understand that could be done with the code. newTimer(400).start().wait() I believe
Yes, Timer elements take a number as a parameter that defines their duration, as documented on this page. It is also illustrated in chapter 9 of the Advanced tutorial
Jeremy
-
AuthorPosts