00001 function [err, v, Info] = Read_1D (fname, p1)
00002 %
00003 % [err,M, Info] = Read_1D (fname, [opt])
00004 %
00005 %Purpose:
00006 % Reads an AFNI 1D file into M
00007 %
00008 % The file is to contain an ASCII table
00009 % of numbers. All rows must have the same number of entries
00010 % or the function will fail.
00011 % Lines starting with a '#' are considered
00012 % comment lines and are ignored.
00013 %
00014 % The function will create a temporary file with
00015 % methods 0 and 2. If your files are huge, consider
00016 % disk space issues.
00017 %
00018 %Input Parameters:
00019 % fname : the name of the 1D file
00020 % Opt: An optional options structure
00021 % .verb (0/1) verbose mode, default is 1
00022 % .method (0/1/2) default is 0.
00023 % 0: use matlab to interpret 1D files
00024 % that have comments and other
00025 % 1D formatting gimmicks (slow for large files)
00026 % 1: use matlab to load a pure 1D file.
00027 % i.e. one that has only numbers in it.
00028 % 2: use ConvertDset program to purify 1D file
00029 % then read it into matlab.
00030 % .chunk_size: number of rows to read at a time
00031 % (think number of voxels per slice)
00032 % set to zero to read entire dataset
00033 % .chunk_index: which chunk to read (1st chunk is indexed 0)
00034 % .col_index: which column to read (think sub-brick, 1st column is 0)
00035 % can use a vector of indices. Set to empty vector
00036 % if you want to read all columns.
00037 % Note that the use of chunk_size, chunk_index, col_index is only
00038 % a convenience with Opt.method 0 and 1. It does speed things up
00039 % some when using Opt.method 2
00040 %Output Parameters:
00041 % err : 0 No Problem
00042 % : 1 Problems
00043 % M : Matrix containing values in fname
00044 % Info: An Info header structure to pass along to
00045 % the WriteBrik function
00046 %
00047 %
00048 %Key Terms:
00049 %
00050 %More Info :
00051 %
00052 %
00053 %
00054 %
00055 % Author : Ziad Saad
00056 % Date : Fri Jul 23 10:11:34 EDT 2004
00057 % SSCC/NIMH/ National Institutes of Health, Bethesda Maryland
00058
00059
00060 %Define the function name for easy referencing
00061 FuncName = 'Read_1D';
00062
00063 %Debug Flag
00064 DBG = 1;
00065
00066 if (nargin == 1),
00067 verb = 1; Opt = [];
00068 else
00069 if (isstruct(p1)),
00070 Opt = p1;
00071 if (isfield(Opt, 'verb') & ~isempty(Opt.verb)) verb = Opt.verb;
00072 else verb = 1; end
00073 else
00074 verb = p1;
00075 Opt.method = 0;
00076 end
00077 end
00078 if (~isfield(Opt, 'method') | isempty(Opt.method)), Opt.method = 0; end
00079 if (~isfield(Opt, 'verb') | isempty(Opt.verb)), verb = 1; else verb = Opt.verb; end
00080 if (~isfield(Opt, 'chunk_size') | isempty(Opt.chunk_size)), Opt.chunk_size = 0; end
00081 if (~isfield(Opt, 'col_index')) Opt.col_index = []; end
00082 if (~isfield(Opt, 'chunk_index')) Opt.chunk_index = 0; end
00083
00084 if (length(Opt.chunk_index(:)) ~= 1), fprintf(2,'Opt.chunk_index must contain one value'); return; end
00085
00086 %initailize return variables
00087 err = 1;
00088
00089 v = [];
00090 Info = [];
00091 if (Opt.method < 0 | Opt.method > 2),
00092 fprintf(2,'Opt.method must be an integer between 0 and 2\n');
00093 return;
00094 end
00095 if (~filexist(fname)), % try with extension
00096 fname2 = sprintf('%s.1D', fname);
00097 fname3 = sprintf('%s.1D.dset', fname);
00098 if (verb), fprintf(1,'Trying for %s or %s\n', fname2, fname3); end
00099 if (filexist(fname2)),
00100 fname = sprintf('%s', fname2);
00101 elseif (filexist(fname3)),
00102 fname = sprintf('%s', fname3);
00103 else
00104 fprintf (2, 'Error %s:\n %s not found\n', FuncName, fname);
00105 return;
00106 end
00107 else
00108 if (verb), fprintf(1,'File %s exists and will be read.\n', fname); end
00109 end
00110
00111 if (Opt.method == 0),
00112 %load the 1D file
00113 if (verb), fprintf(1,'Reading file\n'); end
00114 fid = fopen(fname,'r');
00115 if (fid < 0),
00116 fprintf(1,'Error %s:\nCould not read %s.\nCheck for file existence\n', FuncName, fname);
00117 err = 1;
00118 return;
00119 end
00120 c = fscanf(fid,'%c');
00121 fclose(fid);
00122
00123 %purge comments
00124 if (verb > 1), fprintf(1,'Purging comments\n'); end
00125 c = PurgeComments(c, '#');
00126 nc = length(c);
00127 %remove line breaks and the following new line
00128 if (verb > 1), fprintf(1,'Removing line breaks\n'); end
00129 ib = find (c == '\');
00130 nib = length(ib);
00131 for (i=1:1:nib),
00132 c(ib(i)) = ' ';
00133 if (c(ib(i)+1) ~= 10),
00134 fprintf(1,'Error %s:\nline break not followed by newline.\n', FuncName);
00135 err = 1;
00136 return;
00137 else c(ib(i)+1) = ' ';
00138 end
00139 end
00140 if (verb > 1), fprintf(1,'Replacing @\n'); end
00141 %work the @ cats
00142 ia = find (c == '@');
00143 lst = 1;
00144 nia = length(ia);
00145 cnew = '';
00146 if (nia),
00147 for (i=1:1:nia),
00148 %bracket @
00149 found = 0;
00150 j = ia(i)-1;
00151 while (j>0 & ~found),
00152 if (c(j) >= '0' & c(j) <= '9'),
00153 j = j -1;
00154 else
00155 found = j;
00156 end
00157 end
00158 cnew = [cnew ' ' c(lst:found )]; % Copy OK stuff
00159 if (found),
00160 prod = str2num(c(found:ia(i)-1));
00161 else
00162 fprintf(1,'Error %s:\nno number preceding @\n', FuncName);
00163 err = 1;
00164 return;
00165 end
00166 %Now find the value to replicate
00167 if (ia(i)+100 < nc) nxtchunk = ia(i)+100;
00168 else nxtchunk = nc; end
00169 [vr, cnt, err, nxt] = sscanf(c(ia(i)+1:nxtchunk), '%f', 1);
00170 %insert the replacement
00171 cinsert = num2str(ones(1,prod)*vr);
00172 cnew = [cnew ' ' cinsert ' '];
00173 lst = ia(i)+nxt;c(lst);
00174 end
00175 cnew = [cnew ' ' c(lst:nc)];
00176 c = cnew;
00177 end
00178
00179
00180 meth = 2;
00181 switch (meth),
00182 case 1
00183 %this one's slow as hell
00184 if (verb > 1), fprintf(1,'The str2num operation ...\n'); end
00185 v = str2num(c); % str2double fails miserably where str2num does not
00186 case 2
00187 if (verb > 1), fprintf(1,'The round about way ...\n'); end
00188 ftmp = sprintf('%s_Read_1D_tmp_', fname);
00189 fid = fopen(ftmp,'w');
00190 if (fid < 0),
00191 fprintf(1,'Error %s:\nFailed to open tempfile %s for writing\n', FuncName, ftmp);
00192 err = 1;
00193 return;
00194 end
00195 fprintf(fid,'%c',c);
00196 v = load(ftmp);
00197 fclose(fid);
00198 rmcom = sprintf('rm -f %s', ftmp);
00199 unix(rmcom);
00200 end
00201
00202 % sub-bricks?
00203 if (~isempty(Opt.col_index)),
00204 if (verb) fprintf(1,'Selecting columns ...\n'); end
00205 v = v(:, Opt.col_index+1);
00206 end
00207
00208 %slices?
00209 if (Opt.chunk_size > 0),
00210 strt = (Opt.chunk_size .* Opt.chunk_index) + 1;
00211 stp = Opt.chunk_size .* (Opt.chunk_index+1);
00212 if (strt > size(v,1)),
00213 fprintf(1,'Error %s:\nNothing left to read (strt = %d, nvec = %d)\n', FuncName, strt, size(v,1));
00214 err = 1;
00215 return;
00216 end
00217 if (stp > size(v,1)) stp = size(v,1); end
00218 v = v (strt:stp,:);
00219 end
00220 elseif (Opt.method == 1),
00221 if (verb) fprintf(1,'Assuming 1D file has no comments.\n'); end
00222 v = load(fname);
00223 if (isempty(v)), fprintf(2,'Failed to read 1D file. If file exists Try method 0\n'); err = 1; return; end
00224 % sub-bricks?
00225 if (~isempty(Opt.col_index)),
00226 if (verb) fprintf(1,'Selecting columns ...\n'); end
00227 v = v(:, Opt.col_index+1);
00228 end
00229
00230 %slices?
00231 if (Opt.chunk_size > 0),
00232 strt = (Opt.chunk_size .* Opt.chunk_index) + 1;
00233 stp = Opt.chunk_size .* (Opt.chunk_index+1);
00234 if (strt > size(v,1)),
00235 fprintf(1,'Error %s:\nNothing left to read (strt = %d, nvec = %d)\n', FuncName, strt, size(v,1));
00236 err = 1;
00237 return;
00238 end
00239 if (stp > size(v,1)) stp = size(v,1); end
00240 v = v (strt:stp,:);
00241 end
00242 elseif (Opt.method == 2),
00243 if (verb) fprintf(1,'Running ConvertDset to purging 1D file of bells and whistles\n'); end
00244 ftmp = sprintf('%s_Read_1D_tmp_', fname);
00245 ftmpout = sprintf('%s.1D.dset', ftmp);
00246 rmcom = sprintf('rm -f %s', ftmpout);
00247 if (filexist(ftmpout)),
00248 unix(rmcom);% cleanup
00249 end
00250 % sub-bricks?
00251 if (~isempty(Opt.col_index)),
00252 ssel = sprintf('''[');
00253 for (ii=1:1:length(Opt.col_index)-1) ssel = sprintf('%s %d,', ssel, Opt.col_index(ii)); end
00254 ssel = sprintf('%s %d ]''', ssel, Opt.col_index(length(Opt.col_index)));
00255 else ssel = '';
00256 end
00257 convcom = sprintf('ConvertDset -o_1dp -input %s%s -i_1D -prefix %s', fname, ssel, ftmp);
00258 if (verb > 1) fprintf(2,'Command is:\n%s\n', convcom); end
00259 unix(convcom);
00260 v = load(ftmpout);
00261 unix(rmcom);
00262 %slices?
00263 if (Opt.chunk_size > 0),
00264 strt = (Opt.chunk_size .* Opt.chunk_index) + 1;
00265 stp = Opt.chunk_size .* (Opt.chunk_index+1);
00266 if (strt > size(v,1)),
00267 fprintf(1,'Error %s:\nNothing left to read (strt = %d, nvec = %d)\n', FuncName, strt, size(v,1));
00268 err = 1;
00269 return;
00270 end
00271 if (stp > size(v,1)) stp = size(v,1); end
00272 v = v (strt:stp,:);
00273 end
00274 end
00275
00276 %some fake Info stuff
00277 if (nargout == 3),
00278 [err, Info] = Info_1D(v, fname);
00279 end
00280
00281 err = 0;
00282 return;
00283