Subscribe

present() with ButtonChooser and maxDuration

  1. 2009-10-22 00:52:01 PDT
    Hi, I came across a problem and would be interested in how to solve this nicely. I have a stimulus, that should be presented exactly 2000 ms and the participant should indicate that s/he has seen the stimuli by pressing SPACE as soon as s/he becomes aware of the object. In the present function, adding a ButtonChooser will not help here as the stimuli is unshown as soon as the participant reacts. Is there a way to show the stimuli for the full 2 secs and record the RT? Thanks, Andrej
  2. 2009-10-22 01:31:27 PDT
    After thinking a little bit about it, I came up with a hack. Looking for a nicer way, I looked into display.py. It seems like almost exactly copied the present function of the Image class. Main difference is, that I got rid of the if-else loop on line 467 - 470, so bc and clk.delay() are now both called. Also, my bc is called with the waitChoice() function. I am somewhat surprised that my code is so close to the original function :) Please let me know if you now other ways how to do that.
  3. 2009-10-22 01:36:35 PDT
    Hi Andrej, I don't have my code with me right now, but for the exact same problem what I did was show the actual text (e.g., "SPACE") with vt.showProportional (where vt is my VideoTrack), and use the present() and buttonchooser with an empty text string. This way I get the RT, but I can separately decide when to remove the text with clk.delay(). I hope that makes sense, if not I'll try and give more details :). ~ Chris
  4. 2009-10-22 01:47:23 PDT
    Hi Chris, that sounds also like it should work fine, maybe with a tiny bit more latency. If you still have the code, could you post it here? I would be interested. Thanks, Andrej
  5. 2009-10-22 09:01:21 PDT
    Hey guys, I had a similar problem that I wanted to solve. I ended up taking a different approach and subclassing Text and Image to create a new [PRESENT_FIXED_DUR function][1]. g [1]: http://pyepl.blogspot.com/2009/10/presenting-stimulus-for-fixed-duration.html
  6. 2009-10-22 15:26:10 PDT
    Nice. I had further trouble, when I wanted to play a beep after a certain amount of time while the ButtonChooser ran with present_fixed _dur(). But I kind of solved this (after trying to implement a new ButtonChooser class for an hour) by having a normal present() chained with a present_ fixed_ dur(), playing the beep in between. So instead of having only audio feedback after a certain time passed, I now have an additional visual feedback aka flicker. It's not a bug, it's a feature. Andrej
  7. 2009-10-30 17:18:11 PDT
    I thought I could give you an update on this: It turned out, that we could not leave it as described as most response would be within the timeframe where the sound is played. I searched for some way to play the sound concurrent with the picture presentation and the ButtonChooser active, but I had no luck. First, I tried using a threading.Timer object, but it would ever play the sound immediately after picture onset or after the picture was shown. Next, I tried to make an own process out of the beep by using multiprocessing.Process. According to the timestamp, it played the sound at the right moment, but I never heard it. As a last resort, I figured that if multithreading and such in python are insufficient to play the sound, I need to try something more basic. Here is the code: def beeper(timeframe): timeframe = float("0." + str(timeframe)) os.system("sleep " + str(timeframe) + " && printf '\a' &") It is very crude and I have problems checking whether the timing is exact enough, but I thought I share this with you. ;) Oh, the timeframe-to-float-to-string is a left over from previous code and will be changed soonish. Andrej
  8. 2009-10-31 06:38:33 PDT
    Hi Andrej: I'm sorry that I did not respond earlier because there is a much easier way to solve this problem. The .present() methods are just convenience functions for displaying a stimulus, but I actually rarely use them in more complex situations and use the core display functions instead that allow me to update the screen when I please. Here's some code (modify to suit): #!/usr/bin/python # get access to pyepl objects & functions from pyepl.locals import * # create an experiment object: # parse command-line arguments # & initialize pyepl subsystems exp = Experiment() exp.setBreak() # Create a VideoTrack object for interfacing # with monitor, and a KeyTrack object for # interfacing with keyboard vt = VideoTrack("video") kt = KeyTrack("key") at = AudioTrack("audio") # reset the display to black vt.clear("black") # create a PresentationClock object # for timing clock = PresentationClock() def fixed_stim_with_response(stim,duration,bc,clock): """Present stim for fixed duration, but getting response anytime in that time range.""" feedback = Text('Pressed!!!') shown = vt.showProportional(stim,.5,.3) onTime = vt.updateScreen(clock) # keep it up for desired time startTime = clock.get() endTime = startTime + duration # get response kret,timestamp = bc.waitWithTime(maxDuration = duration, clock=clock) # give feedback fshown = vt.showProportional(feedback,.5,.7) vt.updateScreen() # no clock needed b/c we want it now if timestamp[0] < endTime: # must still delay a bit clock.delay(endTime-timestamp[0]) # remove the stims vt.unshow(shown,fshown) vt.updateScreen(clock) # return button time and what key return (kret,timestamp) # set up a key chooser for the responses respChooser = kt.keyChooser('SPACE') # set up the stim stim = Text('Press Space!!!') for dur in [1000,2000,3000]: fixed_stim_with_response(stim,dur,respChooser,clock) clock.delay(1000) Text("Done").present(clk=clock,duration=2000) Where I added that feedback you can play sounds or whatever you like... Best, Per
  9. 2009-11-02 10:01:19 PST
    This is actually pretty close to what gregdetre posted: http://pyepl.blogspot.com/2009/10/presenting-stimulus-for-fixed-duration.html However, this does only solve one of my problems. The sound playing problem needs concurrency for the following reason: The sound needs to played at certain time after stimulus onset independent of a button press. It is therefore not a feedback in the classical sense. Here a bit more in detail, why I need this. The participant should press space as soon as they see a change on the screen. Too keep the task interesting, they should only be correct 75% of the time. To do that, I dynamically adjust a variable to which the stimulus onset and the button press is compared to (if (start - bc) > x: ... ). But I need to be able to tell the participant independent of their response, when there response was expected. Therefore, I need to be able to present a sound or feedback WHILE the button chooser is running. From looking into the pyepl code, the ButtonChooser starts a hardware poll event that effectively makes it impossible to issue a another command (Please correct me if I am wrong). Therefore, I need to get either python or pyepl to run two commands at the same time or I need to to issue the feedback command with some other program e.g. the shell. Issuing two consecutive presentations with an attached ButtonChooser does not solve the problem as the majority of the responses will be close to the feedback and therefore there is great chance that neither one of them will catch the actual button press. Andrej
  10. 2009-11-02 18:52:59 PST
    Howdy Andrej: I now finally understand the problem!!! I think a possible solution is to actually use a PyEPL callback, which will actually be called in the event loop. You can pretty much put anything you want in a callback, like start playing a sound at a particular time. Look at the addPollCallback and removePollCallback functions in hardware. There are some examples of their use to play and record sound in the sound.py file. Just be sure and remove the poll callback when you are done :) I can't write example code right now, but feel free to send followup questions if you can't find what you need from what I told you above. Best, Per
  11. 2009-11-02 20:03:45 PST
    Hi Per, thanks for your answer. I will look into this later. A remark on my ugly solution above: I wrote a simple C command that times the shell version and it seems like this works pretty well. the os.system call only adds between 2 and 8 ms to the wanted onset, which should be good enough for sound, but of course is still unwanted. Of course, talking about timing sleep and profiling in general, there are a lot of strings attached. Thank you for giving me some work on this evening ;) Andrej
Jump To:
< Previous | 1 | Next >

Add a Reply

This forum does not allow anonymous participation.

Log in to add a reply. Not registered? Create an account to participate and receive email updates when replies are posted to this topic.