0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 function event = importevent(event, oldevent, srate, varargin);
0077
0078 if nargin < 1
0079 help importevent;
0080 return;
0081 end;
0082
0083 I = [];
0084
0085
0086
0087 if ~isempty(oldevent), allfields = fieldnames(oldevent);
0088 else allfields = {}; end;
0089
0090 g = finputcheck( varargin, { 'fields' 'cell' [] {};
0091 'skipline' 'integer' [0 Inf] 0;
0092 'indices' 'integer' [1 Inf] [];
0093 'append' 'string' {'yes' 'no' '''yes''' '''no''' } 'yes';
0094 'timeunit' 'real' [0 Inf] 1;
0095 'event' { 'real' 'string' } [] [];
0096 'align' 'integer' [] NaN;
0097 'optimalign' 'string' { 'on' 'off' } 'on';
0098 'delim' {'integer' 'string'} [] char([9 32])}, 'importevent');
0099 if isstr(g), error(g); end;
0100 if ~isempty(g.indices), g.append = 'yes'; end;
0101 g.delim = char(g.delim);
0102
0103
0104
0105 if ~isempty(g.event)
0106 event = g.event;
0107 end;
0108
0109
0110
0111 g.align.val = g.align;
0112 if ~isnan(g.align.val)
0113 if isempty(oldevent)
0114 error('Setevent: no pre-existing event, cannot perform alignment');
0115 end;
0116 if ~isfield(oldevent, 'latency')
0117 error('Setevent: pre-existing events do not have a latency field for re-alignment');
0118 end;
0119 switch g.append
0120 case {'yes' '''yes'''}, disp('Setevent warning: using align, events should not be appended but erased');
0121 end;
0122 if g.align.val < 0
0123 g.align.event = oldevent(1).latency;
0124 else
0125 g.align.event = oldevent(g.align.val+1).latency;
0126 end
0127 g.align.nbevent = length(oldevent);
0128 g.oldevents = oldevent;
0129 g.align.txt = sprintf([ 'Check alignment between pre-existing (old) and loaded event' ...
0130 ' latencies:\nOld event latencies (10 first): %s ...\n' ], ...
0131 int2str(cell2mat({ oldevent(1:min(10, length(oldevent))).latency })));
0132 else
0133 g.oldevents = [];
0134 end;
0135
0136 tmpfields = fieldnames(g);
0137 event = oldevent;
0138
0139
0140 for curfield = tmpfields'
0141 if ~isempty(event), allfields = fieldnames(event);
0142 else allfields = {}; end;
0143 switch lower(curfield{1})
0144 case {'append', 'fields', 'skipline', 'indices', 'timeunit', 'align', 'delim' }, ;
0145 case 'event',
0146 switch g.append
0147 case { '''no''' 'no' }
0148 event = load_file_or_array( g.event, g.skipline, g.delim );
0149 allfields = g.fields(1:min(length(g.fields), size(event,2)));
0150 event = eeg_eventformat(event, 'struct', allfields);
0151
0152
0153 for index = 1:length(event)
0154 event(index).init_index = index;
0155 event(index).init_time = event(index).latency*g.timeunit;
0156 end;
0157 event = recomputelatency( event, 1:length(event), srate, ...
0158 g.timeunit, g.align, g.oldevents, g.optimalign);
0159 case { '''yes''' 'yes' }
0160
0161
0162 tmparray = load_file_or_array( g.event, g.skipline, g.delim );
0163 if isempty(g.indices) g.indices = [1:size(tmparray,1)] + length(event); end;
0164 if length(g.indices) ~= size(tmparray,1)
0165 error('Set error: number of row in file does not match the number of event given as input');
0166 end;
0167
0168
0169
0170 g.fields = getnewfields( g.fields, size(tmparray,2)-length(g.fields));
0171
0172
0173
0174 for eventfield = 1:size(tmparray,2)
0175
0176
0177
0178
0179 event = setstruct( event, g.fields{eventfield}, g.indices, tmparray(:,eventfield));
0180
0181
0182
0183
0184
0185
0186
0187
0188 end;
0189
0190
0191 offset = length(event)-size(tmparray,2);
0192 for index = 1:size(tmparray,2)
0193 event(index+offset).init_index = index;
0194 event(index+offset).init_time = event(index+offset).latency*g.timeunit;
0195 end;
0196 event = recomputelatency( event, g.indices, srate, g.timeunit, ...
0197 g.align, g.oldevents, g.optimalign);
0198 end;
0199 end;
0200 end;
0201
0202 if isempty(event)
0203 event = [];
0204 end;
0205
0206
0207
0208 if isfield(event, 'latency')
0209 try
0210 res = cellfun('isempty', { event.latency });
0211 res = find(res);
0212 if ~isempty(res)
0213 fprintf( 'importevent warning: %d/%d have invalid latencies and were removed\n', ...
0214 length(res), length(event));
0215 event( res ) = [];
0216 end;
0217 end;
0218 end;
0219
0220
0221
0222 function array = load_file_or_array( varname, skipline, delim );
0223 if isstr(varname) & exist(varname) == 2
0224
0225 array = loadtxt( varname, 'skipline', skipline, 'delim', delim );
0226
0227 else
0228
0229 if isstr(varname)
0230 array = evalin('base', varname);
0231 if ~iscell(array)
0232 array = mat2cell(array, ones(1, size(array,1)), ones(1, size(array,2)));
0233 end;
0234 else
0235 array = varname;
0236 end;
0237 end;
0238 return;
0239
0240
0241
0242 function event = recomputelatency( event, indices, srate, timeunit, align, oldevents, optimalign);
0243
0244
0245
0246 if ~isfield(event, 'latency'),
0247 if isfield(event, 'duration')
0248 error('A duration field cannot be defined if a latency field has not been defined');
0249 end;
0250 return;
0251 end;
0252 for index = indices
0253 event(index).latency = event(index).latency*srate*timeunit;
0254 if isfield(event, 'duration')
0255 event(index).duration = event(index).duration*srate*timeunit;
0256 end;
0257 end;
0258
0259
0260
0261 if ~isnan( align.val )
0262 if align.val >= 0, alignlatency = event(1).latency;
0263 else alignlatency = event(-align.val+1).latency;
0264 end;
0265 for index = indices
0266 event(index).latency = event(index).latency-alignlatency+align.event;
0267 end;
0268 if length(event) ~= align.nbevent
0269 disp([ 'Setevent warning: the number of pre-existing events do not correspond to the ' ...
0270 'number of event that were read, so their latencies may have been wrongly re-aligned' ]);
0271 end;
0272 fprintf(align.txt);
0273 fprintf('New event latencies (10 first): %s ...\n', int2str(round(cell2mat({ event(1:min(10, length(event))).latency }))));
0274 end;
0275 if strcmpi(optimalign, 'on') & ~isempty(oldevents)
0276 newlat = cell2mat({ event.latency });
0277 oldlat = cell2mat({ oldevents.latency });
0278
0279 newlat = repmat(newlat, [length(oldlat) 1]);
0280 oldlat = repmat(oldlat', [1 size(newlat,2)]);
0281 if align.val >= 0
0282 newlat = newlat-newlat(1);
0283 oldlat = oldlat-oldlat(1+align.val);
0284 else
0285 newlat = newlat-newlat(1-align.val);
0286 oldlat = oldlat-oldlat(1);
0287 end;
0288
0289 newfactor = fminsearch('eventalign',1,[],newlat, oldlat);
0290 fprintf('Best sampling rate ratio found is %1.7f. Below latencies after adjustment\n', newfactor);
0291 if newfactor > 1.01 | newfactor < 0.99
0292 disp('Difference is more than 1%, something is wrong; ignoring ratio');
0293 newfactor = 1;
0294 end;
0295
0296
0297
0298
0299 else
0300 newfactor = 1;
0301 end;
0302 if ~isnan( align.val ) & newfactor ~= 1
0303 if align.val >= 0
0304 latfirstevent = event(1).latency;
0305 else
0306 latfirstevent = event(-align.val+1).latency;
0307 end;
0308 for index = setdiff(indices, 1)
0309 event(index).latency = round(event(index).latency-latfirstevent)*newfactor+latfirstevent;
0310 end;
0311 if ~isempty(oldevents)
0312 fprintf('Old event latencies (10 first): %s ...\n', int2str(round(cell2mat({ event(1:min(10, length(event))).latency }))));
0313 fprintf('New event latencies (10 first): %s ...\n', int2str(round(cell2mat({ oldevents(1:min(10, length(oldevents))).latency }))));
0314 end;
0315 else
0316
0317
0318 for index = indices
0319 event(index).latency = round((event(index).latency+1)*1000*newfactor)/1000;
0320 end;
0321 end;
0322
0323
0324
0325
0326 function epochfield = getnewfields( epochfield, nbfields )
0327 count = 1;
0328 while nbfields > 0
0329 if isempty( strmatch([ 'var' int2str(count) ], epochfield ) )
0330 epochfield = { epochfield{:} [ 'var' int2str(count) ] };
0331 nbfields = nbfields-1;
0332 else count = count+1;
0333 end;
0334 end;
0335 return;
0336
0337 function var = setstruct( var, fieldname, indices, values )
0338 if exist('indices') ~= 1, indices = 1:length(var); end;
0339 for index = 1:length(indices)
0340 var = setfield(var, {indices(index)}, fieldname, values{index});
0341
0342 end;
0343 return;