Home > matlabmk > avgs2GND.m

avgs2GND

PURPOSE ^

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

SYNOPSIS ^

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

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