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