Welcome! Log In Create A New Profile

Advanced

Coordinate conversion

Posted by Jaewon 
Coordinate conversion
August 17, 2019 07:20PM
There are several coordinate systems used in NIMH ML for calibration and graphics.

sig is analog voltage or digital input (X & Y) fed from eye trackers or joysticks.
deg is visual degrees measured from the center of the screen. NIMH ML mostly works on this coordinate system in timing scripts.
pix is native pixel coordinates of Windows. The top-left corner is (0,0) and x & y increase as moving toward the bottom-right corner. This is the coordinate system that MGL works with.
norm is normalized coordinates in which both x & y have a value between 0 and 1. It is useful when you design layouts independent of the screen size.



The mlcalibrate object provides methods to convert xy coordinates from one system to another. There are 4 objects available in timing scripts: EyeCal, Eye2Cal, JoyCal and Joy2Cal.

xy_deg = EyeCal.sig2deg(xy_sig, offset);  % can use Eye2Cal, JoyCal or Joy2Cal instead
                                          % set the offset [0 0], if it is not necessary
EyeCal.translate(xy_offset);       % translate the system so that xy_offset becomes a new (0,0)
EyeCal.rotate(theta);              % rotate the coordinates system by theta (in degrees) temporarily
EyeCal.custom_calfunc(user_func);  % for user manipulation of calibration
The sig2deg method is device-dependent. It is meaningful only when the calibration process is complete. There are three other methods that can affect how sig2deg works. The translate method updates the calibration matrix so that the given coordinates become a new origin of the system. The rotate method turns the axes on the origin by the given angle. Its effect is temporary, meaning that the change is effective in the current trial only. With the custom_calfunc method, you can plug in a custom function to manipulate the calibration. For example, if you want to move the origin to [3 3], you can write a timing script like the following.
new_origin = [3 3];  % in degrees
JoyCal.custom_calfunc(@custom_joy);
...
...
...
function xy_deg = custom_joy(xy_deg)  % note that input and output are both in degrees
    n = size(xy_deg,1);
    xy_deg = xy_deg + repmat(new_origin, n, 1);
end
The difference between JoyCal.translate([3 3]) and the above code is that the former brings [3 3] to [0 0] and the latter moves [0 0] to [3 3].

Additionally the following methods are usable. Except sig2pix, all methods are device-independent, meaning that you will get the same results no matter which object you choose among EyeCal, Eye2Cal, JoyCal and Joy2Cal to call them.
xy_pix = EyeCal.sig2pix(xy_sig, offset);  % this is a conjugation of sig2deg and deg2pix
xy_deg = EyeCal.pix2deg(xy_pix);
xy_pix = EyeCal.deg2pix(xy_deg);
xy_deg = EyeCal.subject2deg(xy);  % get the degree coordinates of a point on the subject screen
xy_pix = EyeCal.subject2pix(xy);
xy_deg = EyeCal.control2deg(xy);  % get the degree coordinates of a point on the control screen
xy_pix = EyeCal.control2pix(xy);
xy_deg = EyeCal.norm2deg(xy);
xy_pix = EyeCal.norm2pix(xy);
wh_deg = EyeCal.norm2size(wh);    % convert the normalized size (width & height) to visual degrees

In the scene framework, you can access Tracker's mlcalibrate object inside the adapter like the following.
classdef YourAdapter < mladapter
    properties
        Position
    end
    properties (SetAccess = protected)
        ScreenPosition
    end
    methods
        function obj = YourAdapter(varargin)
            obj = obj@mladapter(varargin{:});
        end
        function set.Position(obj,xy_deg)
            obj.Position = xy_deg;
            % If the tracker is EyeTracker, obj.Tracker.CalFun indicates EyeCal.
            obj.ScreenPosition = obj.Tracker.CalFun.deg2pix(xy_deg);
        end
    end
end
Attachments:
open | download - coordinates.png (4.3 KB)

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.