plot_erpimages() - Plots ERPimages from two sets of bins at a single channel and their difference using erpimage2bins.m. Usage: >> plot_erpimages(bins1,bins2,chan1,chan2,in_fname1,in_fname2,sort_var,varargin) Required Inputs: bins1 = [integer vector | []] a bin number or set of bin numbers (e.g., [1 12 13]). If [], all bins in eim file are used. bins2 = [integer vector | []] a bin number or set of bin numbers (e.g., [2 132]). If [] and in_fname2 differs from in_fname1, all bins in in_fname2 eim file are used. Otherwise, if [], bins2 is assumed to be the same as bins1. Note, if in_fname1 and in_fname2 are the same, bins1 and bins2 must be exaclty the same or not share any bins. chan1 = [string] name of the electrode to image for bins1 (e.g., 'LLOc') chan2 = [string | []] name of the electrode to image for bins1 (e.g., 'RLOc'). If chan2=[], chan2 is assumed to be the same as chan1. in_fname1 = [string] File from compile_erpimageMK.m in which data are stored. Include the file's path unless the file is the current working directory. in_fname2 = [string | []] File from compile_erpimageMK.m in which data are stored. Include the file's path unless the file is the current working directory. If in_fname2=[], in_fname2 is assumed to be the same as in_fname1. sort_var = [vector] Variable to sort epochs on (length(sort_var) = # of epochs) Example: sort_var may by subject response time in each epoch (in msec). Unordered Optional Inputs: fig_id = [positive integer | [] ] ID number of Matlab figure window in which to create the plots. If [], the plots will be generated in a new figure window. {default: []} title = [string] Plot title {default: Channel name and/or bins and number of trials} img1_title = [string] Title of the ERPimage for bins1/chan1/in_fname1 {default: the bin descriptor or the list of bins and possibly the channel name and file source} img2_title = [string] Title of the ERPimage for bins2/chan2/in_fname2 {default: the bin descriptor or the list of bins and possibly the channel name and file source} stdev = [scalar>0]. The standard deviation (in units of epochs) of the Gaussian window used to smooth (vertically) with a moving-average. Gaussian window extends three standard deviations below and three standard deviations above window center (trials beyond window are not incorporated into average). {default: 1/7, no smoothing} decfactor = Factor to decimate|interpolate ntrials by (may be non-integer) Else, if this is large (> sqrt(# of epochs)), output this many epochs. {default: no decimation} cbarlimits = [min max] Two element vector specifying the minimum and maximum value of the ERPimage color scale. {default: -/+ max(abs(data)))} cbartitle = [string] Title of color scale {default: '\muV'} timelimits = [min max] Two element vector specifying the minimum and maximum value of all time axes (in ms). {default: [min(times) max(times)] erplimits = [min max] Two element vector specifying the minimum and maximum value (in uV) of the voltage axis for bins1/chan1/in_fname1's and bins2/chan2/in_fname2's ERPs. {default: -/+ max(max(abs([erp1 erp2])))} erpdiflimits = [min max] Two element vector specifying the minimum and maximum value (in uV) of the voltage axis for the difference wave between bins1/chan1/in_fname1 and bins2/chan2/in_fname2. {default: -/+ max(max(abs([erp1-erp2])))} sortvarlimits = [min max] Two element vector specifying the minimum and maximum value (in units of 'Trials' or the sorting variable, depending on yimglabel) of the ERPimage y-axis. ERPs are computed only from epochs that fall within this range. {default: ERPimage min and max} yerplabel = The label for the voltage axis on ERP plots {default: 'ERP (\muV)'} erpgrid = ['on' | 'off'] If 'on', horizontal dashed lines will be plot at voltage axis tick marks on ERP plots. {default: 'on'} topos = ['on' | 'off'] If 'on', two cartoon heads will appear above ERPimages to illustrate locations of chan1 chan2. {default: 'on'} renorm = ['on'|'off'| formula] Normalize sorting variable to epoch time range. 'on'= autoscale. formula must be a linear transformation in the format 'a*x+b' (e.g., '3*x+2'). {default: 'off'} rmerp = ['on'|'off'] Subtract the average ERP from each trial before processing {default: 'off'} showsortvar = ['on'|'off'] Plot sort_var on top of ERPimages {default: 'on'} marktimes = [vector of times] Plot vertical dashed lines at specified latencies (in ms). erpimage.m's "vert" option. {default: ignored} marktrials = [vector] Plot horizontal lines at specified ERPimage y-axis values. Depending on value of 'yimglabel' argument (above), vector should be in units of either 'Trials' or the sorting variable. Analogous to erpimage.m's "horz" option. {default: ignored} filt = [low_boundary high_boundary] a two element vector indicating the frequency cut-offs for a 3rd order Butterworth filter that will be applied to each trial of data. If low_boundary=0, the filter is a high pass filter. If high_boundary=srate/2, then the filter is a low pass filter. If both boundaries are between 0 and srate/2, then the filter is a bandpass filter. If both boundaries are between 0 and -srate/2, then the filter is a bandstop filter (with boundaries equal to the absolute values of low_boundary and high_boundary). Note, using this option requires the signal processing toolbox function butter.m. You should probably use the 'baseline' option (see below) as well since the mean prestimulus baseline may no longer be 0 after the filter is applied. {default: no filtering} baseline = [low_boundary high_boundary] a time window (in msec) whose mean amplitude in each epoch will be removed from each epoch (e.g., [-100 0]) after filtering. Useful in conjunction with 'filt' option to re-basline trials after they have been filtered. Not necessary if data have already been baselined and ERPimage processing does not affect baseline amplitude {default: no further baselining of data} verblevel = an integer specifiying the amount of information you want functions to provide about what they are 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 if not already globally specified} 3 - stuff that might help you debug (show all reports) img_trialax_label = [string] Label for ERPimage y-axes. If not 'Trials', ERPimage y-ticks are automatically set to units of sorting variable. {default: 'Trials'} img_trialax_ticks = [ vector ] Points on ERPimage y-axes at which to make tick marks. Provide values in units of y-axes label (either 'Trials' or sorting variable). {default: MATLAB default ticks} Outputs: If data are not already in memory, the function sets some global variables (see below). Global Variables: VERBLEVEL = level of verbosity (i.e., tells functions how much how much to report about what they're doing during runtime) set by the optional function argument 'verblevel' in_fname = .eim file from which data were loaded (produced by compile_erpimageMK.m) chans = cell array specifiying the names of the channels loaded into memory chan_data = the EEG at all of the channels loaded into memory chanlocs = EEG.chanlocs struct specifying channel locations ep_info = information about each trial/epoch of data (in format of EEG.event struct) ep_times = start and stop time of each epoch (in ms) bindesc = struct array of bin descriptors srate = sampling rate eim_bins = bins that were expicitly loaded when .eim file was created rtmsec = reaction time info for each epoch (may be empty) rtbins = specifies which reaction time value in rtmsec goes with which bin (i.e., enables the same epoch to have different RTs depending on which bin it is assigned to). Example: (Contrasts ERPimages at LLOc and RLOc, sorted by reaction time) >> in_fname1='/homes/dgroppe/SANDBOX/RTERPM/rtm#y.set'; >> chans={'MiPf','MiCe','MiOc','LLOc','RLOc'}; >> compile_erpimageMK(1:4,'setfile_tplate',setfile_tplate,'chans',chans, ... 'bins',[127 133 142 157],'out_fname','demo.eim'); >> plot_erpimages([],[],'LLOc','RLOc','demo.eim',[],'rtmsec','stdev',4); Author: David Groppe Kutaslab, 11/2009 Notes: -Relies on erpimages.m to make the plots -Epochs with identical sorting variable values are replaced with their mean. Thus, if there are such "tied" epochs, there is smoothing in addition to the moving average window. #/% of epochs that tie other epochs are reported in the MATLAB command line window. -The number of trials that are reported in the automatically generated figure title are the number of trials before decimation.
0001 function plot_erpimages(bins1,bins2,chan1,chan2,in_fname1,in_fname2,sort_var,varargin) 0002 % plot_erpimages() - Plots ERPimages from two sets of bins at a single channel 0003 % and their difference using erpimage2bins.m. 0004 % 0005 % Usage: 0006 % >> plot_erpimages(bins1,bins2,chan1,chan2,in_fname1,in_fname2,sort_var,varargin) 0007 % 0008 % 0009 % Required Inputs: 0010 % bins1 = [integer vector | []] a bin number or set of bin numbers (e.g., 0011 % [1 12 13]). If [], all bins in eim file are used. 0012 % bins2 = [integer vector | []] a bin number or set of bin numbers (e.g., 0013 % [2 132]). If [] and in_fname2 differs from in_fname1, all bins in 0014 % in_fname2 eim file are used. Otherwise, if [], bins2 is assumed 0015 % to be the same as bins1. Note, if in_fname1 and in_fname2 are 0016 % the same, bins1 and bins2 must be exaclty the same or not 0017 % share any bins. 0018 % chan1 = [string] name of the electrode to image for bins1 (e.g., 'LLOc') 0019 % chan2 = [string | []] name of the electrode to image for bins1 (e.g., 0020 % 'RLOc'). If chan2=[], chan2 is assumed to be the same as chan1. 0021 % in_fname1 = [string] File from compile_erpimageMK.m in which data are 0022 % stored. Include the file's path unless the file is the 0023 % current working directory. 0024 % in_fname2 = [string | []] File from compile_erpimageMK.m in which data are 0025 % stored. Include the file's path unless the file is the 0026 % current working directory. If in_fname2=[], in_fname2 is 0027 % assumed to be the same as in_fname1. 0028 % sort_var = [vector] Variable to sort epochs on (length(sort_var) = # of epochs) 0029 % Example: sort_var may by subject response time in each 0030 % epoch (in msec). 0031 % 0032 % Unordered Optional Inputs: 0033 % fig_id = [positive integer | [] ] ID number of Matlab figure window in which to create 0034 % the plots. If [], the plots will be generated in a new 0035 % figure window. {default: []} 0036 % title = [string] Plot title {default: Channel name and/or bins and number of trials} 0037 % img1_title = [string] Title of the ERPimage for bins1/chan1/in_fname1 0038 % {default: the bin descriptor or the list of bins and possibly 0039 % the channel name and file source} 0040 % img2_title = [string] Title of the ERPimage for bins2/chan2/in_fname2 0041 % {default: the bin descriptor or the list of bins and possibly 0042 % the channel name and file source} 0043 % stdev = [scalar>0]. The standard deviation (in units of epochs) of the Gaussian 0044 % window used to smooth (vertically) with a moving-average. Gaussian 0045 % window extends three standard deviations below and three standard 0046 % deviations above window center (trials beyond window are not incorporated 0047 % into average). {default: 1/7, no smoothing} 0048 % decfactor = Factor to decimate|interpolate ntrials by (may be non-integer) 0049 % Else, if this is large (> sqrt(# of epochs)), output this many epochs. 0050 % {default: no decimation} 0051 % cbarlimits = [min max] Two element vector specifying the minimum and 0052 % maximum value of the ERPimage color scale. {default: 0053 % -/+ max(abs(data)))} 0054 % cbartitle = [string] Title of color scale {default: '\muV'} 0055 % timelimits = [min max] Two element vector specifying the minimum and 0056 % maximum value of all time axes (in ms). {default: [min(times) 0057 % max(times)] 0058 % erplimits = [min max] Two element vector specifying the minimum and 0059 % maximum value (in uV) of the voltage axis for bins1/chan1/in_fname1's and 0060 % bins2/chan2/in_fname2's ERPs. {default: -/+ max(max(abs([erp1 erp2])))} 0061 % erpdiflimits = [min max] Two element vector specifying the minimum and 0062 % maximum value (in uV) of the voltage axis for the difference 0063 % wave between bins1/chan1/in_fname1 and bins2/chan2/in_fname2. 0064 % {default: -/+ max(max(abs([erp1-erp2])))} 0065 % sortvarlimits = [min max] Two element vector specifying the minimum and 0066 % maximum value (in units of 'Trials' or the sorting variable, depending on 0067 % yimglabel) of the ERPimage y-axis. ERPs are computed 0068 % only from epochs that fall within this range. 0069 % {default: ERPimage min and max} 0070 % yerplabel = The label for the voltage axis on ERP plots {default: 0071 % 'ERP (\muV)'} 0072 % erpgrid = ['on' | 'off'] If 'on', horizontal dashed lines will 0073 % be plot at voltage axis tick marks on ERP plots. {default: 'on'} 0074 % topos = ['on' | 'off'] If 'on', two cartoon heads will appear 0075 % above ERPimages to illustrate locations of chan1 0076 % chan2. {default: 'on'} 0077 % renorm = ['on'|'off'| formula] Normalize sorting variable to epoch 0078 % time range. 'on'= autoscale. formula must be a linear 0079 % transformation in the format 'a*x+b' (e.g., '3*x+2'). 0080 % {default: 'off'} 0081 % rmerp = ['on'|'off'] Subtract the average ERP from each trial before 0082 % processing {default: 'off'} 0083 % showsortvar = ['on'|'off'] Plot sort_var on top of ERPimages {default: 'on'} 0084 % marktimes = [vector of times] Plot vertical dashed lines at specified latencies (in ms). 0085 % erpimage.m's "vert" option. {default: ignored} 0086 % marktrials = [vector] Plot horizontal lines at specified ERPimage y-axis 0087 % values. Depending on value of 'yimglabel' argument (above), 0088 % vector should be in units of either 'Trials' or the 0089 % sorting variable. Analogous to erpimage.m's "horz" option. 0090 % {default: ignored} 0091 % filt = [low_boundary high_boundary] a two element vector indicating 0092 % the frequency cut-offs for a 3rd order Butterworth filter that 0093 % will be applied to each trial of data. If low_boundary=0, the 0094 % filter is a high pass filter. If high_boundary=srate/2, then 0095 % the filter is a low pass filter. If both boundaries are between 0096 % 0 and srate/2, then the filter is a bandpass filter. If both 0097 % boundaries are between 0 and -srate/2, then the filter is a bandstop 0098 % filter (with boundaries equal to the absolute values of low_boundary 0099 % and high_boundary). Note, using this option requires the signal 0100 % processing toolbox function butter.m. You should probably 0101 % use the 'baseline' option (see below) as well since the mean 0102 % prestimulus baseline may no longer be 0 after the filter is 0103 % applied. {default: no filtering} 0104 % baseline = [low_boundary high_boundary] a time window (in msec) whose mean 0105 % amplitude in each epoch will be removed from each epoch (e.g., 0106 % [-100 0]) after filtering. Useful in conjunction with 'filt' option 0107 % to re-basline trials after they have been filtered. Not necessary 0108 % if data have already been baselined and ERPimage processing does not 0109 % affect baseline amplitude {default: no further 0110 % baselining of data} 0111 % verblevel = an integer specifiying the amount of information you want 0112 % functions to provide about what they are doing during runtime. 0113 % Options are: 0114 % 0 - quiet, only show errors, warnings, and EEGLAB reports 0115 % 1 - stuff anyone should probably know 0116 % 2 - stuff you should know the first time you start working 0117 % with a data set {default value if not already globally 0118 % specified} 0119 % 3 - stuff that might help you debug (show all reports) 0120 % img_trialax_label = [string] Label for ERPimage y-axes. If not 'Trials', ERPimage y-ticks are automatically 0121 % set to units of sorting variable. {default: 'Trials'} 0122 % img_trialax_ticks = [ vector ] Points on ERPimage y-axes at which to make 0123 % tick marks. Provide values in units of y-axes label (either 'Trials' or 0124 % sorting variable). {default: MATLAB default ticks} 0125 % 0126 % 0127 % Outputs: 0128 % If data are not already in memory, the function sets some global 0129 % variables (see below). 0130 % 0131 % 0132 % Global Variables: 0133 % VERBLEVEL = level of verbosity (i.e., tells functions how much 0134 % how much to report about what they're doing during 0135 % runtime) set by the optional function argument 'verblevel' 0136 % in_fname = .eim file from which data were loaded (produced by 0137 % compile_erpimageMK.m) 0138 % chans = cell array specifiying the names of the channels loaded 0139 % into memory 0140 % chan_data = the EEG at all of the channels loaded into memory 0141 % chanlocs = EEG.chanlocs struct specifying channel locations 0142 % ep_info = information about each trial/epoch of data (in format of 0143 % EEG.event struct) 0144 % ep_times = start and stop time of each epoch (in ms) 0145 % bindesc = struct array of bin descriptors 0146 % srate = sampling rate 0147 % eim_bins = bins that were expicitly loaded when .eim file was created 0148 % rtmsec = reaction time info for each epoch (may be empty) 0149 % rtbins = specifies which reaction time value in rtmsec goes with 0150 % which bin (i.e., enables the same epoch to have different 0151 % RTs depending on which bin it is assigned to). 0152 % 0153 % Example: 0154 % (Contrasts ERPimages at LLOc and RLOc, sorted by reaction time) 0155 % >> in_fname1='/homes/dgroppe/SANDBOX/RTERPM/rtm#y.set'; 0156 % >> chans={'MiPf','MiCe','MiOc','LLOc','RLOc'}; 0157 % >> compile_erpimageMK(1:4,'setfile_tplate',setfile_tplate,'chans',chans, ... 0158 % 'bins',[127 133 142 157],'out_fname','demo.eim'); 0159 % >> plot_erpimages([],[],'LLOc','RLOc','demo.eim',[],'rtmsec','stdev',4); 0160 % 0161 % 0162 % 0163 % Author: 0164 % David Groppe 0165 % Kutaslab, 11/2009 0166 % 0167 % Notes: 0168 % -Relies on erpimages.m to make the plots 0169 % 0170 % -Epochs with identical sorting variable values are replaced with their 0171 % mean. Thus, if there are such "tied" epochs, there is smoothing in addition 0172 % to the moving average window. #/% of epochs that tie other epochs are reported 0173 % in the MATLAB command line window. 0174 % 0175 % -The number of trials that are reported in the automatically generated 0176 % figure title are the number of trials before decimation. 0177 0178 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%% 0179 % 0180 0181 %%%%%%%%%%%%%%%% POSSIBLE FUTURE DEVELOPMENT %%%%%%%%%%%%%%%% 0182 %-VERBLEVEL currently modulates very little of the information provided by 0183 %the function during runtime. This could be improved. 0184 % 0185 0186 global in_fname; 0187 global chan_data; 0188 global chans; 0189 global chanlocs; 0190 global ep_info; 0191 global ep_times; 0192 global bindesc; 0193 global srate; 0194 global rtmsec; 0195 global rtbins; 0196 global eim_bins 0197 global VERBLEVEL 0198 0199 %Input Parser 0200 p=inputParser; 0201 %Note: the order of the required arguments needs to match precisely their 0202 %order in the function definition (which is also the order used by p.parse 0203 %below) 0204 p.addRequired('bins1',@isnumeric); 0205 p.addRequired('bins2',@(x) isnumeric(x) || isempty(x)); 0206 p.addRequired('chan1',@ischar); 0207 p.addRequired('chan2',@(x) ischar(x) || isempty(x)); 0208 p.addRequired('in_fname1',@ischar); 0209 p.addRequired('in_fname2',@(x) ischar(x) || isempty(x)); 0210 p.addRequired('sort_var',@ischar); 0211 p.addParamValue('fig_id',[],@(x) sum(x>=0) || isempty(x)); 0212 p.addParamValue('stdev',1/7,@(x) isnumeric(x) && (x>=0)); 0213 p.addParamValue('verblevel',[],@(x) x>=0); 0214 p.addParamValue('title',[],@(x) ischar(x) || isempty(x));%default is to use chan name and/or bins & # of trials 0215 p.addParamValue('cbarlimits',[],@(x) (isnumeric(x) && (length(x)==2)) || isempty(x)); 0216 p.addParamValue('cbartitle','\muV',@ischar); 0217 p.addParamValue('img_trialax_label','Trials',@ischar); 0218 p.addParamValue('img_trialax_ticks',[],@isnumeric); 0219 p.addParamValue('timelimits',[],@(x) isnumeric(x) && (length(x)==2)); 0220 p.addParamValue('erplimits',[],@(x) (isnumeric(x) && (length(x)==2)) || isempty(x)); 0221 p.addParamValue('erpdiflimits',[],@(x) isnumeric(x) && (length(x)==2)); 0222 p.addParamValue('sortvarlimits',[],@(x) (isnumeric(x) && (length(x)==2)) || isempty(x)); 0223 p.addParamValue('yerplabel','ERP (\muV)',@ischar); 0224 p.addParamValue('erpgrid','on',@(x) strcmpi(x,'on') || strcmpi(x,'off')); 0225 p.addParamValue('topos','on',@(x) strcmpi(x,'on') || strcmpi(x,'off')); 0226 p.addParamValue('renorm','off',@ischar); %check for legality of value later 0227 p.addParamValue('rmerp','off',@(x) strcmpi(x,'on') || strcmpi(x,'off')); 0228 p.addParamValue('showsortvar','on',@(x) strcmpi(x,'on') || strcmpi(x,'off')); 0229 p.addParamValue('decfactor',0,@isnumeric); 0230 p.addParamValue('baseline',[],@(x) isnumeric(x) && (length(x)==2)); 0231 p.addParamValue('filt',[],@(x) isnumeric(x) && (length(x)==2)); 0232 p.addParamValue('marktimes',[],@isnumeric); 0233 p.addParamValue('marktrials',[],@isnumeric); 0234 p.addParamValue('img1_title',[],@ischar); 0235 p.addParamValue('img2_title',[],@ischar); 0236 p.parse(bins1,bins2,chan1,chan2,in_fname1,in_fname2,sort_var,varargin{:}); 0237 0238 if isempty(VERBLEVEL) && isempty(p.Results.verblevel) 0239 VERBLEVEL=2; 0240 elseif ~isempty(p.Results.verblevel) 0241 VERBLEVEL=p.Results.verblevel; 0242 end 0243 0244 %?? put in error for arguments that should be integers when they are not 0245 %integers? 0246 0247 0248 if isempty(chan2), 0249 chan2=chan1; 0250 end 0251 0252 0253 %input filenames are required 0254 dif_in_fnames=0; 0255 if isempty(in_fname2), 0256 in_fname2=in_fname1; 0257 elseif ~strcmpi(in_fname1,in_fname2) 0258 dif_in_fnames=1; 0259 end 0260 0261 0262 if dif_in_fnames, 0263 %load second in_fname first and copy variables to new names 0264 load(in_fname2,'-MAT'); 0265 chan_data2=chan_data; 0266 chans2=chans; 0267 chanlocs2=chanlocs; 0268 ep_info2=ep_info; 0269 ep_times2=ep_times; 0270 bindesc2=bindesc; 0271 srate2=srate; 0272 rtmsec2=rtmsec; 0273 rtbins2=rtbins; 0274 eim_bins2=eim_bins; 0275 0276 %load first file (overwrites original variables from in_fname2 that was just loaded) 0277 load(in_fname1,'-MAT'); 0278 in_fname=in_fname1; %set global variable in_fname to reflect source of current values of global variables 0279 0280 elseif strcmp(in_fname,in_fname1) 0281 %if input file matches file from which data in global variables were 0282 %taken from, use the data in global variables to save the time it takes 0283 %to reload the data from the file 0284 if isempty(chan_data) || isempty(chans) || isempty(chanlocs) || isempty(ep_info), 0285 %some critical variables are not already in global memory, try to 0286 %load everything from file afterall 0287 load(in_fname1,'-MAT'); 0288 else 0289 fprintf('in_filename %s matches source of data already in memory.\n',in_fname1); 0290 fprintf('Will use data already in memory to save time.\n'); 0291 fprintf('If you would rather load the data from the file enter the\n'); 0292 fprintf(' following at the Matlab command line: '); 0293 fprintf('>> clear global in_fname\n'); 0294 end 0295 chans2=chans; 0296 chanlocs2=chanlocs; 0297 bindesc2=bindesc; 0298 else 0299 load(in_fname1,'-MAT'); 0300 in_fname=in_fname1; %set global variable in_fname to reflect source of current values of global variables 0301 msg=sprintf('Loading file %s into global variables.\n',in_fname); 0302 msg=[msg sprintf('One of these variables, chan_data, may be quite large.\n')]; 0303 msg=[msg sprintf('To delete it, enter >> clear global chan_data\n')]; 0304 VerbReport(msg,2,VERBLEVEL); 0305 chans2=chans; 0306 chanlocs2=chanlocs; 0307 bindesc2=bindesc; 0308 end 0309 0310 0311 %Are the sets of bins different? 0312 dif_bins=0; 0313 if ~dif_in_fnames 0314 if isempty(bins2) 0315 bins2=bins1; 0316 else 0317 comn_bins=intersect(bins1,bins2); 0318 if ~isempty(comn_bins) 0319 if length(comn_bins)~=length(bins1) || length(comn_bins)~=length(bins2), 0320 error(['You''ve included bin(s) ' num2str(comn_bins) ' in both contrasts. The two sets of bins should be unique or exactly the same.']); 0321 end %otherwise they are the exact same set of bins 0322 elseif ~isempty(bins1) && ~isempty(bins2), %if not using all bins in both contrasts 0323 dif_bins=1; 0324 end 0325 end 0326 else 0327 %check to see if bin descriptors are exactly the same for the bins from both files 0328 if isempty(bins1), 0329 use_bins1=eim_bins; 0330 else 0331 use_bins1=bins1; 0332 end 0333 if isempty(bins2), 0334 use_bins2=eim_bins2; 0335 else 0336 use_bins2=bins2; 0337 end 0338 n_bindesc1=length(use_bins1); 0339 n_bindesc2=length(use_bins2); 0340 if n_bindesc1==n_bindesc2, 0341 matched=[]; 0342 for bd_loop1=use_bins1, 0343 for bd_loop2=setdiff(use_bins2,matched), 0344 if strcmpi(bindesc{bd_loop1},bindesc2{bd_loop2}), 0345 matched=[matched bd_loop2]; 0346 break; %leave bd_loop2 0347 end 0348 end 0349 end 0350 if ~isempty(setdiff(use_bins2,matched)) 0351 dif_bins=1; 0352 end 0353 else 0354 dif_bins=1; 0355 end 0356 end 0357 0358 %%%%%%% Find index to desired electrodes in chans (a cell array of channel names 0359 %%%%%%% currently loaded into memory) 0360 % Channel for first image 0361 chans_id1=0; 0362 for a=1:length(chans), 0363 if strcmpi(chans{a},chan1), 0364 chans_id1=a; 0365 end 0366 end 0367 if ~chans_id1 0368 msg=sprintf('Channel %s is not an option.\nCurrently loaded channels are: ',chan1); 0369 for a=1:(length(chans)-1), 0370 msg=[msg chans{a} ', ']; 0371 end 0372 msg=[msg chans{length(chans)}]; 0373 error(msg); 0374 end 0375 0376 % Channel for second image 0377 if strcmpi(chan1,chan2), 0378 dif_chans=0; 0379 else 0380 dif_chans=1; 0381 end 0382 0383 chans_id2=0; 0384 for a=1:length(chans2), 0385 if strcmpi(chans2{a},chan2), 0386 chans_id2=a; 0387 end 0388 end 0389 if ~chans_id2 0390 msg=sprintf('Channel %s is not an option.\nCurrently loaded channels are: ',chan2); 0391 for a=1:(length(chans2)-1), 0392 msg=[msg chans2{a} ', ']; 0393 end 0394 msg=[msg chans2{length(chans2)}]; 0395 error(msg); 0396 end 0397 0398 0399 if ~dif_chans && ~dif_bins && ~dif_in_fnames, 0400 error('You''re trying to compare the same channel to itself, using the same set of bins. That doesn''t make any sense. Those two sets of data are exactly the same.'); 0401 end 0402 0403 if dif_in_fnames, 0404 %use only time points common to both datasets 0405 [comn_tpts tm_id2 tm_id1]=intersect(ep_times2,ep_times); 0406 n_comn=length(comn_tpts); 0407 if n_comn==0, 0408 error('The two data sets you''re contrasting are composed of completely different time points.'); 0409 elseif (n_comn~=length(ep_times)) || (n_comn~=length(ep_times2)) 0410 fprintf('\nThe two data sets you''re contrasting have somewhat different time points. Only using time points common to both.\n\n'); 0411 ep_times2=ep_times2(tm_id2); 0412 chan_data2{chans_id2}=chan_data2{chans_id2}(tm_id2,:); 0413 ep_times=ep_times(tm_id1); 0414 chan_data{chans_id1}=chan_data{chans_id1}(tm_id1,:); 0415 end 0416 end 0417 0418 %% Does First in_fname have Sorting Variable? 0419 %Check to make sure we have the desired sorting variable 0420 got_srtvar=0; 0421 %RT is a special sorting variable, since there may be more than one RT per 0422 %trial 0423 sortby_rt=0; 0424 rt_loaded=0; 0425 if exist('rtmsec','var') 0426 if ~isempty(rtmsec), 0427 rt_loaded=1; 0428 if strcmpi(sort_var,'rtmsec'), 0429 sortby_rt=1; 0430 got_srtvar=1; 0431 end 0432 end 0433 end 0434 0435 %Check for non-RT sorting variables 0436 if ~sortby_rt, 0437 fldnms=fieldnames(ep_info); 0438 possible=[]; 0439 desired=['event' sort_var]; 0440 for a=1:length(fldnms), 0441 if strcmpi('event',fldnms{a}(1:5)) && ~strcmpi('eventrtmsec',fldnms{a}) && (length(fldnms{a})>5), 0442 %i.e., it is not "event", note rtmsec sorting variable should 0443 %have been caught above already 0444 cmnd=['isnumeric(ep_info(a).' fldnms{a} ')']; 0445 if (eval(cmnd)), 0446 if strcmpi(desired,fldnms{a}), 0447 got_srtvar=1; 0448 break; %break a loop 0449 else 0450 possible=[possible a]; 0451 end 0452 end 0453 end 0454 end 0455 end 0456 if ~got_srtvar, 0457 msg=sprintf('Sorting variable %s is not an option for %s.\nCurrently loaded sorting variables are: ',sort_var,in_fname1); 0458 for a=1:(length(possible)-1), 0459 msg=[msg fldnms{possible(a)}(6:end) ', ']; 0460 end 0461 msg=[msg fldnms{possible(end)}(6:end)]; %last/penultimate possibility doesn't need comma 0462 if rt_loaded, 0463 msg=[msg ', rtmsec']; 0464 end 0465 error(msg); 0466 end 0467 0468 0469 %% Does Second in_fname have Sorting Variable? 0470 if dif_in_fnames, 0471 got_srtvar2=0; 0472 %RT is a special sorting variable, since there may be more than one RT per 0473 %trial 0474 rt_loaded2=0; 0475 if exist('rtmsec2','var') 0476 if ~isempty(rtmsec2), 0477 rt_loaded2=1; 0478 if sortby_rt, 0479 got_srtvar2=1; 0480 end 0481 end 0482 end 0483 0484 % Collect possible sorting variables 0485 fldnms=fieldnames(ep_info2); 0486 possible=[]; 0487 for a=1:length(fldnms), 0488 if strcmpi('event',fldnms{a}(1:5)) && ~strcmpi('eventrtmsec',fldnms{a}) && (length(fldnms{a})>5), 0489 %i.e., it is not "event", note rtmsec sorting variable should 0490 %have been caught above already 0491 cmnd=['isnumeric(ep_info2(a).' fldnms{a} ')']; 0492 if (eval(cmnd)), 0493 possible=[possible a]; 0494 end 0495 end 0496 end 0497 0498 0499 %Check for non-RT sorting variables 0500 if ~sortby_rt, 0501 fldnms=fieldnames(ep_info2); 0502 % possible=[]; 0503 desired=['event' sort_var]; 0504 for a=1:length(fldnms), 0505 if strcmpi('event',fldnms{a}(1:5)) && ~strcmpi('eventrtmsec',fldnms{a}) && (length(fldnms{a})>5), 0506 %i.e., it is not "event", note rtmsec sorting variable should 0507 %have been caught above already 0508 cmnd=['isnumeric(ep_info2(a).' fldnms{a} ')']; 0509 if (eval(cmnd)), 0510 if strcmpi(desired,fldnms{a}), 0511 got_srtvar2=1; 0512 break; %break a loop 0513 else 0514 % possible=[possible a]; 0515 end 0516 end 0517 end 0518 end 0519 end 0520 if ~got_srtvar2, 0521 msg=sprintf('Sorting variable %s is not an option for %s.\nCurrently loaded sorting variables are: ',sort_var,in_fname2); 0522 for a=1:(length(possible)-1), 0523 msg=[msg fldnms{possible(a)}(6:end) ', ']; 0524 end 0525 msg=[msg fldnms{possible(end)}(6:end)]; %last/penultimate possibility doesn't need comma 0526 if rt_loaded2, 0527 msg=[msg ', rtmsec']; 0528 end 0529 error(msg); 0530 end 0531 end 0532 0533 0534 %% %%%%%%%%%%%%%%% Sorting Variable Values 0535 % for FIRST Set of Bins 0536 srt_val1=get_svar_val(ep_info,rtbins,rtmsec,bins1,sortby_rt,sort_var); 0537 % for SECOND Set of Bins 0538 if dif_in_fnames, 0539 srt_val2=get_svar_val(ep_info2,rtbins2,rtmsec2,bins2,sortby_rt,sort_var); 0540 else 0541 if dif_bins 0542 srt_val2=get_svar_val(ep_info,rtbins,rtmsec,bins2,sortby_rt,sort_var); 0543 else 0544 srt_val2=srt_val1; 0545 end 0546 end 0547 0548 %Compile figure title 0549 bin1_title=[]; 0550 bin2_title=[]; 0551 if isempty(bins1), %convert empty bins1 to all bins (that's what bins=[] means) 0552 bins1=num2str(eim_bins); 0553 end 0554 if isempty(bins2) 0555 if dif_in_fnames, 0556 bins2=num2str(eim_bins2); 0557 else 0558 bins2=bins1; 0559 end 0560 end 0561 % grab just the file name for figure display 0562 rmndr=in_fname1; 0563 while ~isempty(rmndr) 0564 [fname1, rmndr]=strtok(rmndr,'/'); 0565 end 0566 if dif_in_fnames, 0567 rmndr=in_fname2; 0568 while ~isempty(rmndr) 0569 [fname2, rmndr]=strtok(rmndr,'/'); 0570 end 0571 else 0572 fname2=fname1; 0573 end 0574 0575 if ~dif_chans && ~dif_bins, 0576 if length(bins1)>1 0577 fig_title=['Channel ' chan1 ', Bins ' num2str(bins1)]; 0578 else 0579 fig_title=['Channel ' chan1 ', ' bindesc{bins1}]; 0580 end 0581 elseif ~dif_chans && dif_bins, 0582 fig_title=['Channel ' chan1]; 0583 elseif dif_chans && ~dif_bins, 0584 if length(bins1)>1 0585 fig_title=['Bins ' num2str(bins1)]; 0586 else 0587 fig_title=bindesc{bins1}; 0588 end 0589 else 0590 fig_title=[]; 0591 end 0592 0593 %Compile erpimage titles and window title 0594 if dif_chans 0595 wind_title=[chan1 ' vs. ' chan2 ': ']; 0596 bin1_title=chan1; 0597 bin2_title=chan2; 0598 if dif_bins, 0599 bin1_title=[bin1_title ': ']; 0600 bin2_title=[bin2_title ': ']; 0601 end 0602 else 0603 wind_title=[chan1 ': ']; 0604 bin1_title=[]; 0605 bin2_title=[]; 0606 end 0607 0608 if dif_bins, 0609 if length(bins1)>1, 0610 bin1_title=[bin1_title 'Bins ' num2str(bins1)]; 0611 if dif_in_fnames, 0612 wind_title=[wind_title 'Bins ' num2str(bins1) '(' fname1 ') vs. ']; 0613 bin1_title=[bin1_title ' (' fname1 ')']; 0614 else 0615 wind_title=[wind_title 'Bins ' num2str(bins1) ' vs. ']; 0616 end 0617 else 0618 bin1_title=[bin1_title bindesc{bins1}]; 0619 if dif_in_fnames, 0620 wind_title=[wind_title 'Bin ' num2str(bins1) '(' fname1 ') vs. ']; 0621 bin1_title=[bin1_title ' (' fname1 ')']; 0622 else 0623 wind_title=[wind_title 'Bin ' num2str(bins1) ' vs. ']; 0624 end 0625 end 0626 if length(bins2)>1, 0627 bin2_title=[bin2_title 'Bins ' num2str(bins2)]; 0628 if dif_in_fnames, 0629 wind_title=[wind_title 'Bins ' num2str(bins2) '(' fname2 ')']; 0630 bin2_title=[bin2_title ' (' fname2 ')']; 0631 else 0632 wind_title=[wind_title ' Bins ' num2str(bins2)]; 0633 end 0634 else 0635 bin2_title=[bin2_title bindesc2{bins2}]; 0636 if dif_in_fnames, 0637 wind_title=[wind_title 'Bin ' num2str(bins2) '(' fname2 ')']; 0638 bin2_title=[bin2_title ' (' fname2 ')']; 0639 else 0640 wind_title=[wind_title ' Bin ' num2str(bins2)]; 0641 end 0642 end 0643 else %bins are the same for both images 0644 if dif_in_fnames, 0645 if dif_chans, 0646 bin1_title=[bin1_title ' (' fname1 ')']; 0647 bin2_title=[bin2_title ' (' fname2 ')']; 0648 else 0649 bin1_title=fname1; 0650 bin2_title=fname2; 0651 end 0652 end 0653 if length(bins1)>1, 0654 if dif_in_fnames, 0655 wind_title=[wind_title 'Bins ' num2str(bins1) ' (' fname1 ' vs. ' fname2 ')']; 0656 else 0657 wind_title=[wind_title 'Bins ' num2str(bins1)]; 0658 end 0659 else 0660 if dif_in_fnames, 0661 wind_title=[wind_title bindesc{bins1} ' (' fname1 ' vs. ' fname2 ')']; 0662 else 0663 wind_title=[wind_title bindesc{bins1}]; 0664 end 0665 end 0666 end 0667 if ~isempty(p.Results.title), %title specified as optional input argument 0668 fig_title=p.Results.title; 0669 wind_title=fig_title; 0670 end 0671 0672 if ~isempty(p.Results.img1_title), 0673 bin1_title=p.Results.img1_title; 0674 end 0675 if ~isempty(p.Results.img2_title), 0676 bin2_title=p.Results.img2_title; 0677 end 0678 0679 % Add the number of trials that will be imaged to the figure title 0680 comn=intersect(srt_val1,srt_val2); 0681 trial_ct=0; 0682 for sval_loop=comn, 0683 ids1=find(srt_val1==sval_loop); 0684 ids2=find(srt_val2==sval_loop); 0685 mn_ct=min([length(ids1) length(ids2)]); 0686 trial_ct=trial_ct+mn_ct; 0687 end 0688 use_title=[fig_title ' (' int2str(trial_ct) ' Trials)']; 0689 0690 0691 %%%%%%%%%%%%%%%%%%%%%%%%%%%% Plot ERPimage %%%%%%%%%%%%%%%%%%%%%%%%%%%% 0692 0693 if dif_in_fnames, 0694 cmd=['erpimages(chan_data{chans_id1},chan_data2{chans_id2},']; 0695 else 0696 cmd=['erpimages(chan_data{chans_id1},chan_data{chans_id2},']; 0697 end 0698 0699 cmd=[cmd 'srt_val1,srt_val2,chan1,chan2,' ... 0700 '"times",ep_times,' ... 0701 '"title",use_title,' ... 0702 '"img1_title",bin1_title,' ... 0703 '"img2_title",bin2_title,' ... 0704 '"stdev",p.Results.stdev,' ... 0705 '"decfactor",p.Results.decfactor,' ... 0706 '"cbarlimits",p.Results.cbarlimits,' ... 0707 '"cbartitle",p.Results.cbartitle,' ... 0708 '"yimglabel",p.Results.img_trialax_label,' ... 0709 '"yimgticks",p.Results.img_trialax_ticks,' ... 0710 '"timelimits",p.Results.timelimits,' ... 0711 '"sortvarlimits",p.Results.sortvarlimits,' ... 0712 '"erplimits",p.Results.erplimits,' ... 0713 '"erpdiflimits",p.Results.erpdiflimits,' ... 0714 '"yerplabel",p.Results.yerplabel,' ... 0715 '"erpgrid",p.Results.erpgrid,' ... 0716 '"topos",p.Results.topos,' ... 0717 '"chanlocs1",chanlocs,' ... 0718 '"chanlocs2",chanlocs2,' ... 0719 '"renorm",p.Results.renorm,' ... 0720 '"rmerp",p.Results.rmerp,' ... 0721 '"showsortvar",p.Results.showsortvar,' ... 0722 '"marktimes",p.Results.marktimes,' ... 0723 '"marktrials",p.Results.marktrials,' ... 0724 '"baseline",p.Results.baseline,' ... 0725 '"srate",srate,' ... 0726 '"filt",p.Results.filt);']; 0727 0728 %replace double quotes with single quotes 0729 dq_id=find(cmd=='"'); 0730 cmd(dq_id)=39; 0731 %display erpimage command if user wants max verbosity 0732 VerbReport('',3,VERBLEVEL); 0733 VerbReport('plot_erpimages function call:',3,VERBLEVEL); 0734 VerbReport(cmd,3,VERBLEVEL); 0735 VerbReport('',3,VERBLEVEL); 0736 0737 %Open/Select Figure 0738 if isempty(p.Results.fig_id) || ~p.Results.fig_id, 0739 figure; 0740 else 0741 figure(p.Results.fig_id);clf; 0742 end 0743 0744 eval(cmd); 0745 set(gcf,'name',['[' wind_title ']']); 0746 0747 0748 0749 function srt_val=get_svar_val(ep_info,rtbins,rtmsec,bins,sortby_rt,sort_var) 0750 %function srt_val=get_svar_val(ep_info,rtbins,rtmsec,bins,sortby_rt,sort_var) 0751 % 0752 % Extracts a vector of sorting values from variables taken from a .eim 0753 % file. 0754 % 0755 % Inputs: 0756 % ep_info - struct array of epoch information 0757 % rtbins - cell array indicating which values of rtmsec belong to which 0758 % bins 0759 % rtmsec - cell array containing reaction times for each epoch 0760 % bins - subset of bins to use 0761 % sortyby_rt - whether or not to sort by reaction time 0762 % sort_var - variable to sort on (e.g., 'rtmsec') 0763 % 0764 % Outputs: 0765 % srt_val - a vector of sorting values for each epoch 0766 % 0767 0768 %Extract data from specified bins and sorting variable from epoch info 0769 n_ep=length(ep_info); 0770 0771 0772 %%%%%%%%%%%%%%%%% Sorting Variable Values for FIRST Set of Bins 0773 srt_val=zeros(1,n_ep)*NaN; 0774 0775 %note, srt_val indicates which epochs are to be ignored with NaN values 0776 %erpimage.m automatically ignores epochs with NaN srt_var values 0777 for a=1:n_ep, 0778 %%%%%% use a subset of bins %%%%%% 0779 if ~isempty(bins), 0780 got_it=0; 0781 if sortby_rt, 0782 %make sure the RTs are the same for all bins 0783 %preallocate memory 0784 rt_ids=zeros(1,length(bins)); 0785 rt_ids_ct=0; 0786 for d=bins, 0787 rt_id=find(rtbins{a}==d); 0788 if ~isempty(rt_id), 0789 rt_ids_ct=rt_ids_ct+1; 0790 rt_ids(rt_ids_ct)=rt_id; 0791 end 0792 end 0793 if rt_ids_ct>0, 0794 uni_rt=unique(rtmsec{a}(rt_ids(1:rt_ids_ct))); 0795 if length(uni_rt)>1, 0796 error(sprintf(['Different bins have different RTs for epoch %d.\n' ... 0797 'You must specify bins that have the same RTs.'],a)); 0798 else 0799 srt_val(a)=uni_rt; %get the RT 0800 got_it=1; 0801 end 0802 end 0803 else %non-RT sorting variable 0804 for b=bins, 0805 for c=1:length(ep_info(a).eventtype), 0806 if strcmpi(ep_info(a).eventtype{c},['bin' int2str(b)]), %does this trial fall in a desired bin? 0807 %c=length(ep_info(a).eventtype); %break c loop 0808 %b=p.Results.bins(end); %break b loop 0809 cmnd=['srt_val(a)=ep_info(a).event' sort_var ';']; 0810 eval(cmnd); 0811 got_it=1; 0812 break; %break c loop 0813 end 0814 end 0815 if got_it, 0816 break; %break b loop 0817 end 0818 end 0819 end 0820 if ~got_it, %epoch not a member of desired bin 0821 srt_val(a)=NaN; 0822 end 0823 0824 %%%%%% no bins specified, use all bins %%%%%% 0825 else 0826 if sortby_rt, 0827 uni_rt=unique(rtmsec{a}); 0828 if length(uni_rt)>1, 0829 error(sprintf(['Different bins have different RTs for epoch %d.\n' ... 0830 'You must specify bins that have the same RTs.'],a)); 0831 else 0832 srt_val(a)=uni_rt; 0833 end 0834 else 0835 cmnd=['srt_val(a)=ep_info(a).event' sort_var ';']; 0836 eval(cmnd); 0837 end 0838 end 0839 end 0840 0841