Welcome! Log In Create A New Profile

Advanced

detecting when gaze goes off fixation point

Posted by Pawel 
detecting when gaze goes off fixation point
December 08, 2023 05:46PM
Hi all,

I am struggling to figure out how to limit whether saccade from fixation point to target is considered successful to the saccades that are completed within certain time limit after the subject's gaze left the fixation point.

In other words, I want to prevent the subject from using multiples saccades to reach the target. This limit is different from the time limit between target display to when the target is reached.

So the structure of the trial at this point is:

scene 1: fixate on the fixation point and hold fixation

scene 2:
show target
subject has to saccade to the target
monitor when the gaze leaves the fixation point

if the subject does not reach the target in x milliseconds since target onset -> failure X
if the subject reaches the target in more than y milliseconds since they left the fixation point -> failure Y
if the subject reaches the target in less than x milliseconds since the target onset AND in less than y milliseconds since their gaze moved away from the fixation point --> go to scene 3
(note: reaching the target in less than x milliseconds since target is shown while never leaving the fixation point is fine - target may be close to fixation and threshold circles may overlap)


scene 3
hold the target for z milliseconds


My thinking for scene 2 is:
Chain A:
- detect leaving the fixation point
- only then start a TimeCounter for y milliseconds

Chain B:
show the target (ImageGraphic)
detect reaching the target via SingleTarget(eye_) and WaitThenHold with hold time 0 (actual holding in scene 3)

Combine A & B with AllContinue

Then after the scene is run
success of TimeCounter means failure Y
~success of WaitThenHold means failure X
success of WaitThenHold --> go to Scene 3.


But I can't figure out the "detect leaving the fixation point, only then start a TimeCounter for y milliseconds" part. It feels as if I needed something like ComplementaryWindow but working with eye_

The manual advises to use NotAdapter with SingleFix, but NotAdapter only reverses the Success property, and I feel like I need to reverse the Stop property.

I am probably missing a simple solution... if someone could help I would be very grateful.


Here are relevant parts of the code, using NotAdapter (as a placeholder, because as I said does not work)

   %target image
    target_img = ImageGraphic(null_);
    target_img.List = {target_image, [Info.X, Info.Y]};

    %measure time since leaving fix 
    leave_fix = SingleTarget(eye_);
    leave_fix.Target = fix_dot;
    leave_fix.Threshold = center_fix_window;

    not_fixing = NotAdapter(leave_fix);

    leave_timer = TimeCounter(not_fixing); 
    leave_timer.Duration = target_limit_time;

    % >> success and stop if too late since fix

    %find target 
    target_look = SingleTarget(eye_);
    target_look.Target = target_img;
    target_look.Threshold = target_window;

    target_capture = WaitThenHold(target_look); 
    target_capture.WaitTime = target_wait_time;
    target_capture.HoldTime = 0;  %only wait to capture, hold dealt wih lh_target in another scene
    % >> stop if found target or if overtime
    % >> success if found target


    %combine finding the target and testing time from leaving fix 
    find_target_and_leave_fix = AllContinue(target_capture);
    find_target_and_leave_fix.add(leave_timer);
    % >> stop if found target or overtime or too late since fix
    % >> success if any of the above happened

    target_search_scene = create_scene(find_target_and_leave_fix);




        run_scene(target_search_scene, target_start_mk);


        if leave_timer.Success  %too much time since left fix

            trialerror(0); %considered correct for the purpose of trial counting,
            %only trials in which fixation failed are to be repeated

            eventmarker(target_too_slow_mk);

            trial_result = result_target_too_slow; %looking for target for too long since leaving fix

        else

            if ~target_capture.Success  %timeout of target search

                trialerror(0); %considered correct for the purpose of trial counting,
                %only trials in which fixation failed are to be repeated
                eventmarker(target_acq_failed_mk);

                trial_result = result_target_not_found;  %failed to find target


            else  %target found, now hold

                eventmarker(target_acquired_mk);

                run_scene(target_hold_scene, target_hold_start_mk);
%that's scene 3








Re: detecting when gaze goes off fixation point
December 09, 2023 06:22AM
Use WaitThenHold, instead of TimeCounter, like the following.
leave_fix = SingleTarget(eye_);
not_fixing = NotAdapter(leave_fix);
leave_timer = WaitThenHold(not_fixing);
leave_timer.WaitTime = target_wait_time;
leave_timer.HoldTime = target_limit_time;

By adding NotAdapter, not_fixing succeeds when the eye is not on the target. Therefore, what leave_timer does is to await the fixation break for target_wait_time and see if it is maintained for target_limit_time, which I think is what you want.
Re: detecting when gaze goes off fixation point
December 09, 2023 11:32AM
Thank you, Jaewon!

Reading the code I thing this is exactly what I needed. I'll test it on Monday!

Best,

Pawel

The National Institute of Mental Health (NIMH) is part of the National Institutes of Health (NIH), a component of the U.S. Department of Health and Human Services.