spm_select.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. function varargout = spm_select(varargin)
  2. % File selector
  3. % FORMAT [t,sts] = spm_select(n,typ,mesg,sel,wd,filt,frames)
  4. % n - number of files [Default: Inf]
  5. % A single value or a range. e.g.
  6. % 1 - select one file
  7. % Inf - select any number of files
  8. % [1 Inf] - select 1 to Inf files
  9. % [0 1] - select 0 or 1 files
  10. % [10 12] - select from 10 to 12 files
  11. % typ - file type [Default: 'any']
  12. % 'any' - all files
  13. % 'image' - Image files (".img" and ".nii")
  14. % Note that it gives the option to select individuals
  15. % volumes of the images.
  16. % 'mesh' - Surface mesh files (".gii")
  17. % 'xml' - XML files
  18. % 'mat' - MATLAB .mat files or .txt files (assumed to contain
  19. % ASCII representation of a 2D-numeric array)
  20. % 'batch' - SPM batch files (.m or .mat)
  21. % 'dir' - select a directory
  22. % Other strings act as a filter to regexp. This means that
  23. % e.g. DCM*.mat files should have a typ of '^DCM.*\.mat$'
  24. % mesg - a prompt [Default: 'Select files...']
  25. % sel - list of already selected files [Default: {}]
  26. % wd - directory to start off in [Default: pwd]
  27. % filt - value for user-editable filter [Default: '.*']
  28. % frames - image frame numbers to include [Default: '1']
  29. %
  30. % t - selected files
  31. % sts - status (1 means OK, 0 means window quit)
  32. %
  33. % FORMAT [files,dirs] = spm_select('List',direc,filt)
  34. % Return files matching the filter 'filt' and directories within 'direc'
  35. % direc - directory to search [Default: pwd]
  36. % filt - filter to select files with regexp, e.g. '^w.*\.img$' [Default: '.*']
  37. %
  38. % files - files matching 'filt' in directory 'direc'
  39. % dirs - subdirectories of 'direc'
  40. %
  41. % FORMAT [files,dirs] = spm_select('ExtList',direc,filt,frames)
  42. % As above, but for selecting frames of 4D NIfTI files
  43. % frames - vector of frames to select (defaults to 1, if not specified).
  44. % If the frame number is Inf, all frames for the matching images
  45. % are listed.
  46. %
  47. % FORMAT [files,dirs] = spm_select('FPList',direc,filt)
  48. % FORMAT [files,dirs] = spm_select('ExtFPList',direc,filt,frames)
  49. % As above, but return files with full paths (i.e. prefixes 'direc' to each)
  50. %
  51. % FORMAT [files,dirs] = spm_select('FPListRec',direc,filt)
  52. % FORMAT [files,dirs] = spm_select('ExtFPListRec',direc,filt,frames)
  53. % As above, but return files with full paths (i.e. prefixes 'direc' to each)
  54. % and search through sub directories recursively.
  55. %
  56. % FORMAT [dirs] = spm_select('List',direc,'dir',filt)
  57. % FORMAT [dirs] = spm_select('FPList',direc,'dir',filt)
  58. % FORMAT [dirs] = spm_select('FPListRec',direc,'dir',filt)
  59. % Return directory names matching filter 'filt' within 'direc'
  60. %__________________________________________________________________________
  61. % Copyright (C) 2005-2015 Wellcome Trust Centre for Neuroimaging
  62. % John Ashburner
  63. % $Id: spm_select.m 6530 2015-08-21 14:43:52Z guillaume $
  64. % For developers:
  65. %--------------------------------------------------------------------------
  66. % FORMAT cpath = spm_select('CPath',path,cwd)
  67. % Canonicalise paths: prepend cwd to relative paths, process '..' & '.'
  68. % directories embedded in path.
  69. % path - string matrix containing path name
  70. % cwd - current working directory [Default: '.']
  71. % cpath - canonicalised paths, in same format as input path argument
  72. %
  73. % FORMAT [t,ind] = spm_select('Filter',files,typ,filt,frames)
  74. % Filter the list of files (cell or char array) in the same way as the
  75. % GUI would do. There is an additional typ 'extimage' which will match
  76. % images with frame specifications, too. Also, there is a typ 'extdir',
  77. % which will match canonicalised directory names. The 'frames' argument
  78. % is currently ignored, i.e. image files will not be filtered out if
  79. % their frame numbers do not match.
  80. % t returns the filtered list (cell or char array, depending on input),
  81. % ind an index array, such that t = files{ind}, or t = files(ind,:).
  82. %
  83. % FORMAT spm_select('PrevDirs',dir)
  84. % Add directory dir to list of previous directories.
  85. % FORMAT dirs = spm_select('PrevDirs')
  86. % Retrieve list of previous directories.
  87. %
  88. % FORMAT files = spm_select('Expand',files)
  89. % Return a list of image filenames with appended frame numbers.
  90. persistent isInitSelect;
  91. if isempty(isInitSelect)
  92. isInitSelect = true;
  93. spm_select('init');
  94. if nargin == 1 && strcmpi(varargin{1},'init'), return; end
  95. end
  96. %-Commands that are not passed to cfg_getfile
  97. local_cmds = {'regfilter', 'init', 'expand'};
  98. if nargin && ischar(varargin{1}) && any(strcmpi(varargin{1},local_cmds))
  99. switch lower(varargin{1})
  100. case 'init'
  101. if ~isdeployed && ~exist('cfg_getfile','file')
  102. addpath(fullfile(spm('dir'),'matlabbatch'));
  103. end
  104. spm_select('regfilter');
  105. spm_select('prevdirs',spm('Dir'));
  106. case 'regfilter'
  107. % Regexp based filters without special handlers
  108. cfg_getfile('regfilter', 'mesh', {'\.gii$'});
  109. cfg_getfile('regfilter', 'gifti', {'\.gii$'});
  110. cfg_getfile('regfilter', 'nifti', {'\.nii$','\.img$'});
  111. % Filter for 3D images that handles frame expansion
  112. frames = cfg_entry;
  113. frames.name = 'Frames';
  114. frames.tag = 'frames';
  115. frames.strtype = 'n';
  116. frames.num = [1 Inf];
  117. frames.val = {1};
  118. cfg_getfile('regfilter', 'image',...
  119. {'.*\.nii(,\d+){0,2}$','.*\.img(,\d+){0,2}$'},...
  120. false, @spm_select_image, {frames});
  121. case 'expand'
  122. varargout{1} = spm_select_expand(varargin{2});
  123. if ischar(varargin{2}), varargout{1} = char(varargout{1}); end
  124. end
  125. else
  126. needchar = false;
  127. % cfg_getfile expects cellstr arguments for multi-line strings
  128. if nargin > 1 && ischar(varargin{1}) && ...
  129. ismember(lower(varargin{1}),{'filter','cpath'}) && ischar(varargin{2})
  130. varargin{2} = cellstr(varargin{2});
  131. needchar = true;
  132. elseif nargin > 0 && ischar(varargin{1}) && ...
  133. ismember(lower(varargin{1}),{'extlist','extfplist','extfplistrec'})
  134. varargin{1} = varargin{1}(4:end);
  135. if nargin > 3
  136. varargin{5} = struct('frames', varargin{4});
  137. else
  138. varargin{5} = struct('frames', Inf);
  139. end
  140. varargin{4} = varargin{3};
  141. varargin{3} = 'image';
  142. elseif nargin > 6 && isnumeric(varargin{1})
  143. varargin{7} = struct('frames', varargin{7});
  144. end
  145. [t, sts] = cfg_getfile(varargin{:});
  146. % cfg_getfile returns cellstr arrays, convert to char arrays
  147. if nargin > 0 && ischar(varargin{1})
  148. switch lower(varargin{1})
  149. case {'filter','cpath'}
  150. if needchar
  151. t = char(t);
  152. end
  153. case {'list','fplist','extlist','extfplist','fplistrec','extfplistrec'}
  154. t = char(t);
  155. sts = char(sts);
  156. end
  157. else
  158. t = char(t);
  159. end
  160. varargout{1} = t;
  161. if nargout > 1
  162. varargout{2} = sts;
  163. end
  164. end
  165. %==========================================================================
  166. % FUNCTION varargout = spm_select_image(cmd, varargin)
  167. %==========================================================================
  168. function varargout = spm_select_image(cmd, varargin)
  169. % Implements extended filtering for NIfTI images (including 3D frame
  170. % selection)
  171. switch lower(cmd)
  172. case 'list'
  173. dr = varargin{1};
  174. files = varargin{2};
  175. prms = varargin{3};
  176. frames = prms.frames;
  177. ii = cell(1,numel(files));
  178. if numel(frames)==1 && isnan(frames)
  179. [ii{:}] = deal(1);
  180. elseif numel(frames)~=1 || frames(1)~=1
  181. % if domsg
  182. % msg(ob,['Reading headers of ' num2str(numel(f)) ' images...']);
  183. % end
  184. for i=1:numel(files)
  185. try
  186. n = spm_select_get_nbframes(fullfile(dr,files{i}));
  187. d4 = (1:n)';
  188. catch
  189. d4 = 1;
  190. end
  191. if all(isfinite(frames))
  192. ii{i} = intersect(d4, frames(:))';
  193. else
  194. ii{i} = d4(:)';
  195. end
  196. end
  197. elseif numel(frames)==1 && frames(1)==1
  198. [ii{:}] = deal(1);
  199. end
  200. % if domsg
  201. % msg(ob,['Listing ' num2str(numel(f)) ' files...']);
  202. % end
  203. % Combine filename and frame number(s)
  204. nii = cellfun(@numel, ii);
  205. cfiles = cell(sum(nii),1);
  206. fi = cell(numel(files),1);
  207. for k = 1:numel(fi)
  208. fi{k} = k*ones(1,nii(k));
  209. end
  210. ii = [ii{:}];
  211. fi = [fi{:}]';
  212. if numel(frames)==1 && isnan(frames)
  213. cfiles = files;
  214. else
  215. for i=1:numel(cfiles)
  216. cfiles{i} = sprintf('%s,%d', files{fi(i)}, ii(i));
  217. end
  218. end
  219. varargout{1} = cfiles;
  220. varargout{2} = fi;
  221. case 'filter'
  222. % Do not filter for frame numbers
  223. varargout{1} = varargin{1};
  224. varargout{2} = 1:numel(varargout{1});
  225. end
  226. %==========================================================================
  227. % FUNCTION ofiles = spm_select_expand(ifiles)
  228. %==========================================================================
  229. function ofiles = spm_select_expand(ifiles)
  230. ifiles = cellstr(ifiles);
  231. ofiles = {};
  232. for i=1:numel(ifiles)
  233. [p,f,e,n] = spm_fileparts(ifiles{i});
  234. if ~isempty(n)
  235. ofiles = [ofiles; ifiles{i}];
  236. else
  237. n = spm_select_get_nbframes(ifiles{i});
  238. vfiles = cell(n,1);
  239. for j=1:n
  240. vfiles{j} = [ifiles{i} ',' num2str(j)];
  241. end
  242. ofiles = [ofiles; vfiles];
  243. end
  244. end
  245. %==========================================================================
  246. % FUNCTION n = spm_select_get_nbframes(file)
  247. %==========================================================================
  248. function n = spm_select_get_nbframes(file)
  249. N = nifti(file);
  250. dim = [N.dat.dim 1 1 1 1 1];
  251. n = dim(4);
  252. % % A faster, direct implementation
  253. % [p,f,e] = fileparts(file);
  254. % unchanged = true;
  255. % ind = find(e==',');
  256. % if ~isempty(ind)
  257. % unchanged = false;
  258. % e = e(1:(ind(1)-1));
  259. % end
  260. % switch e
  261. % case {'.img'}
  262. % unchanged = false;
  263. % e = '.hdr';
  264. % case {'.IMG'}
  265. % unchanged = false;
  266. % e = '.HDR';
  267. % end
  268. % if ~unchanged
  269. % file = fullfile(p,[f e]);
  270. % end
  271. %
  272. % n = [];
  273. %
  274. % fp = fopen(file,'r','native');
  275. % if fp==-1, return; end
  276. %
  277. % %sts = fseek(fp,344,'bof');
  278. % %if sts==-1, fclose(fp); return; end
  279. % %mgc = deblank(char(fread(fp,4,'uint8')'));
  280. %
  281. % sts = fseek(fp,40,'bof');
  282. % if sts==-1, fclose(fp); return; end
  283. % dim = fread(fp,8,'*int16');
  284. % fclose(fp);
  285. % if isempty(dim), return; end
  286. % if dim(1)<1 || dim(1)>7
  287. % dim = swapbytes(dim);
  288. % end
  289. % dim = double(dim(2:(dim(1)+1)))';
  290. % dim = [dim 1 1 1 1 1];
  291. % n = dim(4);