PennController for IBEX › Forums › Support › Counterbalancing issues
- This topic has 2 replies, 3 voices, and was last updated 2 years, 4 months ago by MiekeS.
-
AuthorPosts
-
April 20, 2022 at 9:13 am #8083MiekeParticipant
Demonstration link to the experiment: https://farm.pcibex.net/r/DcVgRE/
Hi Jeremy,
I’m working on an experiment that involves the presentation of four images on each trial (which are presented on the screen with accompanying audio files, e.g., ‘here’s one cheetah’). These four pictures depict (1) the correct agent of the test sentence, (2) a foil agent, (3) the correct theme, and (4) a foil theme. The position in which these pictures appear on the screen vary: The agent-related pictures are always in the top two quadrants (but it differs whether the correct one is on the left or right), and the theme-related pictures are always in the bottom two quadrants (but again, it differs whether the correct one is on the left or right). This yields the following four possible displays:
A. (clockwise from top-left): CorAgent, FoilAgent, CorTheme, FoilTheme
B. (clockwise from top-left): FoilAgent, CorAgent, CorTheme, FoilTheme
C. (clockwise from top-left): CorAgent, FoilAgent, FoilTheme, CorTheme
D. (clockwise from top-left): FoilAgent, CorAgent, FoilTheme, CorThemeI would like to randomise order of these display configurations across trials: They all need to appear an equal number of times (balanced across filler sentences, of which there are 24, and target sentences, of which there are 12). I did this was by first defining a list that specifies the total number in which each display appears, which is then randomised:
FillerDisplays = ["A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "D"].sort(v=>Math.random()-Math.random()); TargetDisplays = ["A", "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D"].sort(v=>Math.random()-Math.random());
Then, in each trial, I use two variables (
nTarget
andnFiller
) to ‘loop’ over these lists and specify the display configuration (A, B, C, or D) in another variable (“Display”
). This variable, in turn, is used to generate the displays, in the following way:getVar("Display").log() .test.is("A").success( // Display configuration 1 (clockwise from top-left): CorAgent, FoilAgent, CorTheme, FoilTheme newImage("Topleft_image", row.CorAgent) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 25%") , newImage("Topright_image", row.FoilAgent) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 25%") , newImage("Bottomright_image", row.CorTheme) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 75%") , newImage("Bottomleft_image", row.FoilTheme) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 75%") , newAudio("Topleft_audio", row.CorAgent_sound) , newAudio("Topright_audio", row.FoilAgent_sound) , newAudio("Bottomright_audio", row.CorTheme_sound) , newAudio("Bottomleft_audio", row.FoilTheme_sound) , newText("Display A") // <- for testing purposes only .print() ) .test.is("B").success( // Display configuration 2 (clockwise from top-left): FoilAgent, CorAgent, CorTheme, FoilTheme newImage("Topleft_image", row.FoilAgent) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 25%") , newImage("Topright_image", row.CorAgent) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 25%") , newImage("Bottomright_image", row.CorTheme) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 75%") , newImage("Bottomleft_image", row.FoilTheme) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 75%") , newAudio("Topleft_audio", row.FoilAgent_sound) , newAudio("Topright_audio", row.CorAgent_sound) , newAudio("Bottomright_audio", row.CorTheme_sound) , newAudio("Bottomleft_audio", row.FoilTheme_sound) , newText("Display B") // <- for testing purposes only .print() ) .test.is("C").success( // Display configuration 3 (clockwise from top-left): CorAgent, FoilAgent, FoilTheme, CorTheme newImage("Topleft_image", row.CorAgent) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 25%") , newImage("Topright_image", row.FoilAgent) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 25%") , newImage("Bottomright_image", row.FoilTheme) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 75%") , newImage("Bottomleft_image", row.CorTheme) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 75%") , newAudio("Topleft_audio", row.CorAgent_sound) , newAudio("Topright_audio", row.FoilAgent_sound) , newAudio("Bottomright_audio", row.FoilTheme_sound) , newAudio("Bottomleft_audio", row.CorTheme_sound) , newText("Display C") // <- for testing purposes only .print() ) .test.is("D").success( // Display configuration 4 (clockwise from top-left): FoilAgent, CorAgent, FoilTheme, CorTheme newImage("Topleft_image", row.FoilAgent) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 25%") , newImage("Topright_image", row.CorAgent) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 25%") , newImage("Bottomright_image", row.FoilTheme) .log() .size("30vw", "30vh") .print("center at 75%", "middle at 75%") , newImage("Bottomleft_image", row.CorTheme) .log() .size("30vw", "30vh") .print("center at 25%", "middle at 75%") , newAudio("Topleft_audio", row.FoilAgent_sound) , newAudio("Topright_audio", row.CorAgent_sound) , newAudio("Bottomright_audio", row.FoilTheme_sound) , newAudio("Bottomleft_audio", row.CorTheme_sound) , newText("Display D") // <- for testing purposes only .print() )
However, I’ve been struggling a lot to get this to work. A previous version of this code worked, but then I must have done something to break it. In its current form, it can generate display A correctly, but not any of the others. However, it does print ‘Display B’, ‘Display C’ or ‘Display D’ on each trial, suggesting that the does correctly specify the Display variable. I must be missing something (potentially something stupid), but I’ve not been able to locate my mistake.
By the way, as you can see in the demonstration link, I’ve left out quite some script. In the actual experiment, people need to drag the correct images onto the robot that is presented in the center of the screen, but in this testing script, I’ve commented the DragDrop element out.
I’m curious if you have any idea about what’s going wrong!
Best,
MiekeApril 20, 2022 at 11:43 am #8088JeremyKeymasterHi Mieke,
As reported in the Errors tab of the debugger, you are creating multiple Image elements with the same name, which causes problems when you refer back to them later (eg.
getImage("Topleft_image").visible()
). See explanations hereHere is a possible solution, let me know if it works as you expect:
FillerDisplays = ["A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "D"]; TargetDisplays = ["A", "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D"]; fisherYates(FillerDisplays) fisherYates(TargetDisplays) DisplayMap = { A: {TopLeft: "CorAgent", TopRight: "FoilAgent", BottomRight: "CorTheme", BottomLeft: "FoilTheme"}, B: {TopLeft: "FoilAgent", TopRight: "CorAgent", BottomRight: "CorTheme", BottomLeft: "FoilTheme"}, C: {TopLeft: "CorAgent", TopRight: "FoilAgent", BottomRight: "FoilTheme", BottomLeft: "CorTheme"}, D: {TopLeft: "FoilAgent", TopRight: "CorAgent", BottomRight: "FoilTheme", BottomLeft: "CorTheme"} } Template("trials.csv", row => newTrial("Trials", defaultImage.hidden() , newVar("dropped", 0) , newFunction( ()=> $("body").css({width: '100vw',height: '100vh'}) ).call() , getVar("nTrials") .log() .test.is(18) .success( newHtml("HalfWay", "Halfway.html") .center() .cssContainer({"width":"720px"}) .print("center at 50%", "middle at 50%") , newButton("continue", "Continue to the next trial") .center() .print("center at 50%", "middle at 80%") .wait() , fullscreen() , clear() ) , newFunction( ()=> $("body").css('cursor','none') ).call() , newImage("Al", "Al.png") .size("15vw", "20vh") .print("center at 50%", "middle at 50%") , newImage("Speaker", "speaker_green.png") .size("7vw", "7vw") .print("center at 50%", "middle at 50%") , newAudio("TestSentence", row.TestSentence) , displayGroup = (row.StimulusType=="Target"?TargetDisplays.pop():FillerDisplays.pop()) , defaultImage.log().size("30vw","30vh") , newImage("Topleft_image", row[DisplayMap[displayGroup].TopLeft]).print("center at 25%", "middle at 25%") , newImage("Topright_image", row[DisplayMap[displayGroup].TopRight]).print("center at 75%", "middle at 25%") , newImage("Bottomright_image", row[DisplayMap[displayGroup].BottomRight]).print("center at 75%", "middle at 75%") , newImage("Bottomleft_image", row[DisplayMap[displayGroup].BottomLeft]).print("center at 25%", "middle at 75%") , newAudio("Topleft_audio", row[DisplayMap[displayGroup].TopLeft+"_sound"]) , newAudio("Topright_audio", row[DisplayMap[displayGroup].TopRight+"_sound"]) , newAudio("Bottomright_audio", row[DisplayMap[displayGroup].BottomRight+"_sound"]) , newAudio("Bottomleft_audio", row[DisplayMap[displayGroup].BottomLeft+"_sound"]) , newText("Display_"+displayGroup).print() , getImage("Al").visible() , newAudio(IntroSentence[Math.floor(Math.random() * 3)]).play().log().wait() , getImage("Topleft_image").visible() , getAudio("Topleft_audio").play().log().wait() , newTimer(300).start().wait() , getImage("Topright_image").visible() , getAudio("Topright_audio").play().log().wait() , newTimer(300).start().wait() , getImage("Bottomright_image").visible() , getAudio("Bottomright_audio").play().log().wait() , newTimer(300).start().wait() , getImage("Bottomleft_image").visible() , newAudio(And[Math.floor(Math.random() * 12)]).play().log().wait() , getAudio("Bottomleft_audio").play().log().wait() , newTimer(500).start().wait() , getImage("Al").hidden() , newTimer(200).start().wait() , getImage("Speaker").visible().log() , getAudio("TestSentence").play().log().wait() , newTimer(200).start().wait() , getImage("Speaker").hidden().log() , getImage("Al").visible().log() , newKey(" ").wait() , clear() , getVar("nTrials").set( v => v+1) // increase nTrials ) .log("Quantifier", row.Quantifier) .log("Version", row.Version) .log("Item", row.Item) .log("StimulusType", row.StimulusType) .log("Group", row.Group) .log("Sentence", row.Sentence) .log("Verb", row.Verb) .log("CorAgent", row.CorAgent) .log("FoilAgent",row.FoilAgent) .log("CorTheme",row.CorTheme) .log("FoilTheme",row.FoilTheme) .log("TestSentence",row.TestSentence) .log("CorAgent_sound",row.CorAgent_sound) .log("FoilAgent_sound",row.FoilAgent_sound) .log("CorTheme_sound",row.CorTheme_sound) .log("FoilTheme_sound",row.FoilTheme_sound) .log("DisplayGroup", displayGroup) )
Jeremy
May 19, 2022 at 3:01 pm #8194MiekeSParticipantHey Jeremy,
My apologies for replying a month later! This fix worked perfectly, thank you again for your great help 🙂
-
AuthorPosts
- You must be logged in to reply to this topic.