function varargout = polgui_ver1_r14(varargin)
% -------------------------------------------------------------------------
% Copyright (C) 2004 , Nitin B. Bangera (nitinb2@gmail.com)
% POLGUI Ver 1.0 is distributed under the terms of the open-source BSD License,
% See license.txt for more information.
% -------------------------------------------------------------------------
% -- POLGUI Ver 1.0 for Matlab R14 --
% -------------------------------------------------------------------------
% Matlab Interface for Polhemus Digitizer( Only with one stylus pen )
% Author Nitin B Bangera
%
% NOTE : Set Screen Resolution to "1280 by 1024" or higher for GUI to be
% displayed correctly
%
% Usage :
%
%
% ------ polgui_ver1_r14, by itself, creates a new POLGUI_VER1_R14 with
% default settings of 1 receivers (stylus pen)
%
% ------ modify line 235 to change EEG Montage
% ------ modify line 271 and 273 to set Baud rate euivalent to that on
% Polhemus (default set to 57600)
% Baud Rate Settings on switch on back of Polhemus ( 1= UP, 0=Down)
% Baud rate SW 1 SW 2 SW 3
% 1200 0 0 0
% 2400 1 0 0
% 4800 0 1 0
% 9600 1 1 0
% 19200 0 0 1
% 38400 1 0 1
% 57600 0 1 1
% 115200 1 1 1
% Important Variables Saved: in file collected_data.mat
% -------------------------------------------------------------------------
% data_orig --> Original Data including the 3 consecutive points collected
% for each location for averaging and pen movement error detection
% data -> Averaged data
% data_transf -> Data transformed to head co-ordinate frame
% location -> Names of locations digitized
% count -> Total number of digitized points
% M -> Rotation matrix for transformation
% T -> Translation matrix
% -------------------------------------------------------------------------
% Description of global variables and counters in the code
%
% needed_loc LOC DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 special_case strmatch_index redigitize additional T M
%
% needed_loc -> chararcter array with the CARDINAL POINT locations
% and EEG montage locations
% LOC-> Set of digitized locations
% DATA_ORIG -> Original Data before averaging
% DATA -> Data after averaging 3 successive digitizations for each point
% DATA_TRANSF -> Data after co-ordinate transformation
% COUNTER -> Main Counter
% COUNTER1-> Counter which includes count for 3 successive digitization for each point
% Tag for 4 cases for remove button :
% special_case
% Case 0-> Initial Condition , Case 1-> counter <=4
% Case 2-> Counter between 4 and length of needed montage
% Case 3-> Additional Points
%
% strmatch_index -> matches current Vaue in the listbox with needed_loc matrix and returns index
% redigitize -> Tag to check if redigitization is needed Values: 0 or 1
% additional -> Tag to check if digitization of additional points is needed Values: 0 or 1
% T -> Translation Matrix
% M -> Rotation Matrtix
% --------------------------------------------------------------------------
% Steps for head digitization using POLGUI
% 1.Before starting GUI, edit EEG_MONTAGE variable (on line 215 in this m-file) to set required
% montage to be acquired.
%
% 2. Start GUI by typing name of this m-file in MATLAB command line (GUI
% mode) e.g. polgui_ver4_r14
%
%
% Follow these steps in GUI by clicking on respective buttons in sequential
% order
% a. Initialise Device:
% Serial Object created with specific Baud rate. Change this call back to
% change serial port properties
%
% To digitize position the tip of the Isotrack Stylus at the desired point
% and click on the dialog box within the GUI. The co-ordinates
% displayed are the averages of three sequential readings taken from the
% digitizer. If they differ from each other by more than 2 mm, you are asked
% to digitize the point again.
%
% b. Get Test Point:
% Secure one test point
%
% c. Get Cardinal Points in order LA(left Auricular), RA(Right Auricular)
% and Nasion.
%
% d. Align Frame from device coordinates to head co-ordinate axes determined
% by the cardinal points
% Head Coordinate system:
% The head coordinate system is defined as folloew: The x axis passes through the
% preauricular points with positive values on the right, the y-axis will be
% perpendicular to x axis, passing through the nasion and the positive axis
% pointing towards the nose, and the z axis will be pointed up, perpendicular to xy plane.
% The auricular points are known as anatomical landmarks or cardinal points.
%
% Principle:
% When Align Frame is press, the coordinates of the cardinal locations will
% change to head frame. Notice the z coordinates of all three points are
% zero. The y coordinates of the auricular points are zero with a positive x
% coordinate on the right and a negative on the left auricular point,
% respectively. The nasion has a zero x coordinate and its y coordinate is
% positive. The auricular points will be almost symmetrically located: their
% x coordinates are opposite and about of equal magnitude
%
% -Procedure for alignment-------------------------------------------------
% a1. Calculate the new origin coordinates o
% Define three vectors a(nasion-la), b1(ra-la) and b2(la-ra)
% Drop projection of a on b1 and b2 to calculatet1 and t2 respectively.
% find ratio in which projection from b1 (point o) divides vector b1
% o=la+t*b1 o=(Ox,Oy,Oz)
%
% b1. Define the three new coordinate axes ox(normalised ra-o),oy(normalised
% nasion-o),oz(cross(ox,oy))
%
% c1. First translate orgin by -o
% Define Translation matrix T as follows:
% | 1 0 0 0|
% | 0 1 0 0|
% T = | 0 0 1 0|
% |-Ox -Oy -Oz 0|
%
% d1. Then Rotate .Define Rotation Matrix M as folows:
% R=[ox;oy;oz]
% R1=inverse(R) or transpose(R)
% |" " "|
% |" R1 "|
% M= |" " "|
% |0 0 0|
%
% e1. Transform points to new co-ordinate axes with center at o and three
% axes ox,oy and oz
% [xnew ynew znew ]=[xold yold zold 1]*T*M;
% -------------------------------------------------------------------------
% e. Get EEG montage points.
%
% f. Get additional points
% Fot additional points , click the stylus pen for digitization.
%
% g. Press stop to close the serial device and delete objects from memory.
% -------------------------------------------------------------------------
%
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @polgui_ver1_r14_OpeningFcn, ...
'gui_OutputFcn', @polgui_ver1_r14_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
%--------------------------------------------------------------------------
% --- Executes just before polgui_ver1_r14 is made visible.
function polgui_ver1_r14_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to polgui_ver1_r14 (see VARARGIN)
set(hObject, 'Units', 'pixels');
handles.banner = imread('head.png'); % Read the image file banner.jpg
info = imfinfo('head.png'); % Determine the size of the image file
axes(handles.logo);
image(handles.banner)
set(handles.logo, ...
'Visible', 'off', ...
'Units', 'pixels');
% Choose default command line output for polgui_ver1_r14
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes polgui_ver1_r14 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
%--------------------------------------------------------------------------
% --- Outputs from this function are returned to the command line.
function varargout = polgui_ver1_r14_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
%--------------------------------------------------------------------------
% --- Executes on button press in initialise.
%Sets Baudrate and created serial object
% To change port name and baudrate change int this callback
function initialise_Callback(hObject, eventdata, handles)
% hObject handle to initialise (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% EEG Montage to be aquired . Pts 2,3 and 4 are cardinal points_pen
% Edit EEG_MONTAGE to change EEG Montage
EEG_MONTAGE=strvcat('Fp1','Fp2','F3','F4','C3','C4','P3',...
'P4','O1','02','F7','F8','T3','T4','T5','T6','FZ','CZ','PZ','OZ','A1','A2','Ref','PO1',...
'PO2','CP1','CP2','FTC1','FTC2','TCP1','TCP2','X31','X32','X33');
handles.needed_loc=strvcat('test','LA','RA','NASION',EEG_MONTAGE);
global special_case strmatch_index no_add additional redigitize T M k;
handles.location=[]; % Handles structure for location names
handles.data=[]; % Handles Structure for final DATA
handles.count=1; % Handles structure for overall count of points digitized
special_case=0;% Tag for 4 cases for remove button :
% Case 0-> Initial Condition , Case 1-> counter <=4
% Case 2-> Counter between 4 and length of needed montage
% Case 3-> Additional Points
strmatch_index=0;
no_add=0;
additional=0; % Tag to get additonal points, Values:0 or 1
redigitize=0; % Tag to keep track of redigitization ,Values 0 or 1
k=5;
str1=sprintf('\n\n\nInitialising device \n');
set(handles.points,'String',[]);
set(handles.text1,'String',str1);
set(handles.remove,'Enable','on');
set(handles.get_test,'Enable','on');
set(handles.align,'Enable','off');
set(handles.get_la,'Enable','off');
set(handles.get_ra,'Enable','off');
set(handles.get_nasion,'Enable','off');
set(handles.get_montage,'Enable','off');
set(handles.get_additional,'Enable','off');
set(handles.stop,'Enable','on');
% Create serial object and set baud rate
tmp_pc=ispc;
if (tmp_pc)
handles.s=serial('COM1','BaudRate',57600);
else
handles.s=serial('/dev/ttyS0','BaudRate',57600);
end
%handles.s=serial('COM1','BaudRate',57600);
guidata(hObject,handles);
str_text1=sprintf('\nDEVICE READY \n\n\nRemove : deletes last digitized point');
str_text2=sprintf('\n\nGet Test Point');
set(handles.text2,'String',str_text2);
set(handles.text1,'String',str_text1);
set(handles.initialise,'Enable','off');
set(handles.text_nasion,'String','No Points Digitized');
set(handles.text_la,'String','No Points Digitized');
set(handles.text_ra,'String','No Points Digitized');
%--------------------------------------------------------------------------
% --- Executes on button press in stop.
% Save data in mat file collected_data
function stop_Callback(hObject, eventdata, handles)
% hObject handle to stop (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.initialise,'Enable','on');
global DATA DATA_ORIG DATA_TRANSF COUNTER1 COUNTER LOC count T M redigitize;
data_orig=DATA_ORIG;
data=DATA;
data_transf=DATA_TRANSF;
count=COUNTER-1;
location=LOC;
COUNTER1=[];
COUNTER=[];
DATA_ORIG=[];
DATA=[];
DATA_TRANSF=[];
LOC=[];
save collected_data data_orig data data_transf count location T M;
hold(handles.coordinates,'off');
fclose(handles.s);
delete(handles.s);
clear handles.s;
clear handles.data;
clear handles.location;
clear handles.T;
clear handles.M;
guidata(hObject,handles);
str3=sprintf('\n\n\nPOLGUI Ver 1.0');
str4=sprintf('\n\n\nPoints Digitized\n\nPress "Initialise" to Start');
set(handles.text1,'String',str3);
set(handles.text2,'String',str4);
set(handles.remove,'Enable','off');
set(handles.stop,'Enable','off');
set(handles.remove,'Enable','on');
set(handles.get_test,'Enable','on');
set(handles.align,'Enable','on');
set(handles.get_la,'Enable','on');
set(handles.get_ra,'Enable','on');
set(handles.get_nasion,'Enable','on');
set(handles.get_montage,'Enable','on');
set(handles.get_additional,'Enable','on');
clear data data_orig data_transf count location T M;
%--------------------------------------------------------------------------
% --- Executes on button press in get_test.
% Secure test point
function get_test_Callback(hObject, eventdata, handles)
% hObject handle to get_test (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 T M redigitize;
if isempty(COUNTER) COUNTER=1; end
if isempty(COUNTER1) COUNTER1=1; end
if (strcmp(handles.s.status,'closed'))
handles.s.BytesAvailableFcnCount=48;
handles.s.BytesAvailableFcnMode = 'byte';
handles.s.BytesAvailableFcn = {@bytesavailablegui_callback,handles};
fopen(handles.s);
end
% This loop send request for three successive digitizations which is
% averaged and checked for pen movement
for i=1:3,
% i
% COUNTER1
fprintf(handles.s,'%s','P');
pause(0.2);
end
if ~isequal(redigitize,1)
str_text2=sprintf('\n\n\nGet Cardinal Point LA');
set(handles.text2,'String',str_text2);
set(handles.get_la,'Enable','on');
set(handles.get_test,'Enable','off')
end
guidata(hObject,handles);
%--------------------------------------------------------------------------
% --- Executes on button press in get_la.
% Secure Cardinal Point LA(Left Auricular)
function get_la_Callback(hObject, eventdata, handles)
% hObject handle to get_la (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 T M redigitize;
% This loop send request for three successive digitizations which is
% averaged and checked for pen movement
for i=1:3,
% i
% COUNTER1
fprintf(handles.s,'%s','P');
pause(0.2);
end
if ~isequal(redigitize,1)
str_text2=sprintf('\n\n\nGet Cardinal Point RA');
set(handles.text2,'String',str_text2);
set(handles.get_ra,'Enable','on');
set(handles.get_la,'Enable','off')
end
guidata(hObject,handles);
% --- Executes on button press in get_ra.
% Secure Cardinal Point RA(Right Auriculur)
function get_ra_Callback(hObject, eventdata, handles)
% hObject handle to get_ra (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 T M redigitize;
% This loop send request for three successive digitizations which is
% averaged and checked for pen movement
for i=1:3,
% i
% COUNTER1
fprintf(handles.s,'%s','P');
pause(0.2);
end
if ~isequal(redigitize,1)
str_text2=sprintf('\n\n\nGet Cardinal Point NASION');
set(handles.text2,'String',str_text2);
set(handles.get_nasion,'Enable','on');
set(handles.get_ra,'Enable','off');
end
guidata(hObject,handles);
%--------------------------------------------------------------------------
% --- Executes on button press in get_nasion.
% Secure Cardinal Point Nasion
function get_nasion_Callback(hObject, eventdata, handles)
% hObject handle to get_nasion (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 T M redigitize;
% This loop send request for three successive digitizations which is
% averaged and checked for pen movement
for i=1:3,
% i
% COUNTER1
fprintf(handles.s,'%s','P');
pause(0.2);
end
if ~isequal(redigitize,1)
str_nasion=sprintf('\n\nCARDINAL POINTS OBTAINED\n\nALIGN FRAME TO HEAD CO-ORDINATE SYSTEM');
set(handles.text2,'String',str_nasion);
set(handles.align,'Enable','on');
set(handles.get_nasion,'Enable','off');
end
guidata(hObject,handles);
%--------------------------------------------------------------------------
% --- Executes on button press in get_montage.
% Secure EEG Montage
function get_montage_Callback(hObject, eventdata, handles)
% hObject handle to get_montage (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global LOC DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 T M redigitize k str_modal;
set(handles.get_montage,'Enable','off');
set(handles.remove,'Enable','Off');
while k<=length(handles.needed_loc) % Check if loop is within the EEG montage points count
if isequal(k,5)
str_modal=sprintf('Get Point %s\nPress ESC to exit',handles.needed_loc(5,:));
str_text2=sprintf('\n\n\n Get Point %s\n\nPress ESC to exit',handles.needed_loc(5,:));
set(handles.text2,'String',str_text2);
end
pos_size = get(handles.figure1,'Position');
user_response = montage_modaldlg_r14('Title','Digitize','String',str_modal);
switch user_response
case 'OK' % Digitize Point
for i=1:3,
% i
% COUNTER1
fprintf(handles.s,'%s','P');
pause(0.2);
end
case 'REMOVE LAST PT' % Remove Last digitized Point
% k
% LOC
% DATA
% DATA_TRANSF
k=k-1;
resultStr= get(handles.points,'String');
resultStr(k) =[];
DATA(k,:)=[];
DATA_TRANSF(k,:)=[];
set(handles.points,'String',resultStr)
LOC(k,:)=[];
redigitize=1;
COUNTER1=COUNTER1-3;
COUNTER=COUNTER-1;
case 'No'
str_text2=sprintf('\n\nPress STOP to finish digitization\nOR\nGet additional Points');
set(handles.text2,'String',str_text2);
set(handles.get_additional,'Enable','Off')
break;
end
pause(0.5);
k=k+1;
if (redigitize==1)
redigitize
k=k-1;
str_text2=sprintf('\n\n\nRedigitize Point %s\n\nPress ESC to exit',handles.needed_loc(k,:));
str_modal=sprintf('Redigitize Point %s\nPress ESC to exit',handles.needed_loc(k,:));
set(handles.text2,'String',str_text2);
redigitize=0;
elseif ~isequal(k,length(handles.needed_loc)+1)
str_text2=sprintf('\n\n\nGet Point %s\n\nPress ESC to exit',handles.needed_loc(k,:));
str_modal=sprintf('Get Point %s\nPress ESC to exit',handles.needed_loc(k,:));
set(handles.text2,'String',str_text2);
else
str_text2=sprintf('\n\n\nGet Additional Points if needed');
set(handles.text2,'String',str_text2);
end
if k==length(handles.needed_loc)+1
str_modal1=sprintf('EEG Montage Digitized\nPress OK to Continue or \nRemove Last Point?');
user_response = montage_modaldlg_r14('Title','Digitize','String',str_modal1);
switch user_response
case 'OK'
str_text2=sprintf('\n\nPress STOP to finish digitization\nOR\nGet additional Points');
set(handles.text2,'String',str_text2);
set(handles.get_additional,'Enable','On')
break;
case 'REMOVE LAST PT'
k
LOC
DATA
DATA_TRANSF
k=k-1;
resultStr= get(handles.points,'String');
resultStr(k) =[];
DATA(k,:)=[];
DATA_TRANSF(k,:)=[];
set(handles.points,'String',resultStr)
LOC(k,:)=[];
redigitize=1;
COUNTER1=COUNTER1-3;
COUNTER=COUNTER-1;
str_modal=sprintf('Redigitize Point %s\nPress ESC to exit',handles.needed_loc(k,:));
case 'No'
str_text2=sprintf('\n\nPress STOP to finish digitization\nOR\nGet additional Points');
set(handles.text2,'String',str_text2);
set(handles.get_additional,'Enable','Off')
break;
end
end
end
set(handles.get_additional,'Enable','on');
set(handles.remove,'Enable','On');
guidata(hObject,handles);
% set(handles.get_additional,'Enable','on');
%--------------------------------------------------------------------------
% --- Executes on button press in get_additional.
function get_additional_Callback(hObject, eventdata, handles)
% hObject handle to get_additional (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA DATA_ORIG DATA_TRANSF COUNTER COUNTER1 additional T M;
set(handles.get_additional,'Enable','off');
additional=1;
str_additional=sprintf('Press Stylus pen to digitize additional points\n Press OK to continue');
uiwait(msgbox(str_additional,'Get Additional Points','help','modal'));
%--------------------------------------------------------------------------
% --- Executes on button press in align.
% Align from device coordinates to head coordinates
function align_Callback(hObject, eventdata, handles)
% hObject handle to align (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA DATA_TRANSF COUNTER T M LOC;
handles.data=DATA;
hold(handles.coordinates,'off');
la1=handles.data(2,:);
ra2=handles.data(3,:);
nasion=handles.data(4,:);
% rest=data(5:end,:)
a=nasion-la1;
b1=ra2-la1;
b2=la1-ra2;
c=nasion-ra2;
t1=dot(a,b1)/sqrt(dot(b1,b1));
t2=dot(c,b2)/sqrt(dot(b2,b2));
if t1<0 t1=t1*-1;
end
if t2<0 t2=t2*-1;
end
t=t1/(t1+t2);
o=la1+t*b1;
oy=nasion-o;
ox=ra2-o;
ox=ox/sqrt(dot(ox,ox));
oy=oy/sqrt(dot(oy,oy));
oz=cross(ox,oy);
% oz1=o+2*oz
T=[ 1 0 0 0; 0 1 0 0 ;0 0 1 0;-o 0];
R=[ox;oy;oz];
R1=inv(R);
M=[R1 ;0 0 0];
% Transformed points from original points
la=[la1 1]*T*M;
ra=[ra2 1]*T*M;
nasion=[nasion 1]*T*M;
% rest_new=rest_new*T*M;
% set(handles.coordinates,'BOX','on','XGrid','on','Ygrid','on','ZGrid','on','ZLim',[0 15]);
plot3([0 5],[0 0],[0 0],'->','Parent',handles.coordinates)
hold(handles.coordinates,'on');
plot3([0 0],[0 5],[0 0],'->','Parent',handles.coordinates)
% hold(handles.coordinates,'on');
plot3([0 0],[0 0],[0 5],'->','Parent',handles.coordinates)
% hold(handles.coordinates,'on');
plot3([la(1,1) ra(1,1) nasion(1,1)],[la(1,2) ra(1,2) nasion(1,2)],[la(1,3) ra(1,3) nasion(1,3)],'*','Parent',handles.coordinates);
hold(handles.coordinates,'on');
set(handles.coordinates,'BOX','on','XGrid','on','Ygrid','on','ZGrid','on','ZLim',[-2 15]);
xlabel(handles.coordinates,'X','Fontweight','bold');
ylabel(handles.coordinates,'Y','Fontweight','bold');
zlabel(handles.coordinates,'Z','Fontweight','bold');
sprintf('Align\n');
handles.center=o;
set(handles.align,'Enable','off');
set(handles.get_montage,'Enable','on');
str_align=sprintf('\n\n\nGet EEG Montage\n\nGet Point %s',handles.needed_loc(COUNTER,:));
set(handles.text2,'String',str_align);
guidata(hObject,handles);
ResultsStr = get(handles.points,'String');
% ResultsStr
DATA_TRANSF(1:4,:)=[DATA(1,:) 1;DATA(2,:) 1;DATA(3,:) 1;DATA(4,:) 1]*T*M;
handles.location=LOC
[r,c]=find(abs(DATA_TRANSF)<1e-5);
for i=1:length(r)
for j=1:length(c)
if (i==j)
DATA_TRANSF(r(i),c(i))=0;
end
end
end
str_la=sprintf('X = %2.3g cm\nY = %2.3g cm\nZ = %2.3g cm',DATA_TRANSF(2,1),DATA_TRANSF(2,2),DATA_TRANSF(2,3));
set(handles.text_la,'String',str_la);
str_ra=sprintf('X = %2.3g cm\nY = %2.3g cm\nZ = %2.3g cm',DATA_TRANSF(3,1),DATA_TRANSF(3,2),DATA_TRANSF(3,3));
set(handles.text_ra,'String',str_ra);
str_nasion=sprintf('X = %2.3g cm\nY = %2.3g cm\nZ = %2.3g cm',DATA_TRANSF(4,1),DATA_TRANSF(4,2),DATA_TRANSF(4,3));
set(handles.text_nasion,'String',str_nasion);
ResultsStr(1,:)={[handles.location(1,:),' : ',num2str(DATA_TRANSF(1,1)),' ',num2str(DATA_TRANSF(1,2)),' ',num2str(DATA_TRANSF(1,3))]};
ResultsStr(2,:)={[handles.location(2,:),' : ',num2str(DATA_TRANSF(2,1)),' ',num2str(DATA_TRANSF(2,2)),' ',num2str(DATA_TRANSF(2,3))]};
ResultsStr(3,:)={[handles.location(3,:),' : ',num2str(DATA_TRANSF(3,1)),' ',num2str(DATA_TRANSF(3,2)),' ',num2str(DATA_TRANSF(3,3))]};
ResultsStr(4,:)={[handles.location(4,:),' : ',num2str(DATA_TRANSF(4,1)),' ',num2str(DATA_TRANSF(4,2)),' ',num2str(DATA_TRANSF(4,3))]};
handles.translation=T;
handles.rotation=M;
set(handles.points,'String',ResultsStr);
guidata(hObject,handles);
%--------------------------------------------------------------------------
% % --- Executes on selection change in points.
% function points_Callback(hObject, eventdata, handles)
% % hObject handle to points (see GCBO)
% % eventdata reserved - to be defined in a future version of MATLAB
% % handles structure with handles and user data (see GUIDATA)
%
% % Hints: contents = get(hObject,'String') returns points contents as cell array
% % contents{get(hObject,'Value')} returns selected item from points
% --- Executes during object creation, after setting all properties.
function points_CreateFcn(hObject, eventdata, handles)
% hObject handle to points (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: listbox controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc
set(hObject,'BackgroundColor','white');
else
set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end
%--------------------------------------------------------------------------
% --- Executes on button press in remove.
% Removes additional points and last digitized points only
function remove_Callback(hObject, eventdata, handles)
% hObject handle to remove (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global special_case strmatch_index no_add LOC DATA DATA_TRANSF COUNTER COUNTER1;
currentVal=get(handles.points,'Value');
handles.data=DATA_TRANSF;
handles.location=LOC;
resultStr= get(handles.points,'String');
numResults = size(resultStr,1);
strmatch_index=strmatch(handles.location(currentVal,:),handles.needed_loc,'exact');
if currentVal<numResults
uiwait(msgbox('User Can remove only the last digitized point','Error','error','modal'));
else
if strmatch(handles.location(currentVal,:),handles.needed_loc,'exact') & (numResults<=4)
special_case=1;
str6=sprintf('\n\n\nGET POINT %s',handles.location(currentVal,:));
set(handles.text2,'String',str6);
resultStr(currentVal) =[];
handles.data(currentVal,:)=[];
handles.location(currentVal,:)=[];
DATA(currentVal,:)=[];
LOC(currentVal,:)=[];
COUNTER1=COUNTER1-3;
switch strmatch_index
case 1
set(handles.get_test,'Enable','on');
case 2
set(handles.get_la,'Enable','on');
case 3
set(handles.get_ra,'Enable','on');
case 4
set(handles.get_nasion,'Enable','on');
end
elseif strmatch(handles.location(currentVal,:),handles.needed_loc,'exact') & (numResults>4) & (numResults<=length(handles.needed_loc))
special_case==2;
set(handles.remove,'Enable','Off');
else
pos_size = get(handles.figure1,'Position');
% Call remove_modaldlg_r14 with the argument 'Position'.
user_response = remove_modaldlg_r14('Title','Redigitize');
switch user_response
case {'No'}
special_case=3;
resultStr(currentVal) =[];
handles.data(currentVal,:)=[];
handles.location(currentVal,:)=[];
LOC(currentVal,:)=[];
if isequal(no_add,0)
no_add=1;
else
no_add=no_add+1;
end
% take no action
case 'Yes'
%
str7=sprintf('GET POINT %s',handles.location(currentVal,:));
set(handles.text2,'String',str7);
resultStr(currentVal) =[];
handles.data(currentVal,:)=[];
handles.location(currentVal,:)=[];
LOC(currentVal,:)=[];
end
end
COUNTER=COUNTER-1;
% % If there are no other entries, disable the Remove and Plot
% button
% and change the list sting to <empty>
if isequal(numResults,length(currentVal)),
resultsStr = {'<empty>'};
currentVal = 1;
set(handles.remove,'Enable','off')
end
% % Ensure that list box Value is valid, then reset Value and String
currentVal = min(currentVal,size(resultStr,1));
set(handles.points,'Value',currentVal,'String',resultStr)
% handles.location
% LOC
% handles.count
% Store the new ResultsData
guidata(hObject, handles);
end
guidata(hObject,handles);
%--------------------------------------------------------------------------
% --- Executes on button press in plot.
% Plot data on seperate figure
function plot_Callback(hObject, eventdata, handles)
% hObject handle to plot (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DATA_TRANSF;
status=get(handles.stop,'Enable');
if isequal(status,'off')
load collected_data.mat;
DATA_TRANSF=data_transf;
end
plotColor = {'b','g','r','c','m','y','k'};
Plotdata_x1=DATA_TRANSF(2:end,1);
Plotdata_y1=DATA_TRANSF(2:end,2);
Plotdata_z1=DATA_TRANSF(2:end,3);
if ~isfield(handles,'PlotFigure') | ~ishandle(handles.PlotFigure),
handles.PlotFigure = figure('Name','Polhemus Digitizer',...
'Visible','off','NumberTitle','off',...
'HandleVisibility','off','IntegerHandle','off');
handles.PlotAxes = axes('Parent',handles.PlotFigure);
guidata(hObject, handles)
end
% Plot data
pHandles = plot3(Plotdata_x1,Plotdata_y1,Plotdata_z1,'o','Parent',handles.PlotAxes);
set(handles.PlotAxes,'BOX','on','XGrid','on','YGrid','on','ZGrid','on');
xlabel(handles.PlotAxes,'X','Fontweight','bold','Fontsize',12);
ylabel(handles.PlotAxes,'Y','Fontweight','bold','Fontsize',12);
zlabel(handles.PlotAxes,'Z','Fontweight','bold','Fontsize',12);
clear DATA_TRANSF
% Make the figure visible and bring it forward
figure(handles.PlotFigure)
%--------------------------------------------------------------------------
% Bytesavailable callback executes when the byte count reaches the one
% specified in the handles.s.BytesAvailableFcnCount variable.
function bytesavailablegui_callback(s,bytesavailable,handles)
global DATA DATA_ORIG DATA_TRANSF COUNTER1 COUNTER additional redigitize ;
global LOC;
global T M;
global special_case strmatch_index no_add ;
set(handles.points,'Value',1);
data_str=fgetl(s);
data_num=str2num(data_str); % Obtains data from digitizer when bytes-count
% reaches the limit specified by BytesAvailableFcnCount
% Format of data obtained for the current settings
% 1 2 3 4 5 6 7
% 1 ->01 Header
% 2 ->X position in cms
% 3-> Y position in cms
% 4-> Z position in cms
% 5-> Azimuth attitude in degrees
% 6-> Elevation attitude in degrees
% 7-> Roll attitude in degrees
% Change for your specific device settings
data_num(1,2:4); % Picks the X,Y,Z data
if isequal(additional,1) & COUNTER>4 % For additional points
DATA(COUNTER,1:3)=data_num(1,2:4);
handles.count=COUNTER;
DATA_TRANSF(COUNTER,1:3)=[data_num(1,2:4) 1]*T*M;
LOC=strvcat(LOC,num2str(COUNTER));
handles.data=DATA_TRANSF;
handles.location=LOC;
Plotdata_x=handles.data(handles.count,1);
Plotdata_y=handles.data(handles.count,2);
Plotdata_z=handles.data(handles.count,3);
if ~isequal(handles.count,1)
plot3(Plotdata_x,Plotdata_y,Plotdata_z,'p','Parent',handles.coordinates);
set(handles.coordinates,'BOX','on','XGrid','on','Ygrid','on','ZGrid','on');
hold(handles.coordinates,'on');
xlabel(handles.coordinates,'X','Fontweight','bold');
ylabel(handles.coordinates,'Y','Fontweight','bold');
zlabel(handles.coordinates,'Z','Fontweight','bold');
end
ResultsStr = get(handles.points,'String');
ResultsStr = [ResultsStr;{[handles.location(handles.count,:),' : ',...
num2str(handles.data(handles.count,1)),' ',num2str(handles.data(handles.count,2)),' ',num2str(handles.data(handles.count,3))]}];
set(handles.points,'String',ResultsStr);
str_text2=sprintf('\n\nPress Stylus Button to digitize additional points \n\n OR\n\nPress STOP to finish digitization');
set(handles.text2,'String',str_text2);
COUNTER=COUNTER+1;
% handles.data
hObject=handles.get_additional;
guidata(hObject,handles);
else
DATA_ORIG(COUNTER1,1:3)=data_num(1,2:4);
if rem(COUNTER1,3)==0 & COUNTER<=length(handles.needed_loc)
if (distance(DATA_ORIG(COUNTER1,:),DATA_ORIG(COUNTER1-1,:))>0.2)|(distance(DATA_ORIG(COUNTER1-1,:),DATA_ORIG(COUNTER1-2,:))>0.2)|(distance(DATA_ORIG(COUNTER1,:),DATA_ORIG(COUNTER1-2,:))>0.2)
redigitize=1; % For redigitization
COUNTER1=COUNTER1-3;
if COUNTER<5 % For test and cardinal points
errorstring=sprintf('Distance between succesive digitization greater than 2 mm\nRedigitize point %s\nPress OK to continue',handles.needed_loc(COUNTER,:));
uiwait(msgbox(errorstring,'Error','error','modal'));
switch COUNTER
case 1
set(handles.get_test,'Enable','on');
set(handles.get_la,'Enable','off');
str_text2=sprintf('\n\n\nGet Test Point');
set(handles.text2,'String',str_text2);
case 2
set(handles.get_la,'Enable','on');
set(handles.get_ra,'Enable','off');
str_text2=sprintf('\n\n\nGet Cardinal Point LA');
set(handles.text2,'String',str_text2);
case 3
set(handles.get_ra,'Enable','on');
set(handles.get_nasion,'Enable','off');
str_text2=sprintf('\n\n\nGet Cardinal Point RA');
set(handles.text2,'String',str_text2);
case 4
set(handles.get_nasion,'Enable','on');
set(handles.get_montage,'Enable','off');
str_text2=sprintf('\n\n\nGet Cardinal Point NASION');
set(handles.text2,'String',str_text2);
end
DATA;
end
else
redigitize=0; % For all EEG Montage points
DATA(COUNTER,:)=(DATA_ORIG(COUNTER1,:)+DATA_ORIG((COUNTER1 -1),:)+DATA_ORIG((COUNTER1-2),:))/3;
switch COUNTER
case 2
str_la=sprintf('X = %2.3g cm\nY = %2.3g cm\nZ = %2.3g cm',DATA(2,1),DATA(2,2),DATA(2,3));
set(handles.text_la,'String',str_la);
case 3
str_ra=sprintf('X = %2.3g cm\nY = %2.3g cm\nZ = %2.3g cm',DATA(3,1),DATA(3,2),DATA(3,3));
set(handles.text_ra,'String',str_ra);
case 4
str_nasion=sprintf('X = %2.3g cm\nY = %2.3g cm\nZ = %2.3g cm',DATA(4,1),DATA(4,2),DATA(4,3));
set(handles.text_nasion,'String',str_nasion);
end
handles.count=COUNTER;
if isequal(handles.count,1)
if special_case==1
LOC=strvcat(LOC,handles.needed_loc(strmatch_index,:));
special_case=0;
else
LOC=strvcat(LOC,handles.needed_loc(COUNTER,:));
end
elseif handles.count<size(handles.needed_loc,1)
if special_case==1
LOC=strvcat(LOC,handles.needed_loc(strmatch_index,:));
special_case=0;
else
LOC=strvcat(LOC,handles.needed_loc(COUNTER,:));
end
elseif handles.count==size(handles.needed_loc,1)
if special_case==1
LOC=strvcat(LOC,handles.needed_loc(strmatch_index,:));
special_case=0;
else
LOC=strvcat(LOC,handles.needed_loc(COUNTER,:));
end
elseif special_case==3
LOC=strvcat(LOC,num2str(COUNTER+no_add));
else
LOC=strvcat(LOC,num2str(COUNTER));
end
handles.location=LOC;
handles.data=DATA;
if COUNTER==length(handles.needed_loc)
str_text2=sprintf('\n\nGet Additional Points if needed');
set(handles.text2,'String',str_text2);
end
if handles.count>4
DATA_TRANSF(COUNTER,1:3)=[data_num(1,2:4) 1]*T*M;
handles.data=DATA_TRANSF;
end
Plotdata_x=handles.data(handles.count,1);
Plotdata_y=handles.data(handles.count,2);
Plotdata_z=handles.data(handles.count,3);
if ~isequal(handles.count,1)
plot3(Plotdata_x,Plotdata_y,Plotdata_z,'p','Parent',handles.coordinates);
set(handles.coordinates,'BOX','on','XGrid','on','Ygrid','on','ZGrid','on');
hold(handles.coordinates,'on');
xlabel(handles.coordinates,'X','Fontweight','bold');
ylabel(handles.coordinates,'Y','Fontweight','bold');
zlabel(handles.coordinates,'Z','Fontweight','bold');
end
COUNTER=COUNTER+1;
ResultsStr = get(handles.points,'String');
if isequal(handles.count,1)
ResultsStr = {[handles.location(handles.count,:),' : ',num2str(handles.data(1,1)),' ',num2str(handles.data(1,2)),' ',num2str(handles.data(1,3))]};
else
ResultsStr = [ResultsStr;{[handles.location(handles.count,:),' : ',...
num2str(handles.data(handles.count,1)),' ',num2str(handles.data(handles.count,2)),' ',num2str(handles.data(handles.count,3))]}];
end
set(handles.points,'String',ResultsStr);
end
end
COUNTER1=COUNTER1+1;
handles.count=COUNTER;
handles.location=LOC;
hObject=handles.get_montage;
guidata(hObject,handles);
LOC
end
%--------------------------------------------------------------------------
% Function to Calculate euclidean distance between digitized points
function d=distance(X,Y)
d=sqrt(sum((X-Y).^2));
%--------------------------------------------------------------------------
% --- Executes during object creation, after setting all properties.
function logo_CreateFcn(hObject, eventdata, handles)
% hObject handle to logo (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate logo
%--------------------------------------------------------------------------