[Master Index]
[Index for Toolbox]
subject_editor
(Toolbox/subject_editor.m in BrainStorm 2.0 (Alpha))
Function Synopsis
varargout = subject_editor(action,varargin)
Help Text
SUBJECT_EDITOR - GUI to edit the BrainStorm Subject information, case switchyard
function varargout = subject_editor(action,varargin)
R11 Case Switchyard, Creates/Edits a brainstormsubject.mat file
Invoke as subject_editor('create');
[FIG,HANDLES] = subject_editor(action) returns the figure and handles
Cross-Reference Information
This function calls
This function is called by
Listing of function C:\BrainStorm_2001\Toolbox\subject_editor.m
function varargout = subject_editor(action,varargin)
%SUBJECT_EDITOR - GUI to edit the BrainStorm Subject information, case switchyard
% function varargout = subject_editor(action,varargin)
% R11 Case Switchyard, Creates/Edits a brainstormsubject.mat file
% Invoke as subject_editor('create');
% [FIG,HANDLES] = subject_editor(action) returns the figure and handles
%<autobegin> ---------------------- 12-Oct-2004 01:12:37 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: GUI and Related
%
% Alphabetical list of external functions (non-Matlab):
% toolbox\bst_color_scheme.m
% toolbox\bst_layout.m
% toolbox\bst_message_window.m
% toolbox\bst_mriviewer.m
% toolbox\bst_win_manager.m
% toolbox\fidufit.m
% toolbox\file_selection_win.m
% toolbox\find_brainstorm_files.m
% toolbox\get_user_directory.m
% toolbox\makeuswait.m
% toolbox\mesh2brainstorm.m
% toolbox\readdfs.m
% toolbox\readdsgl.m
% toolbox\subject_editor.m NOTE: Routine calls itself explicitly
% toolbox\tess_align_tool.m
% toolbox\tri2brainstorm.m
%
% Group : Preference data and their calls in this file:
% Studies = getpref('BrainStorm','Studies',[]);
%
% Application data and their calls in this file:
% 'Comment'
% 'CreateFlag'
% 'DataDir'
% 'TessellationFiles'
% 'TileType'
% 'nFaces'
% 'nVertices'
%
% setappdata(TriList,'TileType','T')
% setappdata(fig,'Comment',Comment)
% setappdata(fig,'CreateFlag',0)
% setappdata(fig,'CreateFlag',1);
% setappdata(fig,'DataDir',DataDir);
% setappdata(fig,'TessellationFiles',TessFiles);
% setappdata(fig,'TileType','T')
% setappdata(fig,'nFaces',nFaces)
% setappdata(fig,'nVertices',nVertices)
% setappdata(hf,'TileType','T')
%
% DataDir = getappdata(fig,'DataDir');
% TessFiles = getappdata(fig,'TessellationFiles');
% nFaces = getappdata(fig,'nFaces');
% nVertices = getappdata(fig,'nVertices');
% switch getappdata(fig,'CreateFlag')
%
% Figure Files opened by this function:
% 'generic_listbox_win.fig'
% mfilename
%
% Format of strings below: Type:Style:Tag, "String", CallBack Type and Call
% <automatic> callback is <Tag>_Callback by Matlab default
%
% Callbacks by figure generic_listbox_win.fig
% uicontrol:pushbutton:DONE "Done" uses Callback for subject_editor ImportTriDone
%
% Callbacks by figure subject_editor.fig
% uicontrol:listbox:e_comment "" uses Callback for subject_editor CurrentEnvelopeInfo
% uicontrol:popupmenu:listboxx "''" uses Callback for subject_editor listboxx
% uicontrol:popupmenu:Tesselation "N/A" uses Callback for subject_editor TessellationFileInfo
% uicontrol:pushbutton:Cancel "Cancel" uses Callback for delete(gcbf)
% uicontrol:pushbutton:fit "Adjust" uses Callback for subject_editor fit
% uicontrol:pushbutton:pushbutton10 "View" uses Callback for subject_editor ViewEnvelope
% uicontrol:pushbutton:pushbutton100 "Save as" uses Callback for subject_editor saveas
% uicontrol:pushbutton:pushbutton11 "Swap faces" uses Callback for subject_editor SwapFaces
% uicontrol:pushbutton:pushbutton12 "Align" uses Callback for subject_editor AlignTessellation
% uicontrol:pushbutton:pushbutton2 "Import" uses Callback for subject_editor ImportAnatomy
% uicontrol:pushbutton:pushbutton4 "Import" uses Callback for subject_editor ImportTessellation
% uicontrol:pushbutton:pushbutton5 "Rename" uses Callback for subject_editor RenameEnvelope
% uicontrol:pushbutton:pushbutton7 "Delete" uses Callback for subject_editor DeleteEnvelope
% uicontrol:pushbutton:Pushbutton8 "Save" uses Callback for subject_editor save
% uicontrol:pushbutton:pushbutton8 "Downsize" uses Callback for subject_editor DownsizeEnvelope
% uicontrol:pushbutton:pushbutton9 "Concatenate" uses Callback for
% subject_editor ConcatenateEnvelope
% uicontrol:pushbutton:QuitPushbutton1 "Done" uses Callback for subject_editor quit
%
% At Check-in: $Author: Mosher $ $Revision: 45 $ $Date: 10/11/04 11:34p $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 23-Sep-2004
%
% Principal Investigators and Developers:
% ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
% University of Southern California, Los Angeles, CA
% ** John C. Mosher, PhD, Biophysics Group,
% Los Alamos National Laboratory, Los Alamos, NM
% ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
% CNRS, Hopital de la Salpetriere, Paris, France
%
% See BrainStorm website at http://neuroimage.usc.edu for further information.
%
% Copyright (c) 2004 BrainStorm by the University of Southern California
% This software distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html .
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%<autoend> ------------------------ 12-Oct-2004 01:12:37 -----------------------
% /---Script Author--------------------------------------\
% | |
% | *** Sylvain Baillet, Ph.D. |
% | Cognitive Neuroscience & Brain Imaging Laboratory |
% | CNRS UPR640 - LENA |
% | Hopital de la Salpetriere, Paris, France |
% | sylvain.baillet@chups.jussieu.fr |
% | |
% | *** John C. Mosher, Ph.D. |
% | Biophysics Group |
% | Los Alamos National Laboratory |
% | Los Alamos, New Mexico, USA |
% | mosher@lanl.gov |
% | |
% | *** Dimitrios Pantazis |
% | Univerisity of Southern California |
% \------------------------------------------------------/
%
% Date of creation: January 1999
%
% Script History -----------------------------------------------------------------------------------------------------------
% SB 28-Mar-2002 Systematic use of getappdata to access DataBase information
% SB 16-Apr-2002 Changed findobj calls to handles. referencing via guihandles
% ............... Fixed bug on tessellation file naming (which is supposed
% to be relative to the subject's folder)
% SB 23-May-2002 Moving to new Tessellation File format
% ............... Removed _brainstormsubject.mat filename tails in file display
% JCM 24-May-2002 changed name to subject_editor to match the GUI, altered GUI calls
% ............... altered flow of cases to be more efficient, added handles output
% SB 27-May-2002 Changed the location of the set(fig,'visible','on') command so
% that SUBJECTEDITOR can be created by direct call
% ............... to subject_editor('loadfile',FILENAME) as well
% JCM 6-June-2002 Fixed 'loadfile' comment above, it was transposed in the arguments.
% JCM 11-Jun-2002 Auto comments, watch pointers, fixed bug in "save" routine
% JCM 20-Jun-2002 "Go" button still calling old routine, fixed.
% Bug with "No Subject Files . . ."
% needs to be a cell array to work with empty case in listboxx. Reworked
% this tool such that DataDir is stored in the Application data as unaltered.
% If DataDir is empty, then no data, and listboxx displays "No subject files"
% Changed SUBJECTEDITOR to fig for readability.
% "Loadfile" no longer used, case removed.
% Changed all explicit subject_editor calls to feval(mfilename).
% generic_listbox_win called old _cb routine as well. Definitely CBB.
% If "Save" does not detect filenames, defaults to "Save As"
% SB 01-Jul-2002 Fixed bugs occuring whem hitting the 'Load' button for
% loading a tessellation file
% SB 22-Jul-2002 Misc. display enhancements
% SB 28-Jul-2002 _brainstormsubject is not longer a mandatory suffix
% .............. Fixed loading issues when some DataBase elements
% (such as some SubjectFiles or StudyFile)
% .............. are not up to date
% SB 22-Oct-2002 Fixed bugs for TessFile access when importing .tri files.
% SB 05-Nov-2002 Updated GUI and Import callbacks - BrainSuite tri files can now
% be imported into BsT
% JCM 06-Nov-2002 Handle case of no studies, just a subject file, don't close GUI.
% Changed the Quit button label to "Done"
% SB 20-Nov-2002 Save the Anatomy field when a subjectimage is available
% SB 28-Feb-2003 Added the SwapFaces feature for tessellated envelopes
% SB 03-Jun-2003 Compliant with the new Tiling of GUIs
% JCM 19-Aug-2003 Handle new database cases, switch back to arrows.
% JCM 5-Sep-2003 handle start of new gui better
% JCM 11-May-2004 Handle case of missing datamanager GUI (e.g. straight to
% subject editor). Set anatomy and tesselation searches to the
% correct paths (find_brainstorm_files).
% JCM 15-May-2004 Added changes from Pantazis for tesselation management
% DP 17-May-2004 More mods from Pantazis for "dfs" file types, other
% tesselation problems.
% DP 18-May-2004 Minor changes for better visualization of surfaces and remove error messages
% Also fix downsize button to give proper name to the generated files
% DP 08-Oct-2004 Supress warning for matlab 6.5 (since tess_align_tool.fig was created in matlab 7)
%------------------------------------------------------------------------------------------------
VERBOSE = 1; % for tri2brainstorm import routine
% old fashioned R11 case switchyard, instead of newer R12.1 feval
% switchyard
% reacquire the figure handle, or open a new one
fig = findobj(0,'tag','subjecteditor');
if(isempty(fig)),
% doesn't exist
fig = openfig(mfilename,'new'); % opens as invisible
bst_color_scheme(fig);
setappdata(fig,'TileType','T')
bst_layout('align',fig,2,1,2)
set(fig,'visible','on'); % .fig saved as invisible until ready
setappdata(fig,'CreateFlag',1); % Set a flag stating that window was just created
end
fig = fig(1); % only the first occurence
handles = guihandles(fig); % reacquire all handles
% get some common data
Users = get_user_directory;
if(nargout),
varargout{1} = fig; % send back the handles
varargout{2} = handles;
end
% now switch
switch(action)
%-----------------------------------------------------------------------
case 'create'
drawnow % takes a long time to do the rest, let user see the figure
makeuswait('start')
DataDir = find_brainstorm_files('Subjects',Users.SUBJECTS,'');
% store the results in Application Data
setappdata(fig,'DataDir',DataDir);
% prepare the display strings
if isempty(DataDir)
cStr = {'No Subject files available in current path'};
else
% strip the suffix off for display purposes
cStr = strrep(DataDir,'_brainstormsubject.mat','');
end
set(handles.listboxx,'String',cStr); % load the listbox
set(handles.DOM,'string',date); % show today's date
% Now get selected study from DataManager window and display information from corresponding subject
GUIs = bst_win_manager;
switch getappdata(fig,'CreateFlag') % Was subject_editor GUI freshly created
case 1 % Yes - go and see which study was selected in DataManager
if ~isempty(GUIs.DataManager), % data manager exists
DMhandles = guihandles(GUIs.DataManager); % Handles from DataManager GUI
iStudy = get(DMhandles.listbox_Study,'Value'); % Current study
else
iStudy = 1; % just set to default
end
% Load subject info from selected study
Studies = getpref('BrainStorm','Studies',[]);
if(~isempty(Studies)),
load(fullfile(Users.STUDIES,Studies(iStudy).StudyFile),'BrainStormSubject')
BrainStormSubject = strrep(BrainStormSubject,'_brainstormsubject.mat','');
% Find subject in list
iSubject = find(strcmp(cStr,BrainStormSubject));
else
iSubject = 1; % Studies are empty, just set iSubject to the first
end
if isempty(iSubject)
% We have studies, but could not find this subject.
% Subject was not found for this study
% ask user to update his/her database
errordlg(...
sprintf('SubjectFile ''%s'' from StudyFile ''%s'' was not found in ''%s''',...
BrainStormSubject,Studies(iStudy).StudyFile,Users.SUBJECTS),...
'DataBase needs updating');
bst_message_window('wrap',{...
sprintf('SubjectFile ''%s'' from StudyFile ''%s'' was not found in ''%s''',...
BrainStormSubject,Studies(iStudy).StudyFile,Users.SUBJECTS),...
' ',...
'Please update or remove problematic files in/from DataBase before going on with BrainStorm'...
})
iSubject = 1; % don't close this figure, just set it to the first
end
set(handles.listboxx,'Value',iSubject);
setappdata(fig,'CreateFlag',0) % That's it - GUI is created and initialized.
case 0 % No - leave subject selection alone
% Leave things alone
end
feval(mfilename,'listboxx'); % Reload current subject information
makeuswait('stop')
%-----------------------------------------------------------------------
case 'listboxx'
% Get the current pointer of the subject listbox and display data available
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
% JCM, my preferred style is to load into structure for easier tracking
Subject = load(DataDir{Val}); % load the brainstormsubject
set(handles.Name,'String',Subject.Name)
% the following fields may not be defined, so test accordingly
if ~isfield(Subject,'DateOfAcquisition')
Subject.DateOfAcquisition = '';
end
set(handles.DOA,'String',Subject.DateOfAcquisition)
if ~isfield(Subject,'DateOfModification') | isempty(Subject.DateOfModification)
Subject.DateOfModification = date;
end
set(handles.DOM,'String',Subject.DateOfModification)
if ~isfield(Subject,'Comments')
Subject.Comments = '';
end
set(handles.Comments,'String',Subject.Comments)
AnatFiles = find_brainstorm_files('anatomy',fullfile(Users.SUBJECTS,SubjectPath));
if isempty(AnatFiles)
AnatFiles = 'N/A';
set(handles.Anatomy,'Enable','off')
nfiles = 0;
else
set(handles.Anatomy,'Enable','on')
nfiles = length(AnatFiles);
end
set(handles.Anatomy,'String',AnatFiles,'Value',1,'Max',nfiles);
set(handles.B_Anatomy,'String',sprintf('%d Anatomy - MRI file(s)',nfiles))
TessFiles = find_brainstorm_files('tess',fullfile(Users.SUBJECTS,SubjectPath));
if isempty(TessFiles)
TessFiles = {'N/A'};
set(handles.Tesselation,'Enable','off')
nfiles = 0;
else
set(handles.Tesselation,'Enable','on')
nfiles = length(TessFiles);
end
set(handles.Tesselation,'String',TessFiles,'Value',1,'Max',nfiles)
set(handles.B_Tessellation,'String',sprintf('%d Tessellation file(s)',nfiles'))
% Store tessellation files
setappdata(fig,'TessellationFiles',TessFiles);
% Display info about first tessellation in list
subject_editor TessellationFileInfo
%-----------------------------------------------------------------------
case 'TessellationFileInfo' % Display information about selected tessellation file
set(fig,'pointer','watch')
drawnow
set(handles.e_comment,'Value',1)
TessFiles = getappdata(fig,'TessellationFiles');
iFile = get(handles.Tesselation,'Value'); % Which file is selected
if strcmpi(TessFiles{iFile},'N/A') % No file available, return
set(fig,'pointer','arrow')
return
end
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
set(fig,'pointer','arrow')
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
load(TessFiles{iFile},'Comment','Faces','Vertices')
if isempty(Comment)
% empty tessellation file - delete
ButtonName=questdlg('This file is apparently empty - would you like to remove it from disk?', ...
'DataBase Cleaning', ...
'Yes','No','No');
switch(ButtonName)
case 'No'
set(fig,'pointer','arrow')
return
case 'Yes'
switch(upper(computer))
case('PCWIN')
dos(sprintf('del %s', TessFiles{iFile}));
case ('UNIX')
unix(sprintf('rm %s %s', TessFiles{iFile}));
end
subject_editor listboxx
end
else
set(handles.e_comment,'string',Comment)
for k = 1:length(Faces);
nFaces(k) = size(Faces{k},1);
end
clear Faces
for k = 1:length(Vertices);
nVertices(k) = size(Vertices{k},2);
end
clear Vertices
setappdata(fig,'Comment',Comment)
setappdata(fig,'nFaces',nFaces)
setappdata(fig,'nVertices',nVertices)
subject_editor CurrentEnvelopeInfo
set(handles.t_envelopes,'String',sprintf('%d Envelope(s)',length(Comment)));
set(handles.e_comment,'Max',length(Comment))
end
set(fig,'pointer','arrow')
%-----------------------------------------------------------------------
case 'CurrentEnvelopeInfo' % Display info related to selected envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
% if length(iCurrent) > 1
% set(handles.e_comment,'Value', min(iCurrent));
% subject_editor CurrentEnvelopeInfo
% return
% end
nFaces = getappdata(fig,'nFaces');
nVertices = getappdata(fig,'nVertices');
try
if length(nFaces) == length(nVertices) % several envelopes of different tissues are stored (pre-MMII convention)
set(handles.t_faces_vertices,'String',sprintf('%d Faces - %d Vertices',nFaces(iCurrent),nVertices(iCurrent)))
else % Variations of the same envelope: number of faces and vertices is the same for all variations
set(handles.t_faces_vertices,'String',sprintf('%d Faces - %d Vertices',nFaces(1),nVertices(1)))
end
catch
set(handles.e_comment,'Value', min(iCurrent));
subject_editor CurrentEnvelopeInfo
return
end
%-----------------------------------------------------------------------
case 'ConcatenateEnvelope' % Concatenate selected envelopes in a single tessellation
makeuswait('start')
TessFiles = getappdata(fig,'TessellationFiles');
% Tessellation file
iFile = get(handles.Tesselation,'Value'); % Which file is selected
% Envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
if length(iCurrent) == 1 % Concatenate tessellation from 2 different files
% Open specific GUI for file selection
TriList = openfig('generic_listbox_win.fig');
setappdata(TriList,'TileType','T')
bst_color_scheme(TriList)
bst_layout('align',TriList,2,2,1)
set(TriList,'Visible','on')
TriHandles = guihandles(TriList);
set(TriHandles.listbox,'String',TessFiles,'ListboxTop',2,'Max',2)
set(TriList,'Name','Select tessellation files to concatenate')
set(TriHandles.DONE,'Callback','subject_editor ConcatenateEnvelope_Done')
return
elseif length(iCurrent) ~= 2
errordlg('Please select 2 envelopes only from list.')
return
end
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
oldTess = load(TessFiles{iFile});
% As per MMII convention - there should be one tessellation file per envelope
% A downsized version of e.g. a cortex is considered as a different envelope
% ans is therefore saved in a separate tessellation file than the original.
Vertices{1} = [oldTess.Vertices{iCurrent(1)},oldTess.Vertices{iCurrent(2)}] ;
Faces{1} = [oldTess.Faces{iCurrent(1)}; oldTess.Faces{iCurrent(2)}+size(oldTess.Vertices{iCurrent(1)},2)];
Comment{1} = [oldTess.Comment{iCurrent(1)},oldTess.Comment{iCurrent(2)}] ;
clear oldTess
newTessFile = strrep(TessFiles{iFile},'tess',[Comment{1},'_tess']);
save(newTessFile,'Faces','Comment','Vertices')
subject_editor listboxx
bst_message_window({...
' ',...
'Wrote new envelope in',...
newTessFile,...
' '})
makeuswait('stop')
%-----------------------------------------------------------------------
case 'ConcatenateEnvelope_Done' % Two files were selected - concatenate their envelopes
set(fig,'pointer','watch'), drawnow
% Assume there is only one envelope per file
TriList = openfig('generic_listbox_win.fig','reuse');
TriHandles = guihandles(TriList);
iCurrent = get(TriHandles.listbox,'Value'); % Selected tess files
if length(iCurrent) ~= 2
errordlg('Please select 2 envelopes only from list.')
return
end
delete(TriList);
TessFiles = getappdata(fig,'TessellationFiles');
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
for k = 1:length(iCurrent)
oldTess{k} = load(TessFiles{iCurrent(k)});
end
% As per MMII convention - there should be one tessellation file per envelope
% A downsized version of e.g. a cortex is considered as a different envelope
% ans is therefore saved in a separate tessellation file than the original.
Vertices{1} = [oldTess{1}.Vertices{1},oldTess{2}.Vertices{1}] ;
Faces{1} = [oldTess{1}.Faces{1}; oldTess{2}.Faces{1}+size(oldTess{1}.Vertices{1},2)];
Comment{1} = [oldTess{1}.Comment{1},oldTess{2}.Comment{1}] ;
clear oldTess
newTessFile = [Comment{1},'_tess.mat'];
save(newTessFile,'Faces','Comment','Vertices')
subject_editor listboxx
bst_message_window({...
' ',...
'Wrote new envelope in',...
newTessFile,...
' '})
set(fig,'pointer','arrow'), drawnow
%-----------------------------------------------------------------------
case 'RenameEnvelope' % Change the comment entry to selected envelope
TessFiles = getappdata(fig,'TessellationFiles');
% Tessellation file
iFile = get(handles.Tesselation,'Value'); % Which file is selected
% Envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
if length(iCurrent) > 1
set(handles.e_comment,'Value', min(iCurrent));
subject_editor RenameEnvelope
return
end
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
load(TessFiles{iFile},'Comment')
newComment = inputdlg('Enter a new name for selected envelope','Edit tessellation file',1,{Comment{iCurrent}});
if isempty(newComment), return, end
Comment{iCurrent} = char(newComment);
save(TessFiles{iFile},'Comment','-append')
set(handles.e_comment,'string',Comment)
setappdata(fig,'Comment',Comment)
%-----------------------------------------------------------------------
case 'SwapFaces' % Swap vertex ordering for face definition as some pacthes normal may happen to be oriented inwards and therefore look dark in 3d
set(fig,'pointer','watch')
TessFiles = getappdata(fig,'TessellationFiles');
% Tessellation file
iFile = get(handles.Tesselation,'Value'); % Which file is selected
% Envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
if length(iCurrent) > 1
set(handles.e_comment,'Value', min(iCurrent));
subject_editor RenameEnvelope
return
end
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
load(TessFiles{iFile},'Faces')
Faces{iCurrent} = Faces{iCurrent}(:,[2 1 3]);
save(TessFiles{iFile},'Faces','-append')
set(fig,'pointer','arrow')
%-----------------------------------------------------------------------
case 'DeleteEnvelope' % Delete selected envelope
TessFiles = getappdata(fig,'TessellationFiles');
% Tessellation file
iFile = get(handles.Tesselation,'Value'); % Which file is selected
% Envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
ButtonName=questdlg('Are you sure you want to delete permanently the selected envelope(s) ?', ...
'Warning', ...
'Yes','No','No');
switch(ButtonName)
case 'No'
return
case 'Yes'
set(fig,'pointer','watch'), drawnow
load(TessFiles{iFile},'Comment','Vertices','Faces')
iValidSet = setdiff(1:length(Comment),iCurrent); % Set of remaining envelopes
if length(Faces) == length(Comment)
Faces = Faces(iValidSet);
end
Comment = Comment(iValidSet);
Vertices = Vertices(iValidSet);
save(TessFiles{iFile},'Comment','Vertices','Faces')
set(handles.e_comment,'string',Comment)
end
% Update display
if length(Comment) < 1 % Empty tessellation file
subject_editor listboxx
return
end
for k = 1:length(Faces);
nFaces(k) = size(Faces{k},1);
end
clear Faces
for k = 1:length(Vertices);
nVertices(k) = size(Vertices{k},2);
end
clear Vertices
setappdata(fig,'Comment',Comment)
setappdata(fig,'nFaces',nFaces)
setappdata(fig,'nVertices',nVertices)
subject_editor CurrentEnvelopeInfo
set(handles.t_envelopes,'String',sprintf('%d Envelope(s)',length(Comment)));
set(fig,'pointer','arrow')
%-----------------------------------------------------------------------
case 'ViewEnvelope' % View of selected envelope
TessFiles = getappdata(fig,'TessellationFiles');
% Tessellation file
iFile = get(handles.Tesselation,'Value'); % Which file is selected
% Envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
if length(iCurrent) > 1
set(handles.e_comment,'Value', min(iCurrent));
subject_editor DownsizeEnvelope
return
end
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
load(TessFiles{iFile});
Faces = Faces{iCurrent};
Vertices = Vertices{iCurrent};
Comment = Comment{iCurrent};
hf = figure('visible','off');
bst_color_scheme(hf);
setappdata(hf,'TileType','T')
set(hf,'menubar','figure','toolbar','figure');
bst_layout('align',hf,1,1,1);
set(hf,'visible','on');
set(hf,'name','Tessellation Viewer');
light
% h = light('visible','off');
% set(h,'position',[0 -1 0],'visible','on');
lighting gouraud
axis equal
axis off
axis vis3d
FV.vertices = Vertices';
FV.faces = Faces;
nVertices = size(FV.vertices,1);
figure(hf);
hpatch = patch(FV,'FaceColor','interp','EdgeColor','none','FaceVertexCData',ones(nVertices,3)*0.9,'faceAlpha',1); %plot surface
lighting gouraud
%-----------------------------------------------------------------------
case 'DownsizeEnvelope' % Create a new version of selected envelope with a reduced number of faces and vertices
TessFiles = getappdata(fig,'TessellationFiles');
% Tessellation file
iFile = get(handles.Tesselation,'Value'); % Which file is selected
% Envelope in tessellation file
iCurrent = get(handles.e_comment,'Value'); % what's the current envelope ?
if length(iCurrent) > 1
set(handles.e_comment,'Value', min(iCurrent));
subject_editor DownsizeEnvelope
return
end
% Go into proper folder
cd(Users.SUBJECTS)
DataDir = getappdata(fig,'DataDir'); % get the list of subject files
if(isempty(DataDir)), % there are no files, listbox displays "No files"
Val = 0; % listbox is pointing at "No files"
return % there is nothing to process
else
Val = get(handles.listboxx,'Value'); % which file are we pointed at?
end
SubjectPath = fileparts(DataDir{Val}); % extract the referential path
if ~isempty(SubjectPath)
cd(SubjectPath)
end
load(TessFiles{iFile});
newVertices = ...
inputdlg('New number of vertices for selected envelope',...
'Tessellation downsizing',...
1,{num2str(size(Vertices{iCurrent},2))});
if isempty(newVertices), return, end
nfv.faces = double(Faces{iCurrent});
nfv.vertices = double(Vertices{iCurrent}');
dsFactor = str2num(newVertices{1})/size(Vertices{iCurrent},2); % Downsize factor
clear Faces Vertices
makeuswait('start')
NFV = reducepatch(nfv, dsFactor);
clear nfv
% As per MMII convention - there should be one tessellation file per envelope
% A downsized version of e.g. a cortex is considered as a different envelope
% ans is therefore saved in a separate tessellation file than the original.
Faces{1} = NFV.faces;
Vertices{1} = NFV.vertices';
clear NFV
OldComment = Comment;
clear Comment
Comment{1} = [OldComment{iCurrent},'_',num2str(newVertices{1}),'V'];%num2str(dsFactor)];
newTessFile = strrep(TessFiles{iFile},'tess',[num2str(newVertices{1}) 'V_tess']);
save(newTessFile,'Faces','Comment','Vertices')
subject_editor listboxx
bst_message_window({...
' ',...
'Wrote new envelope in',...
newTessFile,...
' '})
makeuswait('stop')
%-----------------------------------------------------------------------
case 'save'
DataDir = getappdata(fig,'DataDir');
if(isempty(DataDir)),
% there is no subject, call as a "save as"
feval(mfilename,'saveas'); % no filename
else
% use the existing filename to save
ifile = get(handles.listboxx,'value'); % what is selected in the listbox?
file = DataDir{ifile}; % referential filename
feval(mfilename,'saveas',file) % save with this name
end
%-----------------------------------------------------------------------
case 'saveas'
% called with optional argument of referential filename
cd(Users.SUBJECTS)
Name = get(handles.Name,'String');
DateOfAcquisition = get(handles.DOA,'String');
DateOfModification = date;
set(handles.DOM,'String', date);
Comments = get(handles.Comments,'String');
Anatomy = get(handles.Anatomy,'String');
try
Anatomy = fullfile(fileparts(varargin{1}),Anatomy{get(handles.Anatomy,'Value')}); % referential name
catch
Anatomy = '';
end
Tesselation = get(handles.Tesselation,'Userdata');
if isempty(Tesselation)
Tesselation = '';
end
if nargin == 1 % No handles.Name was specified
DefaultLeader = strrep(Name,' ',''); % Default prefix to Subject filename.
if ~isempty(DefaultLeader)
DefaultLeader = [DefaultLeader,'_brainstormsubject.mat'];
else
DefaultLeader = ['brainstormsubject.mat'];
end
[file,path] = uiputfile(DefaultLeader, 'Save Subject Information');
if file == 0,
return,
end
if isempty(findstr(lower(file),'brainstormsubject.mat'));
file = [file,'_brainstormsubject.mat']; % Add the BST suffix if not entered by user
end
% file is name only, but path is absolute
else
file = varargin{1}; % referential name
path = Users.SUBJECTS;
ifile = get(handles.listboxx,'Value'); % What's the value of the subject file lisbox for future display
end
save(fullfile(path,file),'Name','DateOfAcquisition','DateOfModification','Comments',...
'Anatomy','Tesselation')
bst_message_window('wrap',{sprintf('Saved to %s',path),file}); % filename on second line
% now reinitialize the GUI to seek out the new subject file and load the gui
feval(mfilename,'create');
if nargin > 1
set(handles.listboxx,'Value',ifile)
end
%-----------------------------------------------------------------------
case 'ImportAnatomy'
bst_mriviewer;
%-----------------------------------------------------------------------
case 'ImportTessellation'
% Move to current subject's folder
DataDir = getappdata(fig,'DataDir'); % referential filenames
if(isempty(DataDir)),
% no current subject
bst_message_window('append','No valid subject file selected');
return
else
CurrentSubjectFile = DataDir{get(handles.listboxx,'Value')};
end
% strip the folder name, add to the filename
CurrentSubjectFolder = fileparts(fullfile(Users.SUBJECTS,CurrentSubjectFile));
%Open window to ask for tesselation files
filetype{1} = '.tri';
filetype{2} = '.dsgl';
filetype{3} = '.dfs';
filetype{4} = '.mesh';
[Files Filenames] = file_selection_win(filetype,CurrentSubjectFolder);
if(isempty(Files{1})) %if no files are loaded
return
end
%separate Tri from Dsgl and Dfs files
TriFiles = {};
DsglFiles = {};
DfsFiles = {};
ndxTri = 1;
ndxMesh = 1;
ndxDsgl = 1;
ndxDfs = 1;
for k = 1:size(Files,2)
if strcmp(Files{k}(end-3:end),'.tri')
TriFiles{ndxTri} = Files{k};
ndxTri = ndxTri + 1;
end
if strcmp(Files{k}(end-4:end),'.mesh')
TriFiles{ndxMesh} = Files{k};
ndxMesh = ndxMesh + 1;
end
if strcmp(Files{k}(end-4:end),'.dsgl')
DsglFiles{ndxDsgl} = Files{k};
ndxDsgl = ndxDsgl + 1;
end
if strcmp(Files{k}(end-3:end),'.dfs')
DfsFiles{ndxDfs} = Files{k};
ndxDfs = ndxDfs + 1 ;
end
end
ndxTri = ndxTri - 1;
ndxMesh = ndxMesh - 1;
ndxDsgl = ndxDsgl - 1;
ndxDfs = ndxDfs - 1;
if(ndxTri>0) %if any tri files
[oVertices, oFaces, oComment] = tri2brainstorm(TriFiles,VERBOSE);
elseif(ndxMesh>0) %if any MESH files
for k=1:length(ndxMesh)
[oVertices{k},oFaces{k},normal,vertex_number,faces_number] = mesh2brainstorm(TriFiles{k});
oVertices{k} = oVertices{k}';
oFaces{k} = oFaces{k}+1;
oComment{k} = TriFiles{k};
end
end
%The following code may be used in the future, to automatically align dsgl files
% %we need to check if PCS is present in the subjectimage file:
% %get subject file, to get a link to anatomy file
% % Move to current subject's folder
% CurrentSubjectFile = DataDir{get(handles.listboxx,'Value')};
% SubjectFile = fullfile(Users.SUBJECTS,CurrentSubjectFile);
% warning off %we don't want to scare the user if no anatomy is present
% load(CurrentSubjectFile,'Anatomy');
% warning on
% if(~exist('Anatomy'))
% bst_message_window({' ','-------------------------------------------------',...
% 'Import an anatomy file and define a Patient Coordinate System before importing Dsgl files...'});
% return
% end
% SubjectImageFile = fullfile(Users.SUBJECTS,Anatomy);
%
% %check whether PCS from Anatomy file is defined
% %we need this to align dsgl with mri and channels
% warning off %we don't want to scare the user if no PCS is present
% load(SubjectImageFile,'PCS')
% warning on
% if(~exist('PCS') | ~isfield(PCS,'PERM'))
% bst_message_window({' ','-------------------------------------------------',...
% 'Define a Patient Coordinate System using the MRI Tool before importing Dsgl files...'});
% return
% end
% %now we can use bsuite2PCS function
%load dsgl files
for k = 1:size(DsglFiles,2)
FV = readdsgl(DsglFiles{k});
%now in cube coords, make it engineering dimensions, in meters
FV.vertices(:,1) = FV.vertices(:,1)*(FV.res(1)/1000); %this should not be used with bsuite2PCS
FV.vertices(:,2) = FV.vertices(:,2)*(FV.res(2)/1000); %this should not be used with bsuite2PCS
FV.vertices(:,3) = FV.vertices(:,3)*(FV.res(3)/1000); %this should not be used with bsuite2PCS
FV_PCS = FV; %temp code
clear FV;
% FV_PCS = bsuite2PCS(FV,SubjectImageFile);
oVertices{k+ndxTri} = FV_PCS.vertices'; %append info
oFaces{k+ndxTri} = FV_PCS.faces;
[ignore,fileComment] = fileparts(DsglFiles{k});
oComment{k+ndxTri} = fileComment;
end
%load dfs files
for k = 1:size(DfsFiles,2)
FV = readdfs(DfsFiles{k});
FV.vertices = FV.vertices / 1000; %make mm into m
oVertices{k+ndxTri+ndxDsgl} = FV.vertices'; %append info
oFaces{k+ndxTri+ndxDsgl} = FV.faces;
[ignore,fileComment] = fileparts(DfsFiles{k});
oComment{k+ndxTri+ndxDsgl} = fileComment;
end
% BST.MMII innovation:
% Now save each in a separate tess file
%TessFileLeader = strrep(TriFiles{1},Leader,'');
%TessFileLeader = strrep(TessFileLeader,'.tri',''); % Common leader for every new tessellation file
bst_message_window({' ','-------------------------------------------------',...
'Saving envelopes in separate files...'});
drawnow
for k = 1: length(TriFiles)
% Get corresponding surface specs
Faces{1} = oFaces{k};
Vertices{1} = oVertices{k};
Comment{1} = oComment{k};
% Generate file name
[PATHSTR,NAME,EXT,VERSN] = fileparts(Files{k});
TessFile{k} = strrep(Files{k},EXT,'_tess.mat');
save(TessFile{k},'Comment','Faces','Vertices','-mat');
bst_message_window('wrap',{...
['Saving envelope ''',Comment{1},''' in '],...
TessFile{k},...
});
end
for k = ndxTri+1: ndxTri+ size(DsglFiles,2)
% Get corresponding surface specs
Faces{1} = oFaces{k};
Vertices{1} = oVertices{k};
Comment{1} = oComment{k};
% Generate file name
TessFile{k}= strrep(Files{k},'.dsgl','_tess.mat');
save(TessFile{k},'Comment','Faces','Vertices','-mat');
bst_message_window('wrap',{...
['Saving envelope ''',Comment{1},''' in '],...
TessFile{k},...
});
end
for k = ndxTri+ndxDsgl+1: ndxTri+ndxDsgl + size(DfsFiles,2)
% Get corresponding surface specs
Faces{1} = oFaces{k};
Vertices{1} = oVertices{k};
Comment{1} = oComment{k};
% Generate file name
TessFile{k}= strrep(Files{k},'.dfs','_tess.mat');
save(TessFile{k},'Comment','Faces','Vertices','-mat');
bst_message_window('wrap',{...
['Saving envelope ''',Comment{1},''' in '],...
TessFile{k},...
});
end
bst_message_window({'Saving envelopes in separate files -----> DONE',...
'-------------------------------------------------',' '});
DataDir = getappdata(fig,'DataDir');
if(isempty(DataDir)),
bst_message_window('No valid subject name')
return
end
CurrentSubjectFile = DataDir{get(handles.listboxx,'Value')};
% extract the referential folder name
CurrentSubjectFolder = fileparts(CurrentSubjectFile);
%set(handles.Tesselation,'string',TessFile,'Value',1,'Userdata',fullfile(CurrentSubjectFolder,TessFile))
set(handles.Tesselation,'string',TessFile,'Value',1,'Userdata',TessFile)
subject_editor('listboxx');
%-----------------------------------------------------------------------
case 'quit'
close gcbf
%-----------------------------------------------------------------------
case 'anatomy'
cd(Users.SUBJECTS)
[file,path] = uigetfile(['*subjectimage.mat'], 'Select a BrainStorm ''subjectimage'' file');
if file == 0, return, end
if isempty(findstr(lower(Users.SUBJECTS),lower(path))) % Check if the subjectimage file is in Users.SUBJECTS for correct relative indexing
errordlg(sprintf('Please place %s in %s first',file,Users.SUBJECTS))
return
end
if findstr(lower(fullfile(path,file)),lower(Users.SUBJECTS)) ~=1 % Automount issus on some Linux systems - remove the automount prefix
fname = fullfile(path,file);
istrip = findstr(lower(fullfile(path,file)),lower(Users.SUBJECTS));
fname = fname(istrip:end);
else
fname = fullfile(path,file);
end
fname = strrep(fname,(Users.SUBJECTS),''); % strip the user location
set(handles.Anatomy,'String',file,'Userdata',fname)
cd(path)
set(findobj(gcbf,'Tag','fit'),'Enable','on')
%-----------------------------------------------------------------------
case 'tesselation'
[file,path] = uigetfile(['*tess*.mat'], 'Select a handles.Tesselation file');
if file == 0, return, end
if findstr(lower(fullfile(path,file)),lower(Users.SUBJECTS)) ~=1 % Automount issues on some Linux systems
% Remove the automount prefix
fname = fullfile(path,file);
istrip = findstr(lower(fullfile(path,file)),lower(Users.SUBJECTS));
fname = fname(istrip:end);
else
fname = fullfile(path,file);
end
fname = strrep(fname,Users.SUBJECTS,''); % strip the user location
set(handles.Tesselation,'String',file)
set(handles.Tesselation,'Enable','on')
nfiles = 1;
set(handles.Tesselation,'String',fname,'Value',1,'Max',nfiles)
set(handles.B_Tessellation,'String',sprintf('%d Tessellation file(s)',nfiles'))
cd(path)
%-----------------------------------------------------------------------
case 'TriConn'
[file,path] = uigetfile(['*.mat'], 'Triangle Connectivity file');
if file == 0, return, end
if isempty(strmatch((Users.SUBJECTS),(path))) % Check if the handles.Tesselation file is in Users.SUBJECTS for correct relative indexing
errordlg(sprintf('Please place %s in %s first',file,Users.SUBJECTS))
return
end
fname = strrep((fullfile(path,file)),(Users.SUBJECTS),''); % strip the user location
set(handles.TriConn,'String',file,'Userdata',fname)
cd(path)
%-----------------------------------------------------------------------
case 'VertConn'
[file,path] = uigetfile(['*.mat'], 'Vertex Connectivity file');
if file == 0, return, end
if isempty(strmatch((Users.SUBJECTS),(path))) % Check if the handles.Tesselation file is in Users.SUBJECTS for correct relative indexing
errordlg(sprintf('Please place %s in %s first',file,Users.SUBJECTS))
return
end
fname = strrep((fullfile(path,file)),(Users.SUBJECTS),''); % strip the user location
set(handles.VertConn,'String',file,'Userdata',fname)
cd(path)
%-----------------------------------------------------------------------
case 'fit' % Scale the MRI to the true fiducials
fidufit
load(get(handles.Anatomy,'Userdata'),'PCS');
if ~exist('PCS','var')
errordlg('Please use the original dummy MRI scan')
return
end
PCS.PCSFiducial(abs(PCS.PCSFiducial) < 1e-4) = 0;
set(findobj(gcf,'Tag','old1'),'String',(num2str(PCS.PCSFiducial(:,1)','%3.1f %3.1f %3.1f')));
set(findobj(gcf,'Tag','old2'),'String',(num2str(PCS.PCSFiducial(:,2)','%3.1f %3.1f %3.1f')));
set(findobj(gcf,'Tag','old3'),'String',(num2str(PCS.PCSFiducial(:,3)','%3.1f %3.1f %3.1f')));
%-----------------------------------------------------------------------
case 'fitdone' % Scale the MRI to the true fiducials
%-----------------------------------------------------------------------
new1 = str2num(get(findobj(gcbf,'Tag','new1'),'String'));
new2 = str2num(get(findobj(gcbf,'Tag','new2'),'String'));
new3 = str2num(get(findobj(gcbf,'Tag','new3'),'String'));
load(get(handles.Anatomy,'Userdata'),'PCS');
tmp = mean(abs([new2;new3]));
newfid = [new1',tmp',[0 0 1]'];
tmp = mean(abs(PCS.PCSFiducial(:,2:3)'));
scale_fiducials = newfid*inv([PCS.PCSFiducial(:,1),tmp',[0 0 1]']);
PCS.PCSFiducial = [new1',new2',new3',[0 0 0]'];
save(get(handles.Anatomy,'Userdata'),'PCS','scale_fiducials','-append')
bst_message_window(' ')
bst_message_window('Fiducials points have been properly updated')
bst_message_window(' ')
close(gcbf)
%-----------------------------------------------------------------------
case 'AlignTessellation'
%-----------------------------------------------------------------------
% Align the tesselation to the Subject Coordinate System
%get current subject directory
DataDir = getappdata(fig,'DataDir'); % referential filenames
if(isempty(DataDir)),
% no current subject
bst_message_window('append','No valid subject file selected');
return
else
CurrentSubjectFile = DataDir{get(handles.listboxx,'Value')};
end
% strip the folder name, add to the filename
CurrentSubjectFolder = fileparts(fullfile(Users.SUBJECTS,CurrentSubjectFile));
%launch tesselation alignment tool
warning off; %supress warning for matlab 6.5 (window created on matlab 7)
tess_align_tool('dummy',CurrentSubjectFolder);
warning on;
%-----------------------------------------------------------------------
end % case switches
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