function varargout = rest_DicomSorter_gui(varargin) % varargout = rest_DicomSorter_gui(varargin) % Sort the DICOM files. % By YAN Chao-Gan and Dong Zhang-Ye 091212. % State Key Laboratory of Cognitive Neuroscience and Learning, Beijing Normal University, China, 100875 % http://www.restfmri.net % Mail to Authors: YAN Chao-Gan; DONG Zhang-Ye % Version=1.0; % Release=20091215; %------------------------------------------------------------------------------------------------------------------------------ gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @rest_DicomSorter_gui_OpeningFcn, ... 'gui_OutputFcn', @rest_DicomSorter_gui_OutputFcn, ... 'gui_LayoutFcn', [], ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before rest_DicomSorter_gui is made visible. function rest_DicomSorter_gui_OpeningFcn(hObject, eventdata, handles, varargin) InitControlProperties(hObject, handles); handles.output = hObject; handles.Cfg.DataDirs ={}; %{[pathstr '\SampleData'], 10} ; handles.Cfg.OutputDir =pwd; handles.Cfg.Anonymize=0; handles.Cfg.DirectoryHierarchy=0; set(handles.edtOutDir ,'String', handles.Cfg.OutputDir); % Make Display correct in linux - YAN Chao-Gan 111025 Added. if ~ispc ZoomFactor=0.85; ObjectNames = fieldnames(handles); for i=1:length(ObjectNames); eval(['IsFontSizeProp=isprop(handles.',ObjectNames{i},',''FontSize'');']); if IsFontSizeProp eval(['PCFontSize=get(handles.',ObjectNames{i},',''FontSize'');']); FontSize=PCFontSize*ZoomFactor; eval(['set(handles.',ObjectNames{i},',''FontSize'',',num2str(FontSize),');']); end end end guidata(hObject, handles); UpdateDisplay(handles); movegui(handles.rest_DicomSorter_gui, 'center'); guidata(hObject, handles); % --- Outputs from this function are returned to the command line. function varargout = rest_DicomSorter_gui_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on selection change in listDataDirs. function listDataDirs_Callback(hObject, eventdata, handles) % hObject handle to listDataDirs (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: contents = get(hObject,'String') returns listDataDirs contents as cell array % contents{get(hObject,'Value')} returns selected item from listDataDirs % --- Executes during object creation, after setting all properties. function listDataDirs_CreateFcn(hObject, eventdata, handles) % hObject handle to listDataDirs (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: listbox controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function edtDataDirectory_Callback(hObject, eventdata, handles) % hObject handle to edtDataDirectory (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edtDataDirectory as text % str2double(get(hObject,'String')) returns contents of edtDataDirectory as a double % --- Executes during object creation, after setting all properties. function edtDataDirectory_CreateFcn(hObject, eventdata, handles) % hObject handle to edtDataDirectory (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on button press in btnSelectDataDir. function btnSelectDataDir_Callback(hObject, eventdata, handles) if size(handles.Cfg.DataDirs, 1)>0 theDir =handles.Cfg.DataDirs{1,1}; else theDir =pwd; end theDir =uigetdir(theDir, 'Please select the data directory to convert: '); if ischar(theDir), SetDataDir(hObject, theDir,handles); end function edtOutDir_Callback(hObject, eventdata, handles) % hObject handle to edtOutDir (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edtOutDir as text % str2double(get(hObject,'String')) returns contents of edtOutDir as a double % --- Executes during object creation, after setting all properties. function edtOutDir_CreateFcn(hObject, eventdata, handles) % hObject handle to edtOutDir (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on button press in btnOutDir. function btnOutDir_Callback(hObject, eventdata, handles) theDir =handles.Cfg.OutputDir; theDir =uigetdir(theDir, 'Please select the output directory: '); if ~isequal(theDir, 0) SetOutputDir(hObject,handles, theDir); end function SetOutputDir(hObject, handles, ADir) if 7==exist(ADir,'dir') handles.Cfg.OutputDir =ADir; set(handles.edtOutDir,'String',ADir); guidata(hObject, handles); UpdateDisplay(handles); end function btnRun_Callback(hObject, eventdata, handles) set(handles.btnOutDir,'Enable','off'); set(handles.btnRun,'Enable','off'); set(handles.btnSelectDataDir,'Enable','off'); drawnow; dicomtype=get(handles.edtDicomType,'String'); mkdir([handles.Cfg.OutputDir]); Anonymizeflag=get(handles.checkboxAnonymize,'Value'); for i=1:size(handles.Cfg.DataDirs, 1) outfile=[handles.Cfg.OutputDir]; dirlist={}; dirlist=[rest_DicomSorter(handles.Cfg.DataDirs{i},outfile,dicomtype,handles.Cfg.DirectoryHierarchy);dirlist]; if Anonymizeflag outdirA=[outfile,'_','Anonymized']; if ~isdir(outdirA) mkdir(outdirA); end for j=1:size(dirlist,1) [path,dirnameA]=fileparts(dirlist{j}); [path2,dirnameA2]=fileparts(path); outfileA=[outdirA,filesep,dirnameA2,filesep,dirnameA]; if ~isdir(outfileA) mkdir(outfileA); end rest_ChangeDicomInfo(dirlist{j},outfileA,'',dicomtype); end end end rest_waitbar; fprintf('Done ...\n'); set(handles.btnOutDir,'Enable','on'); set(handles.btnRun,'Enable','on'); set(handles.btnSelectDataDir,'Enable','on'); drawnow; function InitControlProperties(hObject, handles) handles.hContextMenu =uicontextmenu; set(handles.listDataDirs, 'UIContextMenu', handles.hContextMenu); uimenu(handles.hContextMenu, 'Label', 'Add a directory', 'Callback', get(handles.btnSelectDataDir, 'Callback')); uimenu(handles.hContextMenu, 'Label', 'Remove selected directory', 'Callback', 'rest_DicomSorter_gui(''DeleteSelectedDataDir'',gcbo,[], guidata(gcbo))'); uimenu(handles.hContextMenu, 'Label', 'Add recursively all sub-folders of a directory', 'Callback', 'rest_DicomSorter_gui(''RecursiveAddDataDir'',gcbo,[], guidata(gcbo))'); uimenu(handles.hContextMenu, 'Label', '============================='); uimenu(handles.hContextMenu, 'Label', 'Remove all data directories', 'Callback', 'rest_DicomSorter_gui(''ClearDataDirectories'',gcbo,[], guidata(gcbo))'); % Save handles structure guidata(hObject,handles); function SetDataDir(hObject, ADir,handles) if ~ischar(ADir), return; end theOldWarnings =warning('off', 'all'); % if (~isequal(ADir , 0)) &&( (size(handles.Cfg.DataDirs, 1)==0)||(0==seqmatch({ADir} ,handles.Cfg.DataDirs( : , 1) ) ) ) if rest_misc('GetMatlabVersion')>=7.3, ADir =strtrim(ADir); end dicomtype=get(handles.edtDicomType,'String'); if (~isequal(ADir , 0)) &&( (size(handles.Cfg.DataDirs, 1)==0)||(0==length(strmatch(ADir,handles.Cfg.DataDirs( : , 1),'exact' ) ) )) handles.Cfg.DataDirs =[ {ADir , 0}; handles.Cfg.DataDirs];%update the dir theVolumnCount =CheckDataDir(handles.Cfg.DataDirs{1,1},dicomtype); if (theVolumnCount<=0), if isappdata(0, 'FC_DoingRecursiveDir') && getappdata(0, 'FC_DoingRecursiveDir'), else fprintf('There is no data or non-data files in this directory:\n%s\nPlease re-select\n\n', ADir); errordlg( sprintf('There is no data or non-data files in this directory:\n\n%s\n\nPlease re-select', handles.Cfg.DataDirs{1,1} )); end handles.Cfg.DataDirs(1,:)=[]; if size(handles.Cfg.DataDirs, 1)==0 handles.Cfg.DataDirs=[]; end %handles.Cfg.DataDirs = handles.Cfg.DataDirs( 2:end, :);%update the dir else handles.Cfg.DataDirs{1,2} =theVolumnCount; end guidata(hObject, handles); UpdateDisplay(handles); end warning(theOldWarnings); function UpdateDisplay(handles) if size(handles.Cfg.DataDirs,1)>0 theOldIndex =get(handles.listDataDirs, 'Value'); set(handles.listDataDirs, 'String', GetInputDirDisplayList(handles) , 'Value', 1); theCount =size(handles.Cfg.DataDirs,1); if (theOldIndex>0) && (theOldIndex<= theCount) set(handles.listDataDirs, 'Value', theOldIndex); end set(handles.edtDataDirectory,'String', handles.Cfg.DataDirs{1,1}); else set(handles.listDataDirs, 'String', '' , 'Value', 0); end % set(handles.edtVoxelSize,'String',handles.Cfg.VoxelSize); function Result=GetDirName(ADir) if isempty(ADir), Result=ADir; return; end theDir =ADir; if strcmp(theDir(end),filesep)==1 theDir=theDir(1:end-1); end [tmp,Result]=fileparts(theDir); function [nVolumn]=CheckDataDir(ADataDir,dicomtype) theFilenames = dir(ADataDir); nVolumn = 0; if strcmp(dicomtype,'none') for count = 3:size(struct2cell(theFilenames),2) if (length(theFilenames(count).name)>4) &&~theFilenames(count).isdir nVolumn = nVolumn + 1; end end else for count = 3:size(struct2cell(theFilenames),2) if (length(theFilenames(count).name)>4) && ... strcmpi(theFilenames(count).name(end-3:end) , ['.',dicomtype]) nVolumn = nVolumn + 1; end end end function Result=GetInputDirDisplayList(handles) Result ={}; for x=size(handles.Cfg.DataDirs, 1):-1:1 Result =[{sprintf('%d# %s',handles.Cfg.DataDirs{x, 2},handles.Cfg.DataDirs{x, 1})} ;Result]; end function ClearDataDirectories(hObject, eventdata, handles) if prod(size(handles.Cfg.DataDirs))==0 ... || size(handles.Cfg.DataDirs, 1)==0, return; end tmpMsg=sprintf('Attention!\n\n\nDelete all data directories?'); if strcmpi(questdlg(tmpMsg, 'Clear confirmation'), 'Yes'), handles.Cfg.DataDirs(:)=[]; if prod(size(handles.Cfg.DataDirs))==0, handles.Cfg.DataDirs={}; end guidata(hObject, handles); UpdateDisplay(handles); end function RecursiveAddDataDir(hObject, eventdata, handles) if prod(size(handles.Cfg.DataDirs))>0 && size(handles.Cfg.DataDirs, 1)>0, theDir =handles.Cfg.DataDirs{1,1}; else theDir =pwd; end theDir =uigetdir(theDir, 'Please select the parent data directory of many sub-folders containing EPI data to convert: '); if ischar(theDir), %Make the warning dlg off! 20071201 setappdata(0, 'FC_DoingRecursiveDir', 1); theOldColor =get(handles.listDataDirs, 'BackgroundColor'); set(handles.listDataDirs, 'BackgroundColor', [ 0.7373 0.9804 0.4784]); try rest_RecursiveDir(theDir, 'rest_DicomSorter_gui(''SetDataDir'',gcbo, ''%s'', guidata(gcbo) )'); catch rest_misc( 'DisplayLastException'); end set(handles.listDataDirs, 'BackgroundColor', theOldColor); rmappdata(0, 'FC_DoingRecursiveDir'); end function DeleteSelectedDataDir(hObject, eventdata, handles) theIndex =get(handles.listDataDirs, 'Value'); if prod(size(handles.Cfg.DataDirs))==0 ... || size(handles.Cfg.DataDirs, 1)==0 ... || theIndex>size(handles.Cfg.DataDirs, 1), return; end theDir =handles.Cfg.DataDirs{theIndex, 1}; theVolumnCount=handles.Cfg.DataDirs{theIndex, 2}; tmpMsg=sprintf('Delete\n\n "%s" \nVolumn Count :%d ?', theDir, theVolumnCount); if strcmp(questdlg(tmpMsg, 'Delete confirmation'), 'Yes') if theIndex>1, set(handles.listDataDirs, 'Value', theIndex-1); end handles.Cfg.DataDirs(theIndex, :)=[]; if size(handles.Cfg.DataDirs, 1)==0 handles.Cfg.DataDirs={}; end guidata(hObject, handles); UpdateDisplay(handles); end function edtDicomType_Callback(hObject, eventdata, handles) handles.Cfg.DataDirs ={}; uiwait(msgbox('The DICOM file extension has been changed, please re-select the Data Dir.','Re-select Data Dir')); guidata(hObject, handles); UpdateDisplay(handles); % --- Executes during object creation, after setting all properties. function edtDicomType_CreateFcn(hObject, eventdata, handles) % hObject handle to edtDicomType (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on button press in checkboxAnonymize. function checkboxAnonymize_Callback(hObject, eventdata, handles) if get(hObject,'Value') handles.Cfg.Anonymize = 1; else handles.Cfg.Anonymize = 0; end guidata(hObject, handles); set(handles.checkboxAnonymize,'Value',handles.Cfg.Anonymize); % --- Executes on button press in radiobuttonSubjectFirst. function radiobuttonSubjectFirst_Callback(hObject, eventdata, handles) handles.Cfg.DirectoryHierarchy=0; set(handles.radiobuttonSeriesFirst,'Value',0); set(handles.radiobuttonSubjectFirst,'Value',1); drawnow; guidata(hObject, handles); UpdateDisplay(handles); % --- Executes on button press in radiobuttonSeriesFirst. function radiobuttonSeriesFirst_Callback(hObject, eventdata, handles) handles.Cfg.DirectoryHierarchy=1; set(handles.radiobuttonSeriesFirst,'Value',1); set(handles.radiobuttonSubjectFirst,'Value',0); drawnow; guidata(hObject, handles); UpdateDisplay(handles);