Home > matlabmk > avgs2GND_nobase.m

avgs2GND_nobase

PURPOSE ^

avgs2GND() - Create a MATLABmk GND struct variable from a set of

SYNOPSIS ^

function GND=avgs2GND_nobase(gui_infiles_or_tmplt,varargin)

DESCRIPTION ^

 avgs2GND() - Create a MATLABmk GND struct variable from a set of
              Kutaslab ERP files (e.g., files that end in *.nrm) and text
              file indicating electrode positions.

 Usage:
  >> GND=avgs2GND(gui_infiles_or_tmplt,varargin);

 Required Inputs:
   gui_infiles_or_tmplt - ['gui', a cell array of strings, or a string template]
                          If 'gui', a GUI is created that allows you to select
                          which average files to import (this is probably the
                          easiest way to import files).  If a cell array of 
                          of strings, each element of the cell array should 
                          contain the filename of a Kutaslab ERP file (e.g., 
                          {'visodbl01.nrm','visodbl02.nrm'}.  Otherwise, this 
                          input should be filename template (i.e., a string with
                          # where the subject number should be--'visodbl#.nrm').  
                          If you provide a template, you must use the option
                          'sub_ids' (see below) to specify the ID numbers of
                          each subject. Include the files' path unless the files 
                          are in the current working directory.


 Optional Inputs:
   sub_ids          - [integer vector] A set of integers specifying the
                      subject ID numbers to include in the grand average.  
                      Only necessary if a filename template is given as 
                      the input to gui_infiles_or_tmplt.

   locfile          - A text file specifying electrode coordinates according
                      to EEGLAB spherical coordinate conventions. See
                      /usr/local/matlab-toolboxes/matlabmk/demo_files/mk32.loc or
                      /usr/local/matlab-toolboxes/matlabmk/demo_files/mk64.loc  
                      for examples. The order of the channels should match
                      that of the header in the Kutaslab average files
                      (i.e., the order of the channel labels shown when
                      you run headinfo on the average file). If you do NOT
                      specify a locfile, the function will try to assign
                      default electrode coordinates based on standard
                      Kutaslab channel names (e.g., 'MiCe','LLOc','heog').
                      In addition to the standard cap channel names, the
                      following loose lead names are recognized by this
                      function.  Note, channel matching is not case 
                      sensitive (e.g., 'lle' is the same as 'LLE').
                      {default: try to match channel names to standard
                      coordinates}
                       'A2'=Left Mastoid
                       'lle' or 'LLEy'=Left Lower Eye
                       'rle' or 'RLEy'=Right Lower Eye
                       'lhe', 'lhz', 'lhrz', or 'LHEy'=Left Horizontal Eye
                       'rhe', 'rhz', 'rhrz', or 'RHEy'=Right Horizontal Eye
                       'HE' or 'heog'=Horizontal Eye Montage (e.g., lhe-rhe)
                       'VE' or 'veog'=Vertical Eye Montage (e.g., lle-rle)

   bsln             - [vector] A pair of numbers (in milliseconds)
                      specifying the start and end times of the ERP baseline 
                      window.  The mean voltage in the baseline window will
                      be removed from each ERP. {default: use all time 
                      points before time 0).

   use_bins         - [integer vector] A set of integers specifying which
                      bins to import into MATLAB.  If not specified, all 
                      bins will be imported. Note, if you import only a 
                      subset of bins, the bin numberings will start at 1 
                      and run to the number you've imported (i.e., the may
                      differ from the bin numbers in the average file. 
                      {default: import all bins}

   exclude_chans    - A cell array of channel labels to exclude from the
                      permutation test (e.g., {'A2','lle','rhe'}). You cannot
                      use both this option and 'include_chans' (below).{default:
                      not used, import all channels}

   include_chans    - A cell array of channel labels to use in the permutation
                      test (e.g., {'A2','lle','rhe'}).  All other channels will
                      be ignored. You cannot use both this option and 
                      'exclude_chans' (above). {default: not used, import 
                      all channels}

   out_fname        - [string] Filename to save GND variable to.  If empty
                      (i.e., not specified), a GUI will be created to prompt
                      you for a filename. If the string 'no save', the GND 
                      variable will not be saved to disk.  

 Output:
   GND  - Struct variable containing grand averages, individual subject
          ERPs, permutation test results and more.

 Notes:
 -Bin 0 is assumed to be cal pulses and is stored as a separate field
 in GND (it is not stored as a bin).  Consequently, bin indexing starts at 
 1 (not 0 like in the lab).

 Author:
 David Groppe
 Kutaslab, 3/2010

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function GND=avgs2GND_nobase(gui_infiles_or_tmplt,varargin)
0002 % avgs2GND() - Create a MATLABmk GND struct variable from a set of
0003 %              Kutaslab ERP files (e.g., files that end in *.nrm) and text
0004 %              file indicating electrode positions.
0005 %
0006 % Usage:
0007 %  >> GND=avgs2GND(gui_infiles_or_tmplt,varargin);
0008 %
0009 % Required Inputs:
0010 %   gui_infiles_or_tmplt - ['gui', a cell array of strings, or a string template]
0011 %                          If 'gui', a GUI is created that allows you to select
0012 %                          which average files to import (this is probably the
0013 %                          easiest way to import files).  If a cell array of
0014 %                          of strings, each element of the cell array should
0015 %                          contain the filename of a Kutaslab ERP file (e.g.,
0016 %                          {'visodbl01.nrm','visodbl02.nrm'}.  Otherwise, this
0017 %                          input should be filename template (i.e., a string with
0018 %                          # where the subject number should be--'visodbl#.nrm').
0019 %                          If you provide a template, you must use the option
0020 %                          'sub_ids' (see below) to specify the ID numbers of
0021 %                          each subject. Include the files' path unless the files
0022 %                          are in the current working directory.
0023 %
0024 %
0025 % Optional Inputs:
0026 %   sub_ids          - [integer vector] A set of integers specifying the
0027 %                      subject ID numbers to include in the grand average.
0028 %                      Only necessary if a filename template is given as
0029 %                      the input to gui_infiles_or_tmplt.
0030 %
0031 %   locfile          - A text file specifying electrode coordinates according
0032 %                      to EEGLAB spherical coordinate conventions. See
0033 %                      /usr/local/matlab-toolboxes/matlabmk/demo_files/mk32.loc or
0034 %                      /usr/local/matlab-toolboxes/matlabmk/demo_files/mk64.loc
0035 %                      for examples. The order of the channels should match
0036 %                      that of the header in the Kutaslab average files
0037 %                      (i.e., the order of the channel labels shown when
0038 %                      you run headinfo on the average file). If you do NOT
0039 %                      specify a locfile, the function will try to assign
0040 %                      default electrode coordinates based on standard
0041 %                      Kutaslab channel names (e.g., 'MiCe','LLOc','heog').
0042 %                      In addition to the standard cap channel names, the
0043 %                      following loose lead names are recognized by this
0044 %                      function.  Note, channel matching is not case
0045 %                      sensitive (e.g., 'lle' is the same as 'LLE').
0046 %                      {default: try to match channel names to standard
0047 %                      coordinates}
0048 %                       'A2'=Left Mastoid
0049 %                       'lle' or 'LLEy'=Left Lower Eye
0050 %                       'rle' or 'RLEy'=Right Lower Eye
0051 %                       'lhe', 'lhz', 'lhrz', or 'LHEy'=Left Horizontal Eye
0052 %                       'rhe', 'rhz', 'rhrz', or 'RHEy'=Right Horizontal Eye
0053 %                       'HE' or 'heog'=Horizontal Eye Montage (e.g., lhe-rhe)
0054 %                       'VE' or 'veog'=Vertical Eye Montage (e.g., lle-rle)
0055 %
0056 %   bsln             - [vector] A pair of numbers (in milliseconds)
0057 %                      specifying the start and end times of the ERP baseline
0058 %                      window.  The mean voltage in the baseline window will
0059 %                      be removed from each ERP. {default: use all time
0060 %                      points before time 0).
0061 %
0062 %   use_bins         - [integer vector] A set of integers specifying which
0063 %                      bins to import into MATLAB.  If not specified, all
0064 %                      bins will be imported. Note, if you import only a
0065 %                      subset of bins, the bin numberings will start at 1
0066 %                      and run to the number you've imported (i.e., the may
0067 %                      differ from the bin numbers in the average file.
0068 %                      {default: import all bins}
0069 %
0070 %   exclude_chans    - A cell array of channel labels to exclude from the
0071 %                      permutation test (e.g., {'A2','lle','rhe'}). You cannot
0072 %                      use both this option and 'include_chans' (below).{default:
0073 %                      not used, import all channels}
0074 %
0075 %   include_chans    - A cell array of channel labels to use in the permutation
0076 %                      test (e.g., {'A2','lle','rhe'}).  All other channels will
0077 %                      be ignored. You cannot use both this option and
0078 %                      'exclude_chans' (above). {default: not used, import
0079 %                      all channels}
0080 %
0081 %   out_fname        - [string] Filename to save GND variable to.  If empty
0082 %                      (i.e., not specified), a GUI will be created to prompt
0083 %                      you for a filename. If the string 'no save', the GND
0084 %                      variable will not be saved to disk.
0085 %
0086 % Output:
0087 %   GND  - Struct variable containing grand averages, individual subject
0088 %          ERPs, permutation test results and more.
0089 %
0090 % Notes:
0091 % -Bin 0 is assumed to be cal pulses and is stored as a separate field
0092 % in GND (it is not stored as a bin).  Consequently, bin indexing starts at
0093 % 1 (not 0 like in the lab).
0094 %
0095 % Author:
0096 % David Groppe
0097 % Kutaslab, 3/2010
0098 
0099 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%%
0100 %
0101 % 3/9/10 Added 'use_bins' option and code now automatically checks to see
0102 % if it should pad subject ids less than 10 with a 0 in filenames (e.g.,
0103 % odbl02.nrm).  It looks to see if the padded or non-padded files exist, and
0104 % then takes the one that exists. I also got rid of carriage return at end
0105 % of condition descriptors. -DG
0106 %
0107 % 3/9/11 Added 'include_chans' and 'exclude_chans' option.  Added GUI for
0108 % specifying filenames.  Added save option/GUI. -DG
0109 %
0110 
0111 %%%%%%%%%%%%%%%% Future Work  %%%%%%%%%%%%%%%%%
0112 %
0113 % Make a GUI for the code (esp for adding files)
0114 %
0115 % ?? If any input files are not found, ask if user wants to continue
0116 % without them? (currently it just aborts)
0117 %
0118 % ?? add more comments about GND output
0119 %
0120 % make it possible to import subject traits (e.g., age, median RT) from
0121 % text file
0122 
0123 % global VERBLEVEL; ?? uncomment once VERBLEVEL is working
0124 
0125 p=inputParser;
0126 p.addRequired('gui_infiles_or_tmplt',@(x) ischar(x) || iscell(x));
0127 p.addParamValue('locfile',[],@ischar);
0128 p.addParamValue('sub_ids',[],@isnumeric);
0129 p.addParamValue('bsln',[],@(x) isnumeric(x) && length(x)==2);
0130 p.addParamValue('use_bins',[],@isnumeric);
0131 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x));
0132 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x));
0133 p.addParamValue('out_fname',[],@ischar);
0134 p.parse(gui_infiles_or_tmplt,varargin{:});
0135 
0136 %Figure out which channels to ignore if any
0137 %But first make sure exclude & include options were not both used.
0138 if ~isempty(p.Results.include_chans) && ~isempty(p.Results.exclude_chans)
0139     error('You cannot use BOTH ''include_chans'' and ''exclude_chans'' options.');
0140 end
0141 if ischar(p.Results.exclude_chans),
0142     exclude_chans{1}=p.Results.exclude_chans;
0143 elseif isempty(p.Results.exclude_chans)
0144     exclude_chans=[];
0145 else
0146     exclude_chans=p.Results.exclude_chans;
0147 end
0148 if ischar(p.Results.include_chans),
0149     include_chans{1}=p.Results.include_chans;
0150 elseif isempty(p.Results.include_chans)
0151     include_chans=[];
0152 else
0153     include_chans=p.Results.include_chans;
0154 end
0155 
0156 % ?? add verblevel option ?
0157 % ?? add example
0158 
0159 VERBLEVEL=2;
0160 
0161 %Initialize GND
0162 GND.exp_desc=[]; %change from experiment name ??
0163 GND.filename=[];
0164 GND.filepath=[];
0165 GND.n_groups=1;
0166 GND.saved='no';
0167 GND.grands=[];   % <-grand average ERPs (chan x time point x  bin)
0168 GND.grands_stder=[]; % <-standard error of grand average ERPs (chan x time point x  bin)
0169 GND.grands_t=[]; %<-grand average ERPs as t-scores (chan x time point x  bin)
0170 GND.sub_ct=[]; %[37 37 37 37] <-number of subjects contributing to each bin
0171 if ~isempty(p.Results.locfile), %load chans from locfile using EEGLAB function
0172     GND.chanlocs=readlocs(p.Results.locfile,'filetype','loc');
0173     n_chanlocs=length(GND.chanlocs);
0174     use_chanlocs=ones(1,n_chanlocs);
0175     for a=1:n_chanlocs,
0176        use_chan_labels{a}=GND.chanlocs(a).labels; 
0177     end
0178     if ~isempty(exclude_chans),
0179         for a=1:length(exclude_chans),
0180             found=0;
0181             for b=1:n_chanlocs,
0182                 if ismember(GND.chanlocs(b).labels,exclude_chans{a}),
0183                     found=1;
0184                     use_chanlocs(b)=0;
0185                     verbreport(sprintf('Not importing channel %s.',exclude_chans{a}),2,VERBLEVEL);
0186                 end
0187             end
0188             if ~found,
0189                verbreport(sprintf('I attempted to exclude channel %s, but no such channel exists in your loc file.', ...
0190                    exclude_chans{a}),2,VERBLEVEL);
0191             end
0192         end
0193         verbreport(sprintf('All other channels in locfile will be imported.'),2,VERBLEVEL);
0194     elseif ~isempty(include_chans),
0195         use_chanlocs=zeros(1,n_chanlocs);
0196         for a=1:length(include_chans),
0197             found=0;
0198             for b=1:n_chanlocs,
0199                 if ismember(GND.chanlocs(b).labels,include_chans{a}),
0200                     found=1;
0201                     use_chanlocs(b)=1;
0202                     verbreport(sprintf('Importing channel %s.',include_chans{a}),2,VERBLEVEL);
0203                 end
0204             end
0205             if ~found,
0206                 verbreport(sprintf('I attempted to include channel %s, but no such channel exists in your loc file.', ...
0207                     include_chans{a}),2,VERBLEVEL);
0208             end
0209         end
0210         verbreport(sprintf('All other channels in locfile will NOT be imported.'),2,VERBLEVEL);
0211     end
0212     GND.chanlocs=GND.chanlocs(find(use_chanlocs));
0213     use_chan_labels=cell(1,sum(use_chanlocs));
0214     n_use_chans=sum(use_chanlocs);
0215     for a=1:n_use_chans,
0216         use_chan_labels{a}=GND.chanlocs(a).labels;
0217     end
0218 else
0219     GND.chanlocs=struct([]);
0220 end
0221 %GND.bindesc=[]; % Bin descriptors<-now added into GND.bin_info
0222 GND.bin_info=[];
0223 GND.condesc=[]; % One entry for each condition code
0224 %GND.condcode=[]; % One entry for each bin<-now added into GND.bin_info
0225 GND.time_pts=[]; % [1x256 double] <-peri-event time in ms for each time point
0226 GND.bsln_wind=[];
0227 GND.odelay=[];
0228 GND.srate=NaN;
0229 GND.indiv_fnames=[]; % {1x37 cell }<-filenames of *.set or *.avg files from which grands were derived
0230 GND.indiv_subnames=[]; 
0231 GND.indiv_traits=[]; % traits useful for analzing individual differences (e.g., age, WM span)
0232 GND.indiv_bin_ct=[]; % [37x3 double] <-# of trials per participant contributed to each bin
0233 GND.indiv_bin_raw_ct=[]; % [37x3 double] <-# of trials per participant records each bin (includes trials polluted by artifacts)
0234 GND.indiv_erps=[]; % [4-D double] <-individual participant ERPs (chan x time point x  bin x participant)
0235 GND.indiv_art_ics=[]; %indiv_art_ics: {1x37 cell} <-artifact independent components that were removed from each participant's data
0236 GND.cals.indiv_cals=[];
0237 GND.cals.indiv_cal_ct=[];
0238 GND.cals.grand_cals=[];
0239 GND.history=[];
0240 GND.perm_tests=[];
0241 %add option for ignoring calibration bin(s)  ??
0242 
0243 
0244 if strcmpi(gui_infiles_or_tmplt,'GUI'),
0245     loading=1;
0246     infiles=[];
0247     while loading,
0248         [neofname, inpath]=uigetfile({'*.nrf','*.nrf files'; ...
0249             '*.mas','*.mas files'; ...
0250             '*.cms','*.cms files'; ...
0251             '*.nrm','*.nrm files'; ...
0252             '*.cnm','*.cnm files'; ...
0253             '*.iccor',' *.iccor files'; ...
0254             '*.mas;*.cms','*.mas & *.cms files'; ...
0255             '*.nrm;*.cnm','*.nrm & *.cnm files'; ...
0256             '*.*','All Files (*.*)'},'Kutaslab Average Files to Import','MultiSelect','on');
0257         if ischar(neofname),
0258             clear infname;
0259             infname{1}=neofname; %make it a cell array for consistent syntax below
0260         else
0261             infname=neofname;
0262         end
0263         if ~inpath,
0264             if isempty(infiles),
0265                 fprintf('File selection cancelled.  Aborting avgs2GND.\n');
0266                 GND=[];
0267                 return;
0268             else
0269                 loading=0;
0270             end
0271         else
0272             if isempty(infiles),
0273                 infiles=cell(1,length(infname)); %preallocate mem
0274                 for a=1:length(infname),
0275                     infiles{a}=[inpath infname{a}];
0276                 end
0277             else
0278                 n_files=length(infiles);
0279                 ct=0;
0280                 for a=(n_files+1):(n_files+length(infname)),
0281                     ct=ct+1;
0282                     infiles{a}=[inpath infname{ct}];
0283                 end
0284             end
0285             % trigger GUI to see if user wants to load more
0286             resp=questdlg('Do you want to load more files?',...
0287                 'OUTPUT','Yes','No','Yes');
0288             if strcmpi(resp,'No'),
0289                 loading=0;
0290             end
0291         end
0292     end
0293 elseif iscell(p.Results.gui_infiles_or_tmplt)
0294     infiles=p.Results.gui_infiles_or_tmplt;
0295 else
0296     if isempty(p.Results.sub_ids)
0297         error('If gui_infiles_or_tmplt is a string filename template, you must specify the participant numbers with the argument ''sub_ids''.');
0298     elseif ~ismember('#',p.Results.gui_infiles_or_tmplt),
0299         error('The filename template %s need to contain a # to indicate where the participant nubmers go (e.g., odbl#.nrm).', ...
0300             p.Results.gui_infiles_or_tmplt);
0301     else
0302         lb_id=find(p.Results.gui_infiles_or_tmplt=='#');
0303         prefix=p.Results.gui_infiles_or_tmplt(1:(lb_id(1)-1)); %indexing lb_id by 1 in case there are multiple pound signs
0304         postfix=p.Results.gui_infiles_or_tmplt((lb_id(1)+1):end);
0305         n_subs=length(p.Results.sub_ids);
0306         infiles=cell(1,n_subs);
0307         for s=1:n_subs,
0308             no_pad=[prefix num2str(p.Results.sub_ids(s)) postfix];
0309             if p.Results.sub_ids(s)<10,
0310                 padded=[prefix num2str(p.Results.sub_ids(s),'%.2d') postfix];
0311                 [sP wP]=unix(['ls ' padded]); %if sp==0, then the file exists, need wP argument so that it isn't automatically displayed in command window
0312                 [sNP wNP]=unix(['ls ' no_pad]);
0313                 if ~sP
0314                     if ~sNP,
0315                         error('You have a file named %s and one named %s.  I don''t know which one to load!\n', ...
0316                             padded,no_pad);
0317                     else
0318                         infiles{s}=padded;
0319                     end
0320                 else
0321                     infiles{s}=no_pad;
0322                 end
0323             else
0324                 infiles{s}=no_pad;
0325             end
0326         end
0327     end
0328 end
0329 
0330 n_subs=length(infiles);
0331 for sub=1:n_subs,
0332     
0333     %open avg file
0334     fprintf('Opening file %s\n',infiles{sub});
0335     fid=erpio('openavg',infiles{sub});
0336     if (fid==-1)
0337         msg=erpio('get_errstr');
0338         error('Could not open file %s using erpio. According to erpio: %s', ...
0339             infiles{sub},msg);
0340     end
0341     
0342     %% Check Channel Label Compatibility
0343     n_chans=erpio('get_hdrvar',fid,'chans',1);
0344     use_chans=zeros(1,n_chans);
0345     used_chan_ct=0;
0346     % Channel locations from locfile or from initial subject
0347     if ~isempty(p.Results.locfile) || (sub>1), 
0348         for c=1:n_chans,
0349             chan_label=erpio('get_hdrvar',fid,'chndesc',c-1,1); %for chan #c, bin #1
0350             if ismember(chan_label,use_chan_labels),
0351                 used_chan_ct=used_chan_ct+1;
0352                 if ~strcmpi(GND.chanlocs(used_chan_ct).labels,chan_label),
0353                     erpio('close',fid);
0354                     error('In %s, the #%d used channel is %s.  In %s, it is %s.\n', ...
0355                         infiles{sub},used_chan_ct,chan_label,locfile,GND.chanlocs(used_chan_ct).labels);
0356                 else
0357                    use_chans(c)=1; 
0358                 end
0359             end
0360         end
0361         if sum(use_chans)~=n_use_chans,
0362             erpio('close',fid);
0363             error('File %s has a different number of channels than all previous files.', ...
0364                 infiles{sub});
0365         end
0366     else
0367         %Try to create chanlocs from library of locations for initial
0368         %subject
0369         if n_chans>=59,
0370             %Try to match with 59 channel cap "chanlocs" variable
0371             load('/usr/local/matlab-toolboxes/matlabmk/mk66locs');
0372         else
0373             %Try to match with 26 channel cap "chanlocs" variable
0374             load('/usr/local/matlab-toolboxes/matlabmk/mk33locs');
0375         end
0376         n_chanlocs=length(chanlocs);
0377         for c=1:n_chans,
0378             chan_label=erpio('get_hdrvar',fid,'chndesc',c-1,1); %for chan #c, bin #1
0379             use_chans(c)=1;
0380             if ~isempty(exclude_chans) && ismember(chan_label,exclude_chans),
0381                 use_chans(c)=0;
0382             end
0383             if ~isempty(include_chans) && ~ismember(chan_label,include_chans),
0384                 use_chans(c)=0;
0385             end
0386             if use_chans(c),
0387                 used_chan_ct=used_chan_ct+1;
0388                 %Standardize Channel Names
0389                 if strcmpi(chan_label,'lle'),
0390                     avg_label='LLEy';
0391                 elseif strcmpi(chan_label,'rle'),
0392                     avg_label='RLEy';
0393                 elseif strcmpi(chan_label,'lhe') || strcmpi(chan_label,'lhz') || ... 
0394                         strcmpi(chan_label,'lhrz'),
0395                     avg_label='LHEy';
0396                 elseif strcmpi(chan_label,'rhe') || strcmpi(chan_label,'rhz') || ...
0397                         strcmpi(chan_label,'rhrz'),
0398                     avg_label='RHEy';
0399                 elseif strcmpi(chan_label,'HE'),
0400                     avg_label='HEOG';
0401                 elseif strcmpi(chan_label,'VE'),
0402                     avg_label='VEOG';
0403                 else
0404                     avg_label=chan_label;
0405                 end
0406                 found=0;
0407                 for d=1:n_chanlocs,
0408                     if strcmpi(avg_label,chanlocs(d).labels),
0409                         if used_chan_ct==1,
0410                             GND.chanlocs=chanlocs(d); %create new struct
0411                         else
0412                             GND.chanlocs(used_chan_ct)=chanlocs(d);
0413                         end
0414                         GND.chanlocs(used_chan_ct).labels=chan_label;
0415                         found=1;
0416                     end
0417                 end
0418                 if ~found,
0419                     watchit(sprintf(['Could not find a default coordinate for channel %s. ' ...
0420                         'Giving it the bogus coordinate of a few inches in front of the nose.\n'],chan_label));
0421                     GND.chanlocs(used_chan_ct)=chanlocs(n_chanlocs); %the last electrode should be VEOG
0422                     GND.chanlocs(used_chan_ct).labels=chan_label;
0423                 end
0424             end
0425         end
0426         n_use_chans=used_chan_ct;
0427         use_chan_labels=cell(1,n_use_chans);
0428         for d=1:n_use_chans,
0429             use_chan_labels{d}=GND.chanlocs(d).labels;
0430         end
0431     end
0432     
0433     %% Check # of bins
0434     n_bins=erpio('getnbins',fid); %note bin count starts with 0 (i.e. goes from 0 to n_bins-1)
0435     if ~isempty(GND.indiv_erps),
0436         if n_bins~=total_psbl_bins,
0437              erpio('close',fid);
0438              error('File %s has %d bins.  The previous files have %d bins (counting Bin 0, which should contain cal pulses).', ...
0439                  infiles{sub},n_bins,total_psbl_bins);
0440         end
0441     end
0442     if sub==1,
0443         if isempty(p.Results.use_bins),
0444             use_bins=1:(n_bins-1);
0445         else
0446             use_bins=p.Results.use_bins;
0447         end
0448         total_psbl_bins=n_bins;
0449     end
0450     
0451     %% Check Experiment Descriptor
0452     if isempty(GND.exp_desc),
0453         GND.exp_desc=erpio('get_hdrvar',fid,'expdesc',1);
0454     else
0455         neo_desc=erpio('get_hdrvar',fid,'expdesc',1);
0456         if ~strcmpi(GND.exp_desc,neo_desc),
0457             watchit(sprintf('The experiment descriptor for file %s is %s.\nUsing initial descriptor: %s.\n', ...
0458                 infiles{sub},neo_desc,GND.exp_desc));
0459         end
0460     end
0461     
0462     %% Create/Check Bin Descriptor
0463     if sub==1,
0464         %write bindesc
0465         bin_ct=0;
0466         for b=use_bins,
0467             bin_ct=bin_ct+1;
0468             GND.bin_info(bin_ct).bindesc=erpio('get_hdrvar',fid,'bindesc',b);
0469         end
0470         GND.cals.caldesc=erpio('get_hdrvar',fid,'bindesc',0);
0471     else
0472         %check bindesc
0473         bin_ct=0;
0474         for b=use_bins,
0475             bin_ct=bin_ct+1;
0476             neo_bindesc=erpio('get_hdrvar',fid,'bindesc',b);
0477             if ~strcmpi(GND.bin_info(bin_ct).bindesc,neo_bindesc),
0478                 erpio('close',fid);
0479                 error('The bin descriptor for file %s, Bin %d is %s.  For previous file(s) it is %s.', ...
0480                     infiles{sub},b,neo_bindesc,GND.bin_info(bin_ct).bindesc);
0481             end
0482         end
0483         %cal pulse bin
0484         neo_bindesc=erpio('get_hdrvar',fid,'bindesc',0);
0485         if ~strcmpi(GND.cals.caldesc,neo_bindesc),
0486             erpio('close',fid);
0487             error('The bin descriptor for file %s, Bin %d is %s.  For previous file(s) it is %s.', ...
0488                 infiles{sub},0,neo_bindesc,GND.cals.caldesc);
0489         end
0490     end
0491   
0492     %% Create/Check Condition Codes
0493     if sub==1,
0494         %write condition codes
0495         bin_ct=0;
0496         for b=use_bins,
0497             bin_ct=bin_ct+1;
0498             GND.bin_info(bin_ct).condcode=erpio('get_hdrvar',fid,'condcode',b);
0499         end
0500         GND.cals.condcode=erpio('get_hdrvar',fid,'condcode',0);
0501     else
0502         %check condition codes
0503         bin_ct=0;
0504         for b=use_bins,
0505             bin_ct=bin_ct+1;
0506             neo_ccode=erpio('get_hdrvar',fid,'condcode',b);
0507             if neo_ccode~=GND.bin_info(bin_ct).condcode,
0508                 erpio('close',fid);
0509                 error('The condition code for Bin %d in file %s is %d.  In previous file(s) it is %d.', ...
0510                     b,infiles{sub},neo_ccode,GND.bin_info(bin_ct).condcode);
0511             end
0512         end
0513         %cal pulse condition code
0514         neo_ccode=erpio('get_hdrvar',fid,'condcode',0);
0515         if neo_ccode~=GND.cals.condcode,
0516             erpio('close',fid);
0517             error('The condition code for Bin 0 in file %s is %d.  In previous file(s) it is %d.', ...
0518                 infiles{sub},neo_ccode,GND.cals.condcode);
0519         end
0520     end
0521     
0522     %% Check Condition Code Descriptor
0523     if isempty(GND.condesc),
0524         %Create condition code descriptor field
0525         
0526         %cal pulse condition code descriptor
0527         GND.cals.condesc=erpio('get_hdrvar',fid,'condesc',0);
0528         
0529         if sum(use_bins>1),
0530             %write condition code descriptors for ERP bins
0531             n_ccode=1;
0532             GND.condesc{n_ccode}=erpio('get_hdrvar',fid,'condesc',use_bins(1));
0533             if length(use_bins)>1,
0534                 for b=use_bins(2:end),
0535                     neo_ccdesc=erpio('get_hdrvar',fid,'condesc',b);
0536                     if ~strcmpi(neo_ccdesc,GND.condesc{n_ccode}),
0537                         n_ccode=n_ccode+1;
0538                         GND.condesc{n_ccode}=neo_ccdesc;
0539                     end
0540                 end
0541             end
0542         end
0543     else
0544         %Check condition code descriptor field
0545         bin_ct=0;
0546         for b=use_bins,
0547             bin_ct=bin_ct+1;
0548             neo_condesc=erpio('get_hdrvar',fid,'condesc',b);
0549             if ~strcmpi(GND.condesc{GND.bin_info(bin_ct).condcode},neo_condesc),
0550                 erpio('close',fid);
0551                 error('The condition code descriptor for file %s, Bin %d is %s.  For previous file(s) it is %s.', ...
0552                     infiles{sub},b,neo_condesc,GND.condesc{GND.bin_info(bin_ct).condcode});
0553             end
0554         end
0555         %cal pulse bin
0556         neo_condesc=erpio('get_hdrvar',fid,'condesc',0);
0557         if ~strcmpi(GND.cals.condesc,neo_condesc),
0558             erpio('close',fid);
0559             error('The condition code descriptor for file %s, Bin %d is %s.  For previous file(s) it is %s.', ...
0560                 infiles{sub},0,neo_condesc,GND.cals.condesc);
0561         end
0562     end    
0563     
0564     
0565     %% Check Time Points
0566     cprecis=erpio('get_hdrvar',fid,'cprecis',1);
0567     presamp=erpio('get_hdrvar',fid,'presampling',1);
0568     srate=100000/erpio('get_hdrvar',fid,'clktick',1);
0569     GND.srate=srate;
0570     if isempty(GND.time_pts),
0571         n_pts=cprecis*256;
0572         GND.time_pts=[0:(n_pts-1)]*1000/srate-presamp;
0573         if isempty(p.Results.bsln),
0574            bsln=[-presamp -1000/srate]; %stops right before 0
0575            fprintf('Using default baseline of %d to %d ms ', ...
0576                -presamp,-1000/srate);
0577         else
0578            bsln=p.Results.bsln; 
0579            fprintf('Using baseline of %d to %d ms ', ...
0580                bsln(1),bsln(2));
0581         end
0582         bsln_pts=[find_tpt(bsln(1),GND.time_pts):find_tpt(bsln(2),GND.time_pts)];
0583         GND.bsln_wind=[GND.time_pts(bsln_pts(1)) GND.time_pts(bsln_pts(end))];
0584         fprintf('(%d to %d in time points)\n',bsln_pts(1),bsln_pts(end));
0585     else
0586         cprecis=erpio('get_hdrvar',fid,'cprecis',1);
0587         presamp=erpio('get_hdrvar',fid,'presampling',1);
0588         srate=100000/erpio('get_hdrvar',fid,'clktick',1);
0589         neo_pts=cprecis*256;
0590         if neo_pts~=n_pts,
0591             erpio('close',fid);
0592            error('File %s has %d time points of EEG.  Previous file(s) have %d.', ...
0593                infiles{sub},neo_pts,n_pts);
0594         end
0595         neo_time_pts=[0:(n_pts-1)]*1000/srate-presamp;
0596         if sum(neo_time_pts~=GND.time_pts),
0597             erpio('close',fid);
0598             error('File %s has either a different sampling rate or prestimulus baseline than previous file(s).', ...
0599                 infiles{sub});
0600         end
0601     end
0602 
0603     %% odelay: Currently all avg files are required to have same odelay
0604     if isempty(GND.odelay),
0605         GND.odelay=erpio('get_hdrvar',fid,'odelay',1);
0606     else
0607         odelay=erpio('get_hdrvar',fid,'odelay',1);
0608         if GND.odelay~=odelay,
0609            error('File %s has an odelay of %d. Previous files have an odelay %d.', ...
0610                odelay,GND.odelay);
0611         end
0612     end
0613     
0614     
0615     %% Misc
0616     GND.indiv_fnames{sub}=infiles{sub};
0617     GND.indiv_subnames{sub}=erpio('get_hdrvar',fid,'subdesc',1);
0618 
0619     
0620     %% Initialize ERP variables
0621     n_use_bins=length(use_bins);
0622     if isempty(GND.indiv_erps),
0623         GND.grands=zeros(n_use_chans,n_pts,n_use_bins)*NaN;
0624         GND.grands_stder=GND.grands;
0625         GND.grands_t=GND.grands;
0626         GND.sub_ct=zeros(1,n_use_bins);
0627         GND.indiv_bin_ct=zeros(n_subs,n_use_bins);
0628         GND.indiv_bin_raw_ct=zeros(n_subs,n_use_bins);
0629         GND.indiv_erps=zeros(n_use_chans,n_pts,n_use_bins,n_subs)*NaN;
0630         GND.indiv_art_ics=cell(1,n_subs);
0631         GND.cals.indiv_cals=zeros(n_use_chans,n_pts,n_subs)*NaN;
0632         GND.cals.indiv_cal_ct=zeros(1,n_subs);
0633         GND.cals.grand_cals=zeros(n_use_chans,n_pts)*NaN;
0634     end
0635     
0636 
0637     %% Load ERPs
0638     pp10uv=erpio('get_hdrvar',fid,'pp10uv',1);
0639     bin_ct=0;
0640     for b=use_bins,
0641         bin_ct=bin_ct+1;
0642         GND.indiv_bin_ct(sub,bin_ct)=erpio('get_hdrvar',fid,'sums',b);
0643         GND.indiv_bin_raw_ct(sub,bin_ct)=erpio('get_hdrvar',fid,'totrawrecs',b);
0644         erps=10*erpio('readbin',fid,b)/pp10uv;
0645 %        erps=rmbase(erps(find(use_chans),:),n_pts,bsln_pts);
0646         GND.indiv_erps(:,:,bin_ct,sub)=erps;
0647     end
0648 
0649     %% Load cal pulses
0650     GND.cals.indiv_cal_ct(sub)=erpio('get_hdrvar',fid,'totrawrecs',0);
0651     erps=10*erpio('readbin',fid,0)/pp10uv;
0652 %    erps=rmbase(erps(find(use_chans),:),n_pts,bsln_pts);
0653     GND.cals.indiv_cals(:,:,sub)=erps;
0654     
0655     erpio('close',fid);
0656     %cond_code=erpio('get_hdrvar',fid,'condcode',1); %condition code for bin 1
0657     %erpio('get_hdrvar',fid,'condesc',0); %condition descriptor for condition code 0
0658     
0659 end
0660 
0661 
0662 %Average data across participants
0663 for b=1:n_use_bins,
0664     bin_subs=find(GND.indiv_bin_ct(:,b));
0665     GND.sub_ct(b)=length(bin_subs);
0666     if GND.sub_ct(b),
0667         GND.grands(:,:,b)=mean(GND.indiv_erps(:,:,b,bin_subs),4);
0668         GND.grands_stder(:,:,b)=std(GND.indiv_erps(:,:,b,bin_subs),0,4)/sqrt(GND.sub_ct(b));
0669         GND.grands_t(:,:,b)=GND.grands(:,:,b)./GND.grands_stder(:,:,b);
0670     else
0671         watchit(sprintf('No average files contribute to bin %d.',b));
0672     end
0673 end
0674 
0675 %Average cal pulses across participants
0676 GND.cals.grand_cals=mean(GND.cals.indiv_cals,3);
0677 
0678 %get rid of carriage return on bin descriptors
0679 for b=1:n_use_bins,    
0680     if (GND.bin_info(b).bindesc(end)==13)
0681         GND.bin_info(b).bindesc=GND.bin_info(b).bindesc(1: ...
0682             (length(GND.bin_info(b).bindesc)-1));
0683     end
0684 end
0685 if (GND.cals.caldesc(end)==13)
0686     GND.cals.caldesc=GND.cals.caldesc(1:(length(GND.cals.caldesc)-1));
0687 end
0688 
0689 %get rid of carriage return on condition code descriptors
0690 for b=1:length(GND.condesc),    
0691     if (GND.condesc{b}(end)==13)
0692         GND.condesc{b}=GND.condesc{b}(1:length(GND.condesc{b})-1);
0693     end
0694 end
0695 if (GND.cals.condesc(end)==13)
0696     GND.cals.condesc=GND.cals.condesc(1:(length(GND.cals.condesc)-1));
0697 end
0698 
0699 
0700 if isempty(p.Results.out_fname),
0701     %Create GUI
0702     [jname, jpath]=uiputfile({'*.GND','*.GND files'; ...
0703         '*.*','All files'},'Save GND variable as:','untitled.GND');
0704     if ~jpath,
0705         fprintf('Output filename selection cancelled.  GND variable NOT saved to disk.\n');
0706     else
0707         GND=saveGND(GND,jname,jpath,1); % 1 means that user won't be asked again about saving file
0708     end
0709 elseif ~strcmpi(p.Results.out_fname,'no save'),
0710     [jpath, jname]=pathNname(p.Results.out_fname);
0711     GND=saveGND(GND,jname,jpath);
0712 end

Generated on Tue 10-May-2016 16:37:45 by m2html © 2005