Components and Questionnaires

1,157 views
Skip to first unread message

Chris Hissom

unread,
Jul 30, 2014, 7:46:23 PM7/30/14
to psychop...@googlegroups.com
Hello psychopy users, 

I am very new to psychopy and python as well so please excuse me in advance if my questions are straightforward or intuitive. 

1) I am attempting to create a questionnaire on psychopy for multiple choice questions. For example = What color is the sky? a) blue b)red c)purple d)green. Participants should then click either A,B,C, or D and the next question should appear. I figure I should be able to do this in one trial and have multiple text boxes and multiple key response boxes. My question then is how do I set the conditions so that the first question shows up and ends after keyresp1 has been clicked? What are the start/stop conditions for the 1st text and 1st keyboard and what would be the conditions for the next set? 

2) I currently have one trial in a loop that contains a video and a series of rating scales that appear after the video has appeared. Problem- the loop contains an xlxs file to the 4 videos, however, I would like it to Play one video, have the ratings ( all in the same trial) and then go on to a questionnaire that pertains to the video they just watched--before going on to the next video. In other words, The trial would not repeat until after another trial ended. Is this possible or is there another way to do this? I thought It would work if after the video and ratings participants are asked, what video did you just see? followed by multiple choice answers for the videos ( A)video1 B) Video2 etc... Depending on that response, the trial temporarily stops and goes on to one of the 4 other trials that contain the questionnaire for that video. 

3) I believe that in order for this to work I would have to nest the trials. How would I nest the trials with the conditions given? If I have trial one = video plus rating, trial 2 = Video 1 questionnaire, trial 2= Video 2 questionnaire... etc How can I specify these conditions is the outer loop? 

4) Finely, where might I find a list of the start/stop conditions that can be used, what it is they do, and where it is that they go? 

I sincerely appreciate any help I can get with this. 
-Using windows 
-Psychopy version 1.80.06 

Cheers, 

Christian Jaques Hissom 
University of California, San Diego 
Physiology and Neuroscience, Major  
MARC Scholar 
Intern, UCSD Center for Neural Repair 

 

Michael MacAskill

unread,
Jul 30, 2014, 8:17:20 PM7/30/14
to psychop...@googlegroups.com

On 31/07/2014, at 11:46 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> I am very new to psychopy and python as well so please excuse me in advance if my questions are straightforward or intuitive.
Hi Chris, welcome along.

> 1) I am attempting to create a questionnaire on psychopy for multiple choice questions. For example = What color is the sky? a) blue b)red c)purple d)green. Participants should then click either A,B,C, or D and the next question should appear. I figure I should be able to do this in one trial and have multiple text boxes and multiple key response boxes. My question then is how do I set the conditions so that the first question shows up and ends after keyresp1 has been clicked? What are the start/stop conditions for the 1st text and 1st keyboard and what would be the conditions for the next set?
It helps to give very precise descriptions of what you want to achieve. You talk about clicking either A, B, C, etc, which implies a mouse response, but then elsewhere you seem to mean keyboard responses. These are handled in different ways, as the mouse has a spatial element.

Assuming you do just want keyboard responses, you don't need to do anything to specify stop conditions. Don't specify a duration for the text components, so they will by default last indefinitely. Similarly, don't specify a duration for the keyboard response but do select "force end routine". That means that the text will stay on screen indefinitely, until it immediately disappears when the trial is ended by a key being pressed.

You only need one keyboard component, as there is only one response being given (just specify the valid characters as being A, B, C, and D). You can choose whether you want the text in a single text box, or to split it across multiple ones (no real advantage to the latter unless it is actually mouse presses that you want to locate).

> 2) I currently have one trial in a loop that contains a video and a series of rating scales that appear after the video has appeared. Problem- the loop contains an xlxs file to the 4 videos, however, I would like it to Play one video, have the ratings ( all in the same trial) and then go on to a questionnaire that pertains to the video they just watched--before going on to the next video. In other words, The trial would not repeat until after another trial ended. Is this possible or is there another way to do this? I thought It would work if after the video and ratings participants are asked, what video did you just see? followed by multiple choice answers for the videos ( A)video1 B) Video2 etc... Depending on that response, the trial temporarily stops and goes on to one of the 4 other trials that contain the questionnaire for that video.
Sure, you just have a loop that cycles through a conditions file that contains four rows. One column would be the video filename, others would contain the rating questions and responses, etc.

> 3) I believe that in order for this to work I would have to nest the trials. How would I nest the trials with the conditions given? If I have trial one = video plus rating, trial 2 = Video 1 questionnaire, trial 2= Video 2 questionnaire... etc How can I specify these conditions is the outer loop?
I think you should be clearer about your terminology. i.e. I think you are actually just describing a single trial here (i.e. the presentation of a video followed by several questionnaires). That trial can be composed of several "routines" (the boxes that appear in the flow panel in Builder). i.e. the first routine might play the video, the second routine presents questionnaire 1, etc. So there isn't any real nesting here: you have just a single loop of four iterations, possibly encompassing several routines, each of which will be executed just once per iteration. By nesting, we usually mean loops-within-loops. This can be useful in some situations but probably isn't required here (unless you have a very long list of questions per video).

> 4) Finely, where might I find a list of the start/stop conditions that can be used, what it is they do, and where it is that they go?
Again, don't worry about this. The easiest thing to do might be to split up the different steps in your trial across multiple routines. The first plays the video, for example. Don't specify a duration. That routine should then just end automatically when the video does (which allows for varying length videos across trials). Then on the subsequent questionnaire routines, set the keyboard or rating scale component to have no set duration but also to "force end routine". Again, automatically you get the routine to take care of staying open for exactly as long as required before going on to the next step, all without any work on your part.

Make sense?

Mike



--
Michael R. MacAskill, PhD 66 Stewart St
Research Director, Christchurch 8011
New Zealand Brain Research Institute NEW ZEALAND

Research Fellow, michael....@nzbri.org
Te Whare Wānanga o Otāgo, Otautahi Ph: +64 3 3786 072
University of Otago, Christchurch http://www.nzbri.org/macaskill



Chris Hissom

unread,
Jul 31, 2014, 4:02:09 PM7/31/14
to psychop...@googlegroups.com

Hello Mike, 

Thanks for taking the time to read through my explanation and sorry for the lack of clarity. Yes I do mean a keyboard and not a mouse clicker and thank you for clarifying the difference between trial and routine. I cannot use the "force end routine" because that will end the routine prematurely.

To clarify, I have one routine called "Video and ratings." Within this routine there is a video segment and six rating scales. I used the "variable".status==FINISHED condition to specify that rating scale one comes after movie, rating scale 2 comes after rating scale one...etc.I also clicked on the "disappear" option and unclicked the forceenroutine. only the last rating scale has forceendroutine in order to mark then end of the routine. This routine is set on a loop. however, from what you are saying, it seems it would be best to extend this loop so it contains more routines? 

I could have "videorating" routine end with a question that specifies the next routine to go to-i.e questionnaire r#1. Within this routine, how would I have it so that multiple questions appear sequentially much like I did with the rating scales? If I have one Text box with question 1, another text box with question 2 followed with 13 other text boxes for a total of 15 questions, how do I make it so that after someone responds to question 1 by pressing the B Key, for example, question 2 appears and question 1 disappears? 
- Would I be able to make it one routine with one text box and one keyboard response and have questionnaire#1 in a loop with an excel file that have a column title questions and then in each row contains a question? I tried this and I got an error message so i assumed It cant be done or that there must be a specific way to write the questions in the excel box so that it can be presented.    

Thanks again, 
Chris 

University of California, San Diego 
Physiology and Neuroscience, Major  
MARC Scholar 
Intern, UCSD Center for Neural Repair     

Sure, you just have a loop that cycles through a conditions file that contains four rows. One column would be the video filename, others would contain the rating questions and responses, etc. 
Finely, how would I specify the conditions file on the outer loop. I should have 5 routines, one video and rating routine and 4 questionnaire routines all in one loop? ( I do see that there is no need for nesting)? I think it would only contain the videos to be repeated. Looking at the branching demo I see that a code component is used to end the routine and specify to go to routine a or routine b. 


On Wednesday, July 30, 2014 5:17:20 PM UTC-7, Michael MacAskill wrote:

On 31/07/2014, at 11:46 a.m., Chris Hissom <cjhi...@gmail.com> wrote: 

> I am very new to psychopy and python as well so please excuse me in advance if my questions are straightforward or intuitive. 
Hi Chris, welcome along. 


> 1) I am attempting to create a questionnaire on psychopy for multiple choice questions. For example = What color is the sky? a) blue b)red c)purple d)green. Participants should then click either A,B,C, or D and the next question should appear. I figure I should be able to do this in one trial and have multiple text boxes and multiple key response boxes. My question then is how do I set the conditions so that the first question shows up and ends after keyresp1 has been clicked? What are the start/stop conditions for the 1st text and 1st keyboard and what would be the conditions for the next set? 
It helps to give very precise descriptions of what you want to achieve. You talk about clicking either A, B, C, etc, which implies a mouse response, but then elsewhere you seem to mean keyboard responses. These are handled in different ways, as the mouse has a spatial element. 

Michael MacAskill

unread,
Jul 31, 2014, 6:38:51 PM7/31/14
to psychop...@googlegroups.com

On 1/08/2014, at 8:02 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> To clarify, I have one routine called "Video and ratings." Within this routine there is a video segment and six rating scales. I used the "variable".status==FINISHED condition to specify that rating scale one comes after movie, rating scale 2 comes after rating scale one...etc.I also clicked on the "disappear" option and unclicked the forceenroutine. only the last rating scale has forceendroutine in order to mark then end of the routine. This routine is set on a loop. however, from what you are saying, it seems it would be best to extend this loop so it contains more routines?
If what you have works, stick with it. If it doesn't work, then yes, a simple solution would be a loop which encompasses seven routines (one to play the video and one for each of the six rating scales). That allows you to use the "force end routine".

But having six repeated almost-identical routines isn't great programming practice (I thought the number of scales was lower). An error could easily slip in there somehow. A more "correct" solution would indeed then be to have nested loops.

i.e. you would have just two routines, the video routine and a single rating routine. The *rating routine only* is then surrounded by an inner loop set to iterate 6 times (and which *isn't* connected to a conditions file). Both routines, and this inner loop, are encompassed by an outer loop, which *is* connected to your conditions file.

Your conditions file would have this sort of structure:

video quest1 quest2 quest3 quest4 quest5 quest6
v1.mp4 Boring? Cool? Sad? Cats? Dogs? Happy?
v2.mp4 Boring? Cool? Sad? Cats? Dogs? Happy?
etc

So specifying the movie file is simple, you just put $video in the movie file field of the Movie component.
But you only have one rating scale component, and the variable name there needs to change on every iteration, so we need to construct it in code, taking account of the iteration number.

e.g. in the Scale Description field, if the loop surrounding the rating routine was called "ratings", then you could put in an expression something like this:

$eval("quest" + str(ratings.thisN)) # e.g. evaluate "quest" + "1" as quest1

This concatenates the string "quest" with the current iteration number, and then evaluates the result as a variable name (the beauty of Python…)


> I could have "videorating" routine end with a question that specifies the next routine to go to-i.e questionnaire r#1. Within this routine, how would I have it so that multiple questions appear sequentially much like I did with the rating scales? If I have one Text box with question 1, another text box with question 2 followed with 13 other text boxes for a total of 15 questions, how do I make it so that after someone responds to question 1 by pressing the B Key, for example, question 2 appears and question 1 disappears?
With 15 questions, then I definitely think you want a solution like the one above, with a single routine (with a single text box and single keyboard component, set to "force end routine") within a loop which iterates 15 times. Your conditions file will need another 15 columns to provide for all of those.

> - Would I be able to make it one routine with one text box and one keyboard response and have questionnaire#1 in a loop with an excel file that have a column title questions and then in each row contains a question? I tried this and I got an error message so i assumed It cant be done or that there must be a specific way to write the questions in the excel box so that it can be presented.
In essence yes, but note again that you should just use one Excel file, for the outer loop. That will make your data output at the end of the experiment much more straightforward. The inner loops don't need to be linked to a conditions file: just use the trick of concatenating the current iteration number to a label to refer to columns in that main file.

Make sense?

Regards,

Michael

Chris Hissom

unread,
Aug 1, 2014, 7:07:22 PM8/1/14
to psychop...@googlegroups.com
Michael, 

I have been trying to get this ($eval("quest" + str(ratings.thisN))) suggestion to work but I keep getting the error message that reads "ratings" not defined, even though the outer loop is set to "ratings" as you instructed. I tried changing the"looptype" but this does not work either. However, from my understanding the $ symbol is used for a variable defined in an excel, or other, file. Which means that the "quest" aspect is defined in the excel and that works, but the "ratings" variable is not defined in the excel file. I also tried adding the \$ function before rating --$eval("quest" + str(\$ratings.thisN))-- but this did not work either. 

If this code component works, how would I implement it in the text box? Do I just add it in the "text" box? And is there any style guide to follow for how I write these questions in the excel file? Would I write - "what color is the sky? A)green B)Blue C) Red"... or would I have to write something along the lines of "what_color_is_the_sky?_A)green_B)Blue_C)_Red." ( with or without the " " marks?).

To complicate matters just a little bit more, each video has two questionnaires, one asked per trial. Could I follow the above example and just have a total of 30 columns, the fist 15 titled quest1-15 and then the next 15 titled questA1-15? If I could get this code component to work this would definitely be the best way to go about it for the questions segment. I appreciate your help. 

Best, 
Chris  

Michael MacAskill

unread,
Aug 3, 2014, 6:47:12 PM8/3/14
to psychop...@googlegroups.com

On 2/08/2014, at 11:07 a.m., Chris Hissom <cjhi...@gmail.com> wrote:
> I have been trying to get this ($eval("quest" + str(ratings.thisN))) suggestion to work but I keep getting the error message that reads "ratings" not defined, even though the outer loop is set to "ratings" as you instructed.
That is the problem with sending suggestions without actually testing if they work…
In this case, Builder creates the rating scale object before the loop is created. At that time, the "ratings" loop doesn't exist, so the neither does the variable "ratings.thisN".

> If this code component works, how would I implement it in the text box? Do I just add it in the "text" box?

Yes, the easiest thing to do here is just use another Text stimulus: they are designed to have their content updated on each trial. Now that I think about it, you were probably always actually wanting to do this anyway. So you can just put this in its Text field:
> $eval("quest" + str(ratings.thisN))

Just make sure that you select "set every repeat" rather than "constant", or you will see the same error.

> And is there any style guide to follow for how I write these questions in the excel file? Would I write - "what color is the sky? A)green B)Blue C) Red"... or would I have to write something along the lines of "what_color_is_the_sky?_A)green_B)Blue_C)_Red." ( with or without the " " marks?).
Spaces are fine. Use the escape sequence \n to indicate line breaks, e.g.

What color is the sky? \n A)green \n B)Blue \n C) Red

> To complicate matters just a little bit more, each video has two questionnaires, one asked per trial. Could I follow the above example and just have a total of 30 columns, the fist 15 titled quest1-15 and then the next 15 titled questA1-15? If I could get this code component to work this would definitely be the best way to go about it for the questions segment. I appreciate your help.

Do you mean that each video will be shown twice (once each on separate trials)?

If so, then you want two rows per video in your conditions file, as each row corresponds to a separate trial. I would just keep 15 question columns, but add another column that indicates which type of questionnaire it is. e.g.

video qtype quest1 quest2 quest3 quest4 quest5 quest6
v1.mp4 A Boring? Cool? Sad? Cats? Dogs? Happy?
v1.mp4 B Right? Nope? Blah? Etc? Nice? Next?
v2.mp4 A Boring? Cool? Sad? Cats? Dogs? Happy?
v2.mp4 B Right? Nope? Blah? Etc? Nice? Next?
etc

Regards,

Michael



Chris Hissom

unread,
Aug 4, 2014, 5:37:27 PM8/4/14
to psychop...@googlegroups.com
Michael, 

It worked! Two things I had to change were: 1) the excel file has to begin at quest0 and then on to quest1-14 (it reads the first run as n=0) 2) the text box needs to be set to the inner loop so if the inner loop is ratingsin and outer loop is ratingsout I have to use $eval("quest" + str(ratingsin.thisN))  in order for it to work, if not it repeats quest0 15 times and goes onto quest1 after another full loop. For the rest, it works perfectly. 

One final question: if I write something with python and then want to implement it in the experiment, I would simply use the code component correct? Is there anything I have to do in order for the code to work properly in psychopy?   

Cheers, 

Chris  

Michael MacAskill

unread,
Aug 4, 2014, 6:23:04 PM8/4/14
to psychop...@googlegroups.com

On 5/08/2014, at 9:37 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> Michael,
>
> It worked! Two things I had to change were: 1) the excel file has to begin at quest0 and then on to quest1-14 (it reads the first run as n=0)
I always forget that. You could amend the code to read:

$eval("quest" + str(ratings.thisN + 1))

but you've already found a work-around.

> 2) the text box needs to be set to the inner loop so if the inner loop is ratingsin and outer loop is ratingsout I have to use $eval("quest" + str(ratingsin.thisN)) in order for it to work, if not it repeats quest0 15 times and goes onto quest1 after another full loop.
Yes, spot on.


> One final question: if I write something with python and then want to implement it in the experiment, I would simply use the code component correct?
In essence, yes. The Code component has different tabs so it can place the code where it needs to be executed: e.g. once at the very beginning of the experiment, or at the beginning of a given routine, or on every single screen refresh in that routine.

But as you've seen, you can sometimes place judicious small snippets of code in other components as well.

> Is there anything I have to do in order for the code to work properly in psychopy?
Just try it and see if it does what you want.

Don't be afraid to click the "compile script" button to see what the code looks like, what things are called, and so on (but avoid editing that file directly: it gets regenerated afresh by Builder all the time, so any changes are lost).


Cheers,

Mike



Chris Hissom

unread,
Aug 5, 2014, 3:04:57 PM8/5/14
to psychop...@googlegroups.com
Michael, 

Ill give it a shot. Thanks again for all your help! 

Chris 
Message has been deleted

Michael MacAskill

unread,
Aug 5, 2014, 6:57:17 PM8/5/14
to psychop...@googlegroups.com

On 6/08/2014, at 8:37 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> Michael,
>
> I was going to attempt to write this next part but I think It might be unnecessary and should be feasible with whats available. The end goal is to have it so that a screen appears with a text list of pictures and audio(picture 1, picture 2, audio 1, audio 2- written). When the user presses 1,2,3 or any number that corresponds to either the picture or audio that corresponding file is shown.
You can't use conditions file loops for this. They determine the audio/picture depending on the current row in the condition file. You need it to be determined by a key press from the subject. See below for how to do this.

> The subject can then press any key to return to this original screen. Ideally if they had just pressed 1 for audio 1, that text box would be blurred or have some sort of indication that shows the subject that they have already selected that stimuli. This is to go on for a set duration of time.
To do this, you need to create a separate text component for each line: we can't currently change the attributes of text (e..g colour, font, etc) within a paragraph. You will need to split them up to alter each line as a whole as required.

> What I have so far: 3 routines- Stim selection, picture, audio. Stim selection has a text file that displays the list, a key response and a code component similar to the one used in the branching demo. next the picture routine has the image box and a text box, and the audio routine an audio box and key response.The picture routine is in a loop and the audio routine is in a loop and an outer loop encompass all 3 routines. -Ill attach the example below.
As mentioned, you can't use conditions files here. Just have each inner loop have an nReps specified as a variable.

> I figure I can use a code component similar to the branching demo and set it so that If subjects press numbers 1-5 it goes to the picture routine, if they press numbers 6-10 it goes to the audio. Would I be able to do if resp.keys=='1:5': to indicate that if either 1,2,3,4,or 5 is pressed, the picture routine comes up?

keyRange1 = [str(x) for x in range(1,6)]
keyRange2 = [str(x) for x in range(6,11)]

if resp.keys in keyRange1:
trials3.nReps = 1
trials4.nReps = 0
elif resp.keys in keyRange2:
trials3.nReps = 0
trials4.nReps = 1
else:
# can there be out of range responses?


> If it goes to the picture routine but I only want it to do one trial and then restart the loop, how can I use the nameofloop.finished==true to end that loop after one picture has been shown and return to stim selection, without going to the next routine?
Put a nested loop around the next routine with the number of reps specified by some variable. If you don't want that routine to be executed, set that variable to 0. Otherwise, set it to 1. As above. Don't use loop.finished = true.

> I also tried something along the lines of what was done earlier and created two trials, stim selection and stimuli- for stim selection I had the text box as well as a key responce box and stimuli I had a picture and audio component. I put all this together in one loop and attempted to make the excel file such so that if subjects press 1, the first routine ends and the corresponding image appears in the next routine. Obviously ran into several problems there but If there's a way to make it work, I think this way would be better. My excel file looked something like this:
> keyresp stimuli
> 1 V1.jpg
> 2 V2.jpg
> 3 A1.jpg
>
> The problem with this setup is that each keyresp is set to one trial ( even after I changed them to letters instead of numbers). Meaning if i press 3 during trial 1, it doesn't work.

Exactly. You are going to need to handle this yourself, as you aren't doing things the way Builder is designed to work. A way would be to construct two dictionaries like this, at the beginning of the experiment:

pictureFiles = {'1': 'v1.jpg',
'2': 'v2.jpg',
'3': 'v3.jpg'} # etc
audioFiles = {'6': 'A1.wav',
'7': 'A2.wav',
'8': 'A4.wav'} # etc...

They act as a look-up table, linking key presses to stimulus file names. So you can refer to them in the image or audio components like this:

$pictureFiles[resp.keys]


Mike

Message has been deleted

Chris Hissom

unread,
Aug 5, 2014, 7:35:28 PM8/5/14
to psychop...@googlegroups.com
Michael, 

Woops I deleted the earlier message to update it. Ill attempt these changes tomorrow it might work better than what I tried for today. I managed to use the branching method with the end loop option, also added a component to make the entire sequence of events based on time instead of trials, I was also attempting to add a code component to measure how much time was spent on each stimuli (https://groups.google.com/d/topic/psychopy-users/R7_5ARvLko0/discussion).

Ill try the dictionary method but just to specify, would I introduce the two dictionaries as a code component of the first routine? Also would the next two routines both contain inner loops with variables, no condition file? Would only the outer loop contain the condition file and would that condition file contain the "address" to the image and audio or is this irrelevant if I use the dictionary? If the other two routines are still in loops, how else can I end the loops without using the loop.finished=true? 

To do this, you need to create a separate text component for each line: we can't currently change the attributes of text (e..g colour, font, etc) within a paragraph. You will need to split them up to alter each line as a whole as required. 
 - Given individual text boxes, how can a specify that if 1 was pressed, a polygon component or gratin component appears from then until the end of the experiment? 

Thanks, 
Chris 
Sim_select.psyexp

Michael MacAskill

unread,
Aug 5, 2014, 9:15:21 PM8/5/14
to psychop...@googlegroups.com

On 6/08/2014, at 11:35 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> Ill try the dictionary method but just to specify, would I introduce the two dictionaries as a code component of the first routine?
It doesn't really matter: that code would go in the "Begin Experiment" tab, so wherever the Code component is, that particular code will be executed before any routine starts.

> Also would the next two routines both contain inner loops with variables, no condition file?

Yes. And my code contained a typo, you should probably just go

nRepsV=1
nRepsA=0

etc rather than trials_3.nReps = 0 etc.
> Would only the outer loop contain the condition file and would that condition file contain the "address" to the image and audio or is this irrelevant if I use the dictionary?
To specify these stimuli, *don't use any conditions files at all*. As noted, they can't work the way you need, as they are constrained to give you values only for the current row in that file, whereas you need to be able to select from a list. That is what you are doing by constructing the dictionaries: giving you and the participant the requisite control over the stimulus selection.

> If the other two routines are still in loops, how else can I end the loops without using the loop.finished=true?
As stated, just set the relevant nReps variables to 1 or 0 as required. In fact, you are already doing this in the file you sent through before. This is your own code:

if resp.keys=='1':
nRepsV=1
nRepsA=0
else:
nRepsV=0
nRepsA=1

So you aren't "ending" these loops at all. In a routine *before* the loop, you are specifying whether the loop will run at all. So put this code in the "End routine" tab of a code component on your stimulus selection routine (in fact, exactly where it currently is).


> To do this, you need to create a separate text component for each line: we can't currently change the attributes of text (e..g colour, font, etc) within a paragraph. You will need to split them up to alter each line as a whole as required.
> - Given individual text boxes, how can a specify that if 1 was pressed, a polygon component or gratin component appears from then until the end of the experiment?

You need to maintain variables which track across trialswhether an option has been selected.

Again, perhaps initialise some dictionaries like this at the start of the experiment:

For example, lets say you want to change the text colour on the basis of whether an option has been selected. Initialise all text colours to be white:

picOptions = {'1':'white',
'2':'white',
'3':'white'} #etc

Then in your first text component, put this in the 'colour' field:

$picOptions['1'] # and so on for the others.

Once a response has been made, then you would do this to flip the text colour in a code component for the next time the text is displayed:

picOptions[resp.keys] = 'red' # or whatever.

The same technique could be used with True/False values to control visibility of gratings or whatever you want to use.

Mike




Chris Hissom

unread,
Aug 7, 2014, 4:00:23 PM8/7/14
to psychop...@googlegroups.com
Mike, 

I cant believe this is coming together. Thanks for the help, truly appreciate it. The dictionary works perfectly, save that so far I have:
pictureFiles = {'1': 'V1.jpg', 
                '2': 'V2.png', 
                '3': 'V3.jpg'} # etc 
audioFiles   = {'4': 'A1.wav', 
                '5': 'A2.wav', 
                '6': 'A3.wav'} # etc...  
Just those three in order to get everything sorted out. When the experiment is running if I press 1 then return 2 then return and continue down the line it works perfectly. But If I press 3 or 6 on the first run it ends. Also if I press 1 then return and then 6 it doesn't work.  
If I press 1 then 6 or just 6 
Error reads ( I cant copy the error message from the psychopy output, not sure why, so Ill only write what seems relevant) : image_3setImage(pictureFiles[SS_resp.keys])
Keyerror:6
Exception UnicodeDecode Error: ----

If I press just 3
Error read: 
trials_pic=data.TrialHandler(nReps=nRepsV, method='random', 
NameError: name 'nRepsV' is not defined 
Exception UnicodeDecodeErrror: ...

--I changed some of the titles around to make it more consistent (SS_resp is the same as resp from earlier) 

 Also, the white to red text box works. But how could I make it reset for every trial from an outer loop? the Stimuli_selection segment is nested within the questionnaire segment from earlier. Id like it to end, go back to the video segment and then once it gets to the SS segment, the text boxes should be back to white( they remain red). How can I specify this? 

I added a code component title "timer" that ill add bellow but what Im noticing is that, even though its in a later routine (Stim_select) the code compoenet starts with begging experiment so it starts at the begging of the experiment. 
-Begin Experiment 
timer=core.CountdownTimer() #start a 30 second countdown
timer.add(30)
-End Routine 
if timer.getTime()<0:
 trials_SS.finished=True

If I put the first part of the component on "Begin routine" tab it does not work. How can I make it so that It starts once subjects get to the stim_select segment?   

I'm also trying to implement a code component that will track how long the subject spends on each stimulus all together. If you press 1 and then return and then 1 again, how can I make it so that the total time spent on that stim is recorded? I have been trying with this code component and placing it in the beginning routine tab for the picture_2 routine and Audio_2 routine but I get an error that reads:
trialList=data.importConditions('conditionsVid_final.xlsx'),
raise ImportError, "Conditions file not found: %s' %0s.path.abspath(fileName) 

Thanks again, 
Chris  

Chris Hissom

unread,
Aug 7, 2014, 4:01:27 PM8/7/14
to psychop...@googlegroups.com
E1_MoodnArt10_MAIN_recent.psyexp

Michael MacAskill

unread,
Aug 7, 2014, 5:53:39 PM8/7/14
to psychop...@googlegroups.com

On 8/08/2014, at 8:00 a.m., Chris Hissom <cjhi...@gmail.com> wrote:
> When the experiment is running if I press 1 then return 2 then return and continue down the line it works perfectly. But If I press 3 or 6 on the first run it ends. Also if I press 1 then return and then 6 it doesn't work.
> If I press 1 then 6 or just 6
> Error reads ( I cant copy the error message from the psychopy output, not sure why, so Ill only write what seems relevant) : image_3setImage(pictureFiles[SS_resp.keys])
> Keyerror:6
The problem is this code:

keyRange1 = [str(x) for x in range(1,3)]
keyRange2 = [str(x) for x in range(4,6)]

Look up how the range() function in Python works. e.g. range(1,3) returns [1, 2]. So the lists you are generating are missing their final values. So you need:

keyRange1 = [str(x) for x in range(1,4)]
keyRange2 = [str(x) for x in range(4,7)]

> trials_pic=data.TrialHandler(nReps=nRepsV, method='random',
> NameError: name 'nRepsV' is not defined
This is probably caused by the same thing: nRepsV was never defined because the key pressed was not in either of the defined lists. This error should disappear if you fix the above.


> Also, the white to red text box works. But how could I make it reset for every trial from an outer loop? the Stimuli_selection segment is nested within the questionnaire segment from earlier. Id like it to end, go back to the video segment and then once it gets to the SS segment, the text boxes should be back to white( they remain red). How can I specify this?
What you want is to have some code that executes at the beginning of a loop (to reset the values to white). Unfortunately, there is no tab in the Code component for that (there are slots for the beginning of the experiment, beginning of a routine, and so on, but not for the beginning of a loop).

I'm a little lost as to which loop is which, so will leave you to figure out the details. But in essence, put some code in a Begin Routine tab, but check to see if the relevant loop is on its first trial. If so, reset all the values to white. e.g.

if relevantLoopName.thisN == 0: # on first iteration of loop only
picOptions = {'1':'white',
'2':'white',
'3':'white',
'4':'white',
'5':'white',
'6':'white'}


>
> I added a code component title "timer" that ill add bellow but what Im noticing is that, even though its in a later routine (Stim_select) the code compoenet starts with begging experiment so it starts at the begging of the experiment.
> -Begin Experiment
> timer=core.CountdownTimer() #start a 30 second countdown
> timer.add(30)
> -End Routine
> if timer.getTime()<0:
> trials_SS.finished=True
>
> If I put the first part of the component on "Begin routine" tab it does not work. How can I make it so that It starts once subjects get to the stim_select segment?
"It does not work" is a bit vague to help with. In essence, though, I would suggest creating objects only once. This should happen at the beginning of the experiment:

timer=core.CountdownTimer(30.0)

That object will start counting down immediately, but that is OK. You just reset it at the start of the desired routine:

timer.reset()


Chris Hissom

unread,
Aug 7, 2014, 8:34:47 PM8/7/14
to psychop...@googlegroups.com
Mike, 

Sorry fo the lack of specificity. The "doesnt work" meant that If i put that code component in the Begin routine tab, it would not register and continue past the desired time. What I did is that I added  timer.recet(30) in a routine just prior to the stim select segment. thus the timer it reset to 30s just before the stim select loop begins and left the original code components in the stim select segment. 

I had changed the 3 to 4 on the dictionary code earlier but I would have not though about changing the 6 to a 7 and that seems to have done the trick. I also added the if relevant loop code component and It works perfectly. the list is reset to white the next time around. 

The last bit would be how to make it so that each time a subject selects 1 that time is recorded as a total time? 

Thanks, 
Chris 

Michael MacAskill

unread,
Aug 7, 2014, 9:46:17 PM8/7/14
to psychop...@googlegroups.com

On 8/08/2014, at 12:34 p.m., Chris Hissom <cjhi...@gmail.com> wrote:

> The last bit would be how to make it so that each time a subject selects 1 that time is recorded as a total time?

Again, you could initialise a dictionary like this (it might need to be done in the same way as for the text colours so that it resets to zero when needed, or are you trying to collate this info across loops?):

totalTimes = {'1': 0,
'2': 0,
'3': 0} # etc

Then at the end of the relevant stimulus routine, put some code like this to keep a running total:

totalTimes[resp.keys] = totalTimes[resp.keys] + whatever timer value you are using

This info is just a variable held in memory, though. It will disappear unless you explicitly commit it to the saved data file.

Adding info to the current row of the data is generally quite easy, e.g:

thisExp.addData("Stimulus durations", totalTimes)

But the tricky bit will be figuring out when to do that giving the complexity of your loops. I'm not sure what the structure of your output data will be. Make sure you test that and ensure that everything you need is being output, and in the right rows.

Cheers,

Michael

Chris Hissom

unread,
Aug 8, 2014, 6:27:59 PM8/8/14
to psychop...@googlegroups.com
Michael, 

I have tried every permutation of the word "seconds" to use as  "whatever timer value you are using" and I keep getting a seconds not defined error. I have tried also using -totalTimes[SS_resp.keys] = totalTimes[SS_resp.keys] + SS_resp.rt in the picture_2 routine as a code component in the end routine tab. and 
totalTimes[SS_resp.keys] = totalTimes[SS_resp.keys] + key_V.rt and I get output but not the output I'm looking for. 
SS_resp- leads to the 1-7 dictionary for stimuli and Key_V.rt should be the reaction time that relates to the end routine key response akin to the picture stim routine. 
Is there a way I could specify for it to record the duration of time spent on that routine (picture_2) or perhaps better would be the duration of the picture "image_3." This would be better because the subjects could decide not to press the return key. If the don't press return, after 10s the routine will end. 

Thanks, 
Chris 

Michael MacAskill

unread,
Aug 10, 2014, 12:24:24 AM8/10/14
to psychop...@googlegroups.com

On 9/08/2014, at 10:27 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> I have tried every permutation of the word "seconds" to use as "whatever timer value you are using" and I keep getting a seconds not defined error.
Like PsychoPy, I don't know what you mean by "seconds" here either?

> I have tried also using -totalTimes[SS_resp.keys] = totalTimes[SS_resp.keys] + SS_resp.rt in the picture_2 routine as a code component in the end routine tab. and
> totalTimes[SS_resp.keys] = totalTimes[SS_resp.keys] + key_V.rt and I get output but not the output I'm looking for.
> SS_resp- leads to the 1-7 dictionary for stimuli and Key_V.rt should be the reaction time that relates to the end routine key response akin to the picture stim routine.
We need more detail here: "not the output I'm looking for" doesn't give us anything to go on. I wasn't sure exactly what time you wanted, which is why I suggested "whatever timer value you are using".

Describe exactly what time or duration you *do* want to measure.

> Is there a way I could specify for it to record the duration of time spent on that routine (picture_2) or perhaps better would be the duration of the picture "image_3." This would be better because the subjects could decide not to press the return key. If the don't press return, after 10s the routine will end.

The current time in any routine is given by:
trialClock.getTime()

If code is executing at the end of a routine, then that will give you the duration of that current routine, regardless of how it came to end.

I don't know the logic of your routine or whether the image can de displayed for less than the total duration of the routine. You'll need to figure that out.

Michael




Chris Hissom

unread,
Aug 13, 2014, 6:44:15 PM8/13/14
to psychop...@googlegroups.com
Hello Michael, 

Ill copy and past what the output on the data sheet looks like. In this run, I only pressed 1. I pressed the key multiple times and each time I stayed on that page for about 5s and the hit return. Other times I let the trial run the full 10s. Yet the data does not match my time. In essence, Id like to see something that shows that key 1 got a total time of 35s. Even though I went back and forth. So it would have to take the time from when 1 was pressed until the end or that trial or until the return key is pressed. 

I also tried the trialClock.gettime() as a code component and got a "its not defined" error.  based on this, what should I add to the second part (X) of this code component totalTimes[resp.keys] = totalTimes[resp.keys] + X?

SS_resp.rt key_V.keys key_V.rt Stimulus durations rating.response rating.rt
1.311286 return 1.43337 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.713313 return 1.105121 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.260735 return 1.102262 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.080204 return 1.335193 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.246879 return 1.368798 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.363318 return 4.650271 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.396744 return 3.199618 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.529797 return 2.933965 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.030043 return 2.301106 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}
1.396742 return 3.017356 {'1': 0, '3': 0, '2': 0, '5': 0, '4': 0, '6': 0}

Thanks again Michael, 

Chris 

Michael MacAskill

unread,
Aug 13, 2014, 8:50:17 PM8/13/14
to psychop...@googlegroups.com

On 14/08/2014, at 10:44 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> I also tried the trialClock.gettime() as a code component and got a "its not defined" error. based on this, what should I add to the second part (X) of this code component totalTimes[resp.keys] = totalTimes[resp.keys] + X?

We can't guess without seeing *exactly* what you have in the Code component and *exactly* what the error is. Please paste both of those pieces of information directly into your e-mail. For example, what you typed above has a case error (gettime should be getTime). That could cause this error but I don't know if that was actually part of the code you were using or just what you typed into your e-mail.

Regards,

Michael



Chris Hissom

unread,
Aug 14, 2014, 5:45:21 PM8/14/14
to psychop...@googlegroups.com
Michael, 

For some reason I cannot copy and past the error message. Instead I took a screen shot. I also added some extra information. Hope it helps. 

Cheers,
Chris 
E1_MoodnArt10_MAIN4_timetot.psyexp
Code-E1_MoodnArt10_MAIN4_timetot.py
Picture_2_codecomp.PNG
Picture_2_routine.PNG
Stim_select_codecomp.PNG
Stim_select_routine.PNG
audio_routine.PNG
error.PNG

Michael MacAskill

unread,
Aug 14, 2014, 9:30:22 PM8/14/14
to psychop...@googlegroups.com
Hi Chris,

That level of detail is great. It seems that I put you wrong. Each routine gets its own named clock, so your expressions should look like this:

totalTimes[resp.keys] = totalTimes[resp.keys] + picture_2Clock.getTime()

or

totalTimes[resp.keys] = totalTimes[resp.keys] + audio_2Clock.getTime()


as appropriate for the code component in each routine.

Hope that works for you.

Cheers,

Mike

Chris Hissom

unread,
Aug 27, 2014, 6:35:40 PM8/27/14
to psychop...@googlegroups.com
Hello Mike, 

I tried this code component and got an error message. Ill send the error and the code components also showing in which routine they are. I have also noticed that when I add more pictures and audio to this list, I will eventually need to use two digit numbers (10,11,12...). I was thinking of specifying using 01 from the start and have it recognize two digit commands instead. Would this work? 

Thanks, 

Chris  
Capture.pic2code.PNG
Capture.error.PNG
Capture.pic2code.PNG
CaptureStimsel.code.PNG
Capture.aud2.code.PNG

Michael MacAskill

unread,
Aug 27, 2014, 8:44:14 PM8/27/14
to psychop...@googlegroups.com
Dear Chris,

A key error means that you are trying to access an entry in a dictionary that doesn't exist. I think the keys in your dictionary were supposed to be strings representing the numbers from '1' to '5' or something like that.

I have no idea what SS_resp represents, but whenever it is, it doesn't seem to exist in the totalTimes dictionary.

To debug, this, put some extra code immediately before this line:

totalTimes[SS_resp] = totalTimes[SS_resp] + picture_2Clock.getTime()

i.e.

print(totalTimes)
print(SS_resp)
print(type(SS_resp))
totalTimes[SS_resp] = totalTimes[SS_resp] + picture_2Clock.getTime()

Michael

Michael MacAskill

unread,
Aug 27, 2014, 9:00:27 PM8/27/14
to psychop...@googlegroups.com

On 28/08/2014, at 12:43 p.m., Michael MacAskill <michael....@otago.ac.nz> wrote:

> I have no idea what SS_resp represents, but whenever it is, it doesn't seem to exist in the totalTimes dictionary.

OK, looking at that error again, you are passing a whole keyboard response component to the dictionary rather than just the key that was actually pressed. If you look at the code I originally sent, it was:

totalTimes[resp.keys] = totalTimes[resp.keys] + audio_2Clock.getTime()

The ".keys" bit is important. i.e. "resp" is the name of the keyboard component. "resp.keys" gives you just the key it actually detected, e.g. '1' etc. The totalTimes dictionary is constructed using those values. Anything else isn't going to work.

So at a guess, your code should be:
totalTimes[SS_resp.keys] = totalTimes[SS_resp.keys] + picture_2Clock.getTime()

rather than:

Chris Hissom

unread,
Aug 28, 2014, 11:49:35 AM8/28/14
to psychop...@googlegroups.com
Hello Michael, 

It works! I thought .keys was just part of the name of the component but it did the trick. I put the dictionary under the "begin routine" tab and Im able to get the total time spent on each stimuli per loop. Now I just need to figure out how to make it so I can have a list with more than 9 selections. 

Thanks for all your help, 

Chris  

Chris Hissom

unread,
Aug 28, 2014, 1:44:02 PM8/28/14
to psychop...@googlegroups.com
Michael, 

I just double checked and it works but not exactly. If I place the dictionary under the "begin experiment" tab, I get the total time spent on each stimuli per experiment. If I place it under the "begin routine" I get the time spent on each stimuli per routine. How could I get the output to show time spent on stimuli per loop? I was think us leaving the dictionary in the "begin experiment" tab and then have it reset every loop. Would something along the lines of totalTime.reset() work? 

Cheers, 
Chris  

Michael MacAskill

unread,
Aug 28, 2014, 7:07:28 PM8/28/14
to psychop...@googlegroups.com
Hi Chris,

As you've found, the Code component has tabs for "Begin Experiment" and "Begin Routine" but not "Begin Loop" (there's a reason for that, as a routine can be within any number of loops).

So what you want to do is put a check before code in the "Begin Routine" tab so that it only gets executed on the first iteration of the loop. e.g. if your loop is called "trials", then do this:

# create/reset the dictionary only at the beginning of the loop:
if trials.thisN == 0:
totalTime = {'1':0, '2':0} # etc

Regards,

Michael



On 29/08/2014, at 5:44 a.m., Chris Hissom <cjhi...@gmail.com> wrote:

> Michael,
>
> I just double checked and it works but not exactly. If I place the dictionary under the "begin experiment" tab, I get the total time spent on each stimuli per experiment. If I place it under the "begin routine" I get the time spent on each stimuli per routine. How could I get the output to show time spent on stimuli per loop? I was think us leaving the dictionary in the "begin experiment" tab and then have it reset every loop. Would something along the lines of totalTime.reset() work?
>
> Cheers,
> Chris

--
Michael R. MacAskill, PhD 66 Stewart St
Research Director, Christchurch 8011
New Zealand Brain Research Institute NEW ZEALAND

Research Fellow, michael....@nzbri.org
Te Whare Wānanga o Otāgo, Otautahi Ph: +64 3 3786 072
University of Otago, Christchurch http://www.nzbri.org/macaskill



Chris Hissom

unread,
Aug 29, 2014, 12:05:27 PM8/29/14
to psychop...@googlegroups.com
Hi Michael, 

Thats it. Thanks again!

Chris 

Chris Hissom

unread,
Sep 2, 2014, 9:32:15 PM9/2/14
to psychop...@googlegroups.com
Hello Michael, 

I started a new thread asking about making a keyboard selection for numbers greater than 9. Please let me know if you might be able to help me answer this question.
https://groups.google.com/forum/#!topic/psychopy-users/7cQEXwfA0o4

Thanks, 
Chris 
Reply all
Reply to author
Forward
0 new messages