Home > matlabmk > erplab2GND.m

erplab2GND

PURPOSE ^

erplab2GND() - Create a Mass Univariate ERP Toolbox GND struct variable from a set of

SYNOPSIS ^

function GND=erplab2GND(gui_infiles_or_tmplt,varargin)

DESCRIPTION ^

 erplab2GND() - Create a Mass Univariate ERP Toolbox GND struct variable from a set of
              ERPLAB *.erp files

 Usage:
  >> GND=erplab2GND(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 an ERPLAB erp file (e.g.,
                          {'visodbl01.erp','visodbl02.erp'}.  Otherwise, this
                          input should be a filename template (i.e., a string with
                          # where the subject number should be--'visodbl#.erp').
                          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.

   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 set files.
                      {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., {'Fz','Cz','Pz'}).  All other channels will
                      be ignored. You cannot use both this option and
                      'exclude_chans' (above). {default: not used, import
                      all channels}

   exp_name         - [string] Name of the experiment. {default: 'An
                      Experiment'}

   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. If no file
                      extension is given '.GND' will be added to the
                      filename.  If not specified, a GUI will be created
                      to ask for a filename. {default: not specified}

   verblevel        - An integer specifiying the amount of information you want
                      this function to provide about what it is doing during runtime.
                       Options are:
                        0 - quiet, only show errors, warnings, and EEGLAB/ERPLAB reports
                        1 - stuff anyone should probably know
                        2 - stuff you should know the first time you start working
                            with a data set {default value}
                        3 - stuff that might help you debug (show all
                            reports)

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


 Global Variables:
   VERBLEVEL - Mass Univariate ERP Toolbox level of verbosity (i.e., tells 
               functions how much to report about what they're doing during
               runtime) set by the optional function argument 'verblevel'

 Notes:
 -The GND fields odelay, cals, and condesc are specific to Kutaslab data.
 Other labs should be able to ignore them.

 Author:
 David Groppe
 Kutaslab, 11/2010

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % erplab2GND() - Create a Mass Univariate ERP Toolbox GND struct variable from a set of
0002 %              ERPLAB *.erp files
0003 %
0004 % Usage:
0005 %  >> GND=erplab2GND(gui_infiles_or_tmplt,varargin);
0006 %
0007 % Required Inputs:
0008 %   gui_infiles_or_tmplt - ['gui', a cell array of strings, or a string template]
0009 %                          If 'gui', a GUI is created that allows you to select
0010 %                          which average files to import (this is probably the
0011 %                          easiest way to import files).  If a cell array of
0012 %                          of strings, each element of the cell array should
0013 %                          contain the filename of an ERPLAB erp file (e.g.,
0014 %                          {'visodbl01.erp','visodbl02.erp'}.  Otherwise, this
0015 %                          input should be a filename template (i.e., a string with
0016 %                          # where the subject number should be--'visodbl#.erp').
0017 %                          If you provide a template, you must use the option
0018 %                          'sub_ids' (see below) to specify the ID numbers of
0019 %                          each subject. Include the files' path unless the files
0020 %                          are in the current working directory.
0021 %
0022 %
0023 % Optional Inputs:
0024 %   sub_ids          - [integer vector] A set of integers specifying the
0025 %                      subject ID numbers to include in the grand average.
0026 %                      Only necessary if a filename template is given as
0027 %                      the input to gui_infiles_or_tmplt.
0028 %
0029 %   bsln             - [vector] A pair of numbers (in milliseconds)
0030 %                      specifying the start and end times of the ERP baseline
0031 %                      window.  The mean voltage in the baseline window will
0032 %                      be removed from each ERP. {default: use all time
0033 %                      points before time 0).
0034 %
0035 %   use_bins         - [integer vector] A set of integers specifying which
0036 %                      bins to import into MATLAB.  If not specified, all
0037 %                      bins will be imported. Note, if you import only a
0038 %                      subset of bins, the bin numberings will start at 1
0039 %                      and run to the number you've imported (i.e., the may
0040 %                      differ from the bin numbers in the set files.
0041 %                      {default: import all bins}
0042 %
0043 %   exclude_chans    - A cell array of channel labels to exclude from the
0044 %                      importation (e.g., {'A2','lle','rhe'}). You cannot
0045 %                      use both this option and 'include_chans' (below).{default:
0046 %                      not used, import all channels}
0047 %
0048 %   include_chans    - A cell array specifying a subset of channel labels to import
0049 %                      (e.g., {'Fz','Cz','Pz'}).  All other channels will
0050 %                      be ignored. You cannot use both this option and
0051 %                      'exclude_chans' (above). {default: not used, import
0052 %                      all channels}
0053 %
0054 %   exp_name         - [string] Name of the experiment. {default: 'An
0055 %                      Experiment'}
0056 %
0057 %   out_fname        - [string] Filename to save GND variable to.  If empty
0058 %                      (i.e., not specified), a GUI will be created to prompt
0059 %                      you for a filename. If the string 'no save', the GND
0060 %                      variable will not be saved to disk. If no file
0061 %                      extension is given '.GND' will be added to the
0062 %                      filename.  If not specified, a GUI will be created
0063 %                      to ask for a filename. {default: not specified}
0064 %
0065 %   verblevel        - An integer specifiying the amount of information you want
0066 %                      this function to provide about what it is doing during runtime.
0067 %                       Options are:
0068 %                        0 - quiet, only show errors, warnings, and EEGLAB/ERPLAB reports
0069 %                        1 - stuff anyone should probably know
0070 %                        2 - stuff you should know the first time you start working
0071 %                            with a data set {default value}
0072 %                        3 - stuff that might help you debug (show all
0073 %                            reports)
0074 %
0075 % Output:
0076 %   GND  - Struct variable containing grand averages, individual subject
0077 %          ERPs, mass t-test results and more.
0078 %
0079 %
0080 % Global Variables:
0081 %   VERBLEVEL - Mass Univariate ERP Toolbox level of verbosity (i.e., tells
0082 %               functions how much to report about what they're doing during
0083 %               runtime) set by the optional function argument 'verblevel'
0084 %
0085 % Notes:
0086 % -The GND fields odelay, cals, and condesc are specific to Kutaslab data.
0087 % Other labs should be able to ignore them.
0088 %
0089 % Author:
0090 % David Groppe
0091 % Kutaslab, 11/2010
0092 
0093 %%%%%%%%%%%%%%%% Revision History  %%%%%%%%%%%%%%%%%
0094 % 10/31/2010: 'use_bin' option fixed and problem with reshaping data when no
0095 % ICs are labeled as artifacts fixed-TPU
0096 %
0097 % 11/2/2010: Can now deal with condition codes for Kutaslab data (before it
0098 % assumed that all bins had a condition code of 1)
0099 %
0100 % 11/3/2010: Function now checks to make sure GND file can be written to
0101 % disk before attempting to do so.  Code courtesy of Tom Urbach.
0102 %
0103 % 4/4/2011: Made compatible with Windows.
0104 %
0105 
0106 %%%%%%%%%%%%%%%% Future Work  %%%%%%%%%%%%%%%%%
0107 %
0108 % This function needs to be modified to be able to handle ERPLAB
0109 % conventions once it gets released
0110 %
0111 % Add odelay for Kutaslab?  Currently GND.odelay=[];
0112 %
0113 % GND.indiv_traits=[]; <-make import option for this (i.e., function
0114 % should be able to import this info from text file)
0115 %
0116 % Make import option for GND.indiv_traits this (i.e., erplab2GND.m should be able to import
0117 % this info from text file)
0118 
0119 function GND=erplab2GND(gui_infiles_or_tmplt,varargin)
0120 
0121 p=inputParser;
0122 p.addRequired('gui_infiles_or_tmplt',@(x) ischar(x) || iscell(x));
0123 p.addParamValue('locfile',[],@ischar);
0124 p.addParamValue('sub_ids',[],@isnumeric);
0125 p.addParamValue('bsln',[],@(x) isnumeric(x) && length(x)==2);
0126 p.addParamValue('exp_name','An Experiment',@ischar);
0127 p.addParamValue('use_bins',[],@isnumeric);
0128 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x));
0129 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x));
0130 p.addParamValue('out_fname',[],@ischar);
0131 p.addParamValue('verblevel',[],@(x) isnumeric(x) && (length(x)==1));
0132 p.parse(gui_infiles_or_tmplt,varargin{:});
0133 
0134 
0135 global VERBLEVEL;
0136 
0137 if isempty(p.Results.verblevel),
0138     if isempty(VERBLEVEL),
0139         VERBLEVEL=2;
0140     end
0141 else
0142     VERBLEVEL=p.Results.verblevel;
0143 end
0144 
0145 
0146 %% Figure out which channels to ignore if any
0147 %But first make sure exclude & include options were not both used.
0148 if ~isempty(p.Results.include_chans) && ~isempty(p.Results.exclude_chans)
0149     error('You cannot use BOTH ''include_chans'' and ''exclude_chans'' options.');
0150 end
0151 if ischar(p.Results.exclude_chans),
0152     exclude_chans{1}=p.Results.exclude_chans;
0153 elseif isempty(p.Results.exclude_chans)
0154     exclude_chans=[];
0155 else
0156     exclude_chans=p.Results.exclude_chans;
0157 end
0158 if ischar(p.Results.include_chans),
0159     include_chans{1}=p.Results.include_chans;
0160 elseif isempty(p.Results.include_chans)
0161     include_chans=[];
0162 else
0163     include_chans=p.Results.include_chans;
0164 end
0165 
0166 
0167 %%  Select files for loading
0168 if strcmpi(gui_infiles_or_tmplt,'GUI'),
0169     loading=1;
0170     infiles=[];
0171     while loading,
0172         [neofname, inpath]=uigetfile({'*.erp','*.erp files'; ...
0173             '*.*','All Files (*.*)'},'ERPLAB erp Files to Import','MultiSelect','on');
0174         if ischar(neofname),
0175             clear infname;
0176             infname{1}=neofname; %make it a cell array for consistent syntax below
0177         else
0178             infname=neofname;
0179         end
0180         if ~inpath,
0181             if isempty(infiles),
0182                 fprintf('File selection cancelled.  Aborting erplab2GND.\n');
0183                 GND=[];
0184                 return;
0185             else
0186                 loading=0;
0187             end
0188         else
0189             if isempty(infiles),
0190                 infiles=cell(1,length(infname)); %preallocate mem
0191                 for a=1:length(infname),
0192                     infiles{a}=[inpath infname{a}];
0193                 end
0194             else
0195                 n_files=length(infiles);
0196                 ct=0;
0197                 for a=(n_files+1):(n_files+length(infname)),
0198                     ct=ct+1;
0199                     infiles{a}=[inpath infname{ct}];
0200                 end
0201             end
0202             % trigger GUI to see if user wants to load more
0203             resp=questdlg('Do you want to load more files?',...
0204                 'OUTPUT','Yes','No','Yes');
0205             if strcmpi(resp,'No'),
0206                 loading=0;
0207             end
0208         end
0209     end
0210 elseif iscell(p.Results.gui_infiles_or_tmplt)
0211     infiles=p.Results.gui_infiles_or_tmplt;
0212 else
0213     if isempty(p.Results.sub_ids)
0214         error('If gui_infiles_or_tmplt is a string filename template, you must specify the subject numbers with the argument ''sub_ids''.');
0215     elseif ~ismember('#',p.Results.gui_infiles_or_tmplt),
0216         error('The filename template %s needs to contain a # to indicate where the subject numbers go (e.g., odbl#.nrm).', ...
0217             p.Results.gui_infiles_or_tmplt);
0218     else
0219         lb_id=find(p.Results.gui_infiles_or_tmplt=='#');
0220         prefix=p.Results.gui_infiles_or_tmplt(1:(lb_id(1)-1)); %indexing lb_id by 1 in case there are multiple pound signs
0221         postfix=p.Results.gui_infiles_or_tmplt((lb_id(1)+1):end);
0222         n_infiles=length(p.Results.sub_ids);
0223         infiles=cell(1,n_infiles);
0224         for s=1:n_infiles,
0225             no_pad=[prefix num2str(p.Results.sub_ids(s)) postfix];
0226             if p.Results.sub_ids(s)<10,
0227                 padded=[prefix num2str(p.Results.sub_ids(s),'%.2d') postfix];
0228                 if ismac || isunix
0229                     %Mac or Unix OS
0230                     [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
0231                     [sNP wNP]=unix(['ls ' no_pad]); % Need wNP argument so that it isn't automatically displayed in command window
0232                     if ~sP
0233                         if ~sNP,
0234                             error('You have a file named %s and one named %s.  I don''t know which one to load!\n', ...
0235                                 padded,no_pad);
0236                         else
0237                             infiles{s}=padded;
0238                         end
0239                     else
0240                         infiles{s}=no_pad;
0241                     end
0242                 else
0243                     %Must be a PC
0244                     infiles{s}=no_pad;
0245                 end
0246             else
0247                 infiles{s}=no_pad;
0248             end
0249         end
0250     end
0251 end
0252 
0253 %Get rid of any redundant input files
0254 infiles=unique(infiles);
0255 n_infiles=length(infiles);
0256 
0257 
0258 %% Load first data set and draft GND fields
0259 ERP=load_erplab(infiles{1});
0260     
0261 [n_ERP_chans, n_pts, n_ERP_bins]=size(ERP.bindata);
0262 if ~isempty(exclude_chans),
0263     use_chans=zeros(1,n_ERP_chans);
0264     ex_ct=0;
0265     for a=1:n_ERP_chans,
0266         if ~ismember_ci(ERP.chanlocs(a).labels,exclude_chans)
0267             use_chans(a)=1;
0268         else
0269             ex_ct=ex_ct+1;
0270             ex_labels{ex_ct}=ERP.chanlocs(a).labels;
0271         end
0272     end
0273     n_chans=sum(use_chans);
0274     use_chans=find(use_chans==1);
0275     
0276     if VERBLEVEL>1,
0277         missed=setdiff_ci(exclude_chans,ex_labels);
0278         n_missed=length(missed);
0279         if n_missed,
0280             if n_missed==1,
0281                 msg=sprintf('I attempted to exclude the following channel, but it was not found:');
0282             else
0283                 msg=sprintf('I attempted to exclude the following channels, but they were not found:');
0284             end
0285             for a=1:n_missed,
0286                 msg=[msg ' ' missed{a}];
0287             end
0288             watchit(msg);
0289         end
0290     end
0291 elseif ~isempty(include_chans),
0292     use_chans=zeros(1,n_ERP_chans);
0293     in_ct=0;
0294     for a=1:n_ERP_chans,
0295         if ismember_ci(ERP.chanlocs(a).labels,include_chans)
0296             use_chans(a)=1;
0297             in_ct=in_ct+1;
0298             in_labels{in_ct}=ERP.chanlocs(a).labels;
0299         end
0300     end
0301     n_chans=sum(use_chans);
0302     use_chans=find(use_chans==1);
0303     
0304     if VERBLEVEL>1,
0305         missed=setdiff_ci(include_chans,in_labels);
0306         n_missed=length(missed);
0307         if n_missed,
0308             if n_missed==1,
0309                 msg=sprintf('I attempted to include the following channel, but it was not found:');
0310             else
0311                 msg=sprintf('I attempted to include the following channels, but they were not found:');
0312             end
0313             for a=1:n_missed,
0314                 msg=[msg ' ' missed{a}];
0315             end
0316             watchit(msg);
0317         end
0318     end
0319 else
0320     n_chans=n_ERP_chans;
0321     use_chans=1:n_chans;
0322 end
0323 
0324 %Collect bins
0325 if isempty(p.Results.use_bins),
0326     use_bins=1:n_ERP_bins;
0327     n_bins=n_ERP_bins;
0328 else
0329     %modicum of error checking
0330     if min(p.Results.use_bins)<1,
0331         error('You cannot request to import bins with indices less than 1 (e.g., "Bin -1").');
0332     elseif length(unique(p.Results.use_bins)) ~= length(p.Results.use_bins)  % TPU checking for duplicate bin numbers in use_bins
0333         error('You cannot request to import duplicate bins\n');              % TPU
0334     elseif max(p.Results.use_bins)>n_ERP_bins,
0335         error('File %s only has %d bins, but you''ve requested to import Bin %d.\n', ...
0336             infiles{1},n_ERP_bins,max(p.Results.use_bins));
0337     end
0338     use_bins=p.Results.use_bins;
0339     n_bins=length(use_bins);
0340 end
0341 
0342 GND.exp_desc=p.Results.exp_name;
0343 GND.filename=[];
0344 GND.filepath=[];
0345 GND.saved='no';
0346 GND.grands=zeros(n_chans,n_pts,n_bins)*NaN;
0347 GND.grands_stder=GND.grands;
0348 GND.grands_t=GND.grands;
0349 GND.sub_ct=zeros(1,n_bins);
0350 GND.chanlocs=ERP.chanlocs(use_chans);
0351 GND.bin_info=[];
0352 
0353 for b=1:n_bins,
0354     GND.bin_info(b).bindesc=ERP.bindescr{use_bins(b)};
0355     GND.bin_info(b).condcode=1; %Not Kutaslab data, so condition codes aren't important
0356 end
0357 
0358 %Note, Kutaslab data won't have condition descriptors
0359 GND.condesc{1}='Experiment (not cal pulses)';
0360 
0361 GND.time_pts=ERP.times;
0362 if isempty(p.Results.bsln)
0363     %use all time points before 0 or first time point
0364     GND.bsln_wind(1)=ERP.times(1);
0365     ids=find(ERP.times<0);
0366     if isempty(ids)
0367         GND.bsln_wind(2)=ERP.times(1);
0368     else
0369         GND.bsln_wind(2)=ERP.times(max(ids));
0370     end
0371 else
0372     GND.bsln_wind=p.Results.bsln;
0373 end
0374 GND.odelay=[]; 
0375 GND.srate=ERP.srate; 
0376 GND.indiv_fnames=infiles;
0377 if isempty(ERP.subject),
0378     if VERBLEVEL,
0379         fprintf('ERP file, %s, does not have a subject name. I will use the filename as the subject''s name.\n', ...
0380             infiles{1});
0381     end
0382     GND.indiv_subnames{1}=infiles{1};
0383 else
0384     GND.indiv_subnames{1}=ERP.subject;
0385 end
0386 GND.indiv_traits=[]; 
0387 GND.indiv_bin_ct=zeros(n_infiles,n_bins);
0388 GND.indiv_bin_raw_ct=zeros(n_infiles,n_bins);
0389 GND.indiv_erps=zeros(n_chans,n_pts,n_bins,n_infiles);
0390 GND.indiv_art_ics=[];
0391 GND.cals=[];
0392 GND.history=[];
0393 GND.t_tests=[];
0394 
0395 %% Loop through *.erp files
0396 sub_ct=1;
0397 for filenum=1:n_infiles,
0398     %Assume data from this subject has not been already loaded, until we learn otherwise (This is to deal with the fact that data from the same participant may be distributed among multiple erp files)
0399     if filenum>1,
0400         if VERBLEVEL,
0401             fprintf('\n\n');
0402         end
0403         ERP=load_erplab(infiles{filenum});
0404         
0405         %collect sub names
0406         if isempty(ERP.subject),
0407             if VERBLEVEL,
0408                 fprintf('ERP file, %s, does not have a subject name. I will use the filename as the subject''s name.\n', ...
0409                     infiles{filenum});
0410             end
0411             sub_name=infiles{filenum};
0412         else
0413             sub_name=ERP.subject;
0414         end
0415         ur_sub_id=0;
0416         for old_sub=1:sub_ct,
0417             if strcmpi(GND.indiv_subnames{old_sub},sub_name),
0418                 ur_sub_id=old_sub;
0419                 if VERBLEVEL
0420                     fprintf('erp file, %s, will be appended to data already loaded from Subject %s.\n', ...
0421                         infiles{filenum},GND.indiv_subnames{old_sub});
0422                 end
0423                 break;
0424             end
0425         end
0426         if ~ur_sub_id,
0427             sub_ct=sub_ct+1;
0428             sub=sub_ct;
0429             GND.indiv_subnames{sub}=sub_name;
0430         else
0431             sub=ur_sub_id;
0432         end
0433         
0434         [n_ERP_chans2, n_pts2, n_ERP_bins2]=size(ERP.bindata);
0435         
0436         %Figure out which channels to use
0437         if ~isempty(exclude_chans),
0438             use_chans=zeros(1,n_ERP_chans2);
0439             ex_ct=0;
0440             for a=1:n_ERP_chans2,
0441                 if ~ismember_ci(ERP.chanlocs(a).labels,exclude_chans)
0442                     use_chans(a)=1;
0443                 else
0444                     ex_ct=ex_ct+1;
0445                     ex_labels{ex_ct}=ERP.chanlocs(a).labels;
0446                 end
0447             end
0448             n_chans2=sum(use_chans);
0449             use_chans=find(use_chans==1);
0450             
0451             if VERBLEVEL>1,
0452                 missed=setdiff_ci(exclude_chans,ex_labels);
0453                 n_missed=length(missed);
0454                 if n_missed,
0455                     if n_missed==1,
0456                         msg=sprintf('I attempted to exclude the following channel, but it was not found:');
0457                     else
0458                         msg=sprintf('I attempted to exclude the following channels, but they were not found:');
0459                     end
0460                     for a=1:n_missed,
0461                         msg=[msg ' ' missed{a}];
0462                     end
0463                     watchit(msg);
0464                 end
0465             end
0466         elseif ~isempty(include_chans),
0467             use_chans=zeros(1,n_ERP_chans2);
0468             in_ct=0;
0469             for a=1:n_ERP_chans2,
0470                 if ismember_ci(ERP.chanlocs(a).labels,include_chans)
0471                     use_chans(a)=1;
0472                     in_ct=in_ct+1;
0473                     in_labels{in_ct}=ERP.chanlocs(a).labels;
0474                 end
0475             end
0476             n_chans2=sum(use_chans);
0477             use_chans=find(use_chans==1);
0478             
0479             if VERBLEVEL>1,
0480                 missed=setdiff_ci(include_chans,in_labels);
0481                 n_missed=length(missed);
0482                 if n_missed,
0483                     if n_missed==1,
0484                         msg=sprintf('I attempted to include the following channel, but it was not found:');
0485                     else
0486                         msg=sprintf('I attempted to include the following channels, but they were not found:');
0487                     end
0488                     for a=1:n_missed,
0489                         msg=[msg ' ' missed{a}];
0490                     end
0491                     watchit(msg);
0492                 end
0493             end
0494             
0495         else
0496             n_chans2=n_ERP_chans2;
0497             use_chans=1:n_chans2;
0498         end
0499         
0500         %Check for consistency with GND
0501         if ERP.srate~=GND.srate,
0502             error('File %s has a different sampling rate than file %s.\n', ...
0503                 infiles{1},infiles{filenum});
0504         end
0505         if n_chans2~=n_chans,
0506             error('File %s has a different number of channels to import than file %s.\n', ...
0507                 infiles{1},infiles{filenum});
0508         end
0509         if n_pts2~=n_pts,
0510             error('File %s has a different number of time points than file %s.\n', ...
0511                 infiles{1},infiles{filenum});
0512         end
0513         if ~min(ERP.times==GND.time_pts),
0514             error('The epochs in file %s begin and end at different times than file %s.\n', ...
0515                 infiles{1},infiles{filenum});
0516         end
0517         if isempty(p.Results.use_bins),
0518             if n_ERP_bins2~=n_bins,
0519                 error('File %s has a different number of bins than file %s.\n', ...
0520                     infiles{1},infiles{filenum});
0521             end
0522         else
0523             if max(p.Results.use_bins)>n_ERP_bins2,
0524                 error('File %s only has %d bins, but you''ve requested to import Bin %d.\n', ...
0525                     infiles{filenum},n_ERP_bins2,max(p.Results.use_bins));
0526             end
0527         end
0528      
0529         bin_ct=0;
0530         for b=use_bins,
0531             bin_ct=bin_ct+1;
0532             if ~strcmpi(GND.bin_info(bin_ct).bindesc,ERP.bindescr{b}),
0533                 error('The #%d imported bin in file %s is different than that of file %s.\n', ...
0534                     b,infiles{1},infiles{filenum});
0535             end
0536         end
0537         try
0538             [fs1, fs2, er]=comp_struct_quiet(GND.chanlocs,ERP.chanlocs(use_chans));
0539         catch
0540             error('File %s''s imported channel location information differs from that of file %s.\n', ...
0541                 infiles{1},infiles{filenum});
0542         end
0543         if ~isempty(er),
0544             error('File %s''s imported channel location information differs from that of file %s.\n', ...
0545                 infiles{1},infiles{filenum});
0546         end
0547     else
0548         sub=sub_ct; %for first erp file, sub=1 (since sub_ct=1)
0549     end
0550     
0551     %No information about which (if any) ICs were removed are available in
0552     %ERP variables
0553     GND.indiv_art_ics{filenum}=NaN;
0554     
0555     %baseline data (if not already baselined by ics_removed)
0556     if ~isempty(GND.bsln_wind),
0557         bsln_pts(1)=find_tpt(GND.bsln_wind(1),ERP.times);
0558         bsln_pts(2)=find_tpt(GND.bsln_wind(2),ERP.times);
0559         if VERBLEVEL>=2,
0560             fprintf('Baselining data by removing mean EEG between %d and %d ms (time points %d and %d).\n', ...
0561                 GND.bsln_wind(1),GND.bsln_wind(2),bsln_pts(1),bsln_pts(2));
0562         end
0563         
0564         [temp_chans temp_tpts temp_bins]=size(ERP.bindata);
0565         ERP.bindata=rmbase(ERP.bindata,temp_tpts,bsln_pts(1):bsln_pts(2));
0566         ERP.bindata=reshape(ERP.bindata,temp_chans,temp_tpts,temp_bins);
0567     end
0568     
0569     %Copy over individual ERPs and trial counts
0570     GND.indiv_erps(:,:,:,sub)=ERP.bindata(use_chans,:,use_bins);
0571     GND.indiv_bin_raw_ct(sub,:)=ERP.ntrials.accepted(use_bins)+ERP.ntrials.rejected(use_bins);
0572     GND.indiv_bin_ct(sub,:)=ERP.ntrials.accepted(use_bins);
0573 end %filenum loop
0574 
0575 
0576 %remove unused elements of GND variable (if any), because there are fewer
0577 %subjects than erp files
0578 GND.indiv_bin_ct=GND.indiv_bin_ct(1:sub_ct,:);
0579 GND.indiv_bin_raw_ct=GND.indiv_bin_raw_ct(1:sub_ct,:);
0580 GND.indiv_erps=GND.indiv_erps(:,:,:,1:sub_ct);
0581 
0582 %Report # of trials per bin and count # of subjects who contribute to each
0583 %bin
0584 for sub=1:sub_ct,
0585     if VERBLEVEL>1
0586         fprintf('\nTrials per bin for Subject %s:\n',GND.indiv_subnames{sub});
0587     end
0588     for b=1:n_bins,
0589         bin_ct=GND.indiv_bin_ct(sub,b);
0590         if bin_ct,
0591             if VERBLEVEL>1,
0592                 fprintf('Bin %d (%s): %d trials\n',b,GND.bin_info(b).bindesc,bin_ct);
0593             end
0594             GND.sub_ct(b)=GND.sub_ct(b)+1;
0595         else
0596             watchit(sprintf('Subject %s has no epochs that fall into bin %d.',GND.indiv_subnames{sub},b));
0597             GND.indiv_erps(:,:,b,sub)=GND.indiv_erps(:,:,b,sub)*NaN;
0598         end
0599     end
0600 end
0601 
0602 %Baseline individual ERPs/cal pulses and compute grands
0603 if VERBLEVEL>1,
0604     fprintf('\n\n'); %add a couple lines between between counts and baselining info
0605 end
0606 GND=baselineGND(GND,GND.bsln_wind);% This line actually computes the grand average ERPs. It doesn't just baseline them.
0607 
0608 
0609 %% Save GND variable
0610 if isempty(p.Results.out_fname),
0611     %Create GUI
0612     [jname, jpath]=uiputfile({'*.GND','*.GND files'; ...
0613         '*','All files'},'Save GND variable as:','untitled.GND');
0614     if ~jpath,
0615         fprintf('Output filename selection cancelled.  GND variable NOT saved to disk.\n');
0616     else
0617         %test to make sure file can be created
0618         isW=isWriteable([jpath jname]);
0619         if isW,
0620             GND=save_matmk(GND,jname,jpath,1); % 1 means that user won't be asked again about saving file
0621         else
0622             fprintf('GND file could not be saved, but should still exist in MATLAB workspace.');
0623         end
0624     end
0625 elseif ~strcmpi(p.Results.out_fname,'no save'),
0626     [jpath, jname]=pathNname(p.Results.out_fname);
0627     %Add .GND extension if no extension given
0628     if ~ismember('.',jname),
0629         jname=[jname '.GND'];
0630     end
0631     GND=save_matmk(GND,jname,jpath);
0632 end
0633 
0634 
0635 function isW = isWriteable(inFile)
0636 % Function checks to make sure "inFile" can be written to disk. "inFile" is
0637 % not modified by the function.
0638 %
0639 % Author: Tom Urbach
0640 %
0641 
0642 isW = 0;
0643 [fid, message] = fopen(inFile,'a+');
0644 if (fid ~= -1)
0645     isW = 1;
0646     fclose(fid);
0647 else
0648     fprintf('Error opening %s: %s\n', inFile, message);
0649 end
0650 
0651 function ERP=load_erplab(filename)
0652 %function ERP=load_erplab(filename)
0653 %
0654 % Function for loading ERPLAB *.erp files (which should consist of a single
0655 % variable called ERP).
0656 %
0657 
0658 load(filename,'-MAT');
0659 if ~exist('ERP','var'),
0660    error('File %s does not contain a variable named "ERP".',filename); 
0661 end
0662 if ~isfield(ERP,'bindescr')
0663     error('The "ERP" variable in file %s does not appear to have been produced by ERPLAB.',filename);
0664 end
0665 
0666 function yesno=ismember_ci(str,str_array)
0667 % function yesno=ismember_ci(str,str_array)
0668 % A case insensitive version of ismember.m but just for strings
0669 %
0670 % Inputs:
0671 %  str       - a string
0672 %  str_array - a cell array of strings
0673 %
0674 % Outputs:
0675 %  yesno - 1 if str is a member of str_array.  0 otherwise.  Comparison is
0676 %          not case sensitive.
0677 
0678 yesno=0;
0679 n_str=length(str_array);
0680 
0681 for a=1:n_str,
0682     if strcmpi(str,str_array{a})
0683        yesno=1;
0684        break;
0685     end
0686 end
0687 
0688 function dif_str=setdiff_ci(superset,subset)
0689 %function dif_str=setdiff_ci(superset,subset)
0690 %
0691 % Inputs:
0692 %   superset - an cell array of strings
0693 %   subset   - an cell array of strings
0694 %
0695 % Outputs:
0696 %   dif_str - a cell array of the strings that are in superset but NOT
0697 %             subset. Comparison is not case sensitive.
0698 %
0699 
0700 n_super=length(superset);
0701 n_sub=length(subset);
0702 dif_ct=0;
0703 dif_str=[];
0704 for a=1:n_super,
0705     found=0;
0706     for b=1:n_sub,
0707         if strcmpi(superset{a},subset{b}),
0708             found=1;
0709             break
0710         end
0711     end
0712     if ~found,
0713        dif_ct=dif_ct+1;
0714        dif_str{dif_ct}=superset{a};
0715     end
0716 end

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