[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