set2tfr() - Creates a fieldtrip compatible MATLABmk TFR struct variable from an EEGLAB *.set files. The TFR variable contains mean spectrograms per bin. Uses the Fieldtrip function ft_freqanalysis.m. Usage: >> TFR=set2ftr(set_fname,varargin); Required Inputs: set_fname - The name of an EEGLAB *.set file from which the data to be operated on is stored. Kutaslab bin information must have been added to it via the function crw2set.m or bin_info2EEG.m. Include the file's path unless the file is in the current working directory. Optional Inputs: 'time_window' - [number] Duration (in ms) of the moving time window used to compute the spectrograms. {default: 1/4 the duration of each epoch of data} 'time_step' - [number] The delay (in ms) between each time window in the series of time windows used compute the spectrograms. Lowest possible value is 1/sampling rate. It is recommended that you don't use a time_step value greater than 50% of the moving time window duration. {default: half the duration of the moving time window} 'freq_limits' - [min max] The lowest and highest frequency (in Hz) you want included in the spectrogram. 'freq_step' - [number] The distance (in Hz) between successive frequencies. {default: approximately 1/duration of the moving time window} '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., they may differ from the bin numbers in the set files. {default: import all bins} 'units' - ['dB' or 'raw'] If 'dB', power spectra will be returned in units of decibles. If 'raw', power spectra will be in units of raw power. {default: 'dB'} '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} 'demean' - ['yes' or 'no'] If 'yes', the mean of each epoch will be removed. {default: 'yes'} 'exp_name' - [string] Name of the experiment. {default: 'An Experiment'} 'out_fname' - [string] Filename to save TFR variable to. If empty (i.e., not specified), the TFR variable will NOT be saved to disk but will be returned to the MATLAB workspace. If no file extension is given '.tfr' will be added to the 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 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: TFR - Struct variable containing power spectra and associated information (e.g., electrode locations) in a fieldtrip compatible format. Global Variables: VERBLEVEL - MATLABmk 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: -This function expects the EEG variable to have information about bins stored in it. More specifically, there needs to be (1) an EEG.bindesc field that contains a text description of each bin and (2) epochs of data labeled as bin types (e.g., 'bin1'). Bin types are stored in the field EEG.epoch(#).eventtype. Use the function bin_info2EEG.m to add bin information to an EEG variable. -ICs labeled as artifacts will be removed from the data before spectrograms are computed. This is done by the function remove_artifact_ics.m. IC labeling can be done via EEGLAB or MATLABmk functions/conventions. If both conventions appear in the EEG variable, only MATLABmk IC labels will be used. -This function is not yet compatible with ERPLAB's conventions for storing bin information. -Currently this function computes spectrograms using Fourier analysis with a Hann taper. Other options will be available in the future. Author: David Groppe Kutaslab, 1/2011
0001 % set2tfr() - Creates a fieldtrip compatible MATLABmk TFR struct variable 0002 % from an EEGLAB *.set files. The TFR variable contains mean 0003 % spectrograms per bin. Uses the Fieldtrip function 0004 % ft_freqanalysis.m. 0005 % 0006 % Usage: 0007 % >> TFR=set2ftr(set_fname,varargin); 0008 % 0009 % Required Inputs: 0010 % set_fname - The name of an EEGLAB *.set file from which the data to be 0011 % operated on is stored. Kutaslab bin information must have 0012 % been added to it via the function crw2set.m or 0013 % bin_info2EEG.m. Include the file's path unless the file is 0014 % in the current working directory. 0015 % 0016 % 0017 % Optional Inputs: 0018 % 'time_window' - [number] Duration (in ms) of the moving time 0019 % window used to compute the spectrograms. {default: 0020 % 1/4 the duration of each epoch of data} 0021 % 'time_step' - [number] The delay (in ms) between each time 0022 % window in the series of time windows used compute 0023 % the spectrograms. Lowest possible value is 0024 % 1/sampling rate. It is recommended that you don't 0025 % use a time_step value greater than 50% of the moving 0026 % time window duration. {default: half the duration of 0027 % the moving time window} 0028 % 'freq_limits' - [min max] The lowest and highest frequency (in Hz) 0029 % you want included in the spectrogram. 0030 % 'freq_step' - [number] The distance (in Hz) between successive 0031 % frequencies. {default: approximately 1/duration of 0032 % the moving time window} 0033 % 'use_bins' - [integer vector] A set of integers specifying which 0034 % bins to import into MATLAB. If not specified, all 0035 % bins will be imported. Note, if you import only a 0036 % subset of bins, the bin numberings will start at 1 0037 % and run to the number you've imported (i.e., they may 0038 % differ from the bin numbers in the set files. 0039 % {default: import all bins} 0040 % 'units' - ['dB' or 'raw'] If 'dB', power spectra will be 0041 % returned in units of decibles. If 'raw', power 0042 % spectra will be in units of raw power. {default: 0043 % 'dB'} 0044 % 'exclude_chans' - A cell array of channel labels to exclude from the 0045 % importation (e.g., {'A2','lle','rhe'}). You cannot 0046 % use both this option and 'include_chans' (below).{default: 0047 % not used, import all channels} 0048 % 0049 % 'include_chans' - A cell array specifying a subset of channel labels to import 0050 % (e.g., {'Fz','Cz','Pz'}). All other channels will 0051 % be ignored. You cannot use both this option and 0052 % 'exclude_chans' (above). {default: not used, import 0053 % all channels} 0054 % 0055 % 'demean' - ['yes' or 'no'] If 'yes', the mean of each epoch 0056 % will be removed. {default: 'yes'} 0057 % 0058 % 'exp_name' - [string] Name of the experiment. {default: 'An 0059 % Experiment'} 0060 % 0061 % 'out_fname' - [string] Filename to save TFR variable to. If empty 0062 % (i.e., not specified), the TFR variable will NOT be 0063 % saved to disk but will be returned to the MATLAB 0064 % workspace. If no file extension is given '.tfr' will 0065 % be added to the filename. {default: not specified} 0066 % 0067 % 'verblevel' - An integer specifiying the amount of information you want 0068 % this function to provide about what it is doing during runtime. 0069 % Options are: 0070 % 0 - quiet, only show errors, warnings, and EEGLAB reports 0071 % 1 - stuff anyone should probably know 0072 % 2 - stuff you should know the first time you start working 0073 % with a data set {default value} 0074 % 3 - stuff that might help you debug (show all 0075 % reports) 0076 % 0077 % Output: 0078 % TFR - Struct variable containing power spectra and associated 0079 % information (e.g., electrode locations) in a fieldtrip compatible 0080 % format. 0081 % 0082 % Global Variables: 0083 % VERBLEVEL - MATLABmk level of verbosity (i.e., tells 0084 % functions how much to report about what they're doing during 0085 % runtime) set by the optional function argument 'verblevel' 0086 % 0087 % Notes: 0088 % -This function expects the EEG variable to have information about bins 0089 % stored in it. More specifically, there needs to be (1) an EEG.bindesc 0090 % field that contains a text description of each bin and (2) epochs of data 0091 % labeled as bin types (e.g., 'bin1'). Bin types are stored in the field 0092 % EEG.epoch(#).eventtype. Use the function bin_info2EEG.m to add bin 0093 % information to an EEG variable. 0094 % 0095 % -ICs labeled as artifacts will be removed from the data before spectrograms 0096 % are computed. This is done by the function remove_artifact_ics.m. IC labeling 0097 % can be done via EEGLAB or MATLABmk functions/conventions. If both 0098 % conventions appear in the EEG variable, only MATLABmk IC labels will be used. 0099 % 0100 % -This function is not yet compatible with ERPLAB's conventions for 0101 % storing bin information. 0102 % 0103 % -Currently this function computes spectrograms using Fourier analysis 0104 % with a Hann taper. Other options will be available in the future. 0105 % 0106 % Author: 0107 % David Groppe 0108 % Kutaslab, 1/2011 0109 0110 %%%%%%%%%%%%%%%% Revision History %%%%%%%%%%%%%%%%% 0111 % 4/26/2011 - Added TFR.chanlocs field 0112 0113 %%%%%%%%%%%%%%%% Future Work %%%%%%%%%%%%%%%%% 0114 %add error check for step size and round to sampling rate ?? 0115 %add path information for tfr_fname ?? 0116 0117 0118 function TFR=set2tfr(set_fname,varargin) 0119 p=inputParser; 0120 p.addRequired('set_fname',@(x) ischar(x) || iscell(x)); 0121 p.addParamValue('time_window',[],@(x) isnumeric(x) && length(x)==1); 0122 p.addParamValue('time_step',[],@(x) isnumeric(x) && length(x)==1); 0123 p.addParamValue('freq_step',[],@(x) isnumeric(x) && length(x)==1); 0124 p.addParamValue('bsln_wind',[],@(x) isnumeric(x) && length(x)==2); 0125 p.addParamValue('bsln_type','none',@(x) ischar(x) && (strcmpi(x,'relative') || strcmpi(x,'absolute') || strcmpi(x,'none'))); 0126 p.addParamValue('use_bins',[],@isnumeric); 0127 p.addParamValue('freq_limits',[],@(x) isnumeric(x) && length(x)==2); %?? make this simply a vector of frequencies of interest? 0128 p.addParamValue('out_fname',[],@ischar); 0129 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x)); 0130 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x)); 0131 p.addParamValue('verblevel',[],@(x) isnumeric(x) && (length(x)==1)); 0132 p.addParamValue('exp_name','An Experiment',@ischar); 0133 p.addParamValue('demean','yes',@(x) strcmpi('yes',x) || strcmpi('no',x)); 0134 p.addParamValue('units','dB',@(x) ischar(x) && (strcmpi(x,'dB') || strcmpi(x,'raw'))); 0135 0136 0137 0138 p.parse(set_fname,varargin{:}); 0139 0140 0141 global EEG; %necessary for removing artifacts 0142 global VERBLEVEL; 0143 0144 if isempty(p.Results.verblevel), 0145 if isempty(VERBLEVEL), 0146 VERBLEVEL=2; 0147 end 0148 else 0149 VERBLEVEL=p.Results.verblevel; 0150 end 0151 0152 EEG=pop_loadset(set_fname); 0153 if ~isfield(EEG,'bindesc'), 0154 error('This set file doesn''t have an EEG.bindesc field containing bin information!'); 0155 end 0156 0157 [n_EEG_chans, n_tpts, n_epochs]=size(EEG.data); 0158 srate=EEG.srate; 0159 0160 %% Bin selection 0161 n_bins=length(EEG.bindesc); 0162 if isempty(p.Results.use_bins) 0163 use_bins=1:n_bins; 0164 n_use_bins=n_bins; 0165 else 0166 use_bins=p.Results.use_bins; 0167 n_use_bins=length(use_bins); 0168 if max(use_bins)>n_bins, 0169 error('This file only has %d bins, but you requested importing bin %d.\n', ... 0170 n_bins,max(use_bins)); 0171 end 0172 end 0173 0174 0175 %% Figure out which channels to ignore if any 0176 %But first make sure exclude & include options were not both used. 0177 if ~isempty(p.Results.include_chans) && ~isempty(p.Results.exclude_chans) 0178 error('You cannot use BOTH ''include_chans'' and ''exclude_chans'' options.'); 0179 end 0180 if ischar(p.Results.exclude_chans), 0181 exclude_chans{1}=p.Results.exclude_chans; 0182 elseif isempty(p.Results.exclude_chans) 0183 exclude_chans=[]; 0184 else 0185 exclude_chans=p.Results.exclude_chans; 0186 end 0187 if ischar(p.Results.include_chans), 0188 include_chans{1}=p.Results.include_chans; 0189 elseif isempty(p.Results.include_chans) 0190 include_chans=[]; 0191 else 0192 include_chans=p.Results.include_chans; 0193 end 0194 0195 if ~isempty(exclude_chans), 0196 use_chans=zeros(1,n_EEG_chans); 0197 ex_ct=0; 0198 for a=1:n_EEG_chans, 0199 if ~ismember_ci(EEG.chanlocs(a).labels,exclude_chans) 0200 use_chans(a)=1; 0201 else 0202 ex_ct=ex_ct+1; 0203 ex_labels{ex_ct}=EEG.chanlocs(a).labels; 0204 end 0205 end 0206 use_chans=find(use_chans==1); 0207 0208 if VERBLEVEL>1, 0209 missed=setdiff_ci(exclude_chans,ex_labels); 0210 n_missed=length(missed); 0211 if n_missed, 0212 if n_missed==1, 0213 msg=sprintf('I attempted to exclude the following channel, but it was not found:'); 0214 else 0215 msg=sprintf('I attempted to exclude the following channels, but they were not found:'); 0216 end 0217 for a=1:n_missed, 0218 msg=[msg ' ' missed{a}]; 0219 end 0220 watchit(msg); 0221 end 0222 end 0223 elseif ~isempty(include_chans), 0224 use_chans=zeros(1,n_EEG_chans); 0225 in_ct=0; 0226 for a=1:n_EEG_chans, 0227 if ismember_ci(EEG.chanlocs(a).labels,include_chans) 0228 use_chans(a)=1; 0229 in_ct=in_ct+1; 0230 in_labels{in_ct}=EEG.chanlocs(a).labels; 0231 end 0232 end 0233 use_chans=find(use_chans==1); 0234 0235 if VERBLEVEL>1, 0236 missed=setdiff_ci(include_chans,in_labels); 0237 n_missed=length(missed); 0238 if n_missed, 0239 if n_missed==1, 0240 msg=sprintf('I attempted to include the following channel, but it was not found:'); 0241 else 0242 msg=sprintf('I attempted to include the following channels, but they were not found:'); 0243 end 0244 for a=1:n_missed, 0245 msg=[msg ' ' missed{a}]; 0246 end 0247 watchit(msg); 0248 end 0249 end 0250 else 0251 n_chans=n_EEG_chans; 0252 use_chans=1:n_chans; 0253 end 0254 n_use_chans=length(use_chans); 0255 0256 0257 %% Intialize TFR variable 0258 TFR.bindesc=cell(1,n_use_bins); 0259 for b=1:n_use_bins, 0260 TFR.bindesc{b}=EEG.bindesc{use_bins(b)}; 0261 end 0262 TFR.exp_name=p.Results.exp_name; 0263 TFR.set_fname=set_fname; 0264 TFR.tfr_fname=p.Results.out_fname; 0265 0266 TFR.bins=cell(1,n_use_bins); %where the spectrograms will be stored 0267 TFR.bsln_wind=p.Results.bsln_wind; 0268 TFR.bsln_type=p.Results.bsln_type; 0269 TFR.units=p.Results.units; 0270 0271 % Basline error checking 0272 if ~strcmpi(TFR.bsln_type,'none') && isempty(TFR.bsln_wind), 0273 error('You specified a spectrogram baseline type of ''%s'', but you did NOT specify a baseline time window.',TFR.bsln_type); 0274 elseif strcmpi(TFR.bsln_type,'none') && ~isempty(TFR.bsln_wind), 0275 watchit(sprintf('You specified a spectrogram baseline type of ''none'', but yet you specified a baseline time window.\nIgnoring baseline time window.\n')); 0276 TFR.bsln_wind=[]; 0277 elseif strcmpi(TFR.bsln_type,'relative') && strcmpi(TFR.units,'dB') 0278 error('You probably shouldn''t use a relative baseline if you''re converting your spectrograms into dB.'); 0279 end 0280 0281 remove_artifact_ics(); %ICA artifact correction (operates on the global variable EEG) 0282 %not baselining data there because we'll do it later 0283 0284 %convert EEG variable into a fieldtrip variable 0285 dataPP=eeglab2fieldtrip(EEG,'preprocessing','none'); 0286 0287 cfg_pre=[]; 0288 %note that selecting a subset of channels only removes channel data, not their info in dataPP2.elec 0289 cfg_pre.channel=cell(1,n_use_chans); 0290 for c=1:n_use_chans, 0291 cfg_pre.channel{c}=EEG.chanlocs(use_chans(c)).labels; 0292 end 0293 cfg_pre.demean=p.Results.demean; 0294 cfg_pre.baselinewindow ='all'; % or [begin end], make this an option ?? 0295 cfg_pre.trials = 'all'; %?? select only trials that belong to bins of interest ?? 0296 0297 tpt0_id=find_tpt(EEG.times,0); %time=0 time point index necessary for trial definition 0298 0299 %We have to add a trial configuration to make sure fieldtrip 0300 %doesn't think the data are really continuous. We don't use it for 0301 %anything though (currently). 0302 for a=1:n_epochs, 0303 dataPP.cfg.trl(a,:)=[1 n_tpts tpt0_id a]; %"a" just tells you what EEG.epoch the trial corresponds to. It isn't used for anything now. 0304 %get rid of possible time numerical error; milliseconds is the 0305 %lowest resolution we should ever need 0306 dataPP.time{a}=round(dataPP.time{a}*1000)/1000; 0307 end 0308 %add additional bookkeeping fields to fieldtrip variable 0309 dataPP=ft_preprocessing(cfg_pre,dataPP); 0310 0311 0312 %% Compute spectrogram for each bin, 0313 in_bin=bin_membership(EEG); % figure out which epochs belong in which bins 0314 0315 %Time window length 0316 if isempty(p.Results.time_window), 0317 T=(n_tpts/srate)/4; %1/4 the length of each epoch 0318 else 0319 T=p.Results.time_window/1000; %convert to seconds from ms 0320 end 0321 0322 %fieldtrip statistical analyses and grandaveraging expect different 0323 %conditions to be stored in different variables 0324 cfg = []; 0325 cfg.output = 'pow'; 0326 cfg.channel = 'all'; 0327 % cfg.channel=cell(1,n_use_chans); 0328 % for c=1:n_use_chans, 0329 % cfg.channel{c}= 0330 % end 0331 0332 cfg.method = 'mtmconvol'; 0333 cfg.taper = 'hanning'; % ?? make an option 0334 %cfg.taper = 'dpss'; ?? 0335 %cfg.tapsmofrq = 1; % multitaper option fix ?? 0336 %cfg.foilim = [0 EEG.srate/2]; %?? make an option 0337 if ~isempty(p.Results.freq_step), 0338 freq_step=p.Results.freq_step; 0339 else 0340 freq_step=1/T; %Raleigh frequency for size of moving time window (maximal frequency resolution without interpolation) 0341 end 0342 % Spectral power will be computed at the following frequencies 0343 if isempty(p.Results.freq_limits), 0344 cfg.foi=0:freq_step:srate/2; 0345 else 0346 cfg.foi=p.Results.freq_limits(1):freq_step:p.Results.freq_limits(2); % Spectral power will be computed at these frequencies 0347 end 0348 0349 cfg.pad = ceil((n_tpts/srate)*freq_step)/freq_step; %"pad" is in units of seconds; 0350 %fieldtrip requires "pad" to be at least as long as the length of each 0351 %epoch of data. Here we round up such that the pad length is a multiple 0352 %of our desired frequency step size. ?? make padding an option? 0353 if ~isint(cfg.pad*srate), 0354 error('Choose a different value for freq_step. The current value results in padding that is a multiple of 1/sampling_rate. fieldtrip plots don''t like this.'); 0355 end 0356 %fix the above error; just use pmtm.m for spectrograms 0357 0358 cfg.t_ftimwin=ones(length(cfg.foi),1).*T; % length of time window for each frequency, I'm making them all the same length for now 0359 0360 %find earliest possible time point to center the moving window 0361 start_time=dataPP.time{1}(1)+T/2; 0362 start_time=ceil(start_time*srate)/srate; %you need to round in case start_time falls in between samples 0363 0364 %latest possible time point to center the moving window 0365 end_time=dataPP.time{1}(end)-T/2; 0366 end_time=floor(end_time*srate)/srate; %you need to round in case start_time falls in between samples 0367 if isempty(p.Results.time_step), 0368 time_step=T/2; %half of length of moving time window 0369 else 0370 time_step=p.Results.time_step/1000; %convert to seconds from ms 0371 end 0372 cfg.toi=start_time:time_step:end_time; %make an option ?? 0373 0374 %perform the time frequency analysis for each bin for this subject 0375 for b=1:n_use_bins, 0376 cfg.trials=find(in_bin(:,use_bins(b))); 0377 TFR.bins{b}=ft_freqanalysis(cfg, dataPP); 0378 0379 %convert to decibels 0380 if strcmpi(TFR.units,'dB'), 0381 %convert to dB within ft_freqanalysis instead? ?? 0382 TFR.bins{b}.powspctrm=10*log10(TFR.bins{b}.powspctrm); 0383 end 0384 0385 %baseline if requested 0386 if ~isempty(TFR.bsln_wind) 0387 start_tpt=find(TFR.bins{b}.time<(TFR.bsln_wind(1)/1000)); %note conversion of baseline window from sec to ms 0388 start_tpt=start_tpt(end)+1; %first time point within the baseline window 0389 0390 end_tpt=find(TFR.bins{b}.time<=(TFR.bsln_wind(2)/1000));%note conversion of baseline window from sec to ms 0391 end_tpt=end_tpt(end); %last time point within the baseline window 0392 0393 %error check window 0394 if end_tpt<start_tpt, 0395 error('The first time point of your basline window, %g ms, is greater than the last time point of your baseline window, %g ms.', ... 0396 TFR.bins{b}.time(start_tpt)*1000,TFR.bins{b}.time(end_tpt)*1000); 0397 end 0398 fprintf('Desired spectrogram baseline window is from: %g to %g ms\n', ... 0399 TFR.bsln_wind(1),TFR.bsln_wind(2)); 0400 fprintf('Actual spectrogram baseline window is from: %g to %g ms\n', ... 0401 TFR.bins{b}.time(start_tpt)*1000,TFR.bins{b}.time(end_tpt)*1000) 0402 0403 mn_bsln_pow=squeeze(mean(TFR.bins{b}.powspctrm(:,:,start_tpt:end_tpt),3)); 0404 if strcmpi(TFR.bsln_type,'absolute'), 0405 TFR.bins{b}.powspctrm=TFR.bins{b}.powspctrm-repmat(mn_bsln_pow,[1 1 length(TFR.bins{b}.time)]); 0406 elseif strcmpi(TFR.bsln_type,'relative'), 0407 TFR.bins{b}.powspctrm=TFR.bins{b}.powspctrm./repmat(mn_bsln_pow,[1 1 length(TFR.bins{b}.time)]); 0408 end 0409 end 0410 end 0411 0412 TFR.chanlocs=EEG.chanlocs(use_chans); 0413 TFR.saved='yes'; 0414 0415 if ~isempty(TFR.tfr_fname) 0416 %Add .tfr extension if no extension given 0417 if ~ismember('.',TFR.tfr_fname), 0418 TFR.tfr_fname=[TFR.tfr_fname '.tfr']; 0419 end 0420 fprintf('Saving TFR variable to disk as %s.\n',TFR.tfr_fname); 0421 save(TFR.tfr_fname,'TFR'); 0422 else 0423 fprintf('TFR variable NOT saved to disk.'); 0424 end 0425 0426 0427 0428 %%%%%%%% END OF MAIN FUNCTION %%%%%%% 0429 0430 function in_bin=bin_membership(EEG) 0431 %function in_bin=bin_membership(EEG) 0432 % 0433 %Input: 0434 % EEG - EEGLAB EEG variable with Kutaslab bin information 0435 % 0436 %Output: 0437 % in_bin - epoch x bin binary matrix. A "1" in column N indicates that 0438 % that epoch falls in Bin N 0439 0440 n_bin=length(EEG.bindesc); 0441 n_epoch=length(EEG.epoch); 0442 0443 in_bin=zeros(n_epoch,n_bin); 0444 0445 for a=1:n_bin, 0446 bin_name=['bin' int2str(a)]; 0447 for ep=1:n_epoch, 0448 if ismember(bin_name,EEG.epoch(ep).eventtype) 0449 in_bin(ep,a)=1; 0450 end 0451 end 0452 end 0453 0454 function yesno=ismember_ci(str,str_array) 0455 % function yesno=ismember_ci(str,str_array) 0456 % A case insensitive version of ismember.m but just for strings 0457 % 0458 % Inputs: 0459 % str - a string 0460 % str_array - a cell array of strings 0461 % 0462 % Outputs: 0463 % yesno - 1 if str is a member of str_array. 0 otherwise. Comparison is 0464 % not case sensitive. 0465 0466 yesno=0; 0467 n_str=length(str_array); 0468 0469 for a=1:n_str, 0470 if strcmpi(str,str_array{a}) 0471 yesno=1; 0472 break; 0473 end 0474 end 0475 0476 function dif_str=setdiff_ci(superset,subset) 0477 %function dif_str=setdiff_ci(superset,subset) 0478 % 0479 % Inputs: 0480 % superset - an cell array of strings 0481 % subset - an cell array of strings 0482 % 0483 % Outputs: 0484 % dif_str - a cell array of the strings that are in superset but NOT 0485 % subset. Comparison is not case sensitive. 0486 % 0487 0488 n_super=length(superset); 0489 n_sub=length(subset); 0490 dif_ct=0; 0491 dif_str=[]; 0492 for a=1:n_super, 0493 found=0; 0494 for b=1:n_sub, 0495 if strcmpi(superset{a},subset{b}), 0496 found=1; 0497 break 0498 end 0499 end 0500 if ~found, 0501 dif_ct=dif_ct+1; 0502 dif_str{dif_ct}=superset{a}; 0503 end 0504 end