function [gave_data] =make_gave(nfiles,bad_chan,bad_obs,outfname,infname, params) version 2.0 Grand-average data in EGIS average files. This function accepts either 1, 2, 3, or 5 arguments. The first argument is the number of files to be averaged together. If you specify 1 as nfiles, then it is assumed that there are multiple subjects per cell. If nfiles is greater than one, it is assumed the files are single subject average files. In this case the EGIS grand average file header is taken from the first input filename specified through either of the two means availible. If either outfname or infname are to be passed to this function, then both must be given, and the function is fully batch processed without addition user input. The infname matrix must have nfile rows, and each row must be a string of equal length. If these two arguments are not given then the function runs interactively, querying for an output filename and nfiles input files. The argument bad_chan is a matrix with nfiles rows and no more columns than there were channels of acquisition used to exclude globally bad channels as determined by previous editing. If nfiles is 1 then rows correspond to observations otherwise rows correspond to the file in the equivalent row of infname. The argument bad_obs is used only if nfile is 1. In this case bad_obs is an array specifying observations (i.e. subjects) to be excluded from the grand average for all cells.
0001 function [gave_data] = make_gave(nfiles,bad_chan,bad_obs,outfname,infname, ap) 0002 %function [gave_data] =make_gave(nfiles,bad_chan,bad_obs,outfname,infname, params) 0003 % 0004 %version 2.0 0005 %Grand-average data in EGIS average files. 0006 % 0007 %This function accepts either 1, 2, 3, or 5 arguments. The first 0008 %argument is the number of files to be averaged together. If you specify 0009 %1 as nfiles, then it is assumed that there are multiple subjects per 0010 %cell. If nfiles is greater than one, it is assumed the files are single 0011 %subject average files. In this case the EGIS grand average file 0012 %header is taken from the first input filename specified through either 0013 %of the two means availible. 0014 % 0015 %If either outfname or infname are to be passed to this function, then 0016 %both must be given, and the function is fully batch processed without 0017 %addition user input. The infname matrix must have nfile rows, and each 0018 %row must be a string of equal length. If these two arguments are not given 0019 %then the function runs interactively, querying for an output filename and 0020 %nfiles input files. 0021 % 0022 %The argument bad_chan is a matrix with nfiles rows and no more columns 0023 %than there were channels of acquisition used to exclude globally bad 0024 %channels as determined by previous editing. If nfiles is 1 then rows 0025 %correspond to observations otherwise rows correspond to the file in the 0026 %equivalent row of infname. 0027 % 0028 %The argument bad_obs is used only if nfile is 1. In this case bad_obs 0029 %is an array specifying observations (i.e. subjects) to be excluded from the 0030 %grand average for all cells. 0031 0032 %Modification History 0033 % 0034 % written 9/17/95 p.m. RS 0035 % defogged 9/18/95 a.m. RS 0036 % bad_obs added and error checking expanded 11/27/95 p.m. BCR 0037 % Code fixed for multi-file case, by BCR, 6/23/96 0038 % Bad_Obs warning removed, 10/3/96 BCR 0039 % 0040 % 05/31/00 PJ Cleaned up some of the poor matlab coding. 0041 % Since we are dealing with average data which are relatively 0042 % small, load all data at once. Doing this also enables 0043 % conversion to z-scores (see below). 0044 % 0045 % Added option to convert average data into z-scores prior to 0046 % averaging. Added params variable to input. This is a structure 0047 % that is intended to contain future parameters. In this case it 0048 % has a field called compute_z. 0049 % 0050 % 06/05/00 PJ Added detrending option 0051 0052 byte_order = 'ieee-be'; 0053 0054 gave_data = []; 0055 0056 %Check number of input arguments 0057 %if ~((nargin == 2)|(nargin == 3)|(nargin == 1)|(nargin == 5)) 0058 % error('Number of input arguments must be either 1, 2, 3, or 5.'); 0059 %end 0060 0061 %Check for correct use of Bad_Obs 0062 %if (nfiles > 1) & (bad_obs ~= []) 0063 % disp('Warning: bad_obs argument is ignored when nfiles is greater than zero.'); 0064 %end 0065 0066 %Check input argument dimensions 0067 %if (nargin == 5) 0068 % if ((size(infname,1) ~= nfiles) | (size(outfname,1) ~= nfiles)) 0069 % error('Indicated number of files not equal to number of rows in one or more input arguments.'); 0070 % end 0071 %end 0072 %Code fixed for multi-file case, by BCR, 6/23/96 0073 0074 if nargin < 6 0075 ap = struct('compute_z',0,'detrend',0'); 0076 else 0077 if ~isfield(ap,'compute_z'), ap.compute_z = 0, end 0078 if ~isfield(ap,'detrend'), ap.detrend = 0, end 0079 end 0080 0081 if (nargin >= 5) 0082 if (size(infname,1) ~= nfiles) 0083 error('Indicated number of files not equal to input parameter nfiles.'); 0084 end 0085 if (size(outfname,1) ~= 1) 0086 error('Outfname parameter must be a single row vector.'); 0087 end 0088 end 0089 0090 %Initialize fids 0091 destfid = -1; 0092 %First try batch mode 0093 if nargin >= 5 0094 for i = 1:size(infname,1) 0095 srcfid(i) = fopen(infname(i,:), 'r', byte_order); 0096 if srcfid(i) == -1 0097 error(sprintf('Could not open input file %s', infname(i,:))); 0098 end 0099 end; 0100 destfid = fopen(outfname, 'wb', byte_order); 0101 if destfid == -1 0102 temp =fclose(srcfid); 0103 error(['Could not open output file ' outfname '.']); 0104 end 0105 %Otherwise run interactive mode 0106 elseif nargin <= 3 0107 if nargin < 2, bad_chan = zeros(nfiles,1);, end 0108 if nargin < 3, bad_obs = [];, end 0109 for i=1:nfiles 0110 [srcfid(i), infname(i,:)]=get_fid('r','*.ave*', 'Open Average File:'); 0111 end 0112 while destfid == -1 0113 [destfid, outfname]=put_fid('wb','new.gave_bf','Save Grand Average File As:'); 0114 end 0115 end 0116 0117 nfiles = size(srcfid,2); 0118 0119 % 0120 % Call EGIS hdr index script 0121 % 0122 ave_hdr_offsets_v; 0123 [fhdr,chdr,ename,czeros,cgains,cnames,fcom,ftext, coff]=rd_egis_hdr_v(srcfid(1)); 0124 0125 % 0126 % Copy source header to destination file 0127 % 0128 0129 if nfiles == 1 0130 ave_chdr = chdr; 0131 for c=1:fhdr(NCells) 0132 ave_chdr(c,NObs) = 1; 0133 end; 0134 else 0135 ave_chdr = chdr; 0136 end; 0137 wt_ave_hdr_v(destfid,fhdr,ave_chdr,ename,cnames,fcom,ftext); 0138 0139 % 0140 % Determine the size of the input data array 0141 % 0142 0143 nchan = fhdr(NChan); 0144 npts = chdr(1,NPoints); 0145 ncells = fhdr(NCells); 0146 0147 nsub = 0; 0148 0149 for ifile = 1:nfiles 0150 [fhdr,chdr,ename,czeros,cgains,cnames,fcom,ftext, ... 0151 coff]=rd_egis_hdr_v(srcfid(ifile)); 0152 nsub = nsub + chdr(1,NObs); 0153 end 0154 0155 avgdata = zeros(npts,nchan,ncells,nsub); % Create empty output array 0156 0157 % 0158 % Check to make sure we have bad chan info for each subject 0159 % 0160 0161 if bad_chan & (size(bad_chan,1) ~= nsub) 0162 error(sprintf('Number of rows in bad chan list (%d) does not match number of subjects (%d)', size(bad_chan,1),nsub)) 0163 end 0164 0165 % 0166 % Read the data from all files 0167 % 0168 0169 curr_sub = 0; 0170 0171 for ifile=1:nfiles 0172 % 0173 % Read average file header 0174 % 0175 0176 [fhdr,chdr,ename,czeros,cgains,cnames,fcom,ftext, coff]=rd_egis_hdr_v(srcfid(ifile)); 0177 0178 disp(sprintf('Loading data from %s', infname(ifile,:))) 0179 0180 % 0181 % Begin looping through cells 0182 % 0183 0184 curr_sub = curr_sub+1; 0185 0186 for c=1:fhdr(NCells) 0187 0188 % 0189 % Loop through subject averages 0190 % 0191 0192 nobs = chdr(c,NObs); 0193 good_obs = find(~ismember(1:nobs, bad_obs)); 0194 ngood = length(good_obs); 0195 0196 for t=1:ngood 0197 0198 if t > 1 0199 curr_sub = curr_sub + 1; 0200 end 0201 0202 % 0203 % Read in the data from file 0204 % 0205 0206 curr_obs = good_obs(t); 0207 avgdata(:,:,c,curr_sub) = rd_onetr_allch(srcfid(ifile), coff(c), curr_obs, ... 0208 fhdr(NChan), chdr(c, NPoints)); 0209 0210 if ap.detrend 0211 disp(sprintf(' Detrending subject %d, cell %d ...', curr_sub, c)) 0212 avgdata(:,:,c,curr_sub) = detrend(avgdata(:,:,c,curr_sub)); 0213 end 0214 0215 end %for t=1:chdr(c,NObs) 0216 end %for c=1:fhdr(NCells) 0217 end %for ifile =1:nfiles 0218 0219 disp(sprintf('Loaded data for %d subjects', nsub)) 0220 0221 % 0222 % Construct bad channel masks 0223 % 0224 0225 mask = ones(npts,nchan,ncells,nsub); 0226 0227 for isub = 1:nsub 0228 0229 % Add all channels with all zeros for any given cell and subject to mask 0230 for icell = 1:ncells 0231 mask(:,:,icell,isub) = repmat(any(avgdata(:,:,icell,isub)),npts,1); 0232 % disp(sprintf('Subject %d, cell %d badchans:', isub,icell)) 0233 % disp(sprintf('%d ', find(~any(avgdata(:,:,icell,isub))))) 0234 end 0235 0236 % Take into account bad channels passed as a parameter 0237 badidx = bad_chan(isub,find(bad_chan(isub,:))); 0238 mask(:,badidx,:,isub) = 0; 0239 0240 end % for isub= 0241 0242 % 0243 % Compute z-score on a subject by subject basis if desired 0244 % Base the z-score on all good data from that subject 0245 % 0246 0247 if ap.compute_z 0248 disp('Computing z-scores ...') 0249 for isub = 1:nsub 0250 disp(sprintf(' Subject %d', isub)) 0251 tmpdata = avgdata(:,:,:,isub); 0252 tmpgood = find(mask(:,:,:,isub)); 0253 mu = mean(tmpdata(tmpgood)) 0254 sigma = std(tmpdata(tmpgood)) 0255 tmpdata(tmpgood) = (tmpdata(tmpgood)-mu)/sigma; 0256 avgdata(:,:,:,isub) = tmpdata; 0257 end 0258 0259 % Multiply by scaling factor 0260 avgdata= avgdata * 500; 0261 0262 end % if ap.compute_z 0263 0264 % 0265 % Compute the average 0266 % 0267 0268 disp('Computing average') 0269 gave_data = sum(avgdata,4) ./ sum(mask,4); 0270 0271 % 0272 % Write data to .gave file 0273 % 0274 0275 precision = 'integer*2'; 0276 disp(sprintf('Writing data to %s', outfname)) 0277 for c = 1:fhdr(NCells) 0278 fwrite(destfid, gave_data(:,:,c)', precision); 0279 end; 0280 0281 disp('Finished running make_gave.'); 0282 fclose('all'); 0283