[Master Index] [Index for Toolbox]

# phantom_channel_assignment

## (Toolbox/phantom_channel_assignment.m in BrainStorm 2.0 (Alpha))

### Function Synopsis

    varargout = phantom_channel_assignment(varargin)

### Help Text

    PHANTOM_CHANNEL_ASSIGNMENT - Application M-file for phantom_channel_assignment.fig
     function varargout = phantom_channel_assignment(varargin)
        FIG = PHANTOM_CHANNEL_ASSIGNMENT launch phantom_channel_assignment GUI.
        PHANTOM_CHANNEL_ASSIGNMENT('callback_name', ...) invoke the named callback.
     This tool (window) returns the assignment of an EEG channel structure
     (from any subject)to the phantom channel structure

     Use as:
       [assigned_locs] = phantom_channel_assignment(MontrealChannels,MontrealLandmarks,Channel,Landmark);

       input:
       MontrealChannels:   .Loc:  3xn array of channel locations
                           .Name: 1xn structure of strings containing the names of the channels
       MontrealLandmarks:  .Loc:  3xn array of landmark locations
                           .Name: 1xn structure of strings containing the names of the landmarks
       Channel:            The standard Channel structure of Brainstorm, belonging to the subject of interest
       Landmark:           The standard Landmark of Brainstorm, belonging to the subject of interest

       output:
       assigned_locs:      .phantom: 3xm array of doubles, the channel locations of the phantom that
                                     have common correspondance with the
                                     subject (begining with Nasion, PAL, PAR, ...
                           .subject: 3xm array of doubles, the channel locations of the subject that
                                     have common correspondance with the subject

     See also TESS_ALIGN_TOOL.m

### Cross-Reference Information

This function calls

    bst_color_scheme                   C:\BrainStorm_2001\Toolbox\bst_color_scheme.m
    bst_layout                         C:\BrainStorm_2001\Toolbox\bst_layout.m
    bst_message_window                 C:\BrainStorm_2001\Toolbox\bst_message_window.m
    makeuswait                         C:\BrainStorm_2001\Toolbox\makeuswait.m
    select3d                           C:\BrainStorm_2001\PublicToolbox\OtherTools\select3d.m

This function is called by

    tess_align_tool                    C:\BrainStorm_2001\Toolbox\tess_align_tool.m

### Listing of function C:\BrainStorm_2001\Toolbox\phantom_channel_assignment.m

    function varargout = phantom_channel_assignment(varargin)
    %PHANTOM_CHANNEL_ASSIGNMENT - Application M-file for phantom_channel_assignment.fig
    % function varargout = phantom_channel_assignment(varargin)
    %    FIG = PHANTOM_CHANNEL_ASSIGNMENT launch phantom_channel_assignment GUI.
    %    PHANTOM_CHANNEL_ASSIGNMENT('callback_name', ...) invoke the named callback.
    % This tool (window) returns the assignment of an EEG channel structure
    % (from any subject)to the phantom channel structure
    %
    % Use as:
    %   [assigned_locs] = phantom_channel_assignment(MontrealChannels,MontrealLandmarks,Channel,Landmark);
    %
    %   input:
    %   MontrealChannels:   .Loc:  3xn array of channel locations
    %                       .Name: 1xn structure of strings containing the names of the channels
    %   MontrealLandmarks:  .Loc:  3xn array of landmark locations
    %                       .Name: 1xn structure of strings containing the names of the landmarks
    %   Channel:            The standard Channel structure of Brainstorm, belonging to the subject of interest
    %   Landmark:           The standard Landmark of Brainstorm, belonging to the subject of interest
    %
    %   output:
    %   assigned_locs:      .phantom: 3xm array of doubles, the channel locations of the phantom that
    %                                 have common correspondance with the
    %                                 subject (begining with Nasion, PAL, PAR, ...
    %                       .subject: 3xm array of doubles, the channel locations of the subject that
    %                                 have common correspondance with the subject
    %
    % See also TESS_ALIGN_TOOL.m

    %<autobegin> ---------------------- 12-Oct-2004 12:02:45 -----------------------
    % --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
    %
    % CATEGORY: Database Management
    %
    % 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\makeuswait.m
    %
    % Subfunctions in this file, in order of occurrence in file:
    %   varargout = initialize_gui(h,eventdata,handles,varargin);
    %   Montreal_listbox_Callback(hObject, eventdata, handles)
    %   Subject_listbox_Callback(hObject, eventdata, handles)
    %   Autoassign_Callback(hObject, eventdata, handles)
    %   Assign_Callback(hObject, eventdata, handles)
    %   Deassign_Callback(hObject, eventdata, handles)
    %   varargout = channelClick_Callback
    %   varargout = Done_Callback(h, eventdata, handles, varargin)
    %   varargout = Quit_Callback(h, eventdata, handles, varargin)
    %
    % Application data and their calls in this file:
    %   'TileType'
    %   'data'
    %   'phantom_channel_assignment_handles'
    %
    %   setappdata(0,'phantom_channel_assignment_handles',handles);
    %   setappdata(fig,'TileType','T')
    %   setappdata(fig,'data',data);
    %
    %   data = getappdata(fig,'data');
    %   handles = getappdata(0,'phantom_channel_assignment_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 phantom_channel_assignment.fig
    %   uicontrol:listbox:Montreal_listbox "populating list..." uses Callback for <automatic>
    %   uicontrol:listbox:Subject_listbox "populating list..." uses Callback for <automatic>
    %   uicontrol:pushbutton:Assign "Assign" uses Callback for <automatic>
    %   uicontrol:pushbutton:Autoassign "Auto Assign" uses Callback for <automatic>
    %   uicontrol:pushbutton:Deassign "Deassign" uses Callback for <automatic>
    %   uicontrol:pushbutton:Done "Done" uses Callback for <automatic>
    %   uicontrol:pushbutton:Quit "Quit" uses Callback for <automatic>
    %
    % At Check-in: $Author: Mosher $  $Revision: 2 $  $Date: 10/12/04 10:24a $
    %
    % This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 12-Oct-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 12:02:45 -----------------------

    % Last Modified by GUIDE v2.5 04-Oct-2004 14:34:44

    % /---Script Author--------------------------------------\
    % |                                                      |
    % | *** Dimitrios Pantazis, Ph.D. student                |
    % | University of Southern California                    |
    % |                                                      |
    % \------------------------------------------------------/
    %
    % Date of creation: October 2004

    % ----------------------------- Script History ---------------------------------
    % 03-Oct-2004 DP  Creation
    % JCM 11-Oct-2004 Commenting header
    % ----------------------------- Script History ---------------------------------

    % All communication between functions is done using the 'data' structure
    %
    %data =
    %    MontrealName: {1xnPhantomPoints cell}
    %     MontrealLoc: [3xnPhantomPoints double]
    %     SubjectName: {1xnSubjectPoints cell}
    %      SubjectLoc: [3xnSubjectPoints double]
    %     assignments: [1xnPhantomPoints double]
    %      plotHandle: Handle for the plot figure
    %   hannelHandles: Handle for channels
    %     lineHandles: [1xnPhantomPoints double], stores handles for lines

    if ~ischar(varargin{1})  % LAUNCH GUI

        fig = openfig(mfilename,'reuse');

        bst_color_scheme(fig);
        setappdata(fig,'TileType','T')
        bst_layout('align',fig,2,2,4)
        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);

        %save arguments in data structure
        data.MontrealChannels = varargin{1};
        data.MontrealLandmarks = varargin{2};
        data.Channel = varargin{3};
        data.Landmark = varargin{4};

        %MontrealName & MontrealLoc will be the first listbox
        data.MontrealName = data.MontrealLandmarks.Name;
        data.MontrealName = [data.MontrealName data.MontrealChannels.Name];
        data.MontrealLoc = data.MontrealLandmarks.Loc;
        data.MontrealLoc = [data.MontrealLoc data.MontrealChannels.Loc];

        %SubjectName & SubjectLoc will be the second listbox
        data.SubjectName = data.Landmark.Name;
        data.SubjectName = [data.SubjectName {data.Channel.Name}];
        data.SubjectLoc = data.Landmark.Loc;
        data.SubjectLoc = [data.SubjectLoc data.Channel.Loc];

        %clear useless structures
        data = rmfield(data,'MontrealChannels');
        data = rmfield(data,'MontrealLandmarks');
        data = rmfield(data,'Channel');
        data = rmfield(data,'Landmark');

        %null assignments
        data.assignments = zeros(1,size(data.MontrealName,2));

        %save application data
        setappdata(fig,'data',data);

        %initialize
        initialize_gui(fig,[],handles,varargin{:});

        data = getappdata(fig,'data');
        set(data.plotHandle,'pointer','crosshair');
          % Wait for callbacks to run and window to be dismissed:
        uiwait(fig);

        data = getappdata(fig,'data');

        %delete additional channels and lines
        phantom_points = size(data.MontrealName,2);
        for i = 1:phantom_points
            if ishandle(data.lineHandles(i))
                delete(data.lineHandles(i))
            end
        end
        if(ishandle(data.channelHandles));
            delete(data.channelHandles);
        end
        %delete marker if exist
        if(ishandle(data.channelMarker))
            delete(data.channelMarker)
        end

        %deactivate pointclicking on plotWindow
        set(data.plotHandle,'windowbuttondownfcn','');
        %delet tool handles on root window
        rmappdata(0,'phantom_channel_assignment_handles');
        %restore pointer
        set(data.plotHandle,'pointer','arrow');

        if(~ishandle(fig)) %if figure is closed already
             assigned_locs.phantom = [];
             assigned_locs.subject = [];
             varargout{1} = assigned_locs;
             varargout{2} = {[]};
             return
        end

        varargout{1} = data.assigned_locs;
        close(fig);

    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'

    makeuswait('start')
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %populate lists
    set(handles.Montreal_listbox,'string',data.MontrealName)
    set(handles.Subject_listbox,'string',data.SubjectName)

    %locate plot figure (has the name: tessellations)
    name = 'Tessellations';
    hw = get(0,'children');        % all open windows
    hw = sort(hw);            % in increasing window order
    for i = 1:length(hw),
      s = get(hw(i),'Name');
      if(strcmp(deblank(s),deblank(name))),
        data.plotHandle = hw(i);
      end
    end

    %plot phantom channels
    figure(data.plotHandle)
    if isfield(data,'plotHandle')%if figure exists
        data.channelHandles = plot3(data.MontrealLoc(1,:),data.MontrealLoc(2,:),data.MontrealLoc(3,:),'ko');
        set(data.channelHandles,'markerfacecolor','red');
        axis equal
        axis off
    end

    %initialize data.lineHandles
    data.lineHandles = -1*ones(1,size(data.MontrealLoc,2));

    %activate pointclicking on plotWindow
    set(data.plotHandle,'windowbuttondownfcn','phantom_channel_assignment(''channelClick_Callback'')');
    %save tool handles on root window, so they can be accessed by channelClick fn
    setappdata(0,'phantom_channel_assignment_handles',handles);
    %define channelMarker
    data.channelMarker = line('marker','o','markerfacecolor','k','linewidth',2,'markersize',8,'erasemode','xor','visible','off');
    % channelMarker = data.channelMarker;
    % setappdata(0,'channelMarker',channelMarker);

    setappdata(fig,'data',data);

    makeuswait('stop')

    % --- Executes on selection change in Montreal_listbox.
    function Montreal_listbox_Callback(hObject, eventdata, handles)
    % hObject    handle to Montreal_listbox (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: contents = get(hObject,'String') returns Montreal_listbox contents as cell array
    %        contents{get(hObject,'Value')} returns selected item from Montreal_listbox

    %get handles
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %get selected Montreal channel
    vi = get(handles.Montreal_listbox,'value');

    p = data.MontrealLoc(:,vi);

    %show marker
    set(data.channelMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));

    % --- Executes on selection change in Subject_listbox.
    function Subject_listbox_Callback(hObject, eventdata, handles)
    % hObject    handle to Subject_listbox (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: contents = get(hObject,'String') returns Subject_listbox contents as cell array
    %        contents{get(hObject,'Value')} returns selected item from Subject_listbox

    %get handles
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %get selected Montreal channel
    vj = get(handles.Subject_listbox,'value');

    p = data.SubjectLoc(:,vj);

    %show marker
    set(data.channelMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));

    % --- Executes on button press in Autoassign.
    function Autoassign_Callback(hObject, eventdata, handles)
    % hObject    handle to Autoassign (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    %get handles
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %deassign everything
    data.assignments = zeros(size(data.assignments));

    %number of points
    phantom_points = size(data.MontrealName,2);
    subject_points = size(data.SubjectName,2);

    %make assignments
    for i = 1:phantom_points %for all phantom points
        for j = 1:subject_points %for all subject points
            detect = strfind(lower(data.SubjectName{j}),lower(data.MontrealName{i}));
            %if detected, make assignment
            if ~isempty(detect)
                data.assignments(i) = j;
            end
        end
    end

    %special assignments
    for j = 1:subject_points
         detect = strfind(lower(data.SubjectName{j}),'nas');
         if ~isempty(detect) %nasion
             data.assignments(1) = j;
         end
              detect = strfind(lower(data.SubjectName{j}),'par');
         if ~isempty(detect) %right preauricular
             data.assignments(3) = j;
         end
         detect = strfind(lower(data.SubjectName{j}),'pal');
         if ~isempty(detect) %left preauricular
             data.assignments(2) = j;
         end

    end

    %display assignments
    figure(data.plotHandle)
    for i = 1:phantom_points
        displayStr{i} = data.MontrealName{i};
        if data.assignments(i)~=0 %if assigned
            displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
        end
    end
    set(handles.Montreal_listbox,'string',displayStr)

    %plot lines between assigned channels
    for i = 1:phantom_points
        %if there is already a line, delete it
        if ishandle(data.lineHandles(i))
            delete(data.lineHandles(i))
        end
        if data.assignments(i)~=0 %if assigned
            X = [data.MontrealLoc(1,i) data.SubjectLoc(1,data.assignments(i))];
            Y = [data.MontrealLoc(2,i) data.SubjectLoc(2,data.assignments(i))];
            Z = [data.MontrealLoc(3,i) data.SubjectLoc(3,data.assignments(i))];
            data.lineHandles(i) = line(X,Y,Z);
            set(data.lineHandles(i),'color','black','linewidth',2)
        end
    end

    setappdata(fig,'data',data);

    % --- Executes on button press in Assign.
    function Assign_Callback(hObject, eventdata, handles)
    % hObject    handle to Assign (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    %get handles
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %make assignment
    vi = get(handles.Montreal_listbox,'value');
    vj = get(handles.Subject_listbox,'value');
    data.assignments(vi) = vj;

    %display assignments
    phantom_points = size(data.MontrealName,2);
    for i = 1:phantom_points
        displayStr{i} = data.MontrealName{i};
        if data.assignments(i)~=0 %if assigned
            displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
        end
    end
    set(handles.Montreal_listbox,'string',displayStr)

    %display line
    figure(data.plotHandle)
    if ishandle(data.lineHandles(vi)) %if there is already a line, delete it
         delete(data.lineHandles(vi))
    end
    X = [data.MontrealLoc(1,vi) data.SubjectLoc(1,data.assignments(vi))];
    Y = [data.MontrealLoc(2,vi) data.SubjectLoc(2,data.assignments(vi))];
    Z = [data.MontrealLoc(3,vi) data.SubjectLoc(3,data.assignments(vi))];
    data.lineHandles(vi) = line(X,Y,Z);
    set(data.lineHandles(vi),'color','black','linewidth',2)

    setappdata(fig,'data',data);

    % --- Executes on button press in Deassign.
    function Deassign_Callback(hObject, eventdata, handles)
    % hObject    handle to Deassign (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    %get handles
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %deassign
    i = get(handles.Montreal_listbox,'value');
    data.assignments(i) = 0;
    %remove line if exists
    if ishandle(data.lineHandles(i)) %if there is already a line, delete it
         delete(data.lineHandles(i))
    end

    %display assignments
    phantom_points = size(data.MontrealName,2);
    for i = 1:phantom_points
        displayStr{i} = data.MontrealName{i};
        if data.assignments(i)~=0 %if assigned
            displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
        end
    end
    set(handles.Montreal_listbox,'string',displayStr)

    setappdata(fig,'data',data);

    function varargout = channelClick_Callback

    handles = getappdata(0,'phantom_channel_assignment_handles'); %access tesselation tool
    fig = handles.phantom_channel_assignment; % make sure we have the handle
    data = getappdata(fig,'data');

    %number of points
    phantom_points = size(data.MontrealName,2);
    subject_points = size(data.SubjectName,2);

    %get coordinates of point
    figure(data.plotHandle)
    [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

    %show marker
    set(data.channelMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));

    %change listbox selection
    vi = find(sum(abs(data.MontrealLoc - p'*ones(1,phantom_points)))==0);
    vj = find(sum(abs(data.SubjectLoc - p'*ones(1,subject_points)))==0);
    if(~isempty(vi)) %if a phantom channel is selected
        set(handles.Montreal_listbox,'value',vi);
    end
    if(~isempty(vj)) %if a phantom channel is selected
        set(handles.Subject_listbox,'value',vj);
    end

    % --------------------------------------------------------------------
    function varargout = Done_Callback(h, eventdata, handles, varargin)

    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    %ask if channels already aligned
    if sum(data.assignments~=0)<5 %if less than 5 points selected
        reply = questdlg('At least 5 channels must be assigned. Choose more points?');
        if(strcmp(reply,'No'))
            bst_message_window('append','Process canceled by user because not enough channels where assigned');
            return
        end
        if(strcmp(reply,'Cancel'))
            bst_message_window('append','Please assign more channels');
            return
        end
        if(strcmp(reply,'Yes'))
            bst_message_window('append','Please assign more channels');
            return
        end
    end

    %ask if NAS,PAL,PAR not already assigned
    if sum(data.assignments(1:3)~=0)<3 %if NAS/PAL/PAR
        bst_message_window('append','...');
        bst_message_window('append','Please assign Nasion, Left Preauricular, Right Preauricular');
        bst_message_window('append','These points are necessary to align the MR scan');
        return;
    end

    phantom_points = size(data.MontrealName,2);

    %return locations of common channels (notice , NAS,PAL,PAR will be returned
    %first in this order
    assigned_locs.phantom = [];
    assigned_locs.subject = [];
    for i = 1:phantom_points
        if data.assignments(i)~=0 %if sensor assigned
            assigned_locs.phantom = [assigned_locs.phantom data.MontrealLoc(:,i)];
            assigned_locs.subject = [assigned_locs.subject data.SubjectLoc(:,data.assignments(i))];
        end
    end
    data.assigned_locs = assigned_locs;

    setappdata(fig,'data',data);

    uiresume;

    % --------------------------------------------------------------------
    function varargout = Quit_Callback(h, eventdata, handles, varargin)

    fig = handles.phantom_channel_assignment; % make sure we have the handle
    handles = guidata(fig);
    data = getappdata(fig,'data');

    data.assigned_locs.phantom = [];
    data.assigned_locs.subject = [];
    setappdata(fig,'data',data);

    uiresume;

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