[Master Index]
[Index for Toolbox]
tess_align_tool
(Toolbox/tess_align_tool.m in BrainStorm 2.0 (Alpha))
Function Synopsis
varargout = tess_align_tool(varargin)
Help Text
TESS_ALIGN_TOOL - Application M-file for tess_align_tool.fig
function varargout = tess_align_tool(varargin)
FIG = TESS_ALIGN_TOOL launch tess_align_tool GUI.
TESS_ALIGN_TOOL('callback_name', ...) invoke the named callback.
This tool is used to align tesselated surfaces with the MEG sensor coordinate system
IMPORTANT: All input tesselations MUST be in real dimensions in METERS
All communication between functions is done using the 'data' structure containing the fields:
CurrentSubjectFolder: The current subject folder
Files: A list of all tesselation files loaded from the user (full path)
Filenames: A list of all filenames loaded
Comment: The comment structure inside the tesselation files
View: 1 if user views the tesselated surface
data.View{nFile}(tessNdx), i:#file, j:#tesselation inside the file
RGB: color of patch
data.RGB{nFile}{tessNdx) = [R G B];
Transparency: Transparency of tesselation, between 0 and 1
patchHandles: handles of ploted patches, 0 if the patch is not ploted
data.patchHandles{nFile}(tessNdx)
plotWindow: 1 if plot window has appeared at least once (it maybe closed by the user though)
plotHandle: handle of plot window (but window may not exist any more)
NasionPressed: 1 if Nasion btn pressed, 0 otherwise
LeftEarPressed: 1 if LeftEar btn pressed, 0 otherwise
RightEarPressed: 1 if RightEar btn pressed, 0 otherwise
BtnBackground: color of btn, according to bst color scheme
BtnBackgroundPressed: color of btn, to show it is pressed (during selection of points)
NasionCoord: 3x1 vector containing the coords of Nasion (in meters)
LeftEarCoord: -//-
RightEarCoord: -//-
NasionMarker: handle of marker point for nasion
LeftEarMarker: -//-
RightEarMarker: -//-
nVertices{nFile}(tessNdx)
nFaces{nFile}(tessNdx)
channelFile: full path to the loaded channel file
channelHandles: handle for the channel ploted
Cross-Reference Information
This function calls
This function is called by
Listing of function C:\BrainStorm_2001\Toolbox\tess_align_tool.m
function varargout = tess_align_tool(varargin)
%TESS_ALIGN_TOOL - Application M-file for tess_align_tool.fig
% function varargout = tess_align_tool(varargin)
% FIG = TESS_ALIGN_TOOL launch tess_align_tool GUI.
% TESS_ALIGN_TOOL('callback_name', ...) invoke the named callback.
%
% This tool is used to align tesselated surfaces with the MEG sensor coordinate system
% IMPORTANT: All input tesselations MUST be in real dimensions in METERS
%
%
% All communication between functions is done using the 'data' structure containing the fields:
%
% CurrentSubjectFolder: The current subject folder
% Files: A list of all tesselation files loaded from the user (full path)
% Filenames: A list of all filenames loaded
% Comment: The comment structure inside the tesselation files
% View: 1 if user views the tesselated surface
% data.View{nFile}(tessNdx), i:#file, j:#tesselation inside the file
% RGB: color of patch
% data.RGB{nFile}{tessNdx) = [R G B];
% Transparency: Transparency of tesselation, between 0 and 1
% patchHandles: handles of ploted patches, 0 if the patch is not ploted
% data.patchHandles{nFile}(tessNdx)
% plotWindow: 1 if plot window has appeared at least once (it maybe closed by the user though)
% plotHandle: handle of plot window (but window may not exist any more)
% NasionPressed: 1 if Nasion btn pressed, 0 otherwise
% LeftEarPressed: 1 if LeftEar btn pressed, 0 otherwise
% RightEarPressed: 1 if RightEar btn pressed, 0 otherwise
% BtnBackground: color of btn, according to bst color scheme
% BtnBackgroundPressed: color of btn, to show it is pressed (during selection of points)
% NasionCoord: 3x1 vector containing the coords of Nasion (in meters)
% LeftEarCoord: -//-
% RightEarCoord: -//-
% NasionMarker: handle of marker point for nasion
% LeftEarMarker: -//-
% RightEarMarker: -//-
% nVertices{nFile}(tessNdx)
% nFaces{nFile}(tessNdx)
% channelFile: full path to the loaded channel file
% channelHandles: handle for the channel ploted
%<autobegin> ---------------------- 12-Oct-2004 01:12:39 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: GUI and Related
%
% Alphabetical list of external functions (non-Matlab):
% publictoolbox\othertools\select3d.m
% toolbox\bst_color_scheme.m
% toolbox\bst_layout.m
% toolbox\bst_message_window.m
% toolbox\file_selection_win.m
% toolbox\phantom_channel_assignment.m
% toolbox\warp_everything_bst.m
%
% Subfunctions in this file, in order of occurrence in file:
% varargout = initialize_gui(h,eventdata,handles,varargin);
% varargout = Load_Callback(h, eventdata, handles, varargin)
% varargout = popupmenu1_Callback(h, eventdata, handles, varargin)
% varargout = tess_listbox_Callback(h, eventdata, handles, varargin)
% varargout = View_Callback(h, eventdata, handles, varargin)
% varargout = transp_slider_Callback(h, eventdata, handles, varargin)
% varargout = transp_edit_Callback(h, eventdata, handles, varargin)
% varargout = editRed_Callback(h, eventdata, handles, varargin)
% varargout = editGreen_Callback(h, eventdata, handles, varargin)
% varargout = editBlue_Callback(h, eventdata, handles, varargin)
% varargout = Nasion_Callback(h, eventdata, handles, varargin)
% varargout = NasionClick_Callback
% varargout = LeftEar_Callback(h, eventdata, handles, varargin)
% varargout = LeftEarClick_Callback
% varargout = RightEar_Callback(h, eventdata, handles, varargin)
% varargout = RightEarClick_Callback
% varargout = CTF_Callback(h, eventdata, handles, varargin)
% varargout = Neuromag_Callback(h, eventdata, handles, varargin)
% varargout = Align_Callback(h, eventdata, handles, varargin)
% varargout = Channels_Callback(h, eventdata, handles, varargin)
% varargout = ViewChannels_Callback(h, eventdata, handles, varargin)
% varargout = AlignChannels_Callback(h, eventdata, handles, varargin)
% phantom_Callback(h, eventdata, handles)
% varargout = Quit_Callback(h, eventdata, handles, varargin)
%
% Group : Preference data and their calls in this file:
% BST = getpref('BrainStorm');
%
% Application data and their calls in this file:
% 'LeftEarMarker'
% 'NasionMarker'
% 'RightEarMarker'
% 'TileType'
% 'data'
% 'tess_align_tool_handles'
%
% setappdata(0,'LeftEarMarker',LeftEarMarker);
% setappdata(0,'NasionMarker',NasionMarker);
% setappdata(0,'RightEarMarker',RightEarMarker);
% setappdata(0,'tess_align_tool_handles',handles);
% setappdata(data.plotHandle,'TileType','T')
% setappdata(fig,'TileType','T')
% setappdata(fig,'data',data);
%
% LeftEarMarker = getappdata(0,'LeftEarMarker');
% NasionMarker = getappdata(0,'NasionMarker');
% RightEarMarker = getappdata(0,'RightEarMarker');
% data = getappdata(fig,'data');
% handles = getappdata(0,'tess_align_tool_handles');
%
% Figure Files opened by this function:
% mfilename
%
% Format of strings below: Type:Style:Tag, "String", CallBack Type and Call
% <automatic> callback is <Tag>_Callback by Matlab default
%
% Callbacks by figure tess_align_tool.fig
% uicontrol:checkbox:View "View" uses Callback for <automatic>
% uicontrol:checkbox:ViewChannels "View" uses Callback for <automatic>
% uicontrol:edit:editBlue "240" uses Callback for <automatic>
% uicontrol:edit:editGreen "240" uses Callback for <automatic>
% uicontrol:edit:editRed "240" uses Callback for <automatic>
% uicontrol:edit:transp_edit "1" uses Callback for <automatic>
% uicontrol:listbox:tess_listbox "No Selected Tessellation File" uses Callback for <automatic>
% uicontrol:popupmenu:popupmenu1 "No Tessellations Loaded" uses Callback for <automatic>
% uicontrol:pushbutton:Align "Align Tessellations" uses Callback for <automatic>
% uicontrol:pushbutton:AlignChannels "Align Channels" uses Callback for <automatic>
% uicontrol:pushbutton:Channels "Load Channels" uses Callback for <automatic>
% uicontrol:pushbutton:LeftEar "Left Pre-auricular" uses Callback for <automatic>
% uicontrol:pushbutton:Load "Load" uses Callback for <automatic>
% uicontrol:pushbutton:Nasion "Nasion" uses Callback for <automatic>
% uicontrol:pushbutton:phantom "Phantom Study" uses Callback for <automatic>
% uicontrol:pushbutton:Quit "Quit" uses Callback for <automatic>
% uicontrol:pushbutton:RightEar "Right Pre-auricular" uses Callback for <automatic>
% uicontrol:radiobutton:CTF "CTF" uses Callback for <automatic>
% uicontrol:radiobutton:Neuromag "Neuromag" uses Callback for <automatic>
% uicontrol:slider:transp_slider "" uses Callback for <automatic>
%
% At Check-in: $Author: Mosher $ $Revision: 20 $ $Date: 10/11/04 11:34p $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 23-Sep-2004
%
% Principal Investigators and Developers:
% ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
% University of Southern California, Los Angeles, CA
% ** John C. Mosher, PhD, Biophysics Group,
% Los Alamos National Laboratory, Los Alamos, NM
% ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
% CNRS, Hopital de la Salpetriere, Paris, France
%
% See BrainStorm website at http://neuroimage.usc.edu for further information.
%
% Copyright (c) 2004 BrainStorm by the University of Southern California
% This software distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html .
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%<autoend> ------------------------ 12-Oct-2004 01:12:39 -----------------------
% /---Script Author--------------------------------------\
% | |
% | *** Dimitrios Pantazis, Ph.D. student |
% | University of Southern California |
% | |
% \------------------------------------------------------/
% Date of creation: May 2004
% ----------------------------- Script History ---------------------------------
% 14-May-2004 DP Creation
% 16-May-2004 JCM Commenting
% 17-May-2004 DP More corrections, additions.
% 18-May-2004 DP Minor bug fixes to remove error messages. Aligned files have updated Comments
% Now we can load EEG channels as well
% 20-May-2004 DP Add color, change cursor into cross, fix some bugs, change window into 2x2-1
% 21-May-2004 DP Display number of vertices/faces
% 26-May-2004 DP Align EEG channels by choosing 3 sensors as fiducials
% 04-June-2004 DP When user chooses color outside [0 255] it reverts to previous color
% Fixed bug: when user choosed Neuromage and aligned, the file was saved with CTF tag
% 16-June-2004 JCM find fiducial points, changed to NameList = {Channel.Name};,
% (not Channel.Type)
% 27-Sept-2004 DP Support for Landmark Structure inside the channel file.
% Alignment of channels is done using these landmarks if they exist
% Also, channels are plotted as yellow circles
% 04-Oct-2004 DP Support for EEG phantom study
% ----------------------------- Script History ---------------------------------
% Last Modified by GUIDE v2.5 04-Oct-2004 11:24:10
if nargin == 2 % LAUNCH GUI
fig = openfig(mfilename,'reuse');
bst_color_scheme(fig);
setappdata(fig,'TileType','T')
bst_layout('align',fig,2,1,2)
set(fig,'visible','on'); % .fig saved as invisible until ready
% Generate a structure of handles to pass to callbacks, and store it.
handles = guihandles(fig);
guidata(fig, handles);
if nargout > 0
varargout{1} = fig;
end
%the current subject folder is the second argument
data.CurrentSubjectFolder = varargin{2};
data.plotWindow = 0;
data.NasionPressed = 0;
data.LeftEarPressed = 0;
data.RightEarPressed = 0;
data.BtnBackground = get(handles.Load,'BackgroundColor'); %to restore buttons when unpressed
data.BtnBackgroundPressed = [.7 .7 .3]; %to restore buttons when unpressed
%save application data
setappdata(fig,'data',data);
elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK
try
if (nargout)
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
else
feval(varargin{:}); % FEVAL switchyard
end
catch
disp(lasterr);
end
end
% ------------------- Local Functions --------------------------
% ---------------------------------------------------------------
function varargout = initialize_gui(h,eventdata,handles,varargin);
% This function initializes GUI controls, as well as two structures, 'data' and 'changed'
fig = handles.tess_align_tool; % make sure we have the handle
handles = guidata(fig);
% -------------------- CALLBACKS ---------------------------------
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function varargout = Load_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%Open window to ask for tesselation files
filetype{1} = 'tess';
[Files Filenames] = file_selection_win(filetype,data.CurrentSubjectFolder);
data.Files = Files;
data.Filenames = Filenames;
if(isempty(Files{1})) %if no files are loaded
return
end
%Get comments from files (to show in listbox)
for i = 1:size(Files,2)
temp = load(Files{i},'Comment','Faces','Vertices'); %temp.Comment has the result
data.Comment{i} = temp.Comment; %data.Comment{i}[j]
for j = 1:size(data.Comment{i},2) %for all tessellations inside the file
data.nVertices{i}(j) = size(temp.Vertices{j},2);
data.nFaces{i}(j) = size(temp.Faces{j},1);
end
clear temp
end
%update popupmenu
if ~isempty(Filenames)
set(handles.popupmenu1,'String',Filenames,'Max',length(Filenames),'enable','on','value',1)
else
ErrorString = sprintf('No Tess files were found in %s',data.CurrentSubjectFolder);
set(handles.listbox,'String',ErrorString)
return
end
%update listbox
set(handles.tess_listbox,'String',data.Comment{1},'value',1,'enable','on');
%update other menus and variables
for i = 1:size(Files,2)
data.View{i} = zeros(size(data.Comment{i},2),1); %default not view (memory and speed considerations)
data.Transparency{i} = ones(size(data.Comment{i},2),1); %by default no transparency
data.patchHandles{i} = zeros(size(data.Comment{i},2),1); %default zero, ie no patch is currently ploted
for j = 1:size(data.Comment{i},2) %number tessellations inside the file
data.RGB{i}{j} = [240 240 240];
end
end
set(handles.tessEdit,'string',[num2str(data.nFaces{1}(1)) ' Faces - ' num2str(data.nVertices{1}(1)) ' Vertices ']);
set(handles.View,'enable','on','value',0);
set(handles.transp_slider,'value',1,'enable','on');
set(handles.transp_edit,'string',1,'enable','on');
set(handles.editRed,'enable','on');
set(handles.editGreen,'enable','on');
set(handles.editBlue,'enable','on');
data.NasionPressed = 0;
data.LeftEarPressed = 0;
data.RightEarPressed = 0;
figure(handles.tess_align_tool);
setappdata(fig,'data',data);
%if plot window exists, delete it
if data.plotWindow & isfield(data,'plotHandle')
if(ishandle(data.plotHandle))
delete(data.plotWindow)
end
end
set(handles.ViewChannels,'value',0);
% --------------------------------------------------------------------
function varargout = popupmenu1_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%get selected tesselation
tessNdx = get(handles.popupmenu1,'value');
%update listbox
set(handles.tess_listbox,'String',data.Comment{tessNdx},'value',1,'enable','on');
%update controls
set(handles.View,'value',data.View{tessNdx}(1));
set(handles.transp_slider,'value',data.Transparency{tessNdx}(1));
set(handles.transp_edit,'String',data.Transparency{tessNdx}(1));
set(handles.editRed,'String',data.RGB{tessNdx}{1}(1));
set(handles.editGreen,'String',data.RGB{tessNdx}{1}(2));
set(handles.editBlue,'String',data.RGB{tessNdx}{1}(3));
set(handles.tessEdit,'string',[num2str(data.nFaces{tessNdx}(1)) ' Faces - ' num2str(data.nVertices{tessNdx}(1)) ' Vertices ']);
% --------------------------------------------------------------------
function varargout = tess_listbox_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%get selected tesselation
tessNdx = get(handles.popupmenu1,'value');
tessSubNdx = get(handles.tess_listbox,'value');
%update controls
set(handles.View,'value',data.View{tessNdx}(tessSubNdx));
set(handles.transp_slider,'value',data.Transparency{tessNdx}(tessSubNdx));
set(handles.transp_edit,'String',data.Transparency{tessNdx}(tessSubNdx));
set(handles.editRed,'String',data.RGB{tessNdx}{tessSubNdx}(1));
set(handles.editGreen,'String',data.RGB{tessNdx}{tessSubNdx}(2));
set(handles.editBlue,'String',data.RGB{tessNdx}{tessSubNdx}(3));
set(handles.tessEdit,'string',[num2str(data.nFaces{tessNdx}(tessSubNdx)) ' Faces - ' num2str(data.nVertices{tessNdx}(tessSubNdx)) ' Vertices ']);
% --------------------------------------------------------------------
function varargout = View_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%get current state of controls
viewmode = get(handles.View,'value'); %1 if checked
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
%update view
data.View{tessNdx}(tessSubNdx) = viewmode;
%if plot for the first time (or user closed plot window)
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
%open figure to plot
data.plotHandle = figure('visible','off');
bst_color_scheme(data.plotHandle);
setappdata(data.plotHandle,'TileType','T')
set(data.plotHandle,'menubar','figure','toolbar','figure');
bst_layout('align',data.plotHandle,2,2,1);
figure(data.plotHandle); % make active figure
set(data.plotHandle,'name','Tessellations');
set(data.plotHandle,'visible','on');
light
axis equal
axis off
axis vis3d
%go through all tesselations and see if they need to be ploted
%this is necessary only if figure was accidentaly closed
for i = 1:size(data.Comment,2) %for all files
loadfile = 0; %to avoid loading the same file many times
for j = 1:size(data.Comment{i},2) %for all tesselations inside the file
if (data.View{i}(j)) %if asked to plot
if(loadfile == 0) %load file if nesessary
load(data.Files{i},'Vertices','Faces');
end
FV.vertices = Vertices{j}';
FV.faces = Faces{j};
nVertices = size(FV.vertices,1);
figure(data.plotHandle);
FaceVertexCData = ones(nVertices,1)*data.RGB{i}{j}/255;
data.patchHandles{i}(j) = patch(FV,'FaceColor','interp','EdgeColor','none','FaceVertexCData',FaceVertexCData,'faceAlpha',data.Transparency{i}(j)); %plot surface
lighting gouraud
loadfile = 1;
end
end
loadfile = 0;
end
data.plotWindow = 1;
setappdata(fig,'data',data);
return
end
if(~viewmode) %if asked to stop viewing a surface
setappdata(fig,'data',data);
%if patch exists
h = data.patchHandles{tessNdx}(tessSubNdx);
if ( h~=0 & ishandle(h) )
delete(h);
data.patchHandles{tessNdx}(tessSubNdx)=0;
end
setappdata(fig,'data',data);
return;
end
%This part runs only if plot on the same figure again
load(data.Files{tessNdx},'Vertices','Faces');
FV.vertices = Vertices{tessSubNdx}';
FV.faces = Faces{tessSubNdx};
nVertices = size(FV.vertices,1);
figure(data.plotHandle);
FaceVertexCData = ones(nVertices,1)*data.RGB{tessNdx}{tessSubNdx}/255;
data.patchHandles{tessNdx}(tessSubNdx) = patch(FV,'FaceColor','interp','EdgeColor','none','FaceVertexCData',FaceVertexCData,'faceAlpha',data.Transparency{tessNdx}(tessSubNdx)); %plot surface
lighting gouraud
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = transp_slider_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
% Get the new value for the threshold from the slider
NewVal = get(h,'Value');
% Set the value of the edit box to the new value set by slider
set(handles.transp_edit,'String',NewVal);
%update data
data.Transparency{tessNdx}(tessSubNdx) = NewVal;
%update patch if available
h = data.patchHandles{tessNdx}(tessSubNdx);
if( h~=0 & ishandle(h))
set(h,'faceAlpha',data.Transparency{tessNdx}(tessSubNdx));
end
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = transp_edit_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
% Get the new value for the threshold
NewStrVal = get(h,'String');
NewVal = str2num(NewStrVal);
% Check that the entered value falls within the allowable range
if isempty(NewVal) | (NewVal< 0) | (NewVal>1),
% Revert to last value, as indicated by Threshold Slider
OldVal = get(handles.transp_edit,'Value');
set(h,'String',OldVal);
else
% Set the value of the threshold to the new value
set(handles.transp_slider,'Value',NewVal);
data.Transparency{tessNdx}(tessSubNdx) = NewVal;
%update patch if available
h = data.patchHandles{tessNdx}(tessSubNdx);
if( h~=0 & ishandle(h))
set(h,'faceAlpha',data.Transparency{tessNdx}(tessSubNdx));
end
end
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = editRed_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
% Get the new value for the threshold
NewStrVal = get(h,'String');
NewVal = str2num(NewStrVal);
% Check that the entered value falls within the allowable range
if isempty(NewVal) | (NewVal< 0) | (NewVal>256),
% Revert to previous value
set(h,'String',data.RGB{tessNdx}{tessSubNdx}(1));
else
% Set the value of the threshold to the new value
NewVal = round(NewVal);
set(h,'string',num2str(NewVal));
data.RGB{tessNdx}{tessSubNdx}(1) = NewVal;
%update patch if available
h = data.patchHandles{tessNdx}(tessSubNdx);
if( h~=0 & ishandle(h))
nVertices = size(get(h,'FaceVertexCData'),1);
FaceVertexCData = ones(nVertices,1)*data.RGB{tessNdx}{tessSubNdx}/255;
set(h,'FaceVertexCData',FaceVertexCData);
end
end
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = editGreen_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
% Get the new value for the threshold
NewStrVal = get(h,'String');
NewVal = str2num(NewStrVal);
% Check that the entered value falls within the allowable range
if isempty(NewVal) | (NewVal< 0) | (NewVal>256),
% Revert to previous value
set(h,'String',data.RGB{tessNdx}{tessSubNdx}(2));
else
% Set the value of the threshold to the new value
NewVal = round(NewVal);
set(h,'string',num2str(NewVal));
data.RGB{tessNdx}{tessSubNdx}(2) = NewVal;
%update patch if available
h = data.patchHandles{tessNdx}(tessSubNdx);
if( h~=0 & ishandle(h))
nVertices = size(get(h,'FaceVertexCData'),1);
FaceVertexCData = ones(nVertices,1)*data.RGB{tessNdx}{tessSubNdx}/255;
set(h,'FaceVertexCData',FaceVertexCData);
end
end
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = editBlue_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
% Get the new value for the threshold
NewStrVal = get(h,'String');
NewVal = str2num(NewStrVal);
% Check that the entered value falls within the allowable range
if isempty(NewVal) | (NewVal< 0) | (NewVal>256),
% Revert to previous value
set(h,'String',data.RGB{tessNdx}{tessSubNdx}(3));
else
% Set the value of the threshold to the new value
NewVal = round(NewVal);
set(h,'string',num2str(NewVal));
data.RGB{tessNdx}{tessSubNdx}(3) = NewVal;
%update patch if available
h = data.patchHandles{tessNdx}(tessSubNdx);
if( h~=0 & ishandle(h))
nVertices = size(get(h,'FaceVertexCData'),1);
FaceVertexCData = ones(nVertices,1)*data.RGB{tessNdx}{tessSubNdx}/255;
set(h,'FaceVertexCData',FaceVertexCData);
end
end
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = Nasion_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%if no plotWindow exists
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
bst_message_window('append','Please plot a tesselation surface first');
return
end
%if pressed for first time, activate point clinking
if(data.NasionPressed == 0)
%update button status
set(handles.Nasion,'string','Nasion','backgroundColor',data.BtnBackgroundPressed');
set(handles.LeftEar,'enable','off');
set(handles.RightEar,'enable','off');
set(data.plotHandle,'pointer','crosshair');
%without pause it crashes when another figure is open!
pause(.1);
figure(data.plotHandle);
%save tool handles on root window, so they can be accessed by NasionClick fn
setappdata(0,'tess_align_tool_handles',handles);
%save marker on root window
%check if we already have a nasion marker
if(~isfield(data,'NasionMarker') | ~ishandle(data.NasionMarker))
data.NasionMarker = line('marker','o','markerfacecolor','k','erasemode','xor','visible','off');
end
NasionMarker = data.NasionMarker;
setappdata(0,'NasionMarker',NasionMarker);
%activate pointclicking on plotWindow
set(data.plotHandle,'windowbuttondownfcn','tess_align_tool(''NasionClick_Callback'')');
data.NasionPressed = 1; %it is now pressed
setappdata(fig,'data',data);
return
end
%if pressed for second time:
%restore buttons
set(handles.Nasion,'string','Nasion','backgroundColor',data.BtnBackground');
set(handles.LeftEar,'enable','on');
set(handles.RightEar,'enable','on');
data.NasionPressed = 0;
%stop finding points in plot window
set(data.plotHandle,'windowbuttondownfcn','');
set(data.plotHandle,'pointer','arrow');
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = NasionClick_Callback
handles = getappdata(0,'tess_align_tool_handles'); %access tesselation tool
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%read the marker from root window
NasionMarker = getappdata(0,'NasionMarker');
%get coordinates of point
[p v vi face facei] = select3d;
if(isempty(p) & isempty(v)) %if user did not click on a tesselation
return
end
if (isempty(p)) %if uses chooses the same point again
p=v;
end
set(NasionMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));
coord = sprintf('%-5.2f %-5.2f %-5.2f (mm)',p(1)*1000,p(2)*1000,p(3)*1000);
set(handles.nasiontext,'string',coord)
data.NasionCoord = p;
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = LeftEar_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%if no plotWindow exists
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
bst_message_window('append','Please plot a tesselation surface first');
return
end
%if pressed for first time, activate point clinking
if(data.LeftEarPressed == 0)
%update button status
set(handles.LeftEar,'string','LeftEar','backgroundColor',data.BtnBackgroundPressed');
set(handles.Nasion,'enable','off');
set(handles.RightEar,'enable','off');
set(data.plotHandle,'pointer','crosshair');
%without pause it crashes when another figure is open!
pause(.1);
figure(data.plotHandle);
%save tool handles on root window, so they can be accessed by NasionClick fn
setappdata(0,'tess_align_tool_handles',handles);
%save marker on root window
%check if we already have a nasion marker
if(~isfield(data,'LeftEarMarker') | ~ishandle(data.LeftEarMarker))
data.LeftEarMarker = line('marker','o','markerfacecolor','k','erasemode','xor','visible','off');
end
LeftEarMarker = data.LeftEarMarker;
setappdata(0,'LeftEarMarker',LeftEarMarker);
%activate pointclicking on plotWindow
set(data.plotHandle,'windowbuttondownfcn','tess_align_tool(''LeftEarClick_Callback'')');
data.LeftEarPressed = 1; %it is now pressed
setappdata(fig,'data',data);
return
end
%if pressed for second time:
%restore buttons
set(handles.LeftEar,'string','LeftEar','backgroundColor',data.BtnBackground');
set(handles.Nasion,'enable','on');
set(handles.RightEar,'enable','on');
data.LeftEarPressed = 0;
%stop finding points in plot window
set(data.plotHandle,'windowbuttondownfcn','');
set(data.plotHandle,'pointer','arrow');
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = LeftEarClick_Callback
handles = getappdata(0,'tess_align_tool_handles'); %access tesselation tool
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%read the marker from root window
LeftEarMarker = getappdata(0,'LeftEarMarker');
%get coordinates of point
[p v vi face facei] = select3d;
if(isempty(p) & isempty(v)) %if user did not click on a tesselation
return
end
if (isempty(p)) %if uses chooses the same point again
p=v;
end
set(LeftEarMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));
coord = sprintf('%-5.2f %-5.2f %-5.2f (mm)',p(1)*1000,p(2)*1000,p(3)*1000);
set(handles.lefteartext,'string',coord)
data.LeftEarCoord = p;
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = RightEar_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%if no plotWindow exists
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
bst_message_window('append','Please plot a tesselation surface first');
return
end
%if pressed for first time, activate point clinking
if(data.RightEarPressed == 0)
%update button status
set(handles.RightEar,'string','RightEar','backgroundColor',data.BtnBackgroundPressed');
set(handles.LeftEar,'enable','off');
set(handles.Nasion,'enable','off');
set(data.plotHandle,'pointer','crosshair');
%without pause it crashes when another figure is open!
pause(.1);
figure(data.plotHandle);
%save tool handles on root window, so they can be accessed by NasionClick fn
setappdata(0,'tess_align_tool_handles',handles);
%save marker on root window
%check if we already have a nasion marker
if(~isfield(data,'RightEarMarker') | ~ishandle(data.RightEarMarker))
data.RightEarMarker = line('marker','o','markerfacecolor','k','erasemode','xor','visible','off');
end
RightEarMarker = data.RightEarMarker;
setappdata(0,'RightEarMarker',RightEarMarker);
%activate pointclicking on plotWindow
set(data.plotHandle,'windowbuttondownfcn','tess_align_tool(''RightEarClick_Callback'')');
data.RightEarPressed = 1; %it is now pressed
setappdata(fig,'data',data);
return
end
%if pressed for second time:
%restore buttons
set(handles.RightEar,'string','RightEar','backgroundColor',data.BtnBackground');
set(handles.LeftEar,'enable','on');
set(handles.Nasion,'enable','on');
data.RightEarPressed = 0;
%stop finding points in plot window
set(data.plotHandle,'windowbuttondownfcn','');
set(data.plotHandle,'pointer','arrow');
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = RightEarClick_Callback
handles = getappdata(0,'tess_align_tool_handles'); %access tesselation tool
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%read the marker from root window
RightEarMarker = getappdata(0,'RightEarMarker');
%get coordinates of point
[p v vi face facei] = select3d;
if(isempty(p) & isempty(v)) %if user did not click on a tesselation
return
end
if (isempty(p)) %if uses chooses the same point again
p=v;
end
set(RightEarMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));
coord = sprintf('%-5.2f %-5.2f %-5.2f (mm)',p(1)*1000,p(2)*1000,p(3)*1000);
set(handles.righteartext,'string',coord)
data.RightEarCoord = p;
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = CTF_Callback(h, eventdata, handles, varargin)
set(handles.Neuromag,'value',0);
% --------------------------------------------------------------------
function varargout = Neuromag_Callback(h, eventdata, handles, varargin)
set(handles.CTF,'value',0);
% --------------------------------------------------------------------
function varargout = Align_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%Check if used specified all points
if(~isfield(data,'NasionCoord') | ~isfield(data,'LeftEarCoord') | ~isfield(data,'RightEarCoord') )
bst_message_window('append','Please choose Nasion, Left Ear and Right Ear points before continuing');
return
end
%if used did not choose CTF or Neuromag
if (get(handles.CTF,'value') == 0 & get(handles.Neuromag,'value') == 0)
bst_message_window('append','Please choose CTF or Neuromag system before aligning tessellations');
return
end
%if already aligned
if ( findstr(data.Files{1},'alignedCTF') | findstr(data.Files{1},'alignedNeuromag') )
ButtonName=questdlg('The file(s) already seem aligned. Do you want to align them again ?', ...
'Warning', ...
'Yes','No','No');
if(strcmp(ButtonName,'No'))
return
end
end
%delete them, the user may want to specify them again
if(isfield(data,'NasionMarker'))
data = rmfield(data,'NasionMarker');
end
if(isfield(data,'LeftEarMarker'))
data = rmfield(data,'LeftEarMarker');
end
if(isfield(data,'RightEarMarker'))
data = rmfield(data,'RightEarMarker');
end
%if used everything ok
bst_message_window('append','Generating files with aligned tessellations...');
%Fiducial coordinates in m
NAS = data.NasionCoord;
LPA = data.LeftEarCoord;
RPA = data.RightEarCoord;
% Move to SCS
% Definition:
% Xscs = R Xmri + T ; Xmri in mm
%if CTF-------------------
if ( get(handles.CTF,'value') == 1 )
Origin = .5*(LPA+RPA); % in m
vx = (NAS-Origin)/norm((NAS-Origin));
vz = cross(vx, LPA-RPA); vz = vz/norm(vz); % Vector normal to the NLR plane, pointing upwards
vy = cross(vz,vx); vy = vy/norm(vy);
R = inv([vx,vy,vz]); % Rotation
T = - R * Origin; % Translation
alignment = 'CTF';
end
%if Neuromag-------------------
if ( get(handles.Neuromag,'value') == 1 )
OR = dot(RPA-NAS,RPA-LPA)/dot(RPA-LPA,RPA-LPA) * (RPA-LPA);
Origin = RPA - OR;
vx = OR/norm(OR);
vy = (NAS-Origin)/norm(NAS - Origin);
vz = cross(vx,vy);
R = inv([vx,vy,vz]); % Rotation
T = - R * Origin; % Translation
alignment = 'Neuromag';
end
%Align tesselations in all files
for i = 1:size(data.Comment,2) %for all files
load(data.Files{i},'Vertices','Faces');
clear Comment;
for j = 1:size(data.Comment{i},2) %for all tesselations inside the file
%vert_pcs = R*vert + T
Vertices{j} = [R T] * [Vertices{j} ; ones(1,size(Vertices{j},2))];
Comment{j} = [data.Comment{i}{j} '_' alignment];
end
data.Comment{i} = Comment;
if ( get(handles.CTF,'value') == 1 )
data.Files{i} = [data.Files{i}(1:end-4) '_alignedCTF.mat'];
data.Filenames{i} = [data.Filenames{i}(1:end-4) '_alignedCTF.mat'];
else
data.Files{i} = [data.Files{i}(1:end-4) '_alignedNeuromag.mat'];
data.Filenames{i} = [data.Filenames{i}(1:end-4) '_alignedNeuromag.mat'];
end
save(data.Files{i},'Vertices','Faces','Comment');
bst_message_window('append',['File created: ' data.Files{i}]);
end
bst_message_window('append','Tessellations were aligned successfully');
%loading aligned tesselations------------
bst_message_window('append','...');
bst_message_window('append','Loading Aligned Tessellations...');
%update popupmenu
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
set(handles.popupmenu1,'String',data.Filenames,'Max',length(data.Filenames),'enable','on')
%if plot window exists, delete it
if data.plotWindow & isfield(data,'plotHandle')
if(ishandle(data.plotHandle))
delete(data.plotWindow)
end
end
setappdata(fig,'data',data);
View_Callback(h, eventdata, handles, varargin)
%update listbox
tessNdx = get(handles.popupmenu1,'value'); %tesselation index
tessSubNdx = get(handles.tess_listbox,'value'); %tess inside the file
set(handles.tess_listbox,'String',data.Comment{tessNdx},'value',tessSubNdx,'enable','on');
bst_message_window('append','Loading done.');
% --------------------------------------------------------------------
function varargout = Channels_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%Open window to ask for channel file
[filename, pathname] = uigetfile('*channel*.*','Load a channel file from a relevant STUDY folder');
if(filename == 0)
return
end
data.channelFile = [pathname filename];
load(data.channelFile);
set(handles.AlignChannels,'enable','on');
%Get locations of landmarks
k = 1;
if exist('Landmark')
for i = 1:size(Landmark.Loc,2) %for all landmarks
SensorLoc(:,k) = Landmark.Loc(:,k);
k=k+1;
end
end
%Get locations of sensors
for i = 1:size(Channel,2) %for all sensors
if ~isempty(Channel(i).Loc) & (strcmp(Channel(i).Type,'MEG') | strcmp(Channel(i).Type,'EEG'))
SensorLoc(:,k) = Channel(i).Loc(:,1);
k=k+1;
end
end
nSensors = size(SensorLoc,2);
%if plot for the first time (or user closed plot window)
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
%open figure to plot
data.plotHandle = figure('visible','off');
bst_color_scheme(data.plotHandle);
setappdata(data.plotHandle,'TileType','T')
set(data.plotHandle,'menubar','figure','toolbar','figure');
bst_layout('align',data.plotHandle,2,2,1);
set(data.plotHandle,'visible','on');
set(data.plotHandle,'name','Tessellations');
light
axis equal
axis off
axis vis3d
end
%if old channel is already ploted
if(isfield(data,'channelHandles') )
if(ishandle(data.channelHandles))
delete(data.channelHandles)
end
end
figure(data.plotHandle);
hold on;
data.channelHandles = plot3(SensorLoc(1,:),SensorLoc(2,:),SensorLoc(3,:),'ko');
set(data.channelHandles,'markerfacecolor','yellow');
data.SensorLoc = SensorLoc;
set(handles.ViewChannels,'enable','on','value',1);
set(handles.AlignChannels,'enable','on');
data.plotWindow = 1;
setappdata(fig,'data',data);
%enable phantom button
set(handles.phantom,'enable','on');
% --------------------------------------------------------------------
function varargout = ViewChannels_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%get current state of controls
viewmode = get(handles.ViewChannels,'value'); %1 if checked
%if view enabled
if(viewmode)
%if plot for the first time (or user closed plot window)
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
%open figure to plot
data.plotHandle = figure('visible','off');
bst_color_scheme(data.plotHandle);
setappdata(data.plotHandle,'TileType','T')
set(data.plotHandle,'menubar','figure','toolbar','figure');
bst_layout('align',data.plotHandle,2,2,1);
set(data.plotHandle,'visible','on');
set(data.plotHandle,'name','Tessellations');
light
axis vis3d
end
figure(data.plotHandle);
hold on
data.channelHandles = plot3(data.SensorLoc(1,:),data.SensorLoc(2,:),data.SensorLoc(3,:),'ko');
set(data.channelHandles,'markerfacecolor','yellow');
axis equal
axis off
else
if(ishandle(data.channelHandles))
delete(data.channelHandles)
end
end
setappdata(fig,'data',data);
% --------------------------------------------------------------------
function varargout = AlignChannels_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
if(~isfield(data,'channelFile'))
bst_message_window('append','No channel file loaded...');
end
%if no CTF or Neuromag is selected
if( ( get(handles.CTF,'value') == 0 ) & ( get(handles.Neuromag,'value') == 0 ) )
bst_message_window('append','Please select CTF or Neuromag before aligning the channels.');
return;
end
bst_message_window('append','Aligning Channels...');
%load channel file
load(data.channelFile)
nChannels = size(Channel,2);
%find fiducial points
if exist('Landmark') %If a Landmark structure is available at channel file
NameList = Landmark.Name;
else %if no Landmark structure, check the channels for fiducials
NameList = {Channel.Name};
end
%find nasion
[nasionNdx,ok] = listdlg('PromptString','Select Nasion:',...
'SelectionMode','single',...
'ListString',NameList);
if(~ok)
bst_message_window('append','Channel alignment canceled by the user.');
return
end
%find left ear
[leftearNdx,ok] = listdlg('PromptString','Select Left Pre-auricular:',...
'SelectionMode','single',...
'ListString',NameList);
if(~ok)
bst_message_window('append','Channel alignment canceled by the user.');
return
end
%find right ear
[rightearNdx,ok] = listdlg('PromptString','Select Right Pre-auricular:',...
'SelectionMode','single',...
'ListString',NameList);
if(~ok)
bst_message_window('append','Channel alignment canceled by the user.');
return
end
%Fiducial coordinates in m
if exist('Landmark') %If a Landmark structure is available at channel file
NAS = Landmark.Loc(:,nasionNdx);
LPA = Landmark.Loc(:,leftearNdx);
RPA = Landmark.Loc(:,rightearNdx);
else
NAS = Channel(nasionNdx).Loc(:,1);
LPA = Channel(leftearNdx).Loc(:,1);
RPA = Channel(rightearNdx).Loc(:,1);
end
%if CTF-------------------
if ( get(handles.CTF,'value') == 1 )
Origin = .5*(LPA+RPA); % in m
vx = (NAS-Origin)/norm((NAS-Origin));
vz = cross(vx, LPA-RPA); vz = vz/norm(vz); % Vector normal to the NLR plane, pointing upwards
vy = cross(vz,vx); vy = vy/norm(vy);
R = inv([vx,vy,vz]); % Rotation
T = - R * Origin; % Translation
alignment = 'CTF';
end
%if Neuromag-------------------
if ( get(handles.Neuromag,'value') == 1 )
OR = dot(RPA-NAS,RPA-LPA)/dot(RPA-LPA,RPA-LPA) * (RPA-LPA);
Origin = RPA - OR;
vx = OR/norm(OR);
vy = (NAS-Origin)/norm(NAS - Origin);
vz = cross(vx,vy);
R = inv([vx,vy,vz]); % Rotation
T = - R * Origin; % Translation
alignment = 'Neuromag';
end
%align channels
for i = 1:nChannels
if ~isempty(Channel(i).Loc)
Channel(i).Loc = R * Channel(i).Loc + T*ones(1,size(Channel(i).Loc,2));
end
end
%align fiducials
if exist('Landmark') %If a Landmark structure is available at channel file
for i = 1:size(Landmark.Name,2) %for all fiducials
Landmark.Loc(:,i) = R * Landmark.Loc(:,i) + T;
end
end
if exist('Landmark') %If a Landmark structure is available at channel file
save(data.channelFile,'Channel','Landmark');
else
save(data.channelFile,'Channel');
end
bst_message_window('append','Aligned Channels saved.');
bst_message_window('append','Use View check box to make sure proper alignment was performed.');
%update 'data' structure with new channel
k = 1;
for i = 1:size(Channel,2) %for all sensors
if ~isempty(Channel(i).Loc) & (strcmp(Channel(i).Type,'MEG') | strcmp(Channel(i).Type,'EEG'))
SensorLoc(:,k) = Channel(i).Loc(:,1);
k=k+1;
end
end
data.SensorLoc = SensorLoc;
setappdata(fig,'data',data);
%if previous channel is ploted, delete it
if ishandle(data.channelHandles)
delete(data.channelHandles)
end
%view new channels
set(handles.ViewChannels,'value',1);
ViewChannels_Callback(h, eventdata, handles, varargin);
% --- Executes on button press in phantom
function phantom_Callback(h, eventdata, handles)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%Load Channel structure of the current subject
load(data.channelFile);
if(~exist('Landmark'))
Landmark.Loc = [];
Landmark.Name = [];
end
%check if channel structure loaded is MEG or EEG
for i = 1:size(Channel,2)
if strcmp(Channel(i).Type,'MEG')
bst_message_window('append','You have loaded an MEG channel file. Phantom study can only be used with EEG data.');
return
end
end
%ask if channels already aligned
reply = questdlg('Is the loaded channel structure already aligned ?');
if(strcmp(reply,'No'))
bst_message_window('append','You need to align the channel structure before beginning a phantom study');
return
end
if(strcmp(reply,'Cancel'))
bst_message_window('append','Phantom study canceled by user');
return
end
%Define Montreal Channel structure
MontrealLandmarks.Name = {'Nasion' 'Left Ear' 'Right Ear' 'Inion' 'Vertex'};
MontrealLandmarks.Loc = ...
[ 0.10434000000000 0 -0.00063000000000
0 0.08362000000000 0
0 -0.08802000000000 0
-0.09573000000000 0 0.01785000000000
-0.01165486688092 0 0.15651869702676]';
MontrealChannels.Name = {'Pz' 'Cz' 'Fz' 'T4' 'C4' 'C3' 'T3' 'F7' 'Fp1' 'Fp2' ...
'F8' 'T5' 'O1' 'O2' 'T6' 'F4' 'F3' 'P4' 'P3'};
MontrealChannels.Loc = ...
[ -0.05792508326798 0 0.13009954873992
0.01779538314226 0 0.15466091749303
0.08767449798897 0 0.11656588167251
0.00653288804504 -0.08629718738544 0.05677778617344
0.01607681017220 -0.04789883192913 0.13972467980692
0.01581340973800 0.04760625938827 0.13743544824075
0.00585282960606 0.08437947505500 0.05086735079364
0.06635064237460 0.07261152071121 0.04376571666545
0.10878654711220 0.02906067377269 0.04002406853314
0.10792762776112 -0.03072211171739 0.04223059574545
0.06732589423211 -0.07503869402653 0.04883069377766
-0.05072450476274 0.07194389107566 0.05392872365086
-0.09056653875182 0.02690390942979 0.05734772561876
-0.08874239284172 -0.03208550284436 0.05931666972874
-0.04994776227688 -0.07387743004978 0.05896934012721
0.08113484130894 -0.04864156248658 0.09509197227580
0.08082812488329 0.05090654332294 0.09286040765330
-0.05540364981173 -0.05125612202637 0.11002586143836
-0.05594232491233 0.04968295002833 0.10654646412878 ]';
%open channel window if not already opened:
%get current state of controls
set(handles.ViewChannels,'value',1); %set checked
%if plot for the first time (or user closed plot window)
if (~data.plotWindow | ~isfield(data,'plotHandle') | ~ishandle(data.plotHandle) )
%open figure to plot
data.plotHandle = figure('visible','off');
bst_color_scheme(data.plotHandle);
setappdata(data.plotHandle,'TileType','T')
set(data.plotHandle,'menubar','figure','toolbar','figure');
bst_layout('align',data.plotHandle,2,2,1);
set(data.plotHandle,'visible','on');
set(data.plotHandle,'name','Tessellations');
light
axis vis3d
end
%if window already open
figure(data.plotHandle);
hold on
if ~ishandle(data.channelHandles)
data.channelHandles = plot3(data.SensorLoc(1,:),data.SensorLoc(2,:),data.SensorLoc(3,:),'ko');
set(data.channelHandles,'markerfacecolor','yellow');
axis equal
axis off
end
setappdata(fig,'data',data);
%Open window to assign phantom/subject channels
warning off; %supress warning that window was created using matlab 7 (6.5 compatible)
[assigned_locs] = phantom_channel_assignment(MontrealChannels,MontrealLandmarks,Channel,Landmark);
warning on;
%if process canceled
if isempty(assigned_locs.phantom)
bst_message_window('append','Phantom study canceled by user');
return
end
%get bst directories
BST = getpref('BrainStorm');
%Get phantom files
surface_file = fullfile(BST.brainstormHomeDir,'Phantom','montreal_subject','montreal_4layer_tess.mat');
mr_file = fullfile(BST.brainstormHomeDir,'Phantom','montreal_subject','montreal_subjectimage.mat');
%name new files (surface and mr)
current_subject = fullfile(BST.UserDataBase(BST.iUserDataBase).SUBJECTS,BST.CurrentData.SubjectFile);
[pathstr,name,ext,versn] = fileparts(current_subject);
warpedsurfacefile = strrep(name,'brainstormsubject','warped_4layer_tess.mat');
warpedsurfacefile = fullfile(pathstr,warpedsurfacefile);
warpedmrfile = strrep(name,'brainstormsubject','warped_subjectimage.mat');
warpedmrfile = fullfile(pathstr,warpedmrfile);
lm_real = assigned_locs.subject';
lm_phantom = assigned_locs.phantom';
warp_everything_bst(lm_real, lm_phantom, surface_file, mr_file,warpedsurfacefile,warpedmrfile);
bst_message_window('append','Files *warped_4layer_tess.mat and warped_subjectimage.mat');
bst_message_window('append','where successfully created and saved in the current');
bst_message_window('append','subject directory');
% --------------------------------------------------------------------
function varargout = Quit_Callback(h, eventdata, handles, varargin)
fig = handles.tess_align_tool; % make sure we have the handle
data = getappdata(fig,'data');
%if plot window exists, delete it
if data.plotWindow & isfield(data,'plotHandle')
if(ishandle(data.plotHandle))
delete(data.plotWindow)
end
end
delete(handles.tess_align_tool);
Produced by color_mat2html, a customized BrainStorm 2.0 (Alpha) version of mat2html on Tue Oct 12 12:05:14 2004
Cross-Directory links are: ON