function [result, ivx]=iViewXCalibrate(ivx) % calibration routine of iViewX toolbox % could also double as driftcorrection with a single point? result=1; try if ~exist('ivx', 'var') || isempty(ivx) txt=[ mfilename ' requires a structure with iViewX default values as input.']; error(txt); end % open connection for receiving data [success, ivx]=iViewX('openconnection', ivx); if success==-1 fprintf([mfilename ': cannot open a connection to iViewX host.\n']); return end % send screen info [success, ivx]=iViewX('setscreensize', ivx); [success, ivx]=iViewX('startrecording', ivx); % send (possibly adapted) calibration point positions % [success, ivx]=iViewX('setcalibration', ivx, ivx.nCalPoints); %?? % [success, ivx]=iViewX('sendcalibrationpoints', ivx); [success, ivx]=iViewX('setcalibration', ivx, ivx.nCalPoints); % now we should wait for iView to send % information on calibration screen size % and calibration point positions tBreak=GetSecs+ivx.commTimeOut; npts=0; klaar=0; while klaar==0 [keyIsDown,secs,keyCode] = KbCheck; if 1==keyCode(ivx.modifierKey) && 1==keyCode(ivx.breakKey) result=-1; return; break; end if GetSecs>tBreak fprintf([mfilename ': timed out waiting for data.\n']); result=-1; return end [data, ivx]=iViewX('receivedata', ivx); if ~isempty(data) && data ~=-1 % data tBreak=GetSecs+ivx.commTimeOut; % reset time out if strfind(data, 'ET_CHG') pt=str2num(data(8:end)); fprintf('Change to point: %d\n', pt); % this signals we have all the points klaar=1; break; elseif strfind(data, 'ET_PNT') coords=str2num(data(8:end)); % fprintf('Coords for point %d:\t%d\t%d\n', coords(1), coords(2), coords(3)); npts=npts+1; if coords(1) ~=npts fprintf('Point order mismatch\n'); end ivx.absCalPos(coords(1),:)=coords(2:3); % 1 is point nr. elseif strfind(data, 'ET_CSZ') % we should receive this message first scr_size=str2num(data(8:end)); fprintf('Screen: %d\t%d\n', scr_size(1), scr_size(2)); % we could check if the screen size reported matches the one % expected end end end fprintf('Calibrating using %d points (%d received).\n', size(ivx.absCalPos,1), npts); iViewX('erasescreen', ivx); nPointsShown=0; allowManAccept=1; % we now draw first calibration point and then % start a loop in which we wait for iView to tell us % when to draw the next calibration point tBreak=GetSecs+ivx.commTimeOut; klaar=0; while klaar==0 % draw calibration point iViewX('drawcalibrationpoint', ivx, [ivx.absCalPos(pt,1), ivx.absCalPos(pt,2)]); nPointsShown=nPointsShown+1; nextPt=0; % After displaying the first point, the software must monitor % the serial port for further "ET_CHG" commands or "ET_BRK", % which cancels the calibration procedure. % we also detect manual acceptance of calibration point while nextPt==0 if GetSecs>tBreak fprintf([mfilename ': timed out waiting for data.\n']); result=-1; return end [keyIsDown,secs,keyCode] = KbCheck; if 1==keyCode(ivx.modifierKey) && 1==keyCode(ivx.breakKey) % stop program altogether result=-1; iViewX('break', ivx); return; end if keyCode(ivx.breakKey), % stop calibration result=-1; iViewX('break', ivx); return; end if keyCode(ivx.nextCalPointKey), % force next calibration point iViewX('accept', ivx); nextPt=1; end % If you want the subject to manually accept the point with a % key press once they fixate, the "ET_ACC" command must then % be sent to the serial port. This instructs iView to change % to the next calibration point rather than having it detect % fixations itself. if keyIsDown==0 allowManAccept=1; % we only accept manually if key has been released in between end if keyCode(ivx.calAcceptKey) && allowManAccept==1, % manually accept calibration point iViewX('accept', ivx); allowManAccept=0; end [data, ivx]=iViewX('receivedata', ivx); data; if ~isempty(data) && data ~=-1 % data if strfind(data, 'ET_CHG') pt=str2num(data(8:end)); fprintf('Change to point: %d\n', pt); % this signals the point was fixated correctly so we can % go the next point nextPt=1; break; elseif strfind(data, 'ET_BRK') result=-1; return elseif strfind(data, 'ET_FIN') % fprintf('Point: %d (pos %d) finished.\n', nPointsShown, pt); result=1; klaar=1; fprintf('Calibration Finished\n'); break end end end end [success, ivx]=iViewX('stoprecording', ivx); % ?? necessary iViewX('erasescreen', ivx); WaitSecs(ivx.calExtraTimeSecs); [success, ivx]=iViewX('closeconnection', ivx); if success~=1 fprintf([mfilename ': could not close connection.\n']); end fprintf('\nEnd of calibration.\n'); catch %this "catch" section executes in case of an error in the "try" section %above. Importantly, it closes the onscreen window if its open. Screen('CloseAll'); rethrow(lasterror); end %try..catch..