function ShapeSpaceTool(varargin)
%   Dr. A. I. Hanna (2005) CMP, UEA, 2006.
error(nargchk(0,inf,nargin));
ad.data.sfam = [];
ad.data.pdm = [];
ad.data.distance = [];
ad.data.details = [];
ad.data.template = [];
ad.data.vectors = [];
ad.data.indices = [];
ad.data.selectedShapePC = [1 2];
ad.data.selectedAppPC = [1 2];
ad.groups = struct([]);
ad.data.dim = 2;
if mod(length(varargin),2) ~= 0
    % input args have not com in pairs, woe is me
    error('Arguments to ShapeSpaceTool must come param/value in pairs.')
end
for i=1:2:length(varargin)
    switch lower(varargin{i})
        case 'pdm'
            ad.data.pdm = varargin{i+1};
        case 'template'
            ad.data.template = varargin{i+1};
            tempname = get(ad.data.template, 'name');
            [temppath, tempname] = fileparts(tempname);
            ad.data.templatename = tempname;
        case 'sfam'
            ad.data.sfam = varargin{i+1};
        case 'details'
            ad.data.details = varargin{i+1};
            ad.data.details
        case 'indices'
            ad.data.indices = varargin{i+1};
        case 'facets'
            ad.data.facets = varargin{i+1};
        otherwise
            error(['Unknown parameter name passed to ShapeSpaceTool.  Name was ' varargin{i}])
    end
end


% Open, move, and get the handles from the figure file.
fig = openfig(mfilename, 'reuse');
% Move the gui and then show it, rather than have it jump all over the
% place.
movegui(fig, 'west');
set(fig, 'visible', 'on');
handles = guihandles(fig);
if isempty(ad.data.sfam)
    set(handles.apppcbtn, 'Enable', 'off');
end
if isempty(ad.data.indices)
    ad.data.indices = 1:length(ad.data.pdm.Xm)/ad.data.dim;
end
handles = setupcallbacks(handles);

% Initialize the application data structure
ad.figMain = fig;
ad.handles = handles;
ad.handles.shapefig = [];
ad.handles.shapeaxis = [];
ad.handles.appfig = [];
ad.handles.areavechandle = [];
ad.handles.appaxis = [];
ad.handles.vectorsh = [];
ad.handles.surface_handle = [];
ad = initPlotHandles(ad);

% Determine if project is 3d
if isProject3D(pwd)
    ad.data.dim = 3;
else
    ad.data.dim = 2;
end

ad = calculateAreaVector(ad);

ad.dirs.pmdir = [pwd, filesep, 'PointModels'];
ad.dirs.groups = [pwd, filesep, 'Groups'];
ad.dirs.cropped = [pwd, filesep, 'Cropped'];

% Begin change by js 080130
% Begin original code

% No replacement code in this case

% End original code
% Begin replacement code
H=findobj(ad.handles.ShapeSpaceTool,'type','uicontrol');
H2=findobj(ad.handles.ShapeSpaceTool,'type','uipanel');
set([H;H2],'fontsize',10);

movegui(fig, 'northeast');
surfaceDirectory = fullfile(pwd, 'Templates');
ad.surfaceData = getSurfaceData('name', tempname, 'mode', 'template', ...
    'surfaceDirectory', surfaceDirectory);

% End replacement code
% End change by js 080130

setappdata(0,'ShapeSpaceToolData',ad);
% try
%     uiwait(fig);
% catch
%     if ishandle(fig)
%         delete(fig)
%     end
% end
return;
%%
%
function handles = setupcallbacks(handles)
% Setup the callback handles

% Group Callbacks
set(handles.addGroupBtn, 'callback', {@doAddGroup});
set(handles.importgrpbtn, 'callback', {@doImportGroup});
set(handles.groupList, 'callback', {@doClickGroupList});
set(handles.deletegrpbtn, 'callback', {@doDeleteGroup});
set(handles.changegrpcolbtn, 'callback', {@doChangeColor});
set(handles.randcolbtn, 'callback', {@doRandomColorGroups});
set(handles.savegrpbtn, 'callback', {@doSaveGroups});
set(handles.opengrpbtn, 'callback', {@doOpenGroups});
set(handles.load_btn, 'callback', {@doLoadGroups});
set(handles.defineordermenu, 'callback', {@doOrderGroups});
set(handles.combinegrpsbtn, 'callback', {@doCombineGroups});

% Data Control Callbacks
set(handles.plotDataBtn, 'callback', {@doPlotData});
set(handles.shapePCbtn, 'callback', {@doChooseShapePC});
set(handles.apppcbtn, 'callback', {@doChooseAppPC});
set(handles.showpcvarmenu, 'callback', {@doDispPCVariance});
set(handles.shapewindmenu, 'callback', {@doHideShapeWindow});
set(handles.appwindmenu, 'callback', {@doHideAppWindow});
set(handles.fitsurfacebtn, 'callback', {@doFitSurface});
set(handles.radiusSlider, 'callback', {@doChangeIsoLevel});
set(handles.lda_chk, 'callback', {@doUseLDA});

% Toggle visuals
set(handles.ellipchk, 'callback', {@doToggleEllipsoid});
set(handles.ptschk, 'callback', {@doToggleParticles});
set(handles.showmeanschk, 'callback', {@doToggleGroupMeans});
set(handles.showlabelschk, 'callback', {@doToggleLabels});
set(handles.surfacechk, 'callback', {@doToggleSurface});
set([handles.particlesmenu, handles.linegrphmenu, handles.rngbarmenu, handles.stdbarmenu, handles.stderrmenu, handles.rngstdbarmenu], 'callback', {@doToggleOneDProjectionView});
set(handles.areavecchk, 'callback', {@doToggleAreaVector});
set(handles.vectorschk, 'callback', {@doToggleVectors});
set(handles.axis_equal_btn, 'callback', {@doAxisEqual});

% Menu callbacks
set(handles.clear_grps_menu, 'callback', {@doClearGroups});
set([handles.rawunitsmenu, handles.stdunitsmenu], 'callback', {@doToggleUnits});
set(handles.defineordermenu, 'callback', {@doDefineOrder});
set([handles.autoorderingmenu, handles.userordermenu], 'callback', {@doToggleOrdering});
set(handles.cldamenu, 'callback', {@doProjectLDAviaPCA});
set(handles.calc_proj_ttest, 'callback', {@doCalcProjTTest});
set(handles.calc_proj_rankedttest, 'callback', {@doCalcProjRankedTTest});
set(handles.calc_proj_var_menuitem, 'callback', {@doCalcProjVar});
set(handles.toggellipmenu, 'callback', {@doSelectEllipsoids});
set(handles.importvectors, 'callback', {@doImportVectors});
set(handles.drawvectorsmenu, 'callback', {@doDrawVectors});
set(handles.exportvectors, 'callback', {@doExportVectors});
set(handles.walkvectors, 'callback', {@doWalkVectors});
set(handles.printvectorsmenu, 'callback', {@doPrintVectors});
set(handles.clearvectorsmenu, 'callback', {@doClearVectors});
set(handles.translate_grps_menu, 'callback', {@doTranslateGroups});
set(handles.export_pc_vals_menu, 'callback', {@doExportPCValues});
set(handles.calcPCcoverage, 'callback', {@doCalcPCCoverage});
set(handles.legend_menu, 'callback', {@doToggleLegend});
set(handles.aam_classifier, 'callback', {@aamlib_pm_classifier});
% set(handles.exportGroupMeanPts, 'callback', {@doExportGroupMeans});
%%%%%
%
%%%%%
function doClickGroupList(list, evd)
UpdateGroupInfo;
return;
%%%
%
%%%
function ad = initPlotHandles(ad)
ad.handles.elliphandle = [];
ad.handles.meanhandle = [];
ad.handles.labelhandle = [];
ad.handles.ptshandle = [];
%%%%%%
%
%
%%%%%%
function doHideShapeWindow(shapechk, evd)
ad = getappdata(0,'ShapeSpaceToolData');
shpfig = ad.handles.shapefig;
if (~isempty(shpfig) && ishandle(shpfig))
    if strcmp(get(shapechk, 'Checked'), 'on')
        set(shpfig, 'Visible', 'off');
        set(shapechk, 'Checked', 'off')
    else
        set(shapechk, 'Checked', 'on')
        set(shpfig, 'Visible', 'on');
    end
end
setappdata(0,'ShapeSpaceToolData', ad);
return
%%%
%
%%%
function temp_g = parseGroup(g)
temp_g = makeNewGroup;
fields = fieldnames(temp_g);
for i=1:length(fields)
    if isfield(g, fields{i})
        temp_g = setfield(temp_g, fields{i}, getfield(g, fields{i})); %#ok<GFLD,SFLD>
    end

end
return;
%%%
%
%%%
function doHideAppWindow(appchk, evd)
ad = getappdata(0,'ShapeSpaceToolData');
appfig = ad.handles.appfig;
if (~isempty(appfig) && ishandle(appfig))
    if strcmp(get(appchk, 'checked'), 'on')
        set(appfig, 'Visible', 'off');
        set(appchk, 'Checked', 'off')
    else
        set(appfig, 'Visible', 'on');
        set(appchk, 'Checked', 'on')
    end
end
setappdata(0,'ShapeSpaceToolData', ad);
return
%%%%%%
%
%
%%%%%%
function doSaveGroups(savebtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
[filename, pathname] = uiputfile([pwd, filesep, 'Groups', filesep, '*.mat'], 'Save as...');
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel');
else
    groups = ad.groups;
    save([pathname, filesep, filename], 'groups');
    fprintf('Save groups file as %s\n', [pathname, filesep, filename]);
end
setappdata(0,'ShapeSpaceToolData', ad);
return;
%%%%%%
%
%%%%%%
function doOpenGroups(loadbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
[filename, pathname] = uigetfile([ad.dirs.groups, filesep, '*.mat'], 'Pick a group file.');
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel')
else
    groups = load([pathname, filesep, filename]);
    if ~isfield(groups, 'groups')
        str = sprintf('You have not selected a valid groups file. Please try again.');
        uiwait(msgbox(str,'Incorrect file type','modal'));
        return;
    end
    groups = groups.groups;
    clear new_groups;
    for i=1:length(groups)
        pgroup = parseGroup(groups(i));
        new_groups(i) = pgroup; 
    end
    ad.groups = new_groups;
    setappdata(0,'ShapeSpaceToolData', ad);
    UpdateGroupInfo;
end
return

%%%%%
%
%
%%%%%
% function  handles=LDAUsePC(handles)
% direc = [pwd, filesep, get(handles.AAM, 'modelDirec')];
% indices = get(handles.AAM, 'pointindices');
%
% template = get(handles.AAM, 'PointModelTemplate');
% template_name = get(template, 'name');
% [templatepath, template_name, ext] = fileparts(template_name);
% pmdirectory = ['PointModels', filesep, template_name];
%
% if ~exist(pmdirectory, 'dir')
%     fprintf('There are no point models for this template');
%     return;
% end
% pdmfile = [direc, filesep, 'mod_pdm.mat'];
% if ~exist(pdmfile)
%     return;
% end
% pdm = load(pdmfile);
% pdm = pdm.pdm;
% [details, detailstr] = getDetails(direc);
% projectLDAviaPCA(handles.groups, pmdirectory, pdm, indices, details);
% return;
%%%%%
%
%%%%%
function  doRandomColorGroups(rndbtn, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
if isempty(ad.groups)
    uiwait(msgbox('Please load some groups','No Group Info.','modal'));
    return;
end
groups = ad.groups;
for i=1:length(groups)
    color = rand(1,3);
    groups(i).color = color;
end
ad.groups = groups;
setappdata(0, 'ShapeSpaceToolData',ad);
UpdateGroupInfo;
return

%%%%%%
%
%
%%%%%%
function doDispPCVariance(showvarbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
b = ad.data.pdm.pca.b;
x = 1:length(b);
figure;

subplot(2,3,1);
stem(x, b, 'MarkerFaceCOlor', 'y');
xlabel('Principle Component');
ylabel('PC Variance');
axis tight;
grid on;

subplot(2,3,2);
stem(x, log10(b), 'MarkerFaceCOlor', 'y');
xlabel('Principle Component');
ylabel('log_{10}(PC Variance)');
axis tight;
grid on;

subplot(2,3,3);
stem(x, cumsum(b), 'MarkerFaceCOlor', 'y');
xlabel('Principle Component');
ylabel('Cumulative PC Variance');
axis tight;
grid on;


subplot(2,3,4);
stem(x, 100*(b./sum(b)), 'MarkerFaceCOlor', 'y');
xlabel('Principle Component');
ylabel('Percentage of Variance Covered (%)');
axis tight;
grid on;

subplot(2,3,5);
stem(x, log10(100*(b./sum(b))), 'MarkerFaceCOlor', 'y');
xlabel('Principle Component');
ylabel('log_{10}(Percentage of Variance Covered (%))');
axis tight;
grid on;

subplot(2,3,6);
stem(x, cumsum(100*(b./sum(b))), 'MarkerFaceCOlor', 'y');
xlabel('Principle Component');
ylabel('Cumulative Percentage of Variance Covered (%)');
axis tight;
grid on;
return;
%%%%%%
%
%
%%%%%%
function showOriginalImage(pm, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
data = get(gco, 'UserData');
if (data.element_num==0)
    fprintf('There is no image for the calculated mean\n');
    return;
end
group = ad.groups(data.groupnumber);
shapedata = group.shapedata(data.element_num);
pts = shapedata.pts;
imname = data.name;
[impath, imname] = fileparts(imname);
imname = [ad.dirs.cropped, filesep, imname(1:end-3), '.jpg'];
if exist(imname, 'file')
    I = imread(imname);
    fig = figure;
    ah = gca;
    hold(ah, 'on');
    movegui(fig, 'southwest');
    imagesc(I, 'Parent', ah);
    plot(pts(1:2:end), pts(2:2:end), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    axis(ah, 'image', 'ij');
    title(data.name, 'Interpreter', 'none');
else
    fprintf('Image %s does not exist\n', imname);
end
return;
%%%%%%
%
%
%%%%%%
function displayShapePCs(pm, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
pcs = ad.data.selectedShapePC;
data = get(gco, 'UserData');
if (data.element_num==0)
    imname = 'Calculate mean shape';
    group = ad.groups(data.groupnumber);
    PCval = group.meanpt(pcs);
else
    imname = data.name;
    PCval = [get(gco, 'XData'),  get(gco, 'YData'),  get(gco, 'ZData')];
end

fprintf('\n%s\n', imname);
for i=1:length(pcs)
    fprintf('   PC%d: %f\n', pcs(i), PCval(i));
end
return;
%%%
%
%%%
function doChooseAppPC(apppcbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.data.sfam)
    return;
end
b = ad.data.pdm.pca.b;
if isempty(b)
    s = sprintf('There are no data to plot. Try clicking ''%s''.', get(ad.handles.load_btn, 'String'));
    uiwait(msgbox(s,'No Groups','modal'));
    return;
end
N = length(b);
str = cell(N, 1);
for i=1:N; str{i} = num2str(i); end;
[shapepcs] = listdlg('Name', 'PC Selection', 'PromptString','Select PC''s:', 'SelectionMode','multiple','ListString',str, 'ListSize', [300 160]);
if isempty(shapepcs)
    return;
end
if length(shapepcs)>3
    shapepcs = shapepcs(1:3);
end
switch length(shapepcs)
    case 1
        set(ad.handles.oneDradio, 'Value', 1);
    case 2
        set(ad.handles.twoDradio, 'Value', 1);
    case 3
        set(ad.handles.threeDradio, 'Value', 1);
end
ad.data.selectedAppPC = shapepcs;
setappdata(0,'ShapeSpaceToolData', ad);
doPlotData;

%%%
%
%%%
function doChooseShapePC(shapepcbtn, evd, shapepcs) %#ok<INUSD,INUSD>
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
b = ad.data.pdm.pca.b;
if isempty(b)
    s = sprintf('There are no data to plot. Try clicking ''%s''.', get(ad.handles.load_btn, 'String'));
    uiwait(msgbox(s,'No Groups','modal'));
    return;
end
N = length(b);
str = cell(N,1);
for i=1:N; str{i} = num2str(i); end;
if(~exist('shapepcs'))
    [shapepcs] = listdlg('Name', 'PC Selection', 'PromptString','Select PC''s:', 'SelectionMode','multiple','ListString',str, 'ListSize', [300 160]);
    if isempty(shapepcs)
        return;
    end
    if length(shapepcs)>3
        shapepcs = shapepcs(1:3);
    end
end
ad.data.selectedShapePC = shapepcs;
switch length(shapepcs)
    case 1
        if strcmp(get(ad.handles.autoorderingmenu, 'Checked'), 'on')
            ad = doGroupsAutomaticOrdering(ad);
        else
            ad = doUserDefinedOrdering(ad);
        end
        set(ad.handles.oneDradio, 'Value', 1);
    case 2
        set(ad.handles.twoDradio, 'Value', 1);
    case 3
        set(ad.handles.threeDradio, 'Value', 1);
end
setappdata(0,'ShapeSpaceToolData', ad);
doPlotData;
%%%
%
%%%
function doChangeColor(chngcol, evd)
ad = getappdata(0,'ShapeSpaceToolData');
groups = ad.groups;
v = get(ad.handles.groupList, 'value');
if isempty(v)
    return;
end
% we are on multi-select so just take the first one
col = uisetcolor;
if length(col)~=3
    col = [1 0 0];
end
for i=1:length(v)
    group = groups(v(i));
    group.color = col;
    groups(v(i)) = group;
end
ad.groups = groups;
%handles.PC{v}.color = color;
setappdata(0,'ShapeSpaceToolData', ad);
UpdateGroupInfo;
return;
%%%
%
%%%
function doDeleteGroup(delbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
v = get(ad.handles.groupList, 'value');
if isempty(v)
    return;
end
groups(v) = [];
ad.groups = groups;
set(ad.handles.groupList, 'value', min(v));
setappdata(0,'ShapeSpaceToolData', ad);
UpdateGroupInfo;
%%%%%
%
% UpdateGroupInfo
%
%%%%%
function UpdateGroupInfo
ad = getappdata(0,'ShapeSpaceToolData');
groups = ad.groups;
if isempty(groups)
    set(ad.handles.groupMemberList, 'value', 1, 'String', 'No group members');
    set(ad.handles.groupList, 'value', 1, 'String', 'No groups');
    return;
else
    indx = get(ad.handles.groupList, 'value');
    if isempty(indx)
        indx = 1;
    end
    if length(indx)==1
        indx = min([indx, length(groups)]);
        group = groups(indx);
        if ~isempty(group.elements)
            str = cell(length(group.elements),1);
            for i=1:length(group.elements)
                str{i}=sprintf('%3d) %s', i, group.elements{i});
            end
            set(ad.handles.groupMemberList, 'value', 1, 'String', str, 'foregroundcolor', group.color);
            set(ad.handles.groupList, 'value', indx, 'String', {groups.name});
        else
            set(ad.handles.groupMemberList, 'value', 1, 'String', 'No members in this group');
            set(ad.handles.groupList, 'value', indx, 'String', {groups.name});
        end
    end
end
setappdata(0,'ShapeSpaceToolData',ad);
%%%%%
%
% ProjectData
%
%%%%%
% function doProjectGroupOntoModel(menuitem, evd)
% ad = getappdata(0,'ShapeSpaceToolData');
% max_var_ratio([], [], ad.data.pdm, [], [], ad.data.details, ad.groups);
% setappdata(0,'ShapeSpaceToolData',ad);
% return;
%%%%%
%
%
%%%%%
function doImportGroup(importbtn, evd, groupFileName)
ad =getappdata(0, 'ShapeSpaceToolData');
if nargin < 3
    [filename, pathname] = uigetfile('*.mat', 'Pick Group File', [pwd, filesep, 'Groups', filesep]);
    if isequal(filename,0) || isequal(pathname,0)
        disp('User pressed cancel')
        return;
    end
else
    pathname = [pwd, filesep, 'Groups'];
    filename = groupFileName;
end

groups = load([pathname, filesep, filename]);
if ~isfield(groups, 'groups')
    str = sprintf('You have selected an invalid groups file.\nPlease try again.');
    uiwait(msgbox(str,'Error','modal'));
    return;
end
groups = groups.groups;
newgroup = makeNewGroup;
fields = fieldnames(newgroup);
for g = 1:length(groups)
    group = groups(g);
    newgroup = parseGroup(group);
    importedGroups(g) = newgroup;
end
ad.groups = [ad.groups, importedGroups];
setappdata(0,'ShapeSpaceToolData',ad);
UpdateGroupInfo;
return;
%%%
%
%%%
function newgroup = makeNewGroup
newgroup.name = '';
newgroup.elements = '';
newgroup.color = '';
newgroup.meanpt = '';
newgroup.appmeanpt = '';
newgroup.shapedata = '';
newgroup.groupnumber = '';
newgroup.appdata = '';
return;

%%%%%
%
%%%%%
function doToggleOrdering(ordermenu, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
if strcmpi(get(ordermenu, 'Label'), 'automatic')
    set(ad.handles.autoorderingmenu, 'Checked', 'on');
    set(ad.handles.userordermenu, 'Checked', 'off');
else
    set(ad.handles.autoorderingmenu, 'Checked', 'off');
    set(ad.handles.userordermenu, 'Checked', 'on');
end
setappdata(0, 'ShapeSpaceToolData', ad);
%%%%%
%
%%%%%
function doToggleUnits(unitsmenu, evd) %#ok<INUSD>
ad =getappdata(0, 'ShapeSpaceToolData');
if strcmpi(get(unitsmenu, 'Label'), 'raw')
    set(ad.handles.rawunitsmenu, 'Checked', 'on');
    set(ad.handles.stdunitsmenu, 'Checked', 'off');
    ad = changeToRawUnits(ad);
else
    set(ad.handles.rawunitsmenu, 'Checked', 'off');
    set(ad.handles.stdunitsmenu, 'Checked', 'on');
    ad = changeToStdUnits(ad);
end
setappdata(0, 'ShapeSpaceToolData', ad);
doPlotData;
%%%%%
%
%%%%%
function ad = changeToStdUnits(ad)
groups = ad.groups;
N = length(groups);
for i=1:N
    grp = groups(i);
    for ii=1:length(grp.shapedata)
        grp.shapedata(ii).b = grp.shapedata(ii).b_std;
         if isfield(grp, 'appdata')
            grp.appdata(ii).b = grp.appdata(ii).b_std;
            grp.appmeanpt = mean([grp.appdata.b],2);
        end
    end
    grp.meanpt = mean([grp.shapedata.b],2);

    groups(i) = grp;
end
ad.groups = groups;
%%%%%
%
%%%%%
function ad = changeToRawUnits(ad)
groups = ad.groups;
N = length(groups);
for i=1:N
    grp = groups(i);
    for ii=1:length(grp.shapedata)
        grp.shapedata(ii).b = grp.shapedata(ii).b_raw;
         if isfield(grp, 'appdata')
            grp.appdata(ii).b = grp.appdata(ii).b_raw;
            grp.appmeanpt = mean([grp.appdata.b],2);
        end
    end
    grp.meanpt = mean([grp.shapedata.b],2);

    groups(i) = grp;
end
ad.groups = groups;
%%%%%
%
%%%%%
function doClearGroups(clearbtn, evd) %#ok<INUSD,INUSD>
ad =getappdata(0, 'ShapeSpaceToolData');
ad.groups = [];
setappdata(0, 'ShapeSpaceToolData', ad);
UpdateGroupInfo;
%%%%%
%
%
%%%%%
function doAddGroup(addgroupbtn, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
template_name = get(ad.data.template, 'name');
[templatepath, template_name, ext] = fileparts(template_name);
if ~exist([ad.dirs.pmdir, filesep, template_name], 'dir')
    fprintf('There are no point models for this template');
    return;
end
files = dir([ad.dirs.pmdir, filesep, template_name,filesep, '*_pm.mat']);
files = {files.name};
[s, v] = CustomListDlg(files);
if isempty(v)
    return;
end
prompt={'Name:'};
name='Group Name';
numlines=1;
defaultanswer={'New group'};
answer=inputdlg(prompt,name,numlines,defaultanswer);
if isempty(answer)
    return;
end
groups = ad.groups;
newgroup = makeNewGroup;
newgroup.name = answer{1};
newgroup.elements = s;
newgroup.color = rand(1,3);
if isempty(groups)
    groups = newgroup;
else
    groups(end+1) = newgroup;
end
set(ad.handles.groupList, 'value', 1);
set(ad.handles.groupList, 'String', {groups.name});
ad.groups = groups;
setappdata(0,'ShapeSpaceToolData',ad);
UpdateGroupInfo;
%%%%%%
%
%
%%%%%%
function doLoadGroups(loadbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
wh = waitbar(0, 'Loading group data, please wait...');
N = length(ad.groups);
for i=1:N
    group = ad.groups(i);
    disp(['Loading group ',group.name]);
    [X] = aamio_getGroupPointModels('Group', group, 'TemplateName', ad.data.templatename, 'Indices', ad.data.indices);
    X = calculateShapeDeviations(X, ad.data.pdm, ad.data.details);
    group.shapedata = X;
    if ~isempty(ad.data.sfam)
        X = calculateAppDeviations(X, ad.data.pdm, ad.data.sfam);
        group.appdata = X;
        group.appmeanpt = mean([group.appdata.b],2);
    end
    group.groupnumber = i;
    group.meanpt = mean([group.shapedata.b],2);
    groups(i) = group;
    waitbar(i/N, wh);
end
ad.groups = groups;
close(wh);
setappdata(0,'ShapeSpaceToolData', ad);
return
%%%%%%
function doCalcPCCoverage(menu, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
calcGroupsPCVarianceCoverage(ad.groups);
setappdata(0,'ShapeSpaceToolData', ad);
return
%%%%
%
%%%%
function calcGroupsPCVarianceCoverage(groups)
if isempty(groups)
    return;
end
N = length(groups(1).meanpt);
str = cell(N,1);
for i=1:N; str{i} = num2str(i); end;
[idx,v] = listdlg('PromptString','Pick PCs for Coverage:', 'SelectionMode','multiple', 'ListString',str);
if isempty(idx)
    return;
end
fprintf('\n\n');
fprintf('Selected Principal Components\n');
disp(idx);
for g=1:length(groups)
    group = groups(g);
    shape_data = group.shapedata;
    X = zeros(N, length(shape_data));
    for i=1:length(shape_data)
        X(:,i) = shape_data(i).b(:);
    end
    total_variance = sum(var(X, 0, 2));
    sub_variance = sum(var(X(idx, :), 0, 2));
    perc_variance_idx = 100*( sub_variance./total_variance);
    fprintf('PC Variance for Group %s: %2.2f%%\n', group.name, perc_variance_idx);
end
return
%%%%
%
%%%%
function X = calculateAppDeviations(X, pdm, sfam)
msiz = sfam.siz;
for i=1:length(X)
    [a, pmname] = fileparts(X(i).name);
    name = pmname(1:end-3);
    imname = ['Cropped', filesep, name, '.jpg'];
    if exist(imname, 'file')
        img = imread(imname);
        fprintf(1,[num2str(i),' ',num2str(i),') ',name,' press return if paused ']);
        [wimg] = warp_to_mean_shape( X(i).pts, sfam.ompts, img, [], sfam.critical_triangle_expansion , [], [msiz(2),msiz(1),msiz(3)],[]);
        b = sfam.P'*(wimg(:) - sfam.Am);
        X(i).b = b(:);
        X(i).b_raw = X(i).b;
        X(i).b_std = b(:)./sqrt(sfam.b);
    else
        X(i).b = [];
        X(i).pts_aligned = [];
        X(i).b_raw = [];
        X(i).b_std = [];
    end
end
return;
%%%%%%
%
%
%%%%%%
function ad = doGroupsAutomaticOrdering(ad)
N = length(ad.groups);
for i=1:N
    group = ad.groups(i);
    X = [group.shapedata.b];
    X = X(ad.data.selectedShapePC(1),:);
    mu(i) = mean(X);
    groups(i) = group;
end
[val, ind] = sort(mu);
indx = 1;
for i=ind
    ad.groups(i).groupnumber = indx;
    indx = indx + 1;
end
return
%%%%%%
%
%
%%%%%%
function ad = doUserDefinedOrdering(ad)
if isempty(ad.groups)
    return;
end
[filename, pathname] = uigetfile('*.mat', 'Load order file');
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel');
    return
end
order = load([pathname, filesep, filename]);
if ~isfield(order, 'order')
    uiwait(msgbox('You have selected an invalid order file. Please try again.','Order file','modal'));
    return;
end
order = order.order;
N = length(ad.groups);
order = order(find(order<=N));
order = [order, setdiff(1:N, order)];
indx = 1;
for i=order
    ad.groups(i).groupnumber = indx;
    indx = indx+1;
end
return
%%%%%
%
%%%%%
function X = calculateShapeDeviations(X, pdm, details)
if isProject3D(pwd)
    dim = 3;
else
    dim = 2;
end
opts = [details.scaling, details.rotation, details.translation];
for i=1:length(X)
    pts = X(i).pts;
    if ~isempty(pts)
        [pts_aligned, template] = pcalib_GPA('data', pts, 'opts', details, 'dimension', dim, 'template', pdm.Xm);
        %pts_aligned = pmalign(pts,opts,pdm.Xm);
        X(i).b = pdm.pca.P'*(pts_aligned - pdm.Xm);
        X(i).pts_aligned = pts_aligned;
        X(i).b_raw = X(i).b;
        X(i).b_std = real(X(i).b./sqrt(pdm.pca.b));
    else
        X(i).b = [];
        X(i).pts_aligned = [];
        X(i).b_raw = [];
        X(i).b_std = [];
    end
end
return;
%%%%
%
%%%%
function ph = plot1dShapePts(X, shapeaxis, color, shapeuimenu, names, grpnum, pts_view_flag, data)
ph = [];
stdx = 2*std(X);
switch pts_view_flag
    case 1
        for i=1:size(X,2)
            data.name = names{i};
            data.element_num = i;
            ph(end+1) = plot(shapeaxis, X(i), grpnum, 'o', 'MarkerEdgeColor', 'k', 'MarkerFaceColor', color, 'UIContextMenu', shapeuimenu, 'UserData', data);
        end
    case 2
        mu = mean(X);
        minx = min(X); maxx = max(X);
        barheight = 0.1;
        ph(end+1)=plot(shapeaxis, [minx mu], [grpnum grpnum], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [mu maxx], [grpnum grpnum], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [minx minx], [grpnum-barheight grpnum+barheight], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [maxx maxx], [grpnum-barheight grpnum+barheight], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
    case 3
        mu = mean(X);
        barheight = 0.1;
        minx = mu-stdx;
        maxx = mu+stdx;
        ph(end+1)=plot(shapeaxis, [minx mu], [grpnum grpnum], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [mu maxx], [grpnum grpnum], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [minx minx], [grpnum-barheight grpnum+barheight], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [maxx maxx], [grpnum-barheight grpnum+barheight], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
    case 4
        mu = mean(X);
        barheight = 0.1;
        stderrx = std(X)./sqrt(length(X));
        minx = mu-stderrx;
        maxx = mu+stderrx;
        ph(end+1)=plot(shapeaxis, [minx mu], [grpnum grpnum], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [mu maxx], [grpnum grpnum], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [minx minx], [grpnum-barheight grpnum+barheight], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [maxx maxx], [grpnum-barheight grpnum+barheight], 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
  case 5
        mu = mean(X);
        minx = min(X); maxx = max(X);
        barheight = 0.1;
        sminx = mu-stdx;
        smaxx = mu+stdx;
        ph(end+1)=plot(shapeaxis, [minx mu], [grpnum grpnum], ':', 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [mu maxx], [grpnum grpnum], ':', 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [minx minx], [grpnum-barheight grpnum+barheight], ':', 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [maxx maxx], [grpnum-barheight grpnum+barheight], ':', 'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [sminx mu], [grpnum grpnum],  'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [mu smaxx], [grpnum grpnum],  'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [sminx sminx], [grpnum-barheight grpnum+barheight],  'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
        ph(end+1)=plot(shapeaxis, [smaxx smaxx], [grpnum-barheight grpnum+barheight],  'Color', color, 'MarkerFaceColor', color, 'MarkerEdgeColor', color, 'MarkerSize', 5, 'LineWidth', 3);
end
return
%%%%
%
%%%%
function ph = plot2dShapePts(X, shapeaxis, color, shapeuimenu, names, data)
ph = [];
for i=1:size(X,2)
    data.name = names{i};
    data.element_num = i;
    ph(end+1) = plot(shapeaxis, X(1,i), X(2,i), 'o', 'MarkerEdgeColor', 'k', 'MarkerFaceColor', color, 'UIContextMenu', shapeuimenu, 'UserData', data);
end
return
%%%%
%
%%%%
function ph = plot3dShapePts(X, shapeaxis, color, shapeuimenu, names, data)
ph = [];
for i=1:size(X,2)
    data.name = names{i};
    data.element_num = i;
    ph(end+1) = plot3(shapeaxis, X(1,i), X(2,i),  X(3,i), 'o', 'MarkerEdgeColor', 'k', 'MarkerFaceColor', color, 'UIContextMenu', shapeuimenu, 'UserData', data);
end
return;
%%%%
%
%%%%
function ad = plotShapePts(group, ad)
selectedPCs = ad.data.selectedShapePC;
shapeuimenu = ad.data.shapeuimenu;
shapeaxis = ad.handles.shapeaxis;
X = [group.shapedata.b];
meanpt = group.meanpt;
names = {group.shapedata.name};
dim = length(selectedPCs);
data.groupname = group.name;
data.groupnumber = group.groupnumber;

if size(X,1)>= max(selectedPCs)
    X = X(selectedPCs,:);
    h = drawEllipsoid(X, group.color, dim, shapeaxis);

    if ~isempty(h)
        ad.handles.elliphandle(end+1) = h;
    end
    switch(size(X,1))
        case 1
            pts_view_flag = 0;
            if strcmp(get(ad.handles.particlesmenu, 'Checked'), 'on')
                pts_view_flag = 1;
            else
                if strcmp(get(ad.handles.rngbarmenu, 'Checked'), 'on')
                    pts_view_flag = 2;
                elseif strcmp(get(ad.handles.stdbarmenu, 'Checked'), 'on')
                    pts_view_flag = 3;
                elseif strcmp(get(ad.handles.rngstdbarmenu, 'Checked'), 'on')
                    pts_view_flag = 5;
                else
                    pts_view_flag = 4;
                end
            end
            %axis(shapeaxis);
            %ad.handles.areavechandle = vectarrow([0 0 0],[areaVec(selectedPCs(1)) 0 0], 40)
            ph = plot1dShapePts(X, shapeaxis, group.color, shapeuimenu, names, group.groupnumber, pts_view_flag, data);
            data.element_num = 0;
            mu_h = plot(shapeaxis, meanpt(selectedPCs), group.groupnumber, 'd', 'MarkerFaceColor', group.color, 'MarkerSize', 10, 'visible', 'off', 'UIContextMenu', shapeuimenu, 'UserData', data);
            la_h = text(mean(X), group.groupnumber, group.name, 'Parent', shapeaxis, 'BackgroundColor', 'w', 'EdgeColor', group.color, 'Interpreter', 'none', 'hittest', 'off', 'HorizontalAlignment', 'Center');
            ad.handles.ptshandle = [ad.handles.ptshandle, ph];
            ad.handles.meanhandle(end+1) = mu_h;
            ad.handles.labelhandle(end+1) = la_h;
            axis(shapeaxis, 'normal');
            %ad.handles.areavechandle = plot(shapeaxis, [0 areaVec(selectedPCs(1))], [0 0], '-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2);

        case 2
            ph = plot2dShapePts(X, shapeaxis, group.color, shapeuimenu, names, data);
            mu = meanpt(selectedPCs);
            %axis(shapeaxis);
            %ad.handles.areavechandle = vectarrow([0 0 0],[areaVec(selectedPCs(1)) areaVec(selectedPCs(2)) 0], 40)
            %ad.handles.areavechandle = plot(shapeaxis, [0 areaVec(selectedPCs(1))], [0 areaVec(selectedPCs(2))], '-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2);
            data.element_num = 0;
            mu_h = plot(shapeaxis, mu(1), mu(2), 'd', 'MarkerFaceColor', group.color, 'MarkerSize', 10, 'visible', 'off', 'UIContextMenu', shapeuimenu, 'UserData', data);
            la_h = text(mu(1), mu(2), group.name, 'Parent', shapeaxis, 'BackgroundColor', 'w', 'EdgeColor', group.color, 'Interpreter', 'none', 'hittest', 'off', 'HorizontalAlignment', 'Center');
            ad.handles.ptshandle = [ad.handles.ptshandle, ph];
            ad.handles.meanhandle(end+1) = mu_h;
            ad.handles.labelhandle(end+1) = la_h;
            axis(shapeaxis, 'image', 'xy');
        case 3
            ph = plot3dShapePts(X, shapeaxis, group.color, shapeuimenu, names, data);
            mu = meanpt(selectedPCs);
            %axis(shapeaxis);
            %ad.handles.areavechandle = vectarrow([0 0 0],[areaVec(selectedPCs(1)) areaVec(selectedPCs(2)) areaVec(selectedPCs(3))], 40)
            %ad.handles.areavechandle = plot3(shapeaxis, [0 areaVec(selectedPCs(1))], [0 areaVec(selectedPCs(2))], [0 areaVec(selectedPCs(3))], '-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2);
            data.element_num = 0;
            mu_h = plot3(shapeaxis, mu(1), mu(2), mu(3), 'd', 'MarkerFaceColor', group.color, 'MarkerSize', 10, 'visible', 'off', 'UIContextMenu', shapeuimenu, 'UserData', data);
            la_h = text(mu(1), mu(2), mu(3), group.name, 'Parent', shapeaxis, 'BackgroundColor', 'w', 'EdgeColor', group.color, 'Interpreter', 'none', 'hittest', 'off', 'HorizontalAlignment', 'Center');
            ad.handles.ptshandle = [ad.handles.ptshandle, ph];
            ad.handles.meanhandle(end+1) = mu_h;
            ad.handles.labelhandle(end+1) = la_h;
            axis(shapeaxis, 'image', 'xy', 'vis3d');
    end

end

%%%%
%
%%%%
function ad = plotAppPts(group, ad)
selectedPCs = ad.data.selectedAppPC;
shapeuimenu = ad.data.shapeuimenu;
shapeuimenu = [];
shapeaxis = ad.handles.appaxis;
X = [group.appdata.b];
meanpt = group.appmeanpt;
names = {group.shapedata.name};
dim = length(selectedPCs);
data.groupname = group.name;
data.groupnumber = group.groupnumber;
if size(X,1)>= max(selectedPCs)
    X = X(selectedPCs,:);
    h = drawEllipsoid(X, group.color, dim, shapeaxis);
    if ~isempty(h)
        ad.handles.elliphandle(end+1) = h;
    end
    switch(size(X,1))
        case 1
            pts_view_flag = 0;
            if strcmp(get(ad.handles.particlesmenu, 'Checked'), 'on')
                pts_view_flag = 1;
            else
                if strcmp(get(ad.handles.rngbarmenu, 'Checked'), 'on')
                    pts_view_flag = 2;
                elseif strcmp(get(ad.handles.stdbarmenu, 'Checked'), 'on')
                    pts_view_flag = 3;
                else
                    pts_view_flag = 4;
                end
            end
            %axis(shapeaxis);
            %ad.handles.areavechandle = vectarrow([0 0 0],[areaVec(selectedPCs(1)) 0 0], 40)
            ph = plot1dShapePts(X, shapeaxis, group.color, shapeuimenu, names, group.groupnumber, pts_view_flag, data);
            data.element_num = 0;
            mu_h = plot(shapeaxis, meanpt(selectedPCs), group.groupnumber, 'd', 'MarkerFaceColor', group.color, 'MarkerSize', 10, 'visible', 'off', 'UIContextMenu', shapeuimenu, 'UserData', data);
            la_h = text(mean(X), group.groupnumber, group.name, 'Parent', shapeaxis, 'BackgroundColor', 'w', 'EdgeColor', group.color, 'Interpreter', 'none', 'hittest', 'off');
            ad.handles.ptshandle = [ad.handles.ptshandle, ph];
            ad.handles.meanhandle(end+1) = mu_h;
            ad.handles.labelhandle(end+1) = la_h;
            axis(shapeaxis, 'normal');
            %ad.handles.areavechandle = plot(shapeaxis, [0 areaVec(selectedPCs(1))], [0 0], '-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2);

        case 2
            ph = plot2dShapePts(X, shapeaxis, group.color, shapeuimenu, names, data);
            mu = meanpt(selectedPCs);
            %axis(shapeaxis);
            %ad.handles.areavechandle = vectarrow([0 0 0],[areaVec(selectedPCs(1)) areaVec(selectedPCs(2)) 0], 40)
            %ad.handles.areavechandle = plot(shapeaxis, [0 areaVec(selectedPCs(1))], [0 areaVec(selectedPCs(2))], '-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2);
            data.element_num = 0;
            mu_h = plot(shapeaxis, mu(1), mu(2), 'd', 'MarkerFaceColor', group.color, 'MarkerSize', 10, 'visible', 'off', 'UIContextMenu', shapeuimenu, 'UserData', data);
            la_h = text(mu(1), mu(2), group.name, 'Parent', shapeaxis, 'BackgroundColor', 'w', 'EdgeColor', group.color, 'Interpreter', 'none', 'hittest', 'off');
            ad.handles.ptshandle = [ad.handles.ptshandle, ph];
            ad.handles.meanhandle(end+1) = mu_h;
            ad.handles.labelhandle(end+1) = la_h;
            axis(shapeaxis, 'image', 'xy');
        case 3
            ph = plot3dShapePts(X, shapeaxis, group.color, shapeuimenu, names, data);
            mu = meanpt(selectedPCs);
            %axis(shapeaxis);
            %ad.handles.areavechandle = vectarrow([0 0 0],[areaVec(selectedPCs(1)) areaVec(selectedPCs(2)) areaVec(selectedPCs(3))], 40)
            %ad.handles.areavechandle = plot3(shapeaxis, [0 areaVec(selectedPCs(1))], [0 areaVec(selectedPCs(2))], [0 areaVec(selectedPCs(3))], '-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2);
            data.element_num = 0;
            mu_h = plot3(shapeaxis, mu(1), mu(2), mu(3), 'd', 'MarkerFaceColor', group.color, 'MarkerSize', 10, 'visible', 'off', 'UIContextMenu', shapeuimenu, 'UserData', data);
            la_h = text(mu(1), mu(2), mu(3), group.name, 'Parent', shapeaxis, 'BackgroundColor', 'w', 'EdgeColor', group.color, 'Interpreter', 'none', 'hittest', 'off');
            ad.handles.ptshandle = [ad.handles.ptshandle, ph];
            ad.handles.meanhandle(end+1) = mu_h;
            ad.handles.labelhandle(end+1) = la_h;
            axis(shapeaxis, 'image', 'xy', 'vis3d');
    end
end
%%%%%
%
%%%%%
function doPlotData(plotbtn, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
set(ad.handles.shapeaxistxt, 'String', num2str(ad.data.selectedShapePC));
ad = plotShapeData(ad);
if ~isempty(ad.data.sfam)
    ad = plotAppearanceData(ad);
end
setappdata(0, 'ShapeSpaceToolData', ad);
plotVectors;
lighting(ad.handles.shapeaxis, 'phong');
toggleVisuals;
return;
%%%%%
%
%%%%%
function ad = plotShapeData(ad)
N = length(ad.groups);
if (isempty(ad.handles.shapefig) | isempty(ad.handles.shapeaxis)) | (~ishandle(ad.handles.shapefig) | ~ishandle(ad.handles.shapeaxis))
    ad = newShapeFigure(ad);
end
cla(ad.handles.shapeaxis);
hold(ad.handles.shapeaxis, 'on');
set(ad.figMain, 'Pointer', 'watch');
set(ad.handles.shapeaxis, 'Visible', 'off');
drawnow;
ad = initPlotHandles(ad);
fprintf(sprintf('Entering plotting shape routine\n'));
legend_str = {};
for g = 1:N
    group = ad.groups(g);
        legend_str = cat(1, legend_str, group.name);
    ad = plotShapePts(group, ad);
end
%l = legend(ad.handles.elliphandle, legend_str);
%set(findobj(l, 'type', 'text'), 'Interpreter', 'none');
%legend(ad.handles.shapeaxis, 'hide');
shapeaxis(ad, ad.handles.shapeaxis);
shapelabels(ad);
ad = shapeareavector(ad);
grid(ad.handles.shapeaxis, 'on');
set(ad.handles.shapeaxis, 'Visible', 'on');
set(ad.figMain, 'Pointer', 'arrow');
set(ad.handles.shapeaxis, 'DataAspectRatioMode', 'auto', 'PlotBoxAspectRatioMode', 'auto', 'CameraViewAngleMode', 'auto');
fprintf(sprintf('Leaving plotting shape routine\n'));
return;
%%%%%
%
%%%%%
function ad = plotAppearanceData(ad)
N = length(ad.groups);
if (isempty(ad.handles.appfig) || isempty(ad.handles.appaxis)) || (~ishandle(ad.handles.appfig) || ~ishandle(ad.handles.appaxis))
    ad = newAppFigure(ad);
end
cla(ad.handles.appaxis);
hold(ad.handles.appaxis, 'on');
set(ad.figMain, 'Pointer', 'watch');
set(ad.handles.appaxis, 'Visible', 'off');
drawnow;
%ad = initPlotHandles(ad);
fprintf(sprintf('Entering plotting app routine\n'));
for g = 1:N
    group = ad.groups(g);
    ad = plotAppPts(group, ad);
end
appaxis(ad, ad.handles.appaxis);
applabels(ad);


grid(ad.handles.appaxis, 'on');
set(ad.handles.appaxis, 'Visible', 'on');
set(ad.figMain, 'Pointer', 'arrow');
set(ad.handles.appaxis, 'DataAspectRatioMode', 'auto', 'PlotBoxAspectRatioMode', 'auto', 'CameraViewAngleMode', 'auto');
fprintf(sprintf('Leaving plotting app routine\n'));
return;
%%%
%
%%%
function doSelectEllipsoids(toggellipbtn, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
groups = ad.groups;
if isempty(groups)
    return;
end
names = {groups.name};
[s,v] = listdlg('PromptString','Select ellipsoids you want to turn off:', 'SelectionMode','multiple', 'ListString',names);
if isempty(s)
    return;
end
for i=s
    set(ad.handles.elliphandle(i), 'Visible', 'off');
end
setappdata(0, 'ShapeSpaceToolData', ad);
return;
%%%%%
%
%%%%%
function ad = shapeareavector(ad)
pc = ad.data.selectedShapePC;
areaVec = ad.data.areavector;
areaVec = areaVec./norm(areaVec);
shapeaxis = ad.handles.shapeaxis;
xlim = get(shapeaxis, 'XLim');
ylim = get(shapeaxis, 'YLim');
zlim = get(shapeaxis, 'ZLim');
switch length(pc)
    case 1
        areaVec = areaVec.*min(abs(xlim));
        yval = length(ad.groups)/2;
        %ad.handles.areavechandle = quiver(shapeaxis, 0, yval, areaVec(pc(1)), 0, 1, 'Color', [1 0 0], 'LineWidth', 1, 'MaxHeadSize', 2, 'AutoScale', 'off');
        ad.handles.areavechandle = plot(shapeaxis, [0 areaVec(pc(1))], [yval yval], 'o-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2, 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    case 2
        areaVec = areaVec.*min([abs(xlim), abs(ylim)]);
    %    ad.handles.areavechandle = quiver(shapeaxis, 0, 0, areaVec(pc(1)), areaVec(pc(2)), 1, 'Color', [1 0 0], 'LineWidth', 1, 'MaxHeadSize', 2);
        ad.handles.areavechandle = plot(shapeaxis, [0 areaVec(pc(1))], [0 areaVec(pc(2))], 'o-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2, 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    case 3
        areaVec = areaVec.*min([abs(xlim), abs(ylim), abs(zlim)]);
      %  ad.handles.areavechandle = quiver3(shapeaxis, 0, 0, 0, areaVec(pc(1)), areaVec(pc(2)), areaVec(pc(2)), 1, 'Color', [1 0 0], 'LineWidth', 1, 'MaxHeadSize', 2);

        ad.handles.areavechandle = plot3(shapeaxis, [0 areaVec(pc(1))], [0 areaVec(pc(2))], [0 areaVec(pc(3))], 'o-', 'Color', 'k', 'Visible', 'off', 'LineWidth', 2, 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
end
return;
%%%%%
%
%%%%%
function applabels(ad)
pc = ad.data.selectedAppPC;
groups = ad.groups;
if get(ad.handles.lda_chk, 'value')
    prjstr = 'LDA ';
else
    prjstr = 'PCA ';
end
xlabel(ad.handles.appaxis, [prjstr, num2str(pc(1))]);
switch length(pc)
    case 1
        for i=1:length(groups)
            grp = groups(i);
            str{grp.groupnumber} = grp.name;
        end
        set(ad.handles.appaxis, 'YTick', 1:length(groups), 'YTickLabel', str);
        ylabel(ad.handles.appaxis, 'Groups');
    case 2
        set(ad.handles.appaxis, 'YTickLabelMode', 'auto', 'YTickMode', 'auto');
        ylabel(ad.handles.appaxis, [prjstr, num2str(pc(2))]);
    case 3
        set(ad.handles.appaxis, 'YTickLabelMode', 'auto', 'YTickMode', 'auto');
        ylabel(ad.handles.appaxis, [prjstr, num2str(pc(2))]);
        zlabel(ad.handles.appaxis, [prjstr, num2str(pc(3))]);
end
return;
%%%%%
%
%%%%%
function shapelabels(ad)
pc = ad.data.selectedShapePC;
groups = ad.groups;
if get(ad.handles.lda_chk, 'value')
    prjstr = 'LD ';
else
    prjstr = 'PC ';
end
xlabel(ad.handles.shapeaxis, [prjstr, num2str(pc(1))]);
switch length(pc)
    case 1
        for i=1:length(groups)
            grp = groups(i);
            str{grp.groupnumber} = grp.name;
        end
        set(ad.handles.shapeaxis, 'YTick', 1:length(groups), 'YTickLabel', str);
        ylabel(ad.handles.shapeaxis, 'Groups');
    case 2
        set(ad.handles.shapeaxis, 'YTickLabelMode', 'auto', 'YTickMode', 'auto');
        ylabel(ad.handles.shapeaxis, [prjstr, num2str(pc(2))]);
    case 3
        set(ad.handles.shapeaxis, 'YTickLabelMode', 'auto', 'YTickMode', 'auto');
        ylabel(ad.handles.shapeaxis, [prjstr, num2str(pc(2))]);
        zlabel(ad.handles.shapeaxis, [prjstr, num2str(pc(3))]);
end
return;
%%%%%
%
%%%%%
function shapeaxis(ad, axish)
switch length(ad.data.selectedShapePC)
    case 1
        view(axish, 2);
        axis(axish, 'tight', 'normal');
    case 2
        view(axish, 2);
        axis(axish, 'image', 'xy');
    case 3
        view(axish, 3);
        axis(axish, 'image', 'xy', 'vis3d');
end
%%%%%
%
%%%%%
function appaxis(ad, axish)
switch length(ad.data.selectedAppPC)
    case 1
        view(axish, 2);
        axis(axish, 'tight', 'normal');
    case 2
        view(axish, 2);
        axis(axish, 'image', 'xy');
    case 3
        view(axish, 3);
        axis(axish, 'image', 'xy', 'vis3d');
end
%%%%%
%
%%%%%
function ad = newShapeFigure(ad)
ad.handles.shapefig = figure('Position', [0, 0, 660, 660]);
set(ad.handles.shapefig, 'Name', 'Shape Window');
set(ad.handles.shapewindmenu, 'Checked', 'on');

ad.handles.shapeaxis = gca;


% Begin change by js, 080531
% Begin original code
 
movegui(ad.handles.shapefig, 'center');

% End original code
% Begin replacement code

% set(ad.handles.shapefig, 'Position', [0, 0, 1461, 1096]);
% movegui(ad.handles.shapefig, 'northwest'); % With the above results in [4, 33, 1461, 1096]

% End replacement code
% End change by js, 080531

set(ad.handles.shapefig, 'DoubleBuffer', 'on');
set(ad.handles.shapeaxis, 'DrawMode', 'fast');
ad.data.shapeuimenu = uicontextmenu('Parent', ad.handles.shapefig);
uimenu(ad.data.shapeuimenu,'Label','Original image','callback',{@showOriginalImage});
uimenu(ad.data.shapeuimenu,'Label','Show PC Values','callback',{@displayShapePCs});
uimenu(ad.data.shapeuimenu,'Label','Distance','callback',{@distanceShapeMethod});
uimenu(ad.data.shapeuimenu,'Label','Add Shape To Vectors','callback',{@addShapeToVectors});
return
%%%%%
%
%%%%%
function ad = newAppFigure(ad)
ad.handles.appfig = figure;
set(ad.handles.appfig, 'Name', 'Appearance Window');
set(ad.handles.appwindmenu, 'Checked', 'on');

ad.handles.appaxis = gca;
movegui(ad.handles.appfig, 'center');
set(ad.handles.appfig, 'DoubleBuffer', 'on');
set(ad.handles.appaxis, 'DrawMode', 'fast');
%ad.data.appuimenu = uicontextmenu('Parent', ad.handles.appfig);
%uimenu(ad.data.appuimenu,'Label','Original image','callback',{@showOriginalImage});
return
%%%%%
%
%%%%%
function doUseLDA(ldachk, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
if get(ldachk, 'value')==0
    doLoadGroups;
    doPlotData;
    return;
end
for g = 1:length(ad.groups)
    X{g} = [ad.groups(g).shapedata.b]';
end
dim = length(ad.data.selectedShapePC);
[Xm, P, b, ldaDat] = lda(X, dim);
for i=1:length(X)
    X{i} = (P*X{i}');
end
for g = 1:length(ad.groups)
    group = ad.groups(g);
    els = length(group.shapedata);
    for i=1:els
        group.shapedata(i).b(ad.data.selectedShapePC) = X{g}(:,i);
    end
    ad.groups(g) = group;
end
setappdata(0, 'ShapeSpaceToolData', ad);
doPlotData;
%%%%%%
%
% projectUsingLDA
%
%%%%%%
function PC = projectUsingLDA(PC, X, N)
[Xm, P, b, pcaDat] = lda(X, N);
for i=1:length(X)
    PC{i} = (P*X{i}')';
end
return;


%%%
%
%%%
function toggleVisuals
doToggleEllipsoid;
doToggleGroupMeans;
doToggleParticles;
doToggleLabels;
doToggleAreaVector;
return
%%%%%%
%
%
%%%%%%
function doToggleParticles(togg, evd)
ad = getappdata(0,'ShapeSpaceToolData');
showstr = 'off';
if get(ad.handles.ptschk, 'Value')
    showstr = 'on';
end
for i=1:length(ad.handles.ptshandle)
    set(ad.handles.ptshandle(i), 'Visible', showstr);
end
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doToggleEllipsoid(toggbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
showstr = 'off';
if get(ad.handles.ellipchk, 'Value')
    showstr = 'on';
end
for i=1:length(ad.handles.elliphandle)
    set(ad.handles.elliphandle(i), 'Visible', showstr);
end
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doToggleAreaVector(areavec, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ShapeSpaceToolData');
showstr = 'off';
if get(ad.handles.areavecchk, 'Value')
    showstr = 'on';
end
if ishandle(ad.handles.areavechandle)
    set(ad.handles.areavechandle, 'Visible', showstr);
end
areaVec = ad.data.areavector;
% calculate the ratio of the squared length of the area vector for our
% selected PCs and the total squared length of the area vector. We use
% squared length because ||v||^2 = x^2 + y^2 + z^2, and ||v_sub||^2 = x^2 +
% y^2, in this way ||v_sub||^2/||v||^2 tells us how much of the area vector
% is covered by x and y.
percCovered = 100*(norm(areaVec(ad.data.selectedShapePC))^2/norm(areaVec)^2);
fprintf('\nPercentage of area vector\ncovered using seleceted PCs: %2.2f%%\n', percCovered);
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doToggleSurface(toggbtn, evd) %#ok<INUSD,INUSD>
ad = getappdata(0,'ShapeSpaceToolData');
showstr = 'off';
if get(ad.handles.surfacechk, 'Value')
    showstr = 'on';
end
for i=1:length(ad.handles.surface_handle)
    set(ad.handles.surface_handle(i), 'Visible', showstr);
end
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doToggleLabels(toggbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
showstr = 'off';
if get(ad.handles.showlabelschk, 'Value')
    showstr = 'on';
end
for i=1:length(ad.handles.labelhandle)
    pos = get(ad.handles.labelhandle(i),'Position');
    %pos(1) = pos(1) + 0.015;
    pos(1) = pos(1) - 35;
    set(ad.handles.labelhandle(i),'Position',pos);
    set(ad.handles.labelhandle(i), 'Visible', showstr);
end
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doToggleOneDProjectionView(menuitem, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if strcmpi(get(menuitem, 'Label'), 'particles')
    set(ad.handles.particlesmenu, 'Checked', 'on');
    set(ad.handles.linegrphmenu, 'Checked', 'off');
else
    set(ad.handles.particlesmenu, 'Checked', 'off');
    set(ad.handles.linegrphmenu, 'Checked', 'on');
    switch lower(get(menuitem, 'tag'))
        case 'rngbarmenu'
            set(ad.handles.rngbarmenu, 'Checked', 'on');
            set(ad.handles.stdbarmenu, 'Checked', 'off');
            set(ad.handles.stderrmenu, 'Checked', 'off');
            set(ad.handles.rngstdbarmenu, 'Checked', 'off');
        case 'stdbarmenu'
            set(ad.handles.rngbarmenu, 'Checked', 'off');
            set(ad.handles.stdbarmenu, 'Checked', 'on');
            set(ad.handles.stderrmenu, 'Checked', 'off');
            set(ad.handles.rngstdbarmenu, 'Checked', 'off');
        case 'stderrmenu'
            set(ad.handles.rngbarmenu, 'Checked', 'off');
            set(ad.handles.stdbarmenu, 'Checked', 'off');
            set(ad.handles.stderrmenu, 'Checked', 'on');
            set(ad.handles.rngstdbarmenu, 'Checked', 'off');
        case 'rngstdbarmenu'
            set(ad.handles.rngbarmenu, 'Checked', 'off');
            set(ad.handles.stdbarmenu, 'Checked', 'off');
            set(ad.handles.stderrmenu, 'Checked', 'off');
            set(ad.handles.rngstdbarmenu, 'Checked', 'on');
    end

end
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doToggleGroupMeans(toggbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
showstr = 'off';
if get(ad.handles.showmeanschk, 'Value')
    showstr = 'on';
end
for i=1:length(ad.handles.meanhandle)
    set(ad.handles.meanhandle(i), 'Visible', showstr);
end
setappdata(0,'ShapeSpaceToolData', ad);
%%%%%%
%
%
%%%%%%
function doCombineGroups(btn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
[s, v] = CustomListDlg({groups.name});
if isempty(s)
    return;
end
prompt={'Name:'};
name='Group Name';
numlines=1;
defaultanswer={'New group'};
answer=inputdlg(prompt,name,numlines,defaultanswer);
if isempty(answer)
    return;
end
supergroup = groups(v(1));
supergroup.name = answer{1};
elements = {};
shapedata = [];
for i=v
    if (isfield(groups(i), 'elements') & isfield(groups(i), 'shapedata'))
        elements = [elements, groups(i).elements];
        shapedata = [shapedata, groups(i).shapedata];
    end
end
supergroup.elements = elements;
supergroup.color = rand(1,3);
supergroup.shapedata = shapedata;
supergroup.groupnumber = length(groups)+1;
groups(length(groups)+1) = supergroup;
ad.groups = groups;

setappdata(0,'ShapeSpaceToolData', ad);
UpdateGroupInfo;

%%%%%%
%
%
%%%%%%
function doOrderGroups
ad = getappdata(0,'ShapeSpaceToolData');
groups = ad.groups;
if isempty(groups)
    return;
end
[s, order, v] = SelectOrderListDlg('ListString', {groups.name});
for i=1:length(order)
    pos = find(order==i);
    q(i) = pos(1);
end
order = q;
if isempty(s)
    return;
end
modelDirec = get(handles.AAM, 'modelDirec');
save([pwd, filesep, modelDirec, filesep, 'usergrouporder.mat'], 'order');
setappdata(0,'ShapeSpaceToolData', ad);
return;
%%%%%%
%
%
%%%%%%

function doChangeIsoLevel(levelslider, evd)
ad = getappdata(0,'ShapeSpaceToolData');
surfdata = ad.surfaceData;

if any(ishandle(ad.handles.surface_handle))
    delete(ad.handles.surface_handle);
end
ad.handles.surface_handle = [];
for i = 1:length(surfdata)
    SD = surfdata(i);
    p = [];
    COLOR = SD.color;
    if (size(SD.V,1) > 0) && (length(size(SD.V)) == 3)
        scale = get(ad.handles.radiusSlider, 'value');
        set(ad.handles.radiusTxt, 'String', num2str(scale));
        p = patch(isosurface(SD.X, SD.Y, SD.Z, SD.V, scale), 'Parent', ad.handles.appaxis);
        isonormals(SD.X, SD.Y, SD.Z, SD.V, p);
        set(p, 'FaceAlpha', .5, 'FaceColor', COLOR, 'EdgeColor', 'none', 'visible', 'off');
        lighting(ad.handles.shapeaxis, 'phong');
    end
    if ~isempty(p)
        ad.handles.surface_handle(end+1) = p;
    end
end
setappdata(0,'ShapeSpaceToolData', ad);
doToggleSurface;
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% showSurface
%
%%%%%%%%%%%%%%%%%%%%%%%%%%
function p = showSurface(surfacedata, COLOR, scale, axish)
if (size(surfacedata.V,1) > 0) & (length(size(surfacedata.V)) == 3)
    %scale = get(handles.radiusSlider, 'value');
    %set(handles.radiusTxt, 'String', num2str(scale));
    p = patch(isosurface(surfacedata.X, surfacedata.Y, surfacedata.Z, surfacedata.V, scale), 'Parent', axish);
    isonormals(surfacedata.X, surfacedata.Y, surfacedata.Z, surfacedata.V, p);
    set(p, 'FaceAlpha', .5, 'FaceColor', COLOR, 'EdgeColor', 'none');
end
return;
%%%
%
%%%
function h = drawEllipsoid(X, COLOR, dim, axish)
switch dim
    case 1
        h = [];
    case 2
        [D, mu] = fit_ellipse(X', 2);
        h = patch(D.x, D.y, COLOR, 'Parent', axish);
        set(h, 'FaceAlpha', .5, 'FaceColor', COLOR, 'EdgeColor', COLOR, 'Visible', 'off');
    case 3
        [D, mu] = fit_ellipse(X');
        h = surf(axish, D.x, D.y, D.z);
        set(h, 'FaceAlpha', .5, 'FaceColor', COLOR, 'EdgeColor', COLOR, 'Visible', 'off');
end
return;
%%%
%
%%%
function doFitSurface(fitbtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
pc = ad.data.selectedShapePC;
if length(pc)~=3
    return;
end
bufferperc = 20;
ad.surfaceData = [];
for g = 1:length(ad.groups)
    group = ad.groups(g);
    pts = [group.shapedata.b];
    pts = [group.appdata.b];
    if ~isempty(pts)
        pts = pts(pc, :)';
        if ~isempty(pts)
            dx = str2num(get(ad.handles.dx_txt, 'String'));
            dy = str2num(get(ad.handles.dy_txt, 'String'));
            dz = str2num(get(ad.handles.dz_txt, 'String'));
            xmin = min(pts(:,1)); xmax = max(pts(:,1));
            ymin = min(pts(:,2)); ymax = max(pts(:,2));
            zmin = min(pts(:,3)); zmax = max(pts(:,3));
            sx = (xmax-xmin)*bufferperc/100; xmin = xmin - sx; xmax = xmax + sx;
            sy = (ymax-ymin)*bufferperc/100; ymin = ymin - sy; ymax = ymax + sy;
            sz = (zmax-zmin)*bufferperc/100; zmin = zmin - sz; zmax = zmax + sz;
            
            
            [X, Y, Z] = meshgrid(linspace(xmin, xmax, dx),linspace(ymin, ymax, dy), linspace(zmin, zmax, dz));
            V = zeros(size(X));
            indx =1;
            N = 1;
            for i=1:size(X,1)
                for j=1:size(X,2)
                    for k = 1:size(X,3)
                        d = sqrt((pts(:,1) - X(i,j,k)).^2 + (pts(:,2) - Y(i,j,k)).^2 + (pts(:,3) - Z(i,j,k)).^2 );
                        [d, ind] = sort(d);
                        V(i, j, k) = 1/((sum(d(1:N))/N));
                    end
                end
            end
            V = smooth3(V, 'gaussian',11, 1);
            V = smooth3(V, 'gaussian',11, 1);
            V = smooth3(V, 'box', 3);
            ad.surfaceData(g).X = X;
            ad.surfaceData(g).Y = Y;
            ad.surfaceData(g).Z = Z;
            ad.surfaceData(g).V = V;
            ad.surfaceData(g).color = group.color;
        end
    else
        ad.surfaceData(g).X = [];
        ad.surfaceData(g).Y = [];
        ad.surfaceData(g).Z = [];
        ad.surfaceData(g).V = [];
        ad.surfaceData(g).color = [];

    end
end
uiwait(msgbox('The volumes have been fitted to the data and the isosurfaces can now be viewed.','Done.','modal'));
setappdata(0,'ShapeSpaceToolData', ad);
%%%
%
%%%
function [data, mean_PC] = fit_ellipse(PC, dim);
% Check to see that there is more than one data point.
if nargin<2
    dim = 3;
end
if dim==2
    PC = PC(:,1:2);
end
if(size(PC,1) < 2)
    data.x = [];
    data.y = [];
    data.z = [];

    mean_PC = [];
    return;
end
mean_PC = mean(PC);
PC = PC - ones(size(PC,1),1)*mean(PC);
[V, D] = eig(PC'*PC);
ProjC = (V'*PC')';
smax = max(abs(ProjC));
if dim == 2

    theta = linspace(0, 2*pi, 100);
    x = cos(theta);
    y = sin(theta);
    C = [x(:)*smax(1) y(:)*smax(2)];
    C = (V*C')';
    x = C(:,1); y = C(:,2);;
    data.x = x + mean_PC(1);
    data.y = y + mean_PC(2);
else
    % Create a sphere
    [x,y,z] = sphere(20);
    [mm,nn] = size(x);
    C = [x(:)*smax(1) y(:)*smax(2) z(:)*smax(3)];
    C = (V*C')';
    x = C(:,1); y = C(:,2); z = C(:,3);
    x = reshape(x,mm,nn);
    y = reshape(y,mm,nn);
    z = reshape(z,mm,nn);
    data.x = x + mean_PC(1);
    data.y = y + mean_PC(2);
    data.z = z + mean_PC(3);
end
return;

%%%%%%
%
%
%%%%%%
function doProjectLDAviaPCA(ldapcabtn, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
G = {};
for g=1:length(groups)
    G{end+1} = [groups(g).shapedata.b_raw];
end
P = ad.data.pdm.pca.P;
for p=1:size(P,2)
    GP = projectGroupsOntoPC(G, p);
    %GP = projectGroupsOntoPC(G, P(:,p));
    Sb(p) = calcBetweenVariance(GP);
    Sw(p) = calcWithinVariance(GP);
end
varRatio= Sb./Sw;
plotProjectedScatter(size(P,2), Sb, Sw, varRatio);
setappdata(0,'ShapeSpaceToolData', ad);
return;
%%%
%
%%%
function plotProjectedScatter(N, Sb, Sw, varRatio)
figure;
x = 1:N;
subplot(2,2,1);
stem(x, log10(Sb), '-o', 'filled', 'MarkerFaceColor', 'y');
grid on; axis tight;
xlabel('PC');
ylabel('log_{10}(S_B)');
title('Between Class Scatter');

subplot(2,2,2);
stem(x, log10(Sw), '-o', 'filled', 'MarkerFaceColor', 'y');
grid on; axis tight;
xlabel('PC');
ylabel('log_{10}(S_W)');
title('Within Class Scatter');

subplot(2,2,3:4);
stem(x, log10(varRatio), '-o', 'filled', 'MarkerFaceColor', 'y');
grid on; axis tight;
xlabel('PC');
ylabel('log_{10}(S_b/S_w)');
title('Ration of Within and Between Scatter');




%%%%%%
%
%
%%%%%%
function GP = projectGroupsOntoPC(G,P)
for i=1:length(G)
    g = G{i};
    GP{i} = g(P,:);
    %GP{i} = P'*g;
end
return;
%%%%%%
%
%
%%%%%%
function Sb = calcBetweenVariance(GP)
for i=1:length(GP)
    g = GP{i};
    mu(i) = mean(g,2);
end
Sb = var(mu);
return
%%%%%%
%
%
%%%%%%
function Sw = calcWithinVariance(GP)
Sw = 0;
for i=1:length(GP)
    g = GP{i};
    Sw(i) = var(g);
end
Sw = mean(Sw);
return
%%%
%
%%%
function pdm = groups2pdm(groups, templatename)
X = [];
for i=1:length(groups)
    grp = groups(i);
    pms = aamio_getGroupPointModels('Group', grp, 'TemplateName', templatename);
    X = [X, [pms.pts]];
end
normalize_size = questdlg('Normalize shapes for size?', 'Normalize Size', 'Yes', 'No', 'Yes');
details = ones(1, 3);
if strcmp(normalize_size, 'No')
    details(3) = 0;
end

%details = ProcrustesParamsDlg;
%details = details(1:3);
[Xaligned, proc_param] = pmalign(X, details);
[Xm, P, b, pcaDat] = principle_component_analysis(Xaligned, 1);
pdm.Xm = Xm;
pdm.P = P;
pdm.b = b;
pdm.pcaDat = pcaDat;
pdm.pts_aligned = Xaligned;
pdm.details = details;
%%%%%
%
%
%%%%%
function doCalcProjTTest(menuitem, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
pdm = ad.data.pdm;
% Select the groups to make the base group on which to compare.
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Base Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
if isempty(groupindx)
    return;
end
baseGroups = ad.groups(groupindx);
baseShape = [baseGroups.shapedata];
base(1).b = [baseShape.b];
% get the groups to project
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
for i=1:length(groupindx)
    group(i).b = [ad.groups(groupindx(i)).shapedata.b];
    group(i).name = ad.groups(groupindx(i)).name;
end
% get the PC's to use on the projection
M = length(pdm.pca.b);
for i=1:M; str{i} = num2str(i); end;
[temp_Pcomponents,v] = listdlg('Name', 'PC Selection', 'PromptString','Select PC''s:', 'SelectionMode','multiple','ListString',str, 'ListSize', [300 160]);
if isempty(temp_Pcomponents)
    return;
end
saveT_TestTable(base, group, temp_Pcomponents);
setappdata(0,'ShapeSpaceToolData', ad);

return;
%%%%%
%
%
%%%%%
function doCalcProjRankedTTest(menuitem, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
pdm = ad.data.pdm;
% Select the groups to make the base group on which to compare.
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Base Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
if isempty(groupindx)
    return;
end
baseGroups = ad.groups(groupindx);
baseShape = [baseGroups.shapedata];
base(1).b = [baseShape.b];
% get the groups to project
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
for i=1:length(groupindx)
    group(i).b = [ad.groups(groupindx(i)).shapedata.b];
    group(i).name = ad.groups(groupindx(i)).name;
end
% get the PC's to use on the projection
M = length(pdm.pca.b);
for i=1:M; str{i} = num2str(i); end;
[temp_Pcomponents,v] = listdlg('Name', 'PC Selection', 'PromptString','Select PC''s:', 'SelectionMode','multiple','ListString',str, 'ListSize', [300 160]);
if isempty(temp_Pcomponents)
    return;
end
saveT_RankedTestTable(base, group, temp_Pcomponents);
setappdata(0,'ShapeSpaceToolData', ad);

return;
%%%%%%
%
%
%%%%%%
function saveT_TestTable(model, group, pcindx)
[filename, pathname] = uiputfile('*.xls', 'Save as...');
if isequal(filename,0) || isequal(pathname,0)
    return;
end
G = {};
indx = 3;
for a = pcindx
    G{indx ,1} = ['PC ', num2str(a)];
    indx = indx + 1;
end
indx = 2;
for i=1:length(group)
    grp = group(i);
    G{1 ,indx} = grp.name;
    G{2 ,indx} = 'Pr(NOT different)';
    G{2 ,indx+1} = 'Variance';
    rindx = 3;
    for a = pcindx
        P_t = ttest(model.b(a,:), grp.b(a,:));
        G{rindx ,indx} = P_t;
        G{rindx ,indx+1} = var(grp.b(a,:));
        rindx = rindx + 1;
    end
    %perc = 100*(sum(grp.projected_var(pcindx))/sum(grp.projected_var));
    %fprintf('Group: %s, %% of variance: %f\n', grp.name, perc);
    indx = indx + 2;
end
[success,msg]=xlswrite([pathname, filesep, filename],G, 'Sheet1');

% Now we print on sheet 2 the PCs that have a probability more than a
% certain threshold.
H = {};
indx = 1;
prompt={'Enter the threshold (keeps PCs with P<threshold):'};
name='Input';
numlines=1;
defaultanswer={'0.5'};
answer=inputdlg(prompt,name,numlines,defaultanswer);
if ~isempty(answer)
    thr = str2num(answer{1});
    for i=1:length(group)
        grp = group(i);
        H{1 ,indx} = grp.name;
        rindx = 2;
        for a = pcindx
            P_t = ttest(model.b(a,:), grp.b(a,:));
            if P_t<thr
                H{rindx ,indx} = sign(mean(grp.b(a,:)))*a;
            else
                H{rindx ,indx} = 0;
            end
            rindx = rindx + 1;
        end
        indx = indx + 1;
    end
    [success,msg]=xlswrite([pathname, filesep, filename],H, 'Sheet2');
end
return
%%%%%%
%
%
%%%%%%
function saveT_RankedTestTable(model, group, pcindx)
[filename, pathname] = uiputfile('*.xls', 'Save as...');
if isequal(filename,0) || isequal(pathname,0)
    return;
end
G = {};
indx = 3;
for a = pcindx
    G{indx ,1} = ['PC ', num2str(a)];
    indx = indx + 1;
end
indx = 2;
for i=1:length(group)
    grp = group(i);
    G{1 ,indx} = grp.name;
    G{2 ,indx} = 'Pr(NOT different) - Ranked T-Test';
    G{2 ,indx+1} = 'Variance';
    rindx = 3;
    for a = pcindx
        P_t = rank_transformation_ttest(model.b(a,:), grp.b(a,:));
        G{rindx ,indx} = P_t;
        G{rindx ,indx+1} = var(grp.b(a,:));
        rindx = rindx + 1;
    end
    %perc = 100*(sum(grp.projected_var(pcindx))/sum(grp.projected_var));
    %fprintf('Group: %s, %% of variance: %f\n', grp.name, perc);
    indx = indx + 2;
end
[success,msg]=xlswrite([pathname, filesep, filename],G, 'Sheet1');

% Now we print on sheet 2 the PCs that have a probability more than a
% certain threshold.
H = {};
indx = 1;
prompt={'Enter the threshold (keeps PCs with P<threshold):'};
name='Input';
numlines=1;
defaultanswer={'0.5'};
answer=inputdlg(prompt,name,numlines,defaultanswer);
if ~isempty(answer)
    thr = str2num(answer{1});
    for i=1:length(group)
        grp = group(i);
        H{1 ,indx} = grp.name;
        rindx = 2;
        for a = pcindx
            P_t = rank_transformation_ttest(model.b(a,:), grp.b(a,:));
            if P_t<thr
                H{rindx ,indx} = sign(mean(grp.b(a,:)))*a;
            else
                H{rindx ,indx} = 0;
            end
            rindx = rindx + 1;
        end
        indx = indx + 1;
    end
    [success,msg]=xlswrite([pathname, filesep, filename],H, 'Sheet2');
end
return
%%%%%
%
%
%%%%%
function doCalcProjVar(menuitem, evd)
ad = getappdata(0,'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;

% Select the groups to make the model on which to project
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Base Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
if isempty(groupindx)
    return;
end

% get the model based on these groups
pdm = groups2pdm(groups(groupindx), ad.data.templatename);

% get the groups to project
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);

model.total_variance = sum(pdm.pcaDat.b);
% each column of P is a principle component and each column of Q is a
% shape, and the inner product of the columns of P with the columns of Q
% gives the projection of each shape onto the PCs (recall P(:,i)'*P(:,i) = 1
P = pdm.pcaDat.P;
Q = pdm.pts_aligned;
model.projected_pts = P'*Q;
model.projected_var = var(model.projected_pts');
groups = groups(groupindx);
proj_group = struct([]);
range = [];
for i=1:length(groups)
    grp = groups(i);
    grppms = aamio_getGroupPointModels('Group', grp, 'TemplateName', ad.data.templatename);
    grpX = [grppms.pts];
    grpXaligned = pmalign(grpX, pdm.details);
    if size(grpXaligned,2)==1
        C = 0;
    else
        C = cov(grpXaligned');
    end
    [V, L] = eig(C);
    proj_group(i).total_variance = trace(L);;
    proj_group(i).projected_pts = P'*grpXaligned;
    proj_group(i).projected_var = var(proj_group(i).projected_pts');
    proj_group(i).name = grp.name;
    proj_group(i).col = grp.color;
    range = getRange(proj_group(i).projected_pts, range);

end
showProjectedVariance(model, proj_group, range);
return;
%%%
%
%%%
function range = getRange(pts, range)
if isempty(range)
    range(:,1) = min(pts,[], 2);
    range(:,2) = max(pts,[], 2);
    return;
end
minpts = min(pts,[], 2);
maxpts = max(pts,[], 2);

ind = find(minpts < range(:,1));
range(ind,1) = minpts(ind);

ind = find(maxpts > range(:,2));
range(ind,2) = maxpts(ind);
return;
%%%
%
%%%
function showProjectedVariance(model, proj_group, range)
N = length(proj_group);
ratio = model.projected_var./proj_group(1).projected_var;
[val, ind] = sort(ratio, 'descend');
ind = ind(1:min(9, length(ind)));
figure; hold on;
R = 3; C = 3; indx = 1;
for i=ind
    ah = subplot(R, C, indx); indx = indx + 1;
    hold(ah, 'on');
    for g = 1:N
        grp = proj_group(g);
        [gxr, gyr] = gaussian_1d(mean(grp.projected_pts(i,:)), std(grp.projected_pts(i,:)), range(i,:), 100);
        if max(abs(gyr))> 0
            gyr = gyr./max(gyr);
        end
        plot(ah,gxr, gyr, '-', 'Color', grp.col);
    end
    [gxr, gyr] = gaussian_1d(mean(model.projected_pts(i,:)), std(model.projected_pts(i,:)), range(i,:), 100);
    gyr = gyr./max(gyr);
    plot(ah, gxr, gyr, '--', 'Color', 'k');
    axis(ah, 'tight'); grid(ah, 'on');
    %title(ah, ['PC: ', num2str(i), ', Ratio: ', num2str(ratio(i))]);
    title(ah, ['PC: ', num2str(i)]);
end
return;


%%%%%%
%
%
%%%%%%
function doDefineOrder(ordermenu, evd)
ad = getappdata(0,'ShapeSpaceToolData');
groups = ad.groups;
if isempty(groups)
    return;
end
indx = 1:length(groups);
[s, order, v] = SelectOrderListDlg('ListString', {groups.name});
if isempty(s)
    return;
end
order = [order, setdiff(indx, order)];
[filename, pathname] = uiputfile('*.mat', 'Save order as...');
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel');
    return;
end
save([pathname, filesep, filename], 'order');
setappdata(0,'ShapeSpaceToolData', ad);
return;
%%%
%
%%%
function ad = calculateAreaVector(ad)
xm = ad.data.pdm.Xm;
P = ad.data.pdm.pca.P;

% Begin change by js, 071217
% Begin original code

% xm = reshape(xm, 2, length(xm)/2);

% End original code
% Begin replacement code

xm = reshape(xm, ad.data.dim, length(xm)/ad.data.dim);

% End replacement code
% End change by js, 071217

cent = mean(xm, 2);
xm = xm - cent*ones(1, size(xm, 2));
xmL = 2*xm;
xmL = xmL + cent*ones(1, size(xm, 2));
b = P'*(xmL(:) - ad.data.pdm.Xm);
b = b./norm(b);
b = b*10;
ad.data.areavector = b;
return;
%%%
%
%%%
function addShapeToVectors(pm, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
groups = ad.groups;
if isempty(groups)
    return;
end
data = get(gco, 'UserData');
group = groups(data.groupnumber);
if (data.element_num==0)
    b = group.meanpt;
else
    element = group.shapedata(data.element_num);
    b = element.b;
end
ad.data.vectors = [ad.data.vectors, b(:)];
setappdata(0, 'ShapeSpaceToolData', ad);
plotVectors;
return;
%%%%%%
%
%
%%%%%%
function distanceShapeMethod(pm, evd)
ad =getappdata(0, 'ShapeSpaceToolData');
groups = ad.groups;
if isempty(groups)
    return;
end
data = get(gco, 'UserData');
group = groups(data.groupnumber);
if (data.element_num==0)
    b = group.meanpt;
else
    element = group.shapedata(data.element_num);
    b = element.b;
end
ad.data.distance = [ad.data.distance, b];
if size(ad.data.distance,2) == 2
    diff =  ad.data.distance(:,2) - ad.data.distance(:,1);
    ad.data.distance = [];
    figh = figure;
    axis1h = subplot(2,1,1);
    axis2h = subplot(2,1,2);
    x = 1:length(diff);
    s = stem(axis1h, x, diff, 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    xlabel(axis1h, 'PC Number');
    ylabel(axis1h, 'PC Value');
    title(axis1h, 'Difference between selected points');
    axis(axis1h, 'tight');
    grid(axis1h, 'on');
    diff = diff.^2;
    s = stem(axis2h, x, (diff./sum(diff))*100, 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
    xlabel(axis2h, 'PC Number');
    ylabel(axis2h, '% of squared PC difference');
    title(axis2h, 'Percentage of Squared Difference');
    axis(axis2h, 'tight');
    grid(axis2h, 'on');
else
    uiwait(msgbox('Please select your next point to caclulate the difference','Select','modal'));
end
setappdata(0, 'ShapeSpaceToolData', ad);
return;
%%%
%
%%%
function doImportVectors(importvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
[filename, pathname] = uigetfile('*.xls', 'Pick a vectors file');
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel')
    return;
else
    disp(['User selected ', fullfile(pathname, filename)]);
    [numeric,txt]=xlsread([pathname, filesep, filename], 'ShapeVectors');
    N = length(ad.data.pdm.pca.b);
    if size(numeric, 1)>N
        numeric = numeric(1:N, :);
    elseif size(numeric,1)<N
        temp = numeric;
        numeric = zeros(N, size(numeric,2));
        numeric(1:size(temp,1),:) = temp;
    end
end
ad.data.vectors = numeric;
setappdata(0, 'ShapeSpaceToolData', ad);
plotVectors;
return;
%%%
%
%%%
function plotVectors(vec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
vectors = ad.data.vectors;
for i=1:length(ad.handles.vectorsh)
    if ishandle(ad.handles.vectorsh(i))
        delete(ad.handles.vectorsh(i));
    end
end
ad.handles.vectorsh = [];
if isempty(ad.handles.shapeaxis)
    return
end
if size(vectors,2)<2
    return;
end
pcs = ad.data.selectedShapePC;
switch length(pcs)
    case 2
        ad = plot2dVectors(ad);
    case 3
        ad = plot3dVectors(ad);
end
setappdata(0, 'ShapeSpaceToolData', ad);
doToggleVectors;
return;
%%%
%
%%%
function ad = plot3dVectors(ad)
vectors = ad.data.vectors;
if isempty(vectors)
    return;
end
pcs = ad.data.selectedShapePC;
shapeaxis = ad.handles.shapeaxis;
vectors = vectors(pcs,:);
vectorsh = [];
for i=2:size(vectors,2)
    v = vectors(:, i-1);
    w = vectors(:,i);
    dv = w-v;
    vectorsh(end+1) = quiver3(shapeaxis, v(1), v(2), v(3), dv(1), dv(2), dv(3), 1, 'MaxHeadSize', 1, 'Visible', 'off', 'LineWidth', 2);
    %vectorsh(end+1) = plot(shapeaxis, [vectors(1, i-1) vectors(1, i)], [vectors(2, i-1), vectors(2, i)]);
end
ad.handles.vectorsh = vectorsh;
return;
%%%
%
%%%
function ad = plot2dVectors(ad)
vectors = ad.data.vectors;
if isempty(vectors)
    return;
end
pcs = ad.data.selectedShapePC;
shapeaxis = ad.handles.shapeaxis;
vectors = vectors(pcs,:);
vectorsh = [];
for i=2:size(vectors,2)
    v = vectors(:, i-1);
    w = vectors(:,i);
    dv = w-v;
    vectorsh(end+1) = quiver(shapeaxis, v(1), v(2), dv(1), dv(2), 1, 'MaxHeadSize', 1, 'Visible', 'off', 'LineWidth', 2);
    %vectorsh(end+1) = plot(shapeaxis, [vectors(1, i-1) vectors(1, i)], [vectors(2, i-1), vectors(2, i)]);
end
ad.handles.vectorsh = vectorsh;
return;
%%%
%
%%%
function doDrawVectors(drawvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
dims = length(ad.data.selectedShapePC);
if dims~=2
    uiwait(msgbox('You can only draw vectors when viewing in 2D.','Warning','modal'));
    return;
end
fprintf('Right click to finish.\n');
for i=1:length(ad.handles.vectorsh)
    if ishandle(ad.handles.vectorsh(i))
        delete(ad.handles.vectorsh(i));
    end
end
ad.data.vectors = [];
set(ad.handles.vectorschk, 'Value', 1);
set(ad.handles.shapeaxis, 'Visible', 'on', 'ButtonDownFcn', {@clickedShapeAxis});
setappdata(0, 'ShapeSpaceToolData', ad);
return
%%%
%
%%%
function clickedShapeAxis(exportvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
N = length(ad.data.pdm.pca.b);
shapepcs = ad.data.selectedShapePC;
shapeaxis = ad.handles.shapeaxis;
shapefig = ad.handles.shapefig;
clicktype = get(shapefig, 'SelectionType');
switch lower(clicktype)
    % Left Click
    case 'normal'
        pt = get(shapeaxis, 'CurrentPoint');
        pt = pt(1,1:2)';
        b = zeros(N,1);
        b(shapepcs) = pt;
        ad.data.vectors = [ad.data.vectors, b];
        % Right Click
    case 'alt'
        set(ad.handles.shapeaxis, 'Visible', 'on', 'ButtonDownFcn', '');
        fprintf('Finished defining vectors\n');
end
setappdata(0, 'ShapeSpaceToolData', ad);
plotVectors;
return;
%%%
%
%%%
function doExportVectors(exportvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
vectors = ad.data.vectors;
if isempty(vectors)
    return;
end
[filename, pathname] = uiputfile('*.xls', 'Save vectors as...');
if isequal(filename,0) || isequal(pathname,0)
    disp('User pressed cancel');
    return;
end
[success, msg]=xlswrite([pathname, filesep, filename],vectors, 'ShapeVectors');
setappdata(0, 'ShapeSpaceToolData', ad);
%%%
%
%%%
function doToggleVectors(vecchk, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
vecchk = ad.handles.vectorschk;
vectors = ad.data.vectors;
if isempty(vectors)
    return;
end
if get(vecchk, 'Value')
    set(ad.handles.vectorsh, 'Visible', 'on');
else
    set(ad.handles.vectorsh, 'Visible', 'off');
end
setappdata(0, 'ShapeSpaceToolData', ad);
%%%
%
%%%
function doWalkVectors(walkvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
vectors = ad.data.vectors;
if isempty(vectors)
    return;
end
if isempty(ad.data.pdm)
    return;
end
ad.data.template
P = ad.data.pdm.pca.P;
b = ad.data.pdm.pca.b;
pcs = ad.data.selectedShapePC;
sqrtb = sqrt(b);
Xm = ad.data.pdm.Xm;
prompt={'Enter the number of steps to walk along each vector:'};
name='Vec. Walk';
numlines=1;
defaultanswer={'10'};
steps=inputdlg(prompt,name,numlines,defaultanswer);
if isempty(steps)
    return;
end
steps = str2double(steps{1});
MB = zeros(size(Xm,1), (size(vectors,2)-1)*10);
indx = 1;
for i=2:size(vectors, 2)
    v = vectors(:,i-1);
    w = vectors(:,i);
    q = w-v;
    L = norm(q);
    V = q./L;
    dv = linspace(0, L, steps);
    for j=dv
        mb = v + j*V;
        MB(:,indx)= mb;
        indx = indx +1;
    end
end
mb = MB(pcs,1);
if length(pcs)==2
    ph = plot(ad.handles.shapeaxis, mb(1), mb(2), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
elseif length(pcs)==3
    ph = plot3(ad.handles.shapeaxis, mb(1), mb(2), mb(3), 'o', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'y');
end
edges = get(ad.data.template, 'loops');
if strcmp(get(ad.handles.stdunitsmenu, 'Checked'), 'on')
    units = 'std';
else
    units = 'var';
end
if isfield(ad.data,'facets')
    VectorWalker('pdm', ad.data.pdm, 'shapes', MB, 'ploth', ph, 'PCs', pcs, ...
        'edges', edges, 'units', units, 'facets', ad.data.facets, 'ShapeSpaceAxisHandle',ad.handles.shapeaxis, ...
		'dim', ad.data.dim, 'surfaceData', ad.surfaceData);
else
    VectorWalker('pdm', ad.data.pdm, 'shapes', MB, 'ploth', ph, 'PCs', pcs, 'edges', edges, 'units', units, ...
		'dim', ad.data.dim, 'surfaceData', ad.surfaceData);
end
setappdata(0, 'ShapeSpaceToolData', ad);
return;
%%%
%
%%%
function doClearVectors(clearvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
ad.data.vectors = [];
setappdata(0, 'ShapeSpaceToolData', ad);
plotVectors;
return;
%%%
%
%%%
function doPrintVectors(clearvec, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
ad.data.vectors
setappdata(0, 'ShapeSpaceToolData', ad);
return;
%%%%
%
%%%%
function doAxisEqual(axisequalbtn, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
if (isempty(ad.handles.shapefig) | isempty(ad.handles.shapeaxis)) | (~ishandle(ad.handles.shapefig) | ~ishandle(ad.handles.shapeaxis))
    ad = newShapeFigure(ad);
end
axis(ad.handles.shapeaxis, 'equal');
setappdata(0, 'ShapeSpaceToolData', ad);
return;
%%%
%
%%%
function doTranslateGroups(transmenu, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
% Select the base groups to translate to
str = sprintf('Select Start of Displacement Vector Group''s:  (N.B. Cancel uses the origin');
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString',str, 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
%if isempty(groupindx)
%    return;
%end
basegroups = groups(groupindx);


% Select the target groups to translate
str = sprintf('Select End of Displacement Vector Group''s:');
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString',str, 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
if isempty(groupindx)
    return;
end
targetgroups = groups(groupindx);


% Select the target groups to translate
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Group''s to translate:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
if isempty(groupindx)
    return;
end
transgroups = groups(groupindx);



base_b = [];
for i=1:length(basegroups)
    base_b = [base_b, basegroups(i).shapedata.b];
end
tran_b = [];
for i=1:length(targetgroups)
    tran_b = [tran_b, targetgroups(i).shapedata.b];
end
base_mu = mean(base_b,2);
tran_mu = mean(tran_b,2);
if isempty(base_mu)
    delta =  - tran_mu;
else
    delta = base_mu - tran_mu;
end
for i=1:length(transgroups)
    tgrp = transgroups(i);
    for j=1:length(tgrp.shapedata)
        if length(tgrp.shapedata(j).b)==length(delta)
            tgrp.shapedata(j).b = tgrp.shapedata(j).b + delta;
        end
    end
    tgrp.meanpt = tgrp.meanpt + delta;
    transgroups(i) = tgrp;
end
groups(groupindx) = transgroups;
ad.groups = groups;
setappdata(0, 'ShapeSpaceToolData', ad);
doPlotData;
fprintf('Re-select Units to get back to old data without reloading\n');
return;
%%%
%
%%%
function doExportPCValues(exportmenu, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
% Select the groups to export
[groupindx,v] = listdlg('Name', 'Group Selection', 'PromptString','Select Group''s:', 'SelectionMode','multiple','ListString',{groups.name}, 'ListSize', [300 160]);
if isempty(groupindx)
    return;
end
export_groups = groups(groupindx);
[filename, pathname] = uiputfile('*.xls', 'Export PC Values To...');
if isequal(filename,0) || isequal(pathname,0)
    return;
end
xlsfilename = [pathname, filesep, filename];
rowindx = 1;
XLSDATA = {};
for i=1:length(export_groups)
    grp = export_groups(i);
    XLSDATA{rowindx, 1} = grp.name; rowindx = rowindx + 1;
    for j=1:length(grp.elements)
        XLSDATA{rowindx, 2} = grp.elements{j};
        shpdat = grp.shapedata(j).b;
        for k=1:length(shpdat)
            XLSDATA{rowindx, k+2} = shpdat(k);
        end
        rowindx = rowindx + 1;
    end
    rowindx = rowindx + 1;
end
[success, message] = xlswrite(xlsfilename, XLSDATA, 'Sheet1');
setappdata(0, 'ShapeSpaceToolData', ad);
return;
%%%
%
%%%
function doToggleLegend(legend_menu, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
legend(ad.handles.shapeaxis, 'toggle');
setappdata(0, 'ShapeSpaceToolData', ad);
return
%%
%%
function doExportGroupMeans(exportGroupMeanPts, evd)
ad = getappdata(0, 'ShapeSpaceToolData');
if isempty(ad.groups)
    return;
end
groups = ad.groups;
[filename, pathname] = uiputfile('*.xls', 'Export PC Values To...');
if isequal(filename,0) || isequal(pathname,0)
    return;
end
xlsfilename = [pathname, filesep, filename];
rowindx = 1;
XLSDATA = {};
for i=1:length(groups)
    grp = groups(i);
    XLSDATA{rowindx, 1} = grp.name;
    for j=1:length(grp.meanpt)
        XLSDATA{rowindx, j+2} = grp.meanpt(j);
    end
    rowindx = rowindx + 1;
end
[success, message] = xlswrite(xlsfilename, XLSDATA, 'Sheet1');
setappdata(0, 'ShapeSpaceToolData', ad);   
return
