Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[solved] Eye-Tracking Experiment Question - Gaze Contingent Stimuli Presentation

edited October 2013 in OpenSesame

Hey guys,

I want to get some guidance on how to implement an eye-tracking paradigm in which stimuli are presented for a free viewing period for three seconds, and stimuli presentation does not continue until the participant fixates on a particular image (i.e., for 100 ms). After this point, the stimuli on the opposite side of the screen appears with a shape wrapped around it and the participant must look at it and press a key indicating what kind of shape it is. I have a few questions:

First, regarding the wait_for_fixation_start function: how is a fixation defined? Can I modify it so a fixation is considered to be greater than or equal to 100 ms?

Second, can the wait_for_fixation_start function be modified to wait for not just any fixation, but for a fixation within a specific region of interest on the screen (i.e., one of the images)? Or must I use an inline script and the sample function in some sort of loop to wait for the eyes to linger in a specified part of the screen for 100ms?

Third, with regard to interest area creation for an ellipse, do the two (x,y) coordinate pairs specified in the command refer to the top/height parts of the ellipse or the side/width parts of the ellipse? I want to specify interest areas for my oval-shaped face stimuli. Also, is there a way to test the actual area covered by the interest area in terms of screen coordinates so I can make sure it's covering the area I think it's covering?

Thanks again for all of your help!

-Ricky

Comments

  • edited 10:48PM

    Hi Ricky,

    First, regarding the wait_for_fixation_start function: how is a fixation defined?

    The wait_for_fixation_start() function, and the other wait_for_[X] functions, simply use the EyeLink's internal event detection algorithms. These are described in the EyeLink manual (in the section The EyeLink On-Line Parser). However, it appears that only the saccade detection algorithm is described and not the fixation detection. (They are not exactly the inverse of each other, as you might think.) So if you want to know the exact algorithm, I would post a question on the SR Support forum.

    Can I modify it so a fixation is considered to be greater than or equal to 100 ms?

    Well... aside from the point above, you cannot really detect the start of a fixation based on how long the fixation will last, right? You can filter fixations afterwards based on duration, of course, either online or during the analysis.

    Second, can the wait_for_fixation_start function be modified to wait for not just any fixation, but for a fixation within a specific region of interest on the screen (i.e., one of the images)? Or must I use an inline script and the sample function in some sort of loop to wait for the eyes to linger in a specified part of the screen for 100ms?

    You will indeed need to implement this with an inline_script. This isn't very difficult though, and feel free to post specific questions here.

    Third, with regard to interest area creation for an ellipse, do the two (x,y) coordinate pairs specified in the command refer to the top/height parts of the ellipse or the side/width parts of the ellipse? I want to specify interest areas for my oval-shaped face stimuli. Also, is there a way to test the actual area covered by the interest area in terms of screen coordinates so I can make sure it's covering the area I think it's covering?

    I assume you are talking about this line from the tutorial:

    self.experiment.eyelink.log(“!V IAREA ELLIPSE 2 300 200 400 300 target”)
    

    I believe the numbers reflect (x1, y1, x2, y2). So the second pair (400, 300) are coordinates, and not dimensions. However, specifying ROIs in this way is actually specific for the EyeLink DataViewer. To OpenSesame, this is just an arbitrary message that is written to the .edf file. To find out exactly which commands you can send, and how they are interpreted by the DataViewer, I would refer to the DataViewer manual, again available from the SR Support forum.

    Cheers!
    Sebastiaan

  • edited September 2013

    Hey Sebastian,

    Thanks for the useful info. I've got an algorithm in mind to do what I need and I wanted to run it by you.

    First, I'm going to use an inline script to enable fixation updates at 100ms so I can detect fixation duration in the target area in real-time before moving forward with stimuli presentation. I have a script with the following commands that is executed after calibration.


    -Enable fixation updates

    -Enable writing of fixation update events to .edf

    self.experiment.eyelink.send_command("file_event_filter = LEFT,RIGHT,FIXATION,FIXUPDATE,SACCADE,BLINK,MESSAGE,BUTTON")

    -Enable sending of fixation updates over link for use in experiment to guide stimuli presentation

    self.experiment.eyelink.send_command("link_event_filter = LEFT,RIGHT,FIXATION,FIXUPDATE,SACCADE,BLINK,BUTTON")

    -Make fixation update interval 100ms

    self.experiment.eyelink.send_command("fixation_update_interval = 100")
    self.experiment.eyelink.send_command("fixation_update_accumulate = 100")


    The above scripts runs, but FIXUPDATE events don't seem to appear in the .edf output. Should I be changing the .py files directly, or should the above inline script code suffice?

    Below is an algorithm I think will do what I need. At a specified time during the experiment, the program waits for the user to fixate for at least 100ms on a predefined oval area of the screen (either the left or right, depending upon trial type). Once this happens, stimuli presentation continues. Below is code I think will do the job.


    -Await fixation on target stimuli

    -Set fixation flag to false

    fixated = false

    self.experiment.eyelink.log("Starting wait for fixation period")

    while fixated = false:

    -wait for the beginning of a fixation and get the coordinates
    -I'm unsure here how to store the x,y gaze coord data that the wait_for_fixation_start function returns?

    start_pos = wait_for_fixation_start()

    -fixate_on is a trial variable that indicates whether the left or
    right side of the screen has the target stimuli for this particular trial

    if fixate_on = "left":

    -use formula for an ellipse to see if the fixation is inside the target
    -ctrx and ctry are the center points of the left ellipse stimuli, a and b are
    the width and height dimensions

    if (((start_pos.x - ctrx)^2/a^2) + ((start_pos.y - ctry)^2/b^2)) <=1:

    -Fixation position is inside image

    -I'm not sure how to get the coordinates out of the float_data
    from the fixation update event?

    data = wait_for_event("pylink.FIXUPDATE")

    -Make sure that at the end of the 100ms fixation update the
    gaze is still in the target ellipse image

    if (((data.x - ctrx)^2/a^2) + ((data.y - ctry)^2/b^2)) <= 1:

    fixated = true

    else:

    -do the same thing as above only the ctrx and ctry coords are for the right ellipse stimuli


    I'm not sure if the second coordinate check after the update event is necessary, but the manual suggests that it will send an update at the end of a fixation too, so I want to make sure the gaze is still in the target stimuli just in case that happens.

    Let me know if you see any obvious problems with this.

    As always, I appreciate all of the help!

    -Ricky

  • edited October 2013

    The above scripts runs, but FIXUPDATE events don't seem to appear in the .edf output. Should I be changing the .py files directly, or should the above inline script code suffice?

    I have never used fixation updates myself (I generally poll gaze samples), but based on the manual this does seem like it should do the trick. The FIXUPDATE events should also appear in the .edf file though. So if they don't, I would check on the SR Support forum what the problem might be. For example, it could be that the fact that libeyelink already specifies a file_event_filter and link_event_filter prevents these settings from being specified again. I'm not sure: This is EyeLink-specific stuff, and not all behavior is fully specified in the manual.

    The logic in your script seems to be ok, as far as I can tell. But it's not even remotely close to syntactically valid Python! For example, ^ is a bitwise exclusive or, and not an exponentiation, which is ** Similarly, = is an assignment, to compare to values, you need ==. And the statement data = wait_for_event("pylink.FIXUPDATE") passes the string 'pylink.FIXUPDATE' to the function wait_for_event(), and not the pylink attribute FIXUPDATE.

    So what I would do is write a working script (i.e. one that doesn't cause syntax errors) that follows the basic logic that you have outlined here and see whether it functions as expected. If it doesn't, you can paste the script here and we can take it from there. To familiarize yourself with the basic Python syntax, I would walk through one of the tutorials described on the documentation site:

    Good luck!
    Sebastiaan

    Edit: Just to get you started with the most tricky part, you should be able to get a FIXUPDATE event approximately like this (see the PyLink manual).

    # Get (timestamp, fixupdate) tuple from `libeyelink`
    time, fixupdate = exp.eyelink.wait_for_event(pylink.FIXUPDATE)
    # This extracts the start coordinates from the fixupdate event object,
    # which are returned as an (x,y) tuple.
    # For other available methods, see PyLink manual.
    x, y = fixupdate.getStartGaze()
    
  • edited 10:48PM

    Hey Sebastian,

    OpenSesame is telling me that the name pylink is not defined when I try to pass pylink.FIXUPDATE to the wait_for_event function...I'm using OpenSesame Portable and Edwin provided me with a new download recently because pylink was not importing correctly...it imports correctly now obviously, since I can connect to and calibrate the tracker, but it looks like it's still not recognizing pylink...?

  • edited October 2013

    Did you specifically import pylink within the inline_script in which you try to pass pylink.FIXUPDATE? To add to Sebastiaans snippet:

    # Import pylink before using anything from it
    # (usually imports are done at the top of a script)
    import pylink
    # Get (timestamp, fixupdate) tuple from `libeyelink`
    time, fixupdate = exp.eyelink.wait_for_event(pylink.FIXUPDATE)
    # This extracts the start coordinates from the fixupdate event object,
    # which are returned as an (x,y) tuple.
    # For other available methods, see PyLink manual.
    x, y = fixupdate.getStartGaze()
    
  • edited 10:48PM

    Hey guys,

    I've got everything working well now, and I'll include the code shortly. I used the getStartGaze/getEndGaze functions and it seems to be working correctly - what's the difference between those functions and the PPD one you included in your sample? Just curious...

    Thanks guys!
    -Ricky

  • edited 10:48PM

    what's the difference between those functions and the PPD one you included in your sample? Just curious...

    Ow right, I simply misread the manual. the getStartPPD() function gets information about the angular resolution. You indeed want getStartGaze() and getEndGaze().

    Good to hear that you got it working!

  • edited October 2013

    Hey guys,

    First, I wanted to include the code below for reference in case any future readers need to implement a similar paradigm:

    #Await fixation on target stimuli
    import pylink
    
    fixated = 0
    self.experiment.eyelink.log("Starting wait for fixation period")
    
    while fixated == 0:
    
        timestamp, startpos = self.experiment.eyelink.wait_for_fixation_start()
        if self.experiment.get('fixate_on') == "left":
            x = startpos[0]
            y = startpos[1]
            x_in_ellipse = ((x - 217)**2)/22350.25
            y_in_ellipse = ((y - 384)**2)/44310.25
            if (x_in_ellipse + y_in_ellipse) <= 1:
                self.experiment.eyelink.log("Fixated inside target left image")
                timestamp, fixupdate = self.experiment.eyelink.wait_for_event(pylink.FIXUPDATE)
                self.experiment.eyelink.log("FIXATION UPDATE LOGGED")
                x, y = fixupdate.getEndGaze()
                x_in_ellipse = ((x - 217)**2)/22350.25
                y_in_ellipse = ((y - 384)**2)/44310.25
                if (x_in_ellipse + y_in_ellipse) <= 1:
                    x, y = self.experiment.eyelink.sample()
                    x_in_ellipse = ((x - 217)**2)/22350.25
                    y_in_ellipse = ((y - 384)**2)/44310.25
                    if (x_in_ellipse + y_in_ellipse) <= 1:
                        self.experiment.eyelink.log("Gaze still in target left image: wait for fixation period over")
                        fixated = 1
        elif self.experiment.get('fixate_on') == "right":
            x = startpos[0]
            y = startpos[1]
            x_in_ellipse = ((x - 807)**2)/22350.25
            y_in_ellipse = ((y - 384)**2)/44310.25
            if (x_in_ellipse + y_in_ellipse) <= 1:
                self.experiment.eyelink.log("Fixated inside target right image")
                timestamp, fixupdate = self.experiment.eyelink.wait_for_event(pylink.FIXUPDATE)
                self.experiment.eyelink.log("FIXATION UPDATE LOGGED")
                x, y = fixupdate.getEndGaze()
                x_in_ellipse = ((x - 807)**2)/22350.25
                y_in_ellipse = ((y - 384)**2)/44310.25
                if (x_in_ellipse + y_in_ellipse) <= 1:
                    x, y = self.experiment.eyelink.sample()
                    x_in_ellipse = ((x - 807)**2)/22350.25
                    y_in_ellipse = ((y - 384)**2)/44310.25
                    if (x_in_ellipse + y_in_ellipse) <= 1:
                        self.experiment.eyelink.log("Gaze still in target right image: wait for fixation period over")
                        fixated = 1
    
Sign In or Register to comment.

agen judi bola , sportbook, casino, togel, number game, singapore, tangkas, basket, slot, poker, dominoqq, agen bola. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 50.000 ,- bonus cashback hingga 10% , diskon togel hingga 66% bisa bermain di android dan IOS kapanpun dan dimana pun. poker , bandarq , aduq, domino qq , dominobet. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 10.000 ,- bonus turnover 0.5% dan bonus referral 20%. Bonus - bonus yang dihadirkan bisa terbilang cukup tinggi dan memuaskan, anda hanya perlu memasang pada situs yang memberikan bursa pasaran terbaik yaitu http://45.77.173.118/ Bola168. Situs penyedia segala jenis permainan poker online kini semakin banyak ditemukan di Internet, salah satunya TahunQQ merupakan situs Agen Judi Domino66 Dan BandarQ Terpercaya yang mampu memberikan banyak provit bagi bettornya. Permainan Yang Di Sediakan Dewi365 Juga sangat banyak Dan menarik dan Peluang untuk memenangkan Taruhan Judi online ini juga sangat mudah . Mainkan Segera Taruhan Sportbook anda bersama Agen Judi Bola Bersama Dewi365 Kemenangan Anda Berapa pun akan Terbayarkan. Tersedia 9 macam permainan seru yang bisa kamu mainkan hanya di dalam 1 ID saja. Permainan seru yang tersedia seperti Poker, Domino QQ Dan juga BandarQ Online. Semuanya tersedia lengkap hanya di ABGQQ. Situs ABGQQ sangat mudah dimenangkan, kamu juga akan mendapatkan mega bonus dan setiap pemain berhak mendapatkan cashback mingguan. ABGQQ juga telah diakui sebagai Bandar Domino Online yang menjamin sistem FAIR PLAY disetiap permainan yang bisa dimainkan dengan deposit minimal hanya Rp.25.000. DEWI365 adalah Bandar Judi Bola Terpercaya & resmi dan terpercaya di indonesia. Situs judi bola ini menyediakan fasilitas bagi anda untuk dapat bermain memainkan permainan judi bola. Didalam situs ini memiliki berbagai permainan taruhan bola terlengkap seperti Sbobet, yang membuat DEWI365 menjadi situs judi bola terbaik dan terpercaya di Indonesia. Tentunya sebagai situs yang bertugas sebagai Bandar Poker Online pastinya akan berusaha untuk menjaga semua informasi dan keamanan yang terdapat di POKERQQ13. Kotakqq adalah situs Judi Poker Online Terpercayayang menyediakan 9 jenis permainan sakong online, dominoqq, domino99, bandarq, bandar ceme, aduq, poker online, bandar poker, balak66, perang baccarat, dan capsa susun. Dengan minimal deposit withdraw 15.000 Anda sudah bisa memainkan semua permaina pkv games di situs kami. Jackpot besar,Win rate tinggi, Fair play, PKV Games