-
Notifications
You must be signed in to change notification settings - Fork 16
/
mff_importevents.m
244 lines (213 loc) · 10.4 KB
/
mff_importevents.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
% mff_importevents - import information from MFF 'eventsxxxxx.xml'
% files. If several files are detected, information
% from all files is imported.
%
% Usage:
% [events, timezone] = mff_importevents(mffFile, begTime, srate, correctevents);
%
% Inputs:
% mffFile - filename/foldername for the MFF file
% begTime - [float] time onset of the experiment
% srate - [float] sampling rate
% correctevents - [0|1] correct (overwrite) event files who have special
% characters and cannot be imported by the Java library
% (default is 0 or false)
%
% Output:
% events - EEGLAB event structure
% timezone - time zone
% This file is part of mffmatlabio.
%
% mffmatlabio is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% mffmatlabio is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with mffmatlabio. If not, see <https://www.gnu.org/licenses/>.
function [events, timeZone] = mff_importevents(mffFile, begTime, srate, correctEvents)
events = [];
timeZone = [];
mff_path;
if nargin < 4
correctEvents = false;
end
% create a factory
mfffactorydelegate = javaObject('com.egi.services.mff.api.LocalMFFFactoryDelegate');
mfffactory = javaObject('com.egi.services.mff.api.MFFFactory', mfffactorydelegate);
% Create Signal object and read in event track file.
% Note that 3 is the value associated with the event track resource type.
eventFile = dir( fullfile(mffFile, 'Events_*.xml'));
if isempty(eventFile), return; end
timeZone = [];
eventCount = 1;
showWarning = true;
% use vararg2str to save events so they may be exported
eeglabExport = true;
if ~exist('vararg2str', 'file')
eeglabExport = false;
end
for iEvent = 1:length(eventFile)
if eventFile(iEvent).bytes == 0
fprintf(2, 'Empty event file detected %s\n', fullfile( eventFile(iEvent).folder, eventFile(iEvent).name));
continue
end
eventtrackfilename = fullfile( eventFile(iEvent).folder, eventFile(iEvent).name);
if correctEvents
disp('Overwriting event files and removing special characters');
fixcharabove128(eventtrackfilename);
end
eventtracktype = javaObject('com.egi.services.mff.api.MFFResourceType', javaMethod('valueOf', 'com.egi.services.mff.api.MFFResourceType$MFFResourceTypes', 'kMFF_RT_EventTrack'));
eventtrackObj = mfffactory.openResourceAtURI(eventtrackfilename, eventtracktype);
% scan file and rewrite special characters
try
res = eventtrackObj.loadResource();
catch
error('Error loading event file. Try calling the function pop_mffimport from the command line and set the option to correct events.');
end
if res
name = eventtrackObj.getName();
trackType = eventtrackObj.getTrackType();
eventlist = eventtrackObj.getEvents();
nevents = eventlist.size();
fprintf('Importing %d events from file %s...\n', nevents, eventFile(iEvent).name);
% Read through each event track and inspect count of events
% and beginTime for last event in each.
if nevents>0
multiplier = 24*60*60*srate;
events(nevents).description = ''; % create last event
for eventnum = 1:nevents
eventObj = eventlist.get(eventnum-1);
% Get keys for event and display key codes
events(eventCount).begintime = char(eventObj.getBeginTime());
if events(eventCount).begintime(end-1) == '-'
events(eventCount).begintime = [ events(eventCount).begintime(1:end-1) '0' events(eventCount).begintime(end) ':00' ];
elseif events(eventCount).begintime(end-2) == '-'
events(eventCount).begintime = [ events(eventCount).begintime(1:end-2) events(eventCount).begintime(end) ':00' ];
end
events(eventCount).classid = char(eventObj.getClassID());
events(eventCount).code = char(eventObj.getCode());
events(eventCount).description = char(eventObj.getDescription());
events(eventCount).duration = eventObj.getDuration();
events(eventCount).label = char(eventObj.getLabel());
events(eventCount).relativebegintime = eventObj.getRelativeBeginTime();
events(eventCount).sourcedevice = char(eventObj.getSourceDevice());
events(eventCount).name = char(name);
events(eventCount).tracktype = char(trackType);
% compute latency in days with ms -> convert to samples
% eventCount = 1;
if events(eventCount).relativebegintime > 0 % for data epochs, this is required
events(eventCount).latency = events(eventCount).relativebegintime / 1000000 * srate;
% see bug 44, STAT events are supposed to be 42 ms
% before the time locking events, this fixes the problem
else
events(eventCount).latency = (mff_decodetime(events(eventCount).begintime)-begTime)*multiplier;
end
% dual time recoding
% tmp = mff_encodetime(events(eventCount).latency/multiplier+begTime, '08:00')
% fprintf('%s\n%s\n', events(eventCount).begintime, tmp);
events(eventCount).type = events(eventCount).code;
% import keys
keylist = eventObj.getKeys();
events = mff_importkeys(events, eventCount, keylist, eeglabExport);
eventCount = eventCount+1;
end
end
else
fprintf('Could not load event file %s\n', eventtrackfilename);
end
end
if ~isempty(events)
% get the time zone (duplicate code in mff_importevents and mff_importinfo)
minusSign = find(events(end).begintime == '+');
if isempty(minusSign)
minusSign = find(events(end).begintime == '-');
minusSign = minusSign(end);
end
timeZone = events(end).begintime(minusSign(end):end);
if length(timeZone) > 6
timeZone = [];
disp('Issue with decoding the time zone');
end
end
% % same as above but 10% faster. Was not retained because the increased
% % complexitity. Does not support importing keys
%
% begintime = cell(1,eventcount);
% classid = cell(1,eventcount);
% code = cell(1,eventcount);
% description = cell(1,eventcount);
% duration = cell(1,eventcount);
% label = cell(1,eventcount);
% relativebegintime = cell(1,eventcount);
% sourcedevice = cell(1,eventcount);
% eventkeys = cell(1,eventcount);
% for eventnum = 1:eventcount
%
% eventObj = eventlist.get(eventnum-1);
%
% % Get keys for event and display key codes
% begintime{eventnum} = eventObj.getBeginTime();
% classid{eventnum} = eventObj.getClassID();
% code{eventnum} = eventObj.getCode();
% description{eventnum} = eventObj.getDescription();
% duration{eventnum} = eventObj.getDuration();
% label{eventnum} = eventObj.getLabel();
% relativebegintime{eventnum} = eventObj.getRelativeBeginTime();
% sourcedevice{eventnum} = eventObj.getSourceDevice();
% eventkeys{eventnum} = eventObj.getKeys();
%
% end
%
% disp('Converting events to Matlab format...')
% begintime = cellfun(@(x)char(x), begintime, 'uniformoutput', false);
% begintime2 = cellfun(@(x)mff_decodetime(x), begintime, 'uniformoutput', false);
% classid = cellfun(@(x)char(x), classid, 'uniformoutput', false);
% code = cellfun(@(x)char(x), code, 'uniformoutput', false);
% description = cellfun(@(x)char(x), description, 'uniformoutput', false);
% label = cellfun(@(x)char(x), label, 'uniformoutput', false);
% relativebegintime = cellfun(@(x)char(x), relativebegintime, 'uniformoutput', false);
% sourcedevice = cellfun(@(x)char(x), sourcedevice, 'uniformoutput', false);
% eventkeys = cellfun(@(x)char(x), eventkeys, 'uniformoutput', false);
%
% events = struct('begintime', begintime, 'latency', begintime2, 'classid', classid, 'code', code, 'description', description, ...
% 'label', label, 'relativebegintime', relativebegintime, 'sourcedevice', sourcedevice, 'eventkeys', eventkeys);
% Save as above but not faster
% eventlist = eventlist.toArray;
% eventlist = cell(eventlist);
%
% begintime = cellfun(@(x)char(x.getBeginTime()), eventlist, 'uniformoutput', false);
% begintime2 = cellfun(@(x)mff_decodetime(x), begintime, 'uniformoutput', false);
% classid = cellfun(@(x)char(x.getClassID()), eventlist, 'uniformoutput', false);
% code = cellfun(@(x)char(x.getCode()), eventlist, 'uniformoutput', false);
% description = cellfun(@(x)char(x.getDescription()), eventlist, 'uniformoutput', false);
% label = cellfun(@(x)char(x.getLabel()), eventlist, 'uniformoutput', false);
% sourcedevice = cellfun(@(x)char(x.getSourceDevice()), eventlist, 'uniformoutput', false);
% eventkeys = cellfun(@(x)char(x.getKeys()), eventlist, 'uniformoutput', false);
%
% relativebegintime = cellfun(@(x)x.getRelativeBeginTime(), eventlist, 'uniformoutput', false);
% duration = cellfun(@(x)x.getDuration(), eventlist, 'uniformoutput', false);
%
% events = struct('begintime', begintime, 'latency', begintime2, 'classid', classid, 'code', code, 'type', code, 'description', description, ...
% 'label', label, 'duration', duration, 'relativebegintime', relativebegintime, 'sourcedevice', sourcedevice, 'eventkeys', eventkeys);
function fixcharabove128(fileName1)
fileName2 = [ fileName1 'x' ];
fid1 = fopen(fileName1, 'r');
fid2 = fopen(fileName2, 'w');
if fid1 == -1, error('Cannot open file %s', fileName1); end
if fid2 == -1, error('Cannot open file %s', fileName2); end
while ~feof(fid1)
str = fgetl(fid1);
str(str > 128) = ' ';
fprintf(fid2, '%s\n', str);
end
fclose(fid1);
fclose(fid2);
delete(fileName1);
copyfile(fileName2, fileName1);
delete(fileName2);