evcode_info2set() - Imports information about types of an experimental event into an EEGLAB .set file from a text file. The new event information (e.g., cloze probability, event duration) is added to the EEG.event and EEG.epoch fields of the EEG struct variable. Usage: >> evcode_info2set(in_setfile,code_infofile,out_setfile,use_ccode,forcewrite,verblevel) Inputs: in_setfile = [string] the name of the source EEGLAB .set file (include the file's pathname unless it is in the current working directory). code_infofile = [string] a space or tab delimited text file containing additional information (numeric or strings) about types of experimental events. The first row of the file is a header line with a one word description of each column in the file. Each row below the headerline corresponds to a different experimental event. The first column of the file specifies the event code (the number that shows up as "Event #" in Kutaslab log files. Additional columns specificy event information (e.g., the cloze probability of the stimulus). This file can specify information in a way that depends on condition codes. To do this, the second column of the file must indicate the condition code. Optional Inputs: out_setfile = [string] the name of the EEGLAB .set file that will be written to (include the file's pathname unless it is in the current working directory) {default: same as in_setfile} use_ccode = ['on' | 'off'] If 'on', the function will add the event information in a way that depends on condition codes. To use this feature, the second column of code_infofile must specifiy the condition code for each row. {default: 'off'} forcewrite = ['on' | 'off'] If 'on', the function will automatically overwrite any pre-existing event information in the .set file that contradicts the event information in code_infofile. If 'off,' the user will be asked whether or not to overwrite any such pre-existing information. {default: 'off'} 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 verblevel not already specified} 3 - stuff that might help you debug (show all reports) Outputs: Function outputs nothing in Matlab. It simply writes/overwites a .set file to disk. Example: >> in_fname='/homes/dgroppe/SANDBOX/PRSENT/prsent41.set'; >> code_infofile='/homes/dgroppe/SANDBOX/PRSENT/tone_durations.txt'; >> evcode_info2set(in_fname,code_infofile,'temp.set'); Additional Notes: Don't use parenthesis in column header names. MATLAB interprets the name as a function call. Use NaN to fill cells for codes that don't have a value for a particular column Author: David Groppe Kutaslab, 8/2009
0001 function evcode_info2set(in_setfile,code_infofile,out_setfile,use_ccode,forcewrite,verblevel) 0002 % 0003 % evcode_info2set() - Imports information about types of an experimental 0004 % event into an EEGLAB .set file from a text file. 0005 % The new event information (e.g., cloze probability, 0006 % event duration) is added to the EEG.event and 0007 % EEG.epoch fields of the EEG struct variable. 0008 % 0009 % Usage: 0010 % >> evcode_info2set(in_setfile,code_infofile,out_setfile,use_ccode,forcewrite,verblevel) 0011 % 0012 % 0013 % Inputs: 0014 % in_setfile = [string] the name of the source EEGLAB .set file 0015 % (include the file's pathname unless it is in the 0016 % current working directory). 0017 % 0018 % code_infofile = [string] a space or tab delimited text file 0019 % containing additional information (numeric or 0020 % strings) about types of experimental events. The 0021 % first row of the file is a header line with a 0022 % one word description of each column in the 0023 % file. Each row below the headerline 0024 % corresponds to a different experimental event. 0025 % The first column of the file specifies the event 0026 % code (the number that shows up as "Event #" in 0027 % Kutaslab log files. Additional columns 0028 % specificy event information (e.g., 0029 % the cloze probability of the stimulus). This file 0030 % can specify information in a way that depends on 0031 % condition codes. To do this, the second column of 0032 % the file must indicate the condition code. 0033 % 0034 % Optional Inputs: 0035 % out_setfile = [string] the name of the EEGLAB .set file that will 0036 % be written to (include the file's pathname unless 0037 % it is in the current working directory) {default: 0038 % same as in_setfile} 0039 % 0040 % use_ccode = ['on' | 'off'] If 'on', the function will add the 0041 % event information in a way that depends on condition 0042 % codes. To use this feature, the second column of 0043 % code_infofile must specifiy the condition code for 0044 % each row. {default: 'off'} 0045 % 0046 % forcewrite = ['on' | 'off'] If 'on', the function will 0047 % automatically overwrite any pre-existing event 0048 % information in the .set file that contradicts the 0049 % event information in code_infofile. If 'off,' the 0050 % user will be asked whether or not to overwrite any 0051 % such pre-existing information. {default: 'off'} 0052 % 0053 % verblevel = an integer specifiying the amount of information you 0054 % want functions to provide about what they are doing 0055 % during runtime. 0056 % Options are: 0057 % 0 - quiet, only show errors, warnings, and EEGLAB 0058 % reports 0059 % 1 - stuff anyone should probably know 0060 % 2 - stuff you should know the first time you start 0061 % working with a data set {default value if 0062 % verblevel not already specified} 0063 % 3 - stuff that might help you debug (show all 0064 % reports) 0065 % 0066 % Outputs: 0067 % Function outputs nothing in Matlab. It simply writes/overwites a .set 0068 % file to disk. 0069 % 0070 % 0071 % Example: 0072 % >> in_fname='/homes/dgroppe/SANDBOX/PRSENT/prsent41.set'; 0073 % >> code_infofile='/homes/dgroppe/SANDBOX/PRSENT/tone_durations.txt'; 0074 % >> evcode_info2set(in_fname,code_infofile,'temp.set'); 0075 % 0076 % 0077 % Additional Notes: 0078 % 0079 % Don't use parenthesis in column header names. MATLAB interprets 0080 % the name as a function call. 0081 % 0082 % Use NaN to fill cells for codes that don't have a value for a 0083 % particular column 0084 % 0085 % Author: 0086 % David Groppe 0087 % Kutaslab, 8/2009 0088 % 0089 0090 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%% 0091 % 0092 % 10/07/09 Function can now add information as strings to EEG struct. 0093 % 0094 0095 0096 global VERBLEVEL 0097 0098 %Check Inputs 0099 if ~ischar(in_setfile), 0100 error('Argument in_setfile needs to be a string that specifies an EEGLAB .set file.'); 0101 end 0102 0103 if ~ischar(code_infofile), 0104 error('Argument code_infofile needs to be a string that specifies a text file.'); 0105 end 0106 0107 if nargin<3, 0108 out_setfile=in_setfile; %default: output file same as input file 0109 VerbReport('New set file will overwrite old set file (default behavior).', ... 0110 2, VERBLEVEL); 0111 else 0112 if ~ischar(out_setfile), 0113 error('Argument out_setfile needs to be a string that specifies an EEGLAB .set file.'); 0114 end 0115 end 0116 0117 if nargin<4, 0118 use_ccode='off'; 0119 elseif (~strcmpi(use_ccode,'on') && ~strcmpi(use_ccode,'off')) 0120 error('Argument "use_ccode" needs to be set to ''on'' or ''off''.'); 0121 end 0122 0123 if nargin<5, 0124 forcewrite='off'; 0125 elseif (~strcmpi(forcewrite,'on') && ~strcmpi(forcewrite,'off')) 0126 error('Argument "forcewrite" needs to be set to ''on'' or ''off''.'); 0127 end 0128 0129 if nargin<6 0130 if isempty(VERBLEVEL), 0131 VERBLEVEL=2; %default 0132 end 0133 else 0134 VERBLEVEL=verblevel; 0135 end 0136 0137 0138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0139 % LOAD .set FILE 0140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0141 EEG=pop_loadset(in_setfile); 0142 0143 0144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0145 % LOAD INFORMATION ABOUT EACH CLASS OF EXPERIMENTAL EVENT (e.g. TARGETS & STANDARDS) FROM A TEXT FILE 0146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0147 VerbReport(sprintf('Getting additional information about stim/response classes of events from %s', ... 0148 code_infofile), 1, VERBLEVEL); 0149 [ev_fid, message]=fopen(code_infofile,'r'); 0150 if (ev_fid==-1), 0151 fprintf('*************** ERROR ******************\n'); 0152 fprintf('Cannot open file %s.\n',code_infofile); 0153 fprintf('According to fopen: %s.\n',message); 0154 error('Aborting import of additional stim/response class information.'); 0155 else 0156 %read column headers 0157 txtline = fgetl(ev_fid); 0158 if (txtline==-1), 0159 fprintf('*************** ERROR ******************\n'); 0160 fprintf('File %s is empty.\n',ev_fid); 0161 error('Aborting import of additional stim/response class information.'); 0162 else 0163 %Parse column header 0164 clear ev_col_hdrs; 0165 col_ct=1; 0166 [ev_col_hdrs{col_ct}, rmndr]=strtok(txtline); 0167 fprintf('Stim/resp code column is: %s\n',ev_col_hdrs{col_ct}); 0168 0169 if strcmpi(use_ccode,'on') 0170 col_ct=col_ct+1; 0171 [ev_col_hdrs{col_ct}, rmndr]=strtok(rmndr); 0172 fprintf('Condition code column is: %s\n',ev_col_hdrs{col_ct}); 0173 end 0174 0175 while ~isempty(rmndr) && charleft(rmndr), 0176 col_ct=col_ct+1; 0177 [ev_col_hdrs{col_ct}, rmndr]=strtok(rmndr); 0178 fprintf('Column %d is: %s\n',col_ct,ev_col_hdrs{col_ct}); 0179 end 0180 0181 %Read stim/resp class information 0182 row_ct=1; 0183 while ~feof(ev_fid) 0184 txtline = fgetl(ev_fid); 0185 col_ct=1; 0186 while ~isempty(txtline) && charleft(txtline), 0187 [neo_val, txtline]=strtok(txtline); 0188 file_ev_info{row_ct,col_ct}=neo_val; 0189 if col_ct==1, 0190 %First column is assumed to be stim/response codes 0191 stimresp_code(row_ct)=str2double(neo_val); %use this below to check for redundant codes 0192 elseif col_ct==2, 0193 %First column is assumed to be condition codes (if 0194 %use_ccode option is on) 0195 cndtn_code(row_ct)=str2double(neo_val); %use this below to check for redundant codes in the same condition 0196 end 0197 col_ct=col_ct+1; 0198 end 0199 row_ct=row_ct+1; 0200 end 0201 0202 if strcmpi(use_ccode,'off') 0203 %Check to make sure each event class only occurs once: 0204 uni=unique(stimresp_code); 0205 if length(uni)~=length(stimresp_code), 0206 fprintf('*************** ERROR ******************\n'); 0207 fprintf('evcode_info2set.m: Your file %s has the same ',code_infofile); 0208 fprintf('code on multiple rows.\n'); 0209 fprintf('All the information for a single stim/response code should '); 0210 fprintf('be on one row.\n'); 0211 fprintf(['Only the topmost row for each code will be' ... 0212 ' imported.\n']); 0213 error('Aborting input of %s.\n',code_infofile); 0214 end 0215 else 0216 %Check to make sure each event class only occurs once per 0217 %condition code 0218 ccodes=unique(cndtn_code); 0219 for cc=ccodes, 0220 cc_id=find(cndtn_code==cc); 0221 uni=unique(stimresp_code(cc_id)); 0222 if length(uni)~=length(cc_id), 0223 fprintf('*************** ERROR ******************\n'); 0224 fprintf('evcode_info2set.m: Your file %s has the same ',code_infofile); 0225 fprintf('event code on multiple rows for Condition Code %d.\n',cc); 0226 fprintf('All the information for a single stim/response code in a single condition code should be on one row.'); 0227 error('Aborting input of %s.\n',code_infofile); 0228 end 0229 end 0230 end 0231 0232 end 0233 fclose(ev_fid); 0234 end 0235 0236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0237 % ADD NEW EPOCH INFORMATION TO EEG STRUCT 0238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0239 0240 fldnames=fieldnames(EEG.epoch); 0241 0242 if strcmpi(use_ccode,'off') 0243 startcol=2; 0244 else 0245 startcol=3; 0246 end 0247 0248 %for each new column (assume first column is event code) 0249 for a=startcol:length(ev_col_hdrs), 0250 doit=1; 0251 %check to make sure column does not already exist 0252 for b=1:length(fldnames), 0253 if strcmpi(['event' ev_col_hdrs{a}],fldnames{b}), 0254 if ~strcmpi(forcewrite,'on') 0255 %ask user if s/he wants to overwrite 0256 fprintf('Field %s already exists in %s.\n',ev_col_hdrs{a},EEG.filename); 0257 erayz=input('Do you want to overwrite existing field? ("y" or "n"): ','s'); 0258 while ~strcmpi(erayz,'y') && ~strcmpi(erayz,'n') 0259 erayz=input('Please enter the single letter "y" or "n": ','s'); 0260 end 0261 else 0262 erayz='y'; 0263 end 0264 if strcmpi(erayz,'n') 0265 fprintf('NOT overwriting EEG.%s.\n',fldnames{b}); 0266 doit=0; 0267 break; 0268 else 0269 fprintf('OVERWRITING EEG.%s.\n',fldnames{b}); 0270 EEG.epoch=rmfield(EEG.epoch,fldnames{b}); 0271 EEG.event=rmfield(EEG.event,fldnames{b}(6:end)); %starting at 6 ignores 'event' 0272 break; 0273 end 0274 end 0275 end 0276 0277 %write new event info to struct 0278 if doit, 0279 %add to EEG.epoch 0280 for c=1:length(EEG.epoch), 0281 if strcmpi(use_ccode,'off'), 0282 info_id=find(stimresp_code==EEG.epoch(c).eventevcode); 0283 else 0284 info_id1=find(stimresp_code==EEG.epoch(c).eventevcode); 0285 info_id2=find(cndtn_code==EEG.epoch(c).eventccode); 0286 info_id=intersect(info_id1,info_id2); 0287 end 0288 if isempty(info_id) 0289 cmd=['EEG.epoch(' int2str(c) ').event' ev_col_hdrs{a} '=NaN;']; %Event code is not listed in file 0290 else 0291 if isempty(str2num(file_ev_info{info_id,a})) 0292 %new info is a string 0293 cmd=['EEG.epoch(' int2str(c) ').event' ev_col_hdrs{a} '=''' file_ev_info{info_id,a} ''';']; 0294 else 0295 %new info is a number 0296 %cmd=['EEG.epoch(' int2str(c) ').event' ev_col_hdrs{a} '=' num2str(file_ev_info{info_id,a}) ';']; 0297 cmd=['EEG.epoch(' int2str(c) ').event' ev_col_hdrs{a} '=' file_ev_info{info_id,a} ';']; 0298 end 0299 end 0300 eval(cmd); 0301 end 0302 0303 %add to EEG.event 0304 for c=1:length(EEG.event), 0305 if strcmpi(use_ccode,'off'), 0306 info_id=find(stimresp_code==EEG.event(c).evcode); 0307 else 0308 info_id1=find(stimresp_code==EEG.event(c).evcode); 0309 info_id2=find(cndtn_code==EEG.event(c).ccode); 0310 info_id=intersect(info_id1,info_id2); 0311 end 0312 if isempty(info_id) 0313 cmd=['EEG.event(' int2str(c) ').' ev_col_hdrs{a} '=NaN;']; %Event code is not listed in file 0314 else 0315 if isempty(str2num(file_ev_info{info_id,a})) 0316 %new info is a string 0317 cmd=['EEG.event(' int2str(c) ').' ev_col_hdrs{a} '=''' file_ev_info{info_id,a} ''';']; 0318 else 0319 %new info is a number 0320 cmd=['EEG.event(' int2str(c) ').' ev_col_hdrs{a} '=' file_ev_info{info_id,a} ';']; 0321 end 0322 end 0323 eval(cmd); 0324 end 0325 end 0326 end 0327 0328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0329 % SAVE .set FILE 0330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0331 0332 [fpath, fname]=pathNname(out_setfile); 0333 EEG=pop_saveset(EEG,'filepath',fpath,'filename',fname); 0334 0335 end 0336 0337 0338 function yesno=charleft(str) 0339 0340 0341 yesno=0; 0342 for x=1:length(str), 0343 if (str(x)~=32) && (str(x)~=13) 0344 %32=space, 13=carriage return 0345 yesno=1; 0346 break; 0347 end 0348 end 0349 0350 0351 end