|
| 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 Inf, 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 | + |
| 62 | +% John Ashburner |
| 63 | +% Copyright (C) 2005-2022 Wellcome Centre for Human Neuroimaging |
| 64 | + |
| 65 | + |
| 66 | +% For developers: |
| 67 | +%-------------------------------------------------------------------------- |
| 68 | +% FORMAT cpath = spm_select('CPath',path,cwd) |
| 69 | +% Canonicalise paths: prepend cwd to relative paths, process '..' & '.' |
| 70 | +% directories embedded in path. |
| 71 | +% path - string matrix containing path name |
| 72 | +% cwd - current working directory [Default: '.'] |
| 73 | +% cpath - canonicalised paths, in same format as input path argument |
| 74 | +% |
| 75 | +% FORMAT [t,ind] = spm_select('Filter',files,typ,filt,frames) |
| 76 | +% Filter the list of files (cell or char array) in the same way as the |
| 77 | +% GUI would do. There is an additional typ 'extimage' which will match |
| 78 | +% images with frame specifications, too. Also, there is a typ 'extdir', |
| 79 | +% which will match canonicalised directory names. The 'frames' argument |
| 80 | +% is currently ignored, i.e. image files will not be filtered out if |
| 81 | +% their frame numbers do not match. |
| 82 | +% t returns the filtered list (cell or char array, depending on input), |
| 83 | +% ind an index array, such that t = files{ind}, or t = files(ind,:). |
| 84 | +% |
| 85 | +% FORMAT spm_select('PrevDirs',dir) |
| 86 | +% Add directory dir to list of previous directories. |
| 87 | +% FORMAT dirs = spm_select('PrevDirs') |
| 88 | +% Retrieve list of previous directories. |
| 89 | +% |
| 90 | +% FORMAT files = spm_select('Expand',files) |
| 91 | +% Return a list of image filenames with appended frame numbers. |
| 92 | + |
| 93 | +persistent isInitSelect; |
| 94 | +if isempty(isInitSelect) |
| 95 | + isInitSelect = true; |
| 96 | + spm_select('init'); |
| 97 | + if nargin == 1 && strcmpi(varargin{1},'init'), return; end |
| 98 | +end |
| 99 | + |
| 100 | +%-Commands that are not passed to cfg_getfile |
| 101 | +local_cmds = {'regfilter', 'init', 'expand'}; |
| 102 | + |
| 103 | +if nargin && ischar(varargin{1}) && any(strcmpi(varargin{1},local_cmds)) |
| 104 | + switch lower(varargin{1}) |
| 105 | + case 'init' |
| 106 | + if ~isdeployed && ~exist('cfg_getfile','file') |
| 107 | + addpath(fullfile(spm('dir'),'matlabbatch')); |
| 108 | + end |
| 109 | + spm_select('regfilter'); |
| 110 | + spm_select('prevdirs',spm('Dir')); |
| 111 | + |
| 112 | + case 'regfilter' |
| 113 | + % Regexp based filters without special handlers |
| 114 | + cfg_getfile('regfilter', 'mesh', {'\.gii$'}); |
| 115 | + cfg_getfile('regfilter', 'gifti', {'\.gii$'}); |
| 116 | + cfg_getfile('regfilter', 'nifti', {'\.nii$','\.img$','\.nii.gz$'}); |
| 117 | + % Filter for 3D images that handles frame expansion |
| 118 | + frames = cfg_entry; |
| 119 | + frames.name = 'Frames'; |
| 120 | + frames.tag = 'frames'; |
| 121 | + frames.strtype = 'n'; |
| 122 | + frames.num = [1 Inf]; |
| 123 | + frames.val = {1}; |
| 124 | + cfg_getfile('regfilter', 'image',... |
| 125 | + {'.*\.nii(,\d+){0,2}$','.*\.nii.gz(,\d+){0,2}$','.*\.img(,\d+){0,2}$'},... |
| 126 | + false, @spm_select_image, {frames}); |
| 127 | + |
| 128 | + case 'expand' |
| 129 | + varargout{1} = spm_select_expand(varargin{2}); |
| 130 | + if ischar(varargin{2}), varargout{1} = char(varargout{1}); end |
| 131 | + end |
| 132 | +else |
| 133 | + needchar = false; |
| 134 | + % cfg_getfile expects cellstr arguments for multi-line strings |
| 135 | + if nargin > 1 && ischar(varargin{1}) && ... |
| 136 | + ismember(lower(varargin{1}),{'filter','cpath'}) && ischar(varargin{2}) |
| 137 | + varargin{2} = cellstr(varargin{2}); |
| 138 | + needchar = true; |
| 139 | + elseif nargin > 0 && ischar(varargin{1}) && ... |
| 140 | + ismember(lower(varargin{1}),{'extlist','extfplist','extfplistrec'}) |
| 141 | + varargin{1} = varargin{1}(4:end); |
| 142 | + if nargin > 3 |
| 143 | + varargin{5} = struct('frames', varargin{4}); |
| 144 | + else |
| 145 | + varargin{5} = struct('frames', Inf); |
| 146 | + end |
| 147 | + varargin{4} = varargin{3}; |
| 148 | + varargin{3} = 'image'; |
| 149 | + elseif nargin > 6 && isnumeric(varargin{1}) |
| 150 | + varargin{7} = struct('frames', varargin{7}); |
| 151 | + end |
| 152 | + |
| 153 | + [t, sts] = cfg_getfile(varargin{:}); |
| 154 | + |
| 155 | + % cfg_getfile returns cellstr arrays, convert to char arrays |
| 156 | + if nargin > 0 && ischar(varargin{1}) |
| 157 | + switch lower(varargin{1}) |
| 158 | + case {'filter','cpath'} |
| 159 | + if needchar |
| 160 | + t = char(t); |
| 161 | + end |
| 162 | + case {'list','fplist','extlist','extfplist','fplistrec','extfplistrec'} |
| 163 | + t = char(t); |
| 164 | + sts = char(sts); |
| 165 | + end |
| 166 | + else |
| 167 | + t = char(t); |
| 168 | + end |
| 169 | + |
| 170 | + varargout{1} = t; |
| 171 | + if nargout > 1 |
| 172 | + varargout{2} = sts; |
| 173 | + end |
| 174 | +end |
| 175 | + |
| 176 | + |
| 177 | +%========================================================================== |
| 178 | +% FUNCTION varargout = spm_select_image(cmd, varargin) |
| 179 | +%========================================================================== |
| 180 | +function varargout = spm_select_image(cmd, varargin) |
| 181 | +% Implements extended filtering for NIfTI images (including 3D frame |
| 182 | +% selection) |
| 183 | +switch lower(cmd) |
| 184 | + case 'list' |
| 185 | + dr = varargin{1}; |
| 186 | + files = varargin{2}; |
| 187 | + prms = varargin{3}; |
| 188 | + frames = prms.frames; |
| 189 | + ii = cell(1,numel(files)); |
| 190 | + if numel(frames)==1 && isnan(frames) |
| 191 | + [ii{:}] = deal(1); |
| 192 | + elseif numel(frames)~=1 || frames(1)~=1 |
| 193 | + % if domsg |
| 194 | + % msg(ob,['Reading headers of ' num2str(numel(f)) ' images...']); |
| 195 | + % end |
| 196 | + for i=1:numel(files) |
| 197 | + try |
| 198 | + n = spm_select_get_nbframes(fullfile(dr,files{i})); |
| 199 | + d4 = (1:n)'; |
| 200 | + catch |
| 201 | + d4 = 1; |
| 202 | + end |
| 203 | + if all(isfinite(frames)) |
| 204 | + ii{i} = intersect(d4, frames(:))'; |
| 205 | + else |
| 206 | + ii{i} = d4(:)'; |
| 207 | + end |
| 208 | + end |
| 209 | + elseif numel(frames)==1 && frames(1)==1 |
| 210 | + [ii{:}] = deal(1); |
| 211 | + end |
| 212 | + |
| 213 | + % if domsg |
| 214 | + % msg(ob,['Listing ' num2str(numel(f)) ' files...']); |
| 215 | + % end |
| 216 | + |
| 217 | + % Combine filename and frame number(s) |
| 218 | + nii = cellfun(@numel, ii); |
| 219 | + cfiles = cell(sum(nii),1); |
| 220 | + fi = cell(numel(files),1); |
| 221 | + for k = 1:numel(fi) |
| 222 | + fi{k} = k*ones(1,nii(k)); |
| 223 | + end |
| 224 | + ii = [ii{:}]; |
| 225 | + fi = [fi{:}]'; |
| 226 | + if numel(frames)==1 && isnan(frames) |
| 227 | + cfiles = files; |
| 228 | + else |
| 229 | + for i=1:numel(cfiles) |
| 230 | + cfiles{i} = sprintf('%s,%d', files{fi(i)}, ii(i)); |
| 231 | + end |
| 232 | + end |
| 233 | + varargout{1} = cfiles; |
| 234 | + varargout{2} = fi; |
| 235 | + case 'filter' |
| 236 | + % Do not filter for frame numbers |
| 237 | + varargout{1} = varargin{1}; |
| 238 | + varargout{2} = 1:numel(varargout{1}); |
| 239 | +end |
| 240 | + |
| 241 | + |
| 242 | +%========================================================================== |
| 243 | +% FUNCTION ofiles = spm_select_expand(ifiles) |
| 244 | +%========================================================================== |
| 245 | +function ofiles = spm_select_expand(ifiles) |
| 246 | +ifiles = cellstr(ifiles); |
| 247 | +ofiles = {}; |
| 248 | +for i=1:numel(ifiles) |
| 249 | + [p,f,e,n] = spm_fileparts(ifiles{i}); |
| 250 | + if ~isempty(n) |
| 251 | + ofiles = [ofiles; ifiles{i}]; |
| 252 | + else |
| 253 | + n = spm_select_get_nbframes(ifiles{i}); |
| 254 | + vfiles = cell(n,1); |
| 255 | + for j=1:n |
| 256 | + vfiles{j} = [ifiles{i} ',' num2str(j)]; |
| 257 | + end |
| 258 | + ofiles = [ofiles; vfiles]; |
| 259 | + end |
| 260 | +end |
| 261 | + |
| 262 | + |
| 263 | +%========================================================================== |
| 264 | +% FUNCTION n = spm_select_get_nbframes(file) |
| 265 | +%========================================================================== |
| 266 | +function n = spm_select_get_nbframes(file) |
| 267 | +N = nifti(file); |
| 268 | +dim = [N.dat.dim 1 1 1 1 1]; |
| 269 | +n = dim(4); |
| 270 | + |
| 271 | +% % A faster, direct implementation |
| 272 | +% [p,f,e] = fileparts(file); |
| 273 | +% unchanged = true; |
| 274 | +% ind = find(e==','); |
| 275 | +% if ~isempty(ind) |
| 276 | +% unchanged = false; |
| 277 | +% e = e(1:(ind(1)-1)); |
| 278 | +% end |
| 279 | +% switch e |
| 280 | +% case {'.img'} |
| 281 | +% unchanged = false; |
| 282 | +% e = '.hdr'; |
| 283 | +% case {'.IMG'} |
| 284 | +% unchanged = false; |
| 285 | +% e = '.HDR'; |
| 286 | +% end |
| 287 | +% if ~unchanged |
| 288 | +% file = fullfile(p,[f e]); |
| 289 | +% end |
| 290 | +% |
| 291 | +% n = []; |
| 292 | +% |
| 293 | +% fp = fopen(file,'r','native'); |
| 294 | +% if fp==-1, return; end |
| 295 | +% |
| 296 | +% %sts = fseek(fp,344,'bof'); |
| 297 | +% %if sts==-1, fclose(fp); return; end |
| 298 | +% %mgc = deblank(char(fread(fp,4,'uint8')')); |
| 299 | +% |
| 300 | +% sts = fseek(fp,40,'bof'); |
| 301 | +% if sts==-1, fclose(fp); return; end |
| 302 | +% dim = fread(fp,8,'*int16'); |
| 303 | +% fclose(fp); |
| 304 | +% if isempty(dim), return; end |
| 305 | +% if dim(1)<1 || dim(1)>7 |
| 306 | +% dim = swapbytes(dim); |
| 307 | +% end |
| 308 | +% dim = double(dim(2:(dim(1)+1)))'; |
| 309 | +% dim = [dim 1 1 1 1 1]; |
| 310 | +% n = dim(4); |
0 commit comments