TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
sopen.m
Go to the documentation of this file.
1 function [HDR,H1,h2] = sopen(arg1,PERMISSION,CHAN,MODE,arg5,arg6)
2 % SOPEN opens signal files for reading and writing and returns
3 % the header information. Many different data formats are supported.
4 %
5 % Reading of data:
6 % HDR = sopen(Filename, 'r', [, CHAN [, MODE]]);
7 % [S,HDR] = sread(HDR, NoR, StartPos);
8 % HDR = sclose(HDR);
9 %
10 % Writing of data:
11 % HDR = sopen(HDR, 'w');
12 % writing requires a predefined HDR struct. see demo3.m
13 %
14 % 2nd argument (PERMISSION) is one of the following strings
15 % 'r' read header
16 % 'w' write header
17 % 'rz' on-the-fly decompression of gzipped files (only supported with Octave 2.9.3 or higher).
18 % 'wz' on-the-fly compression to gzipped files (only supported with Octave 2.9.3 or higher).
19 %
20 % CHAN defines a list of selected Channels
21 % Alternative CHAN can be also a Re-Referencing Matrix ReRefMx,
22 % (i.e. a spatial filter) in form of a matrix or a
23 % filename of a MarketMatrix format
24 % E.g. the following command returns the difference and
25 % the mean of the first two channels.
26 % HDR = sopen(Filename, 'r', [[1;-1],[.5,5]]);
27 % [S,HDR] = sread(HDR, Duration, Start);
28 % HDR = sclose(HDR);
29 %
30 % MODE 'UCAL' uncalibrated data
31 % 'OVERFLOWDETECTION:OFF' turns off automated overflow detection
32 % 'OUTPUT:SINGLE' returned data is of class 'single' [default: 'double']
33 % '32bit' for NeuroScan CNT files reading 4-byte integer data
34 % 'BDF:[n]' with [n] some integer number supported by bdf2biosig_events.m
35 % for details see HELP BDF2BIOSIG_EVENTS
36 % Options can be concatenated within MODE (use some space, tab, colon or
37 % semicolon in between).
38 %
39 % HDR contains the Headerinformation and internal data
40 % S returns the signal data
41 %
42 % Several files can be loaded at once with SLOAD
43 %
44 % see also: SLOAD, SREAD, SSEEK, STELL, SCLOSE, SWRITE, SEOF, BDF2BIOSIG_EVENTS
45 
46 
47 % $Id: sopen.m 3165 2012-12-03 13:39:25Z schloegl $
48 % (C) 1997-2006,2007,2008,2009,2011,2012 by Alois Schloegl <alois.schloegl@gmail.com>
49 % This is part of the BIOSIG-toolbox http://biosig.sf.net/
50 %
51 % BioSig is free software: you can redistribute it and/or modify
52 % it under the terms of the GNU General Public License as published by
53 % the Free Software Foundation, either version 3 of the License, or
54 % (at your option) any later version.
55 %
56 % BioSig is distributed in the hope that it will be useful,
57 % but WITHOUT ANY WARRANTY; without even the implied warranty of
58 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59 % GNU General Public License for more details.
60 %
61 % You should have received a copy of the GNU General Public License
62 % along with BioSig. If not, see <http://www.gnu.org/licenses/>.
63 
64 
65 if isnan(str2double('1, 3'));
66  fprintf(2,'Warning BIOSIG: incorrect version of STR2DOUBLE.\n');
67  fprintf(2,'- Make sure the path to this directory comes before the path to ... /matlab/toolbox/matlab/strfun/\n');
68  fprintf(2,'Running the script below should fix the problem. \n\n');
69  fprintf(2,' x = fileparts( which(''sopen'') );\n');
70  fprintf(2,' rmpath(x);\n addpath(x,''-begin'');\n\n');
71 end;
72 
73 global FLAG_NUMBER_OF_OPEN_FIF_FILES;
74 
75 if ischar(arg1),
76  HDR.FileName = arg1;
77  HDR.FILE.stdout = 1;
78  HDR.FILE.stderr = 2;
79 %elseif length(arg1)~=1,
80 % HDR = [];
81 elseif isfield(arg1,'name')
82  HDR.FileName = arg1.name;
83  HDR.FILE = arg1;
84  HDR.FILE.stdout = 1;
85  HDR.FILE.stderr = 2;
86 else %if isfield(arg1,'FileName')
87  HDR = arg1;
88 %else
89 % HDR = [];
90 end;
91 
92 if ~isfield(HDR,'FILE'),
93  HDR.FILE.stdout = 1;
94  HDR.FILE.stderr = 2;
95 end;
96 if ~isfield(HDR.FILE,'stdout'),
97  HDR.FILE.stdout = 1;
98 end;
99 if ~isfield(HDR.FILE,'stderr'),
100  HDR.FILE.stderr = 2;
101 end;
102 
103 if nargin<3, CHAN = 0; end;
104 if nargin<4, MODE = ''; end;
105 if nargin<2,
106  HDR.FILE.PERMISSION='r';
107 elseif isempty(PERMISSION),
108  HDR.FILE.PERMISSION='r';
109 elseif isnumeric(PERMISSION),
110  fprintf(HDR.FILE.stderr,'Warning SOPEN: second argument should be PERMISSION, assume its the channel selection\n');
111  CHAN = PERMISSION;
112  HDR.FILE.PERMISSION = 'r';
113 elseif ~any(PERMISSION(1)=='RWrw'),
114  fprintf(HDR.FILE.stderr,'Warning SOPEN: PERMISSION must be ''r'' or ''w''. Assume PERMISSION is ''r''\n');
115  HDR.FILE.PERMISSION = 'r';
116 else
117  HDR.FILE.PERMISSION = PERMISSION;
118 end;
119 
120 LABELS = {};
121 if iscell(CHAN),
122  LABELS = CHAN;
123  CHAN = 0;
124  ReRefMx = [];
125 elseif ischar(CHAN)
126  H2 = sopen(CHAN,'r'); H2=sclose(H2);
127  ReRefMx = H2.Calib;
128  CHAN = find(any(CHAN,2));
129 elseif all(size(CHAN)>1) || any(floor(CHAN)~=CHAN) || any(CHAN<0) || (any(CHAN==0) && (numel(CHAN)>1));
130  ReRefMx = CHAN;
131  CHAN = find(any(CHAN,2));
132 elseif all(CHAN>0) && all(floor(CHAN)==CHAN),
133  if any(diff(CHAN)<=0),
134  % fprintf(HDR.FILE.FID,'Warning SOPEN: CHAN-argument not sorted - header information like Labels might not correspond to data.\n');
135  end;
136  ReRefMx = sparse(CHAN,1:length(CHAN),1);
137 else
138  ReRefMx = [];
139 end
140 if isempty(MODE), MODE=' '; end; % Make sure MODE is not empty -> FINDSTR
141 
142 % test for type of file
143 if any(HDR.FILE.PERMISSION=='r'),
144  HDR = getfiletype(HDR);
145  if (HDR.ErrNum>0),
146  fprintf(HDR.FILE.stderr,'%s\n',HDR.ErrMsg);
147  return;
148  end;
149 elseif any(HDR.FILE.PERMISSION=='w'),
150  [pfad,file,FileExt] = fileparts(HDR.FileName);
151  HDR.FILE.Name = file;
152  HDR.FILE.Path = pfad;
153  HDR.FILE.Ext = FileExt(2:length(FileExt));
154  if any(HDR.FILE.PERMISSION=='z')
155  HDR.FILE.Ext = [HDR.FILE.Ext,'.gz'];
156  HDR.FileName = [HDR.FileName,'.gz'];
157  HDR.FILE.PERMISSION = 'wz';
158  else
159  HDR.FILE.PERMISSION = 'w';
160  end;
161  HDR.FILE.OPEN = 0;
162  HDR.FILE.FID = -1;
163  HDR.ErrNum = 0;
164  HDR.ErrMsg = '';
165 
166  if isfield(HDR,'NS') && (HDR.NS>0),
167  HDR = physicalunits(HDR);
168  end;
169 end;
170 
171 %% Initialization
172 if ~isfield(HDR,'NS');
173  HDR.NS = NaN;
174 end;
175 if ~isfield(HDR,'SampleRate');
176  HDR.SampleRate = NaN;
177 end;
178 if ~isfield(HDR,'PhysDim');
179 % HDR.PhysDim = '';
180 end;
181 if ~isfield(HDR,'T0');
182  HDR.T0 = repmat(nan,1,6);
183 end;
184 if ~isfield(HDR,'Filter');
185  HDR.Filter.Notch = NaN;
186  HDR.Filter.LowPass = NaN;
187  HDR.Filter.HighPass = NaN;
188 end;
189 if ~isfield(HDR,'FLAG');
190  HDR.FLAG = [];
191 end;
192 if ~isfield(HDR.FLAG,'FILT')
193  HDR.FLAG.FILT = 0; % FLAG if any filter is applied;
194 end;
195 if ~isfield(HDR.FLAG,'TRIGGERED')
196  HDR.FLAG.TRIGGERED = 0; % the data is untriggered by default
197 end;
198 if ~isfield(HDR.FLAG,'UCAL')
199  HDR.FLAG.UCAL = ~isempty(strfind(MODE,'UCAL')); % FLAG for UN-CALIBRATING
200 end;
201 if ~isfield(HDR.FLAG,'OVERFLOWDETECTION')
202  HDR.FLAG.OVERFLOWDETECTION = isempty(strfind(upper(MODE),'OVERFLOWDETECTION:OFF'));
203 end;
204 if ~isfield(HDR.FLAG,'FORCEALLCHANNEL')
205  HDR.FLAG.FORCEALLCHANNEL = ~isempty(strfind(upper(MODE),'FORCEALLCHANNEL'));
206 end;
207 if ~isfield(HDR.FLAG,'OUTPUT')
208  if ~isempty(strfind(upper(MODE),'OUTPUT:SINGLE'));
209  HDR.FLAG.OUTPUT = 'single';
210  else
211  HDR.FLAG.OUTPUT = 'double';
212  end;
213 end;
214 FLAG.BDF.status2event = regexp (MODE, '(^BDF:|[ \t;,]BDF:)(\d*)([ \t;,]|$)','tokens');
215 if ~isempty(FLAG.BDF.status2event)
216  FLAG.BDF.status2event = num2int(FLAG.BDF.status2event{1}{2})
217 end;
218 
219 if ~isfield(HDR,'EVENT');
220  HDR.EVENT.TYP = [];
221  HDR.EVENT.POS = [];
222 end;
223 %%%%% Define Valid Data types %%%%%%
224 %GDFTYPES=[0 1 2 3 4 5 6 7 16 17 255+(1:64) 511+(1:64)];
225 GDFTYPES=[0 1 2 3 4 5 6 7 16 17 18 255+[1 12 22 24] 511+[1 12 22 24]];
226 
227 %%%%% Define Size for each data type %%%%%
228 GDFTYP_BYTE=zeros(1,512+64);
229 GDFTYP_BYTE(256+(1:64))=(1:64)/8;
230 GDFTYP_BYTE(512+(1:64))=(1:64)/8;
231 GDFTYP_BYTE(1:19)=[1 1 1 2 2 4 4 8 8 4 8 0 0 0 0 0 4 8 16]';
232 
233 if strcmp(HDR.TYPE,'EDF') || strcmp(HDR.TYPE,'GDF') || strcmp(HDR.TYPE,'BDF'),
234  H2idx = [16 80 8 8 8 8 8 80 8 32];
235 
236  HDR.ErrNum = 0;
237  HANDEDNESS = {'unknown','right','left','equal'};
238  GENDER = {'X','Male','Female'};
239  SCALE13 = {'unknown','no','yes'};
240  SCALE14 = {'unknown','no','yes','corrected'};
241 
242  if any(HDR.FILE.PERMISSION=='r');
243  [HDR.FILE.FID]=fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
244 
245  if HDR.FILE.FID<0
246  HDR.ErrNum = [32,HDR.ErrNum];
247  return;
248  end;
249 
250  %%% Read Fixed Header %%%
251  [H1,count]=fread(HDR.FILE.FID,[1,192],'uint8'); %
252  if count<192,
253  HDR.ErrNum = [64,HDR.ErrNum];
254  return;
255  end;
256 
257  HDR.VERSION=char(H1(1:8)); % 8 Byte Versionsnummer
258  if ~(strcmp(HDR.VERSION,'0 ') || all(abs(HDR.VERSION)==[255,abs('BIOSEMI')]) || strcmp(HDR.VERSION(1:3),'GDF'))
259  HDR.ErrNum = [1,HDR.ErrNum];
260  if ~strcmp(HDR.VERSION(1:3),' '); % if not a scoring file,
261  % return;
262  end;
263  end;
264  if strcmp(char(H1(1:8)),'0 ')
265  HDR.VERSION = 0;
266  elseif all(abs(H1(1:8))==[255,abs('BIOSEMI')]),
267  HDR.VERSION = -1;
268  elseif all(H1(1:3)==abs('GDF'))
269  HDR.VERSION = str2double(char(H1(4:8)));
270  else
271  HDR.ErrNum = [1,HDR.ErrNum];
272  if ~strcmp(HDR.VERSION(1:3),' '); % if not a scoring file,
273  % return;
274  end;
275  end;
276 
277  HDR.Patient.Sex = 0;
278  HDR.Patient.Handedness = 0;
279 if 0,
280  HDR.Patient.Weight = NaN;
281  HDR.Patient.Height = NaN;
282  HDR.Patient.Impairment.Visual = NaN;
283  HDR.Patient.Smoking = NaN;
284  HDR.Patient.AlcoholAbuse = NaN;
285  HDR.Patient.DrugAbuse = NaN;
286  HDR.Patient.Medication = NaN;
287 end;
288  %if strcmp(HDR.VERSION(1:3),'GDF'),
289  if strcmp(HDR.TYPE,'GDF'),
290  if (HDR.VERSION >= 1.90)
291  HDR.PID = deblank(char(H1(9:84))); % 80 Byte local patient identification
292  HDR.RID = deblank(char(H1(89:156))); % 80 Byte local recording identification
293  [HDR.Patient.Id,tmp] = strtok(HDR.PID,' ');
294  HDR.Patient.Name = tmp(2:end);
295 
296  HDR.Patient.Medication = SCALE13{bitand(floor(H1(85)/64),3)+1};
297  HDR.Patient.DrugAbuse = SCALE13{bitand(floor(H1(85)/16),3)+1};
298  HDR.Patient.AlcoholAbuse = SCALE13{bitand(floor(H1(85)/4),3)+1};
299  HDR.Patient.Smoking = SCALE13{bitand(H1(85),3)+1};
300  tmp = abs(H1(86:87)); tmp(tmp==0) = NaN; tmp(tmp==255) = inf;
301  HDR.Patient.Weight = tmp(1);
302  HDR.Patient.Height = tmp(2);
303  HDR.Patient.Sex = bitand(H1(88),3); %GENDER{bitand(H1(88),3)+1};
304  HDR.Patient.Handedness = HANDEDNESS{bitand(floor(H1(88)/4),3)+1};
305  HDR.Patient.Impairment.Visual = SCALE14{bitand(floor(H1(88)/16),3)+1};
306  if H1(156)>0,
307  HDR.RID = deblank(char(H1(89:156)));
308  else
309  HDR.RID = deblank(char(H1(89:152)));
310  %HDR.REC.LOC.RFC1876 = 256.^[0:3]*reshape(H1(153:168),4,4);
311  HDR.REC.LOC.Version = abs(H1(156));
312  HDR.REC.LOC.Size = dec2hex(H1(155));
313  HDR.REC.LOC.HorizPre = dec2hex(H1(154));
314  HDR.REC.LOC.VertPre = dec2hex(H1(153));
315  end;
316  HDR.REC.LOC.Latitude = H1(157:160)*256.^[0:3]'/3600000;
317  HDR.REC.LOC.Longitude = H1(161:164)*256.^[0:3]'/3600000;
318  HDR.REC.LOC.Altitude = H1(165:168)*256.^[0:3]'/100;
319 
320  tmp = H1(168+[1:16]);
321  % little endian fixed point number with 32 bits pre and post comma
322  t1 = tmp(1:8 )*256.^[-4:3]';
323  HDR.T0 = datevec(t1);
324  t2 = tmp(9:16)*256.^[-4:3]';
325  HDR.Patient.Birthday = datevec(t2);
326  if (t2 > 1) && (t2 < t1),
327  HDR.Patient.Age = floor((t1-t2)/365.25);
328  end;
329  HDR.REC.Equipment = fread(HDR.FILE.FID,[1,8],'uint8');
330  tmp = fread(HDR.FILE.FID,[1,6],'uint8');
331  if (HDR.VERSION < 2.1)
332  HDR.REC.IPaddr = tmp(6:-1:1);
333  end;
334  tmp = fread(HDR.FILE.FID,[1,3],'uint16');
335  tmp(tmp==0)=NaN;
336  HDR.Patient.Headsize = tmp;
337  tmp = fread(HDR.FILE.FID,[3,2],'float32');
338  HDR.ELEC.REF = tmp(:,1)';
339  HDR.ELEC.GND = tmp(:,2)';
340  else
341  HDR.PID = deblank(char(H1(9:88))); % 80 Byte local patient identification
342  HDR.RID = deblank(char(H1(89:168))); % 80 Byte local recording identification
343  [HDR.Patient.Id,tmp] = strtok(HDR.PID,' ');
344  HDR.Patient.Name = tmp(2:end);
345 
346  tmp = repmat(' ',1,22);
347  tmp([1:4,6:7,9:10,12:13,15:16,18:21]) = char(H1(168+[1:16]));
348  HDR.T0(1:6) = str2double(tmp);
349  HDR.T0(6) = HDR.T0(6)/100;
350  HDR.reserved1 = fread(HDR.FILE.FID,[1,8*3+20],'uint8'); % 44 Byte reserved
351  HDR.REC.Equipment = HDR.reserved1(1:8);
352  HDR.REC.Hospital = HDR.reserved1(9:16);
353  HDR.REC.Technician = HDR.reserved1(17:24);
354  end;
355 
356  %if str2double(HDR.VERSION(4:8))<0.12,
357  if (HDR.VERSION < 0.12),
358  HDR.HeadLen = str2double(H1(185:192)); % 8 Byte Length of Header
359  elseif (HDR.VERSION < 1.92)
360  HDR.HeadLen = H1(185:188)*256.^[0:3]'; % 8 Byte Length of Header
361  HDR.reserved = H1(189:192);
362  else
363  HDR.HeadLen = H1(185:186)*256.^[1:2]'; % 8 Byte Length of Header
364  end;
365  HDR.H1 = H1;
366 
367  %HDR.NRec = fread(HDR.FILE.FID,1,'int64'); % 8 Byte # of data records
368  HDR.NRec = fread(HDR.FILE.FID,1,'int32'); % 8 Byte # of data records
369  fread(HDR.FILE.FID,1,'int32'); % 8 Byte # of data records
370  %if strcmp(HDR.VERSION(4:8),' 0.10')
371  if ((abs(HDR.VERSION - 0.10) < 2*eps) || (HDR.VERSION > 2.20)),
372  HDR.Dur = fread(HDR.FILE.FID,1,'float64'); % 8 Byte # duration of data record in sec
373  else
374  tmp = fread(HDR.FILE.FID,2,'uint32'); % 8 Byte # duration of data record in sec
375  %tmp1 = warning('off');
376  HDR.Dur = tmp(1)./tmp(2);
377  %warning(tmp1);
378  end;
379  tmp = fread(HDR.FILE.FID,2,'uint16'); % 4 Byte # of signals
380  HDR.NS = tmp(1);
381  else
382  H1(193:256)= fread(HDR.FILE.FID,[1,256-192],'uint8'); %
383  H1 = char(H1);
384  HDR.PID = deblank(char(H1(9:88))); % 80 Byte local patient identification
385  HDR.RID = deblank(char(H1(89:168))); % 80 Byte local recording identification
386  [HDR.Patient.Id,tmp] = strtok(HDR.PID,' ');
387  [tmp1,tmp] = strtok(tmp,' ');
388  [tmp1,tmp] = strtok(tmp,' ');
389  HDR.Patient.Name = tmp(2:end);
390 
391  tmp = find((H1<32) | (H1>126)); %%% syntax for Matlab
392  if ~isempty(tmp) %%%%% not EDF because filled out with ASCII(0) - should be spaces
393  %H1(tmp)=32;
394  HDR.ErrNum=[1025,HDR.ErrNum];
395  end;
396 
397  tmp = repmat(' ',1,22);
398  tmp([3:4,6:7,9:10,12:13,15:16,18:19]) = H1(168+[7:8,4:5,1:2,9:10,12:13,15:16]);
399  tmp1 = str2double(tmp);
400  if length(tmp1)==6,
401  HDR.T0(1:6) = tmp1;
402  end;
403 
404  if any(isnan(HDR.T0)),
405  HDR.ErrNum = [1032,HDR.ErrNum];
406 
407  tmp = H1(168 + [1:16]);
408  tmp(tmp=='.' | tmp==':' | tmp=='/' | tmp=='-') = ' ';
409  tmp1 = str2double(tmp(1:8));
410  if length(tmp1)==3,
411  HDR.T0 = tmp1([3,2,1]);
412  end;
413  tmp1 = str2double(tmp(9:16));
414  if length(tmp1)==3,
415  HDR.T0(4:6) = tmp1;
416  end;
417  if any(isnan(HDR.T0)),
418  HDR.ErrNum = [2,HDR.ErrNum];
419  end;
420  end;
421 
422  % Y2K compatibility until year 2084
423  if HDR.T0(1) < 85 % for biomedical data recorded in the 1950's and converted to EDF
424  HDR.T0(1) = 2000+HDR.T0(1);
425  elseif HDR.T0(1) < 100
426  HDR.T0(1) = 1900+HDR.T0(1);
427  %else % already corrected, do not change
428  end;
429 
430  HDR.HeadLen = str2double(H1(185:192)); % 8 Bytes Length of Header
431  HDR.reserved1=H1(193:236); % 44 Bytes reserved
432  HDR.NRec = str2double(H1(237:244)); % 8 Bytes # of data records
433  HDR.Dur = str2double(H1(245:252)); % 8 Bytes # duration of data record in sec
434  HDR.NS = str2double(H1(253:256)); % 4 Bytes # of signals
435  HDR.AS.H1 = H1; % for debugging the EDF Header
436 
437  if strcmp(HDR.reserved1(1:4),'EDF+'), % EDF+ specific header information
438  [HDR.Patient.Id, tmp] = strtok(HDR.PID,' ');
439  [sex, tmp] = strtok(tmp,' ');
440  [bd, tmp] = strtok(tmp,' ');
441  [HDR.Patient.Name, tmp] = strtok(tmp,' ');
442  if length(sex)>0,
443  HDR.Patient.Sex = any(sex(1)=='mM') + any(sex(1)=='Ff')*2;
444  else
445  HDR.Patient.Sex = 0; % unknown
446  end;
447  if (length(bd)==11),
448  HDR.Patient.Birthday = zeros(1,6);
449  bd(bd=='-') = ' ';
450  [n,v,s] = str2double(bd,' ');
451  month_of_birth = strmatch(lower(s{2}),{'jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'},'exact');
452  if ~isempty(month_of_birth)
453  v(2) = 0;
454  end
455  if any(v)
456  HDR.Patient.Birthday(:) = NaN;
457  else
458  HDR.Patient.Birthday(1) = n(3);
459  HDR.Patient.Birthday(2) = month_of_birth;
460  HDR.Patient.Birthday(3) = n(1);
461  HDR.Patient.Birthday(4) = 12;
462  end;
463  end;
464 
465  [chk, tmp] = strtok(HDR.RID,' ');
466  if ~strcmp(chk,'Startdate')
467  fprintf(HDR.FILE.stderr,'Warning SOPEN: EDF+ header is corrupted.\n');
468  end;
469  [HDR.Date2, tmp] = strtok(tmp,' ');
470  [HDR.RID, tmp] = strtok(tmp,' ');
471  [HDR.REC.Technician, tmp] = strtok(tmp,' ');
472  [HDR.REC.Equipment, tmp] = strtok(tmp,' ');
473  end;
474  end;
475 
476  if any(size(HDR.NS)~=1) %%%%% not EDF because filled out with ASCII(0) - should be spaces
477  fprintf(HDR.FILE.stderr, 'Warning SOPEN (GDF/EDF/BDF): invalid NS-value in header of %s\n',HDR.FileName);
478  HDR.ErrNum=[1040,HDR.ErrNum];
479  HDR.NS=1;
480  end;
481  % Octave assumes HDR.NS is a matrix instead of a scalare. Therefore, we need
482  % Otherwise, eye(HDR.NS) will be executed as eye(size(HDR.NS)).
483  HDR.NS = HDR.NS(1);
484 
485  if isempty(HDR.HeadLen) %%%%% not EDF because filled out with ASCII(0) - should be spaces
486  HDR.ErrNum=[1056,HDR.ErrNum];
487  HDR.HeadLen=256*(1+HDR.NS);
488  end;
489 
490  if isempty(HDR.NRec) %%%%% not EDF because filled out with ASCII(0) - should be spaces
491  HDR.ErrNum=[1027,HDR.ErrNum];
492  HDR.NRec = -1;
493  end;
494 
495  if isempty(HDR.Dur) %%%%% not EDF because filled out with ASCII(0) - should be spaces
496  HDR.ErrNum=[1088,HDR.ErrNum];
497  HDR.Dur=30;
498  end;
499 
500  if any(HDR.T0>[2084 12 31 24 59 59]) || any(HDR.T0<[1985 1 1 0 0 0])
501  HDR.ErrNum = [4, HDR.ErrNum];
502  end;
503 
504  %%% Read variable Header %%%
505  %if ~strcmp(HDR.VERSION(1:3),'GDF'),
506  if ~strcmp(HDR.TYPE,'GDF'),
507  idx1=cumsum([0 H2idx]);
508  idx2=HDR.NS*idx1;
509 
510  h2=zeros(HDR.NS,256);
511  [H2,count]=fread(HDR.FILE.FID,HDR.NS*256,'uint8');
512  if count < HDR.NS*256
513  HDR.ErrNum=[8,HDR.ErrNum];
514  return;
515  end;
516 
517  %tmp=find((H2<32) | (H2>126)); % would confirm
518  tmp = find((H2<32) | ((H2>126) & (H2~=255) & (H2~=181)& (H2~=230)));
519  if ~isempty(tmp) %%%%% not EDF because filled out with ASCII(0) - should be spaces
520  H2(tmp) = 32;
521  HDR.ErrNum = [1026,HDR.ErrNum];
522  end;
523 
524  for k=1:length(H2idx);
525  %disp([k size(H2) idx2(k) idx2(k+1) H2idx(k)]);
526  h2(:,idx1(k)+1:idx1(k+1))=reshape(H2(idx2(k)+1:idx2(k+1)),H2idx(k),HDR.NS)';
527  end;
528  h2=char(h2);
529 
530  HDR.Label = cellstr(h2(:,idx1(1)+1:idx1(2)));
531  HDR.Transducer = cellstr(h2(:,idx1(2)+1:idx1(3)));
532  HDR.PhysDim = cellstr(h2(:,idx1(3)+1:idx1(4)));
533  HDR.PhysMin = str2double(cellstr(h2(:,idx1(4)+1:idx1(5))))';
534  HDR.PhysMax = str2double(cellstr(h2(:,idx1(5)+1:idx1(6))))';
535  HDR.DigMin = str2double(cellstr(h2(:,idx1(6)+1:idx1(7))))';
536  HDR.DigMax = str2double(cellstr(h2(:,idx1(7)+1:idx1(8))))';
537  HDR.PreFilt = h2(:,idx1(8)+1:idx1(9));
538  HDR.AS.SPR = str2double(cellstr(h2(:,idx1(9)+1:idx1(10))));
539  %if ~all(abs(HDR.VERSION)==[255,abs('BIOSEMI')]),
540  if (HDR.VERSION ~= -1),
541  HDR.GDFTYP = 3*ones(1,HDR.NS); % datatype
542  else
543  HDR.GDFTYP = (255+24)*ones(1,HDR.NS); % datatype
544  end;
545 
546  if isempty(HDR.AS.SPR),
547  fprintf(HDR.FILE.stderr, 'Warning SOPEN (GDF/EDF/BDF): invalid SPR-value in header of %s\n',HDR.FileName);
548  HDR.AS.SPR=ones(HDR.NS,1);
549  HDR.ErrNum=[1028,HDR.ErrNum];
550  end;
551 
552  elseif (HDR.NS>0)
553  if (ftell(HDR.FILE.FID)~=256),
554  error('position error');
555  end;
556  HDR.Label = char(fread(HDR.FILE.FID,[16,HDR.NS],'uint8')');
557  HDR.Transducer = cellstr(char(fread(HDR.FILE.FID,[80,HDR.NS],'uint8')'));
558 
559  if (HDR.NS<1), % hack for a problem with Matlab 7.1.0.183 (R14) Service Pack 3
560 
561  elseif (HDR.VERSION < 1.9),
562  HDR.PhysDim = char(fread(HDR.FILE.FID,[ 8,HDR.NS],'uint8')');
563  HDR.PhysMin = fread(HDR.FILE.FID,[1,HDR.NS],'float64');
564  HDR.PhysMax = fread(HDR.FILE.FID,[1,HDR.NS],'float64');
565  tmp = fread(HDR.FILE.FID,[1,2*HDR.NS],'int32');
566  HDR.DigMin = tmp((1:HDR.NS)*2-1);
567  tmp = fread(HDR.FILE.FID,[1,2*HDR.NS],'int32');
568  HDR.DigMax = tmp((1:HDR.NS)*2-1);
569 
570  HDR.PreFilt = char(fread(HDR.FILE.FID,[80,HDR.NS],'uint8')'); %
571  HDR.AS.SPR = fread(HDR.FILE.FID,[ 1,HDR.NS],'uint32')'; % samples per data record
572  HDR.GDFTYP = fread(HDR.FILE.FID,[ 1,HDR.NS],'uint32'); % datatype
573 
574  else
575  tmp = char(fread(HDR.FILE.FID,[6,HDR.NS],'uint8')');
576  % HDR.PhysDim = char(fread(HDR.FILE.FID,[6,HDR.NS],'uint8')');
577  HDR.PhysDimCode = fread(HDR.FILE.FID,[1,HDR.NS],'uint16');
578 
579  HDR.PhysMin = fread(HDR.FILE.FID,[1,HDR.NS],'float64');
580  HDR.PhysMax = fread(HDR.FILE.FID,[1,HDR.NS],'float64');
581  HDR.DigMin = fread(HDR.FILE.FID,[1,HDR.NS],'float64');
582  HDR.DigMax = fread(HDR.FILE.FID,[1,HDR.NS],'float64');
583  if (HDR.VERSION < 2.22)
584  HDR.PreFilt = char(fread(HDR.FILE.FID,[80-12,HDR.NS],'uint8')'); %
585  else
586  HDR.PreFilt = char(fread(HDR.FILE.FID,[80-12-4,HDR.NS],'uint8')'); %
587  HDR.TOffset = fread(HDR.FILE.FID,[1,HDR.NS],'float32'); %
588  end;
589  HDR.Filter.LowPass = fread(HDR.FILE.FID,[1,HDR.NS],'float32'); %
590  HDR.Filter.HighPass = fread(HDR.FILE.FID,[1,HDR.NS],'float32'); %
591  HDR.Filter.Notch = fread(HDR.FILE.FID,[1,HDR.NS],'float32'); %
592  HDR.AS.SPR = fread(HDR.FILE.FID,[1,HDR.NS],'uint32')'; % samples per data record
593  HDR.GDFTYP = fread(HDR.FILE.FID,[1,HDR.NS],'uint32'); % datatype
594  HDR.ELEC.XYZ = fread(HDR.FILE.FID,[3,HDR.NS],'float32')'; % datatype
595  if (HDR.VERSION < 2.19)
596  tmp = fread(HDR.FILE.FID,[HDR.NS, 1],'uint8'); % datatype
597  tmp(tmp==255) = NaN;
598  HDR.Impedance = 2.^(tmp/8);
599  fseek(HDR.FILE.FID, HDR.NS*19, 'cof'); % datatype
600  else
601  tmp = fread(HDR.FILE.FID,[5,HDR.NS],'float32'); % datatype
602  ch = bitand(HDR.PhysDimCode, hex2dec('ffe0'))==4256; % channel with voltage data
603  HDR.Impedance(ch) = tmp(1,ch);
604  HDR.Impedance(~ch)= NaN;
605  ch = bitand(HDR.PhysDimCode, hex2dec('ffe0'))==4288; % channel with impedance data
606  HDR.fZ(ch) = tmp(1,ch); % probe frequency
607  HDR.fZ(~ch)= NaN;
608  end;
609  end;
610  end;
611 
612  HDR.SPR = 1;
613  if (HDR.NS>0)
614  if ~isfield(HDR,'THRESHOLD')
615  HDR.THRESHOLD = [HDR.DigMin',HDR.DigMax']; % automated overflow detection
616  if (HDR.VERSION <= 0) && HDR.FLAG.OVERFLOWDETECTION, % in case of EDF and OVERFLOWDETECTION
617  HDR.FLAG.OVERFLOWDETECTION = 0;
618  fprintf(2,'WARNING SOPEN(EDF): Automated Overflowdetection not supported for EDF and BDF data, because \n');
619  fprintf(2,' Physical Max/Min values of EDF/BDF data are not necessarily defining the dynamic range.\n');
620  fprintf(2,' For more information see: http://dx.doi.org/10.1016/S1388-2457(99)00172-8 (A. Schloegl et al. Quality Control ... Clin. Neurophysiol. 1999, Dec; 110(12): 2165 - 2170).\n');
621  fprintf(2,' A copy is available here, too: http://pub.ist.ac.at/~schloegl/publications/neurophys1999_2165.pdf \n');
622  fprintf(2,' See also EEG2HIST: it''s a tool to identify the saturation thresholds.\n');
623  end;
624  end;
625  if any(HDR.PhysMax==HDR.PhysMin), HDR.ErrNum=[1029,HDR.ErrNum]; end;
626  if any(HDR.DigMax ==HDR.DigMin ), HDR.ErrNum=[1030,HDR.ErrNum]; end;
627  HDR.Cal = (HDR.PhysMax-HDR.PhysMin)./(HDR.DigMax-HDR.DigMin);
628  HDR.Off = HDR.PhysMin - HDR.Cal .* HDR.DigMin;
629  if any(~isfinite(HDR.Cal)),
630  fprintf(2,'WARNING SOPEN(GDF/BDF/EDF): Scaling factor is not defined in following channels:\n');
631  find(~isfinite(HDR.Cal))',
632  HDR.Cal(~isfinite(HDR.Cal))=1;
633  HDR.FLAG.UCAL = 1;
634  end;
635 
636  HDR.AS.SampleRate = HDR.AS.SPR / HDR.Dur;
637  if all(CHAN>0)
638  chan = CHAN(:)';
639  elseif (CHAN==0)
640  chan = 1:HDR.NS;
641  if strcmp(HDR.TYPE,'EDF')
642  if strcmp(HDR.reserved1(1:4),'EDF+')
643  tmp = strmatch('EDF Annotations',HDR.Label);
644  chan(tmp)=[];
645  end;
646  elseif strcmp(HDR.TYPE,'BDF')
647  tmp = strmatch('BDF Annotations',HDR.Label);
648  chan(tmp)=[];
649  end;
650  end;
651  for k=chan,
652  if (HDR.AS.SPR(k)>0)
653  HDR.SPR = lcm(HDR.SPR,HDR.AS.SPR(k));
654  end;
655  end;
656  HDR.SampleRate = HDR.SPR/HDR.Dur;
657 
658  HDR.AS.spb = sum(HDR.AS.SPR); % Samples per Block
659  HDR.AS.bi = [0;cumsum(HDR.AS.SPR(:))];
660  HDR.AS.BPR = ceil(HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)');
661  if any(HDR.AS.BPR ~= HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)');
662  fprintf(2,'\nError SOPEN (GDF/EDF/BDF): block configuration in file %s not supported.\n',HDR.FileName);
663  end;
664  HDR.AS.SAMECHANTYP = all(HDR.AS.BPR == (HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)')) && ~any(diff(HDR.GDFTYP));
665  HDR.AS.bpb = sum(ceil(HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)')); % Bytes per Block
666  HDR.Calib = [HDR.Off; diag(HDR.Cal)];
667 
668  else % (if HDR.NS==0)
669  HDR.THRESHOLD = [];
670  HDR.AS.SPR = [];
671  HDR.Calib = zeros(1,0);
672  HDR.AS.bpb = 0;
673  HDR.GDFTYP = [];
674  HDR.Label = {};
675  end;
676 
677  if HDR.VERSION<1.9,
678  HDR.Filter.LowPass = repmat(nan,1,HDR.NS);
679  HDR.Filter.HighPass = repmat(nan,1,HDR.NS);
680  HDR.Filter.Notch = repmat(nan,1,HDR.NS);
681  for k=1:HDR.NS,
682  tmp = HDR.PreFilt(k,:);
683 
684  ixh=strfind(tmp,'HP');
685  ixl=strfind(tmp,'LP');
686  ixn=strfind(tmp,'Notch');
687  ix =strfind(lower(tmp),'hz');
688 
689  [v,c,errmsg]=sscanf(tmp,'%f - %f Hz');
690  if (isempty(errmsg) && (c==2)),
691  HDR.Filter.LowPass(k) = max(v);
692  HDR.Filter.HighPass(k) = min(v);
693  else
694  if any(tmp==';')
695  [tok1,tmp] = strtok(tmp,';');
696  [tok2,tmp] = strtok(tmp,';');
697  [tok3,tmp] = strtok(tmp,';');
698  else
699  [tok1,tmp] = strtok(tmp,' ');
700  [tok2,tmp] = strtok(tmp,' ');
701  [tok3,tmp] = strtok(tmp,' ');
702  end;
703  [T1, F1 ] = strtok(tok1,': ');
704  [T2, F2 ] = strtok(tok2,': ');
705  [T3, F3 ] = strtok(tok3,': ');
706 
707  [F1 ] = strtok(F1,': ');
708  [F2 ] = strtok(F2,': ');
709  [F3 ] = strtok(F3,': ');
710 
711  F1(find(F1==','))='.';
712  F2(find(F2==','))='.';
713  F3(find(F3==','))='.';
714 
715  if strcmp(F1,'DC'), F1='0'; end;
716  if strcmp(F2,'DC'), F2='0'; end;
717  if strcmp(F3,'DC'), F3='0'; end;
718 
719  tmp = strfind(lower(F1),'hz');
720  if ~isempty(tmp), F1=F1(1:tmp-1); end;
721  tmp = strfind(lower(F2),'hz');
722  if ~isempty(tmp), F2=F2(1:tmp-1); end;
723  tmp = strfind(lower(F3),'hz');
724  if ~isempty(tmp), F3=F3(1:tmp-1); end;
725 
726  tmp = str2double(F1);
727  if isempty(tmp),tmp=NaN; end;
728  if strcmp(T1,'LP'),
729  HDR.Filter.LowPass(k) = tmp;
730  elseif strcmp(T1,'HP'),
731  HDR.Filter.HighPass(k)= tmp;
732  elseif strcmp(T1,'Notch'),
733  HDR.Filter.Notch(k) = tmp;
734  end;
735  tmp = str2double(F2);
736  if isempty(tmp),tmp=NaN; end;
737  if strcmp(T2,'LP'),
738  HDR.Filter.LowPass(k) = tmp;
739  elseif strcmp(T2,'HP'),
740  HDR.Filter.HighPass(k)= tmp;
741  elseif strcmp(T2,'Notch'),
742  HDR.Filter.Notch(k) = tmp;
743  end;
744  tmp = str2double(F3);
745  if isempty(tmp),tmp=NaN; end;
746  if strcmp(T3,'LP'),
747  HDR.Filter.LowPass(k) = tmp;
748  elseif strcmp(T3,'HP'),
749  HDR.Filter.HighPass(k)= tmp;
750  elseif strcmp(T3,'Notch'),
751  HDR.Filter.Notch(k) = tmp;
752  end;
753  %catch
754  % fprintf(2,'Cannot interpret: %s\n',HDR.PreFilt(k,:));
755  end;
756  end;
757  end
758 
759  %% GDF Header 3
760  if (HDR.VERSION > 2)
761  pos = 256*(HDR.NS+1);
762  fseek(HDR.FILE.FID,pos,'bof');
763  while (pos <= HDR.HeadLen-4)
764  %% decode TAG-LENGTH-VALUE structure
765  tagval = fread(HDR.FILE.FID,1,'uint32');
766  TAG = bitand(tagval, 255);
767  LEN = (tagval/256);
768  if (pos+4+LEN > HDR.HeadLen)
769  fprintf(HDR.FILE.stderr,'ERROR SOPEN(GDF): T-L-V header broken\n');
770  break;
771  end;
772  switch (TAG)
773  case 0 %% last tag-length-value
774  break;
775  case 1 %% description of user-specified event codes
776  VAL= fread(HDR.FILE.FID,[1,LEN],'uint8=>char');
777  ix = find(VAL==0);
778  N = find(diff(ix)==1);
779  if isempty(N)
780  N = length(ix);
781  ix(N+1)=LEN+1;
782  end;
783  for k = 1:N(1),
784  HDR.EVENT.CodeDesc{k} = VAL(ix(k)+1:ix(k+1)-1);
785  end;
786  case 2 %% bci2000 additional information
787  VAL = fread(HDR.FILE.FID,[1,LEN],'uint8=>char');
788  HDR.BCI2000.INFO = VAL;
789  case 3 %% Manufacturer Information
790  VAL = fread(HDR.FILE.FID,[1,LEN],'uint8=>char');
791  [HDR.Manufacturer.Name,VAL] = strtok(VAL,0);
792  [HDR.Manufacturer.Model,VAL] = strtok(VAL,0);
793  [HDR.Manufacturer.Version,VAL] = strtok(VAL,0);
794  [HDR.Manufacturer.SerialNumber,VAL] = strtok(VAL,0);
795  % case 4 %% OBSOLETE %% Orientation of MEG channels
796  %VAL = fread(HDR.FILE.FID,[HDR.NS,4],'float32');
797  %HDR.ELEC.Orientation = VAL(:,1:3);
798  %HDR.ELEC.Area = VAL(:,4);
799  case 5 %% IP address
800  VAL = fread(HDR.FILE.FID,[1,LEN],'uint8=>uint8');
801  HDR.REC.IPaddr = VAL;
802  case 6 %% recording Technician
803  VAL = fread(HDR.FILE.FID,[1,LEN],'uint8=>char');
804  HDR.REC.Technician = VAL;
805  case 7 %% recording institution/hospital/lab
806  VAL = fread(HDR.FILE.FID,[1,LEN],'uint8=>char');
807  HDR.REC.Hospital = VAL;
808  otherwise
809  fseek(HDR.FILE.FID,LEN,'cof');
810  end;
811  pos = ftell(HDR.FILE.FID);
812  end;
813  end;
814 
815  % filesize, position of eventtable, headerlength, etc.
816  HDR.AS.EVENTTABLEPOS = -1;
817  if (HDR.FILE.size == HDR.HeadLen)
818  HDR.NRec = 0;
819  elseif HDR.NRec == -1 % unknown record size, determine correct NRec
820  HDR.NRec = floor((HDR.FILE.size - HDR.HeadLen) / HDR.AS.bpb);
821  end
822  if (HDR.NRec*HDR.AS.bpb) ~= (HDR.FILE.size - HDR.HeadLen);
823  %if ~strcmp(HDR.VERSION(1:3),'GDF'),
824  if ~strcmp(HDR.TYPE,'GDF'),
825  HDR.ErrNum= [16,HDR.ErrNum];
826  tmp = HDR.NRec;
827  HDR.NRec = floor((HDR.FILE.size - HDR.HeadLen) / HDR.AS.bpb);
828  if tmp~=HDR.NRec,
829  fprintf(2,'\nWarning SOPEN (EDF/BDF): filesize (%i) of %s does not fit headerinformation (NRec = %i not %i).\n',HDR.FILE.size,HDR.FileName,tmp,HDR.NRec);
830  else
831  fprintf(2,'\nWarning: incomplete data block appended (ignored) in file %s.\n',HDR.FileName);
832  end
833  else
834  HDR.AS.EVENTTABLEPOS = HDR.HeadLen + HDR.AS.bpb*HDR.NRec;
835  end;
836  end;
837 
838  % prepare SREAD for different data types
839  n = 0;
840  typ = [-1;HDR.GDFTYP(:)];
841  for k = 1:HDR.NS;
842  if (typ(k) == typ(k+1)),
843  HDR.AS.c(n) = HDR.AS.c(n) + HDR.AS.SPR(k);
844  HDR.AS.c2(n) = HDR.AS.c2(n) + HDR.AS.BPR(k);
845  else
846  n = n + 1;
847  HDR.AS.c(n) = HDR.AS.SPR(k);
848  HDR.AS.c2(n) = HDR.AS.BPR(k);
849  HDR.AS.TYP(n) = HDR.GDFTYP(k);
850  end;
851  end;
852 
853  if 0,
854 
855  elseif strcmp(HDR.TYPE,'GDF') && (HDR.AS.EVENTTABLEPOS > 0),
856  status = fseek(HDR.FILE.FID, HDR.AS.EVENTTABLEPOS, 'bof');
857  if (HDR.VERSION<1.94),
858  [EVENT.Version,c] = fread(HDR.FILE.FID,1,'uint8');
859  HDR.EVENT.SampleRate = [1,256,65536]*fread(HDR.FILE.FID,3,'uint8');
860  [EVENT.N,c] = fread(HDR.FILE.FID,1,'uint32');
861  else %if HDR.VERSION<1.94,
862  [EVENT.Version,c] = fread(HDR.FILE.FID,1,'uint8');
863  EVENT.N = [1,256,65536]*fread(HDR.FILE.FID,3,'uint8');
864  [HDR.EVENT.SampleRate,c] = fread(HDR.FILE.FID,1,'float32');
865  end;
866 
867  if ~HDR.EVENT.SampleRate, % ... is not defined in GDF 1.24 or earlier
868  HDR.EVENT.SampleRate = HDR.SampleRate;
869  end;
870  [HDR.EVENT.POS,c1] = fread(HDR.FILE.FID,[EVENT.N,1],'uint32');
871  [HDR.EVENT.TYP,c2] = fread(HDR.FILE.FID,[EVENT.N,1],'uint16');
872 
873  if EVENT.Version==1,
874  if any([c1,c2]~=EVENT.N)
875  fprintf(2,'\nERROR SOPEN (GDF): Eventtable corrupted in file %s\n',HDR.FileName);
876  end
877 
878  elseif EVENT.Version==3,
879  [HDR.EVENT.CHN,c3] = fread(HDR.FILE.FID,[EVENT.N,1],'uint16');
880  [HDR.EVENT.DUR,c4] = fread(HDR.FILE.FID,[EVENT.N,1],'uint32');
881  %[EVENT.N,HDR.FILE.size,HDR.AS.EVENTTABLEPOS+8+EVENT.N*12]
882  if any([c1,c2,c3,c4]~=EVENT.N),
883  fprintf(2,'\nERROR SOPEN (GDF): Eventtable corrupted in file %s\n',HDR.FileName);
884  end;
885 
886  else
887  fprintf(2,'\nWarning SOPEN (GDF): File %s corrupted (Eventtable version %i ).\n',HDR.FileName,EVENT.Version);
888  end;
889  HDR.AS.endpos = HDR.AS.EVENTTABLEPOS; % set end of data block, might be important for SSEEK
890 
891  % Classlabels according to
892  % http://biosig.cvs.sourceforge.net/*checkout*/biosig/biosig/doc/eventcodes.txt
893  % sort event table before extracting HDR.Classlabel and HDR.TRIG
894  [HDR.EVENT.POS,ix] = sort(HDR.EVENT.POS);
895  HDR.EVENT.TYP = HDR.EVENT.TYP(ix);
896  if isfield(HDR.EVENT,'CHN')
897  HDR.EVENT.CHN = HDR.EVENT.CHN(ix);
898  end;
899  if isfield(HDR.EVENT,'DUR')
900  HDR.EVENT.DUR = HDR.EVENT.DUR(ix);
901  end;
902 
903  if (length(HDR.EVENT.TYP)>0)
904  ix = (HDR.EVENT.TYP>hex2dec('0300')) & (HDR.EVENT.TYP<hex2dec('030d'));
905  ix = ix | ((HDR.EVENT.TYP>=hex2dec('0320')) & (HDR.EVENT.TYP<=hex2dec('037f')));
906  ix = ix | (HDR.EVENT.TYP==hex2dec('030f')); % unknown/undefined cue
907  HDR.Classlabel = mod(HDR.EVENT.TYP(ix),256);
908  HDR.Classlabel(HDR.Classlabel==15) = NaN; % unknown/undefined cue
909  end;
910 
911  % Trigger information and Artifact Selection
912  ix = find(HDR.EVENT.TYP==hex2dec('0300'));
913  HDR.TRIG = HDR.EVENT.POS(ix);
914  ArtifactSelection = repmat(logical(0),length(ix),1);
915  for k = 1:length(ix),
916  ix2 = find(HDR.EVENT.POS(ix(k))==HDR.EVENT.POS);
917  if any(HDR.EVENT.TYP(ix2)==hex2dec('03ff'))
918  ArtifactSelection(k) = logical(1);
919  end;
920  end;
921  if any(ArtifactSelection), % define only if necessary
922  HDR.ArtifactSelection = ArtifactSelection;
923  end;
924  % decode non-equidistant sampling
925  ix = find(HDR.EVENT.TYP==hex2dec('7fff'));
926  if ~isempty(ix),
927  if (HDR.VERSION<1.90),
928  warning('non-equidistant sampling not definded for GDF v1.x')
929  end;
930  % the following is redundant information %
931  HDR.EVENT.VAL = repmat(NaN,size(HDR.EVENT.TYP));
932  HDR.EVENT.VAL(ix) = HDR.EVENT.DUR(ix);
933  end;
934 
935  elseif strcmp(HDR.TYPE,'EDF') && (length(strmatch('EDF Annotations',HDR.Label))==1),
936  % EDF+:
937  tmp = strmatch('EDF Annotations',HDR.Label);
938  HDR.EDF.Annotations = tmp;
939  if isempty(ReRefMx)
940  ReRefMx = sparse(1:HDR.NS,1:HDR.NS,1);
941  ReRefMx(:,tmp) = [];
942  end;
943 
944  status = fseek(HDR.FILE.FID,HDR.HeadLen+HDR.AS.bi(HDR.EDF.Annotations)*2,'bof');
945  t = fread(HDR.FILE.FID,inf,[int2str(HDR.AS.SPR(HDR.EDF.Annotations)*2),'*uchar=>uchar'],HDR.AS.bpb-HDR.AS.SPR(HDR.EDF.Annotations)*2);
946  HDR.EDFplus.ANNONS = char(t');
947 
948 
949  elseif strcmp(HDR.TYPE,'BDF') && (length(strmatch('BDF Annotations',HDR.Label))==1),
950  % BDF+:
951  tmp = strmatch('BDF Annotations',HDR.Label);
952  HDR.EDF.Annotations = tmp;
953  if isempty(ReRefMx)
954  ReRefMx = sparse(1:HDR.NS,1:HDR.NS,1);
955  ReRefMx(:,tmp) = [];
956  end;
957 
958  status = fseek(HDR.FILE.FID,HDR.HeadLen+HDR.AS.bi(HDR.EDF.Annotations)*3,'bof');
959  t = fread(HDR.FILE.FID,inf,[int2str(HDR.AS.SPR(HDR.EDF.Annotations)*3),'*uchar=>uchar'],HDR.AS.bpb-HDR.AS.SPR(HDR.EDF.Annotations)*3);
960  HDR.EDFplus.ANNONS = char(t');
961 
962 
963  elseif strcmp(HDR.TYPE,'EDF') && (length(strmatch('ANNOTATION',HDR.Label))==1),
964  % EEG from Delta/NihonKohden converted into EDF:
965  tmp = strmatch('ANNOTATION',HDR.Label);
966  HDR.EDF.Annotations = tmp;
967  FLAG.ANNONS = 1; % valid
968 
969  status = fseek(HDR.FILE.FID,HDR.HeadLen+HDR.AS.bi(HDR.EDF.Annotations)*2,'bof');
970  t = fread(HDR.FILE.FID,inf,[int2str(HDR.AS.SPR(HDR.EDF.Annotations)*2),'*uchar=>uchar'],HDR.AS.bpb-HDR.AS.SPR(HDR.EDF.Annotations)*2);
971  t = reshape(t,HDR.AS.SPR(HDR.EDF.Annotations)*2,HDR.NRec)';
972  t = t(any(t,2),1:max(find(any(t,1))));
973  HDR.EDF.ANNONS = char(t);
974 
975  N = 0;
976  [t,r] = strtok(char(reshape(t',[1,prod(size(t))])),[0,64]);
977  while ~isempty(r),
978  [m,r] = strtok(r,[0,64]);
979  tb = char([t(1:4),32,t(5:6),32,t(7:8),32,t(9:10),32,t(11:12),32,t(13:end)]);
980  [ta, status] = str2double(tb);
981  t1 = datenum(ta);
982 
983  if any(status),
984  FLAG.ANNONS = 0; % invalid
985  elseif strcmp(char(m),'TEST');
986  t0 = t1;
987  elseif ((length(m)==1) && ~isnan(t1-t0)),
988  N = N+1;
989  HDR.EVENT.POS(N,1) = t1;
990  HDR.EVENT.TYP(N,1) = abs(m);
991  else
992  FLAG.ANNONS = 0; % invalid
993  end;
994  [t,r] = strtok(r,[0,64]);
995  end;
996  HDR.EVENT.POS = round((HDR.EVENT.POS-t0)*(HDR.SampleRate*3600*24))+2;
997 
998  if FLAG.ANNONS;
999  % decoding was successful
1000  if isempty(ReRefMx)
1001  % do not return annotations in signal matrix
1002  ReRefMx = sparse(1:HDR.NS,1:HDR.NS,1);
1003  ReRefMx(:,HDR.EDF.Annotations) = [];
1004  end;
1005  end;
1006 
1007  elseif strcmp(HDR.TYPE,'BDF') && any(strmatch('Status',HDR.Label)),
1008  % BDF:
1009 
1010  tmp = strmatch('Status',HDR.Label);
1011  HDR.BDF.Status.Channel = tmp;
1012  if isempty(ReRefMx)
1013  ReRefMx = sparse(1:HDR.NS,1:HDR.NS,1);
1014  ReRefMx(:,tmp) = [];
1015  end;
1016 
1017  status = fseek(HDR.FILE.FID,HDR.HeadLen+HDR.AS.bi(HDR.BDF.Status.Channel)*3,'bof');
1018  %t = fread(HDR.FILE.FID,[3,inf],'uint8',HDR.AS.bpb-HDR.AS.SPR(HDR.BDF.Status.Channel)*3);
1019  [t,c] = fread(HDR.FILE.FID,inf,[int2str(HDR.AS.SPR(HDR.BDF.Status.Channel)*3),'*uint8'],HDR.AS.bpb-HDR.AS.SPR(HDR.BDF.Status.Channel)*3);
1020  if (c>HDR.NRec*HDR.SPR*3)
1021  % a hack to fix a bug in Octave Ver<=3.0.0
1022  t = t(1:HDR.NRec*HDR.SPR*3);
1023  end;
1024  HDR.BDF.ANNONS = reshape(double(t),3,length(t)/3)'*2.^[0;8;16];
1025  HDR = bdf2biosig_events(HDR, FLAG.BDF.status2event);
1026 
1027  elseif strcmp(HDR.TYPE,'BDF') && ~any(strmatch('Status',HDR.Label)),
1028  HDR.FLAG.OVERFLOWDETECTION = 0;
1029  fprintf(HDR.FILE.stderr,'Warning SOPEN(BDF): File %s does not contain Status Channel - overflowdetection not supported!\n',HDR.FileName);
1030 
1031  end;
1032 
1033  if isfield(HDR,'EDFplus') && isfield(HDR.EDFplus,'ANNONS'),
1034  %% decode EDF+/BDF+ annotations
1035  N = 0;
1036  onset = []; dur=[]; Desc = {};
1037  t = HDR.EDFplus.ANNONS;
1038  while ~isempty(t)
1039  % remove leading 0
1040  t = t(find(t>0,1):end);
1041 
1042  ix = find(t==20,2);
1043  if isempty(ix) break; end;
1044 
1045  % next event
1046  N = N + 1;
1047  [s1,s2] = strtok(t(1:ix(1)-1),21);
1048  s3 = t(ix(1)+1:ix(2)-1);
1049 
1050  tmp = str2double(s1);
1051  onset(N,1) = tmp;
1052  if ~isempty(s2)
1053  tmp = str2double(s2(2:end));
1054  dur(N,1) = tmp;
1055  else
1056  dur(N,1) = 0;
1057  end;
1058  if all(s3(2:2:end)==0) s3 = s3(1:2:end); end; %% unicode to ascii - FIXME
1059  Desc{N} = s3;
1060  HDR.EVENT.TYP(N,1) = length(Desc{N});
1061  t = t(ix(2)+1:end);
1062  end;
1063  HDR.EVENT.POS = onset * HDR.SampleRate;
1064  if any(HDR.EVENT.POS - ceil(HDR.EVENT.POS))
1065  warning('HDR.EVENT.POS is not integer')
1066  %HDR.EVENT.POS = round(HDR.EVENT.POS);
1067  end
1068  HDR.EVENT.DUR = dur * HDR.SampleRate;
1069  HDR.EVENT.CHN = zeros(N,1);
1070  %% TODO: use eventcodes.txt for predefined event types e.g. QRS->0x501
1071  [HDR.EVENT.CodeDesc, CodeIndex, HDR.EVENT.TYP] = unique(Desc(1:N)');
1072  end
1073 
1074  status = fseek(HDR.FILE.FID, HDR.HeadLen, 'bof');
1075  HDR.FILE.POS = 0;
1076  HDR.FILE.OPEN = 1;
1077 
1078  %%% Event file stored in GDF-format
1079  if ~any([HDR.NS,HDR.NRec,~length(HDR.EVENT.POS)]);
1080  HDR.TYPE = 'EVENT';
1081  HDR = sclose(HDR);
1082  end;
1083 
1084  elseif any(HDR.FILE.PERMISSION=='w'); %%%%%%% ============= WRITE ===========%%%%%%%%%%%%
1085  if strcmp(HDR.TYPE,'EDF')
1086  HDR.VERSION = 0;
1087  elseif strcmp(HDR.TYPE,'GDF')
1088  if ~isfield(HDR,'VERSION')
1089  HDR.VERSION = 2.21; %% default version
1090  elseif (HDR.VERSION < 1.30)
1091  HDR.VERSION = 1.25; %% old version
1092  elseif (HDR.VERSION < 2.19)
1093  HDR.VERSION = 2.11; %% stable version
1094  else
1095  HDR.VERSION = 2.22; %% experimental
1096  end;
1097  elseif strcmp(HDR.TYPE,'BDF'),
1098  HDR.VERSION = -1;
1099  end;
1100 
1101  if ~isfield(HDR,'RID')
1102  HDR.RID=char(32+zeros(1,80));
1103  end;
1104  if ~isfield(HDR,'T0')
1105  HDR.T0=zeros(1,6);
1106  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.T0 not defined\n');
1107  elseif any(isnan(HDR.T0))
1108  HDR.T0(isnan(HDR.T0))=0;
1109  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.T0 not completely defined\n');
1110  end;
1111  if ~isfield(HDR,'Patient')
1112  HDR.Patient.Sex = 0;
1113  HDR.Patient.Handedness = 0;
1114  HDR.Patient.Birthday = zeros(1,6);
1115  HDR.Patient.Headsize = [NaN, NaN, NaN];
1116  HDR.Patient.Weight = 0;
1117  HDR.Patient.Height = 0;
1118  end;
1119  if ~isfield(HDR.Patient,'Name')
1120  HDR.Patient.Name = 'X';
1121  end;
1122  if ~isfield(HDR.Patient,'Id')
1123  HDR.Patient.Id = 'X';
1124  end;
1125  if ~isfield(HDR.Patient,'Sex')
1126  HDR.Patient.Sex = 0;
1127  elseif isnumeric(HDR.Patient.Sex)
1128  ; % nothing to be done
1129  elseif strcmpi(HDR.Patient.Sex,'m') || strcmpi(HDR.Patient.Sex,'male')
1130  HDR.Patient.Sex = 1;
1131  elseif strcmpi(HDR.Patient.Sex,'f') || strcmpi(HDR.Patient.Sex,'female')
1132  HDR.Patient.Sex = 2;
1133  else
1134  HDR.Patient.Sex = 0;
1135  end;
1136 
1137  if ~isfield(HDR.Patient,'Handedness')
1138  HDR.Patient.Handedness = 0;
1139  elseif isnumeric(HDR.Patient.Handedness)
1140  ; % nothing to be done
1141  elseif strcmpi(HDR.Patient.Handedness,'r') || strcmpi(HDR.Patient.Handedness,'right')
1142  HDR.Patient.Handedness = 1;
1143  elseif strcmpi(HDR.Patient.Handedness,'l') || strcmpi(HDR.Patient.Handedness,'left')
1144  HDR.Patient.Handedness = 2;
1145  else
1146  HDR.Patient.Handedness = 0;
1147  end;
1148  if ~isfield(HDR.Patient,'Impairment.Visual')
1149  HDR.Patient.Impairment.Visual = 0;
1150  elseif isnumeric(HDR.Patient.Impairment.Visual)
1151  ; % nothing to be done
1152  elseif strcmpi(HDR.Patient.Impairment.Visual,'NO') || strcmpi(HDR.Patient.Impairment.Visual,'NO')
1153  HDR.Patient.Impairment.Visual = 1;
1154  elseif strcmpi(HDR.Patient.Impairment.Visual,'Y') || strcmpi(HDR.Patient.Impairment.Visual,'YES')
1155  HDR.Patient.Impairment.Visual = 2;
1156  elseif strncmpi(HDR.Patient.Impairment.Visual,'corr',4)
1157  HDR.Patient.Impairment.Visual = 3;
1158  elseif isnumeric(HDR.Patient.Impairment.Visual)
1159  else
1160  HDR.Patient.Impairment.Visual = 0;
1161  end;
1162  if ~isfield(HDR.Patient,'Smoking')
1163  HDR.Patient.Smoking = 0;
1164  elseif isnumeric(HDR.Patient.Smoking)
1165  ; % nothing to be done
1166  elseif strcmpi(HDR.Patient.Smoking,'NO') || strcmpi(HDR.Patient.Smoking,'NO')
1167  HDR.Patient.Smoking = 1;
1168  elseif strcmpi(HDR.Patient.Smoking,'Y') || strcmpi(HDR.Patient.Smoking,'YES')
1169  HDR.Patient.Smoking = 2;
1170  elseif isnumeric(HDR.Patient.Smoking)
1171  else
1172  HDR.Patient.Smoking = 0;
1173  end;
1174  if ~isfield(HDR.Patient,'AlcoholAbuse')
1175  HDR.Patient.AlcoholAbuse = 0;
1176  elseif isnumeric(HDR.Patient.AlcoholAbuse)
1177  ; % nothing to be done
1178  elseif strcmpi(HDR.Patient.AlcoholAbuse,'NO') || strcmpi(HDR.Patient.AlcoholAbuse,'NO')
1179  HDR.Patient.AlcoholAbuse = 1;
1180  elseif strcmpi(HDR.Patient.AlcoholAbuse,'Y') || strcmpi(HDR.Patient.AlcoholAbuse,'YES')
1181  HDR.Patient.AlcoholAbuse = 2;
1182  elseif isnumeric(HDR.Patient.AlcoholAbuse)
1183  else
1184  HDR.Patient.AlcoholAbuse = 0;
1185  end;
1186  if ~isfield(HDR.Patient,'DrugAbuse')
1187  HDR.Patient.DrugAbuse = 0;
1188  elseif isnumeric(HDR.Patient.DrugAbuse)
1189  ; % nothing to be done
1190  elseif strcmpi(HDR.Patient.DrugAbuse,'NO') || strcmpi(HDR.Patient.DrugAbuse,'NO')
1191  HDR.Patient.DrugAbuse = 1;
1192  elseif strcmpi(HDR.Patient.DrugAbuse,'Y') || strcmpi(HDR.Patient.DrugAbuse,'YES')
1193  HDR.Patient.DrugAbuse = 2;
1194  elseif isnumeric(HDR.Patient.DrugAbuse)
1195  else
1196  HDR.Patient.DrugAbuse = 0;
1197  end;
1198  if ~isfield(HDR.Patient,'Medication')
1199  HDR.Patient.Medication = 0;
1200  elseif isnumeric(HDR.Patient.Medication)
1201  ; % nothing to be done
1202  elseif strcmpi(HDR.Patient.Medication,'NO') || strcmpi(HDR.Patient.Medication,'NO')
1203  HDR.Patient.Medication = 1;
1204  elseif strcmpi(HDR.Patient.Medication,'Y') || strcmpi(HDR.Patient.Medication,'YES')
1205  HDR.Patient.Medication = 2;
1206  else
1207  HDR.Patient.Medication = 0;
1208  end;
1209  if ~isfield(HDR.Patient,'Weight')
1210  HDR.Patient.Weight = 0;
1211  elseif (HDR.Patient.Weight > 254),
1212  HDR.Patient.Weight = 255;
1213  elseif isnan(HDR.Patient.Weight) || (isnan(HDR.Patient.Weight)<0)
1214  HDR.Patient.Weight = 0;
1215  end;
1216  if ~isfield(HDR.Patient,'Height')
1217  HDR.Patient.Height = 0;
1218  elseif (HDR.Patient.Height > 254),
1219  HDR.Patient.Height = 255;
1220  elseif isnan(HDR.Patient.Height) || (isnan(HDR.Patient.Height)<0)
1221  HDR.Patient.Height = 0;
1222  end;
1223  if ~isfield(HDR.Patient,'Birthday')
1224  if ~isfield(HDR.Patient,'Age')
1225  HDR.Patient.Birthday = zeros(1,6);
1226  elseif isnan(HDR.Patient.Age)
1227  HDR.Patient.Birthday = zeros(1,6);
1228  else
1229  HDR.Patient.Birthday = datevec(datenum(HDR.T0) + HDR.Patient.Age*365.25);
1230  end;
1231  end;
1232  if ~isfield(HDR.Patient,'Headsize')
1233  HDR.Patient.Headsize = [NaN,NaN,NaN];
1234  elseif ~isnumeric(HDR.Patient.Headsize)
1235  fprintf('Warning SOPEN (GDF)-W: HDR.Patient.Headsize must be numeric.\n');
1236  elseif (numel(HDR.Patient.Headsize)~=3)
1237  tmp = [HDR.Patient.Headsize(:);NaN;NaN;NaN]';
1238  HDR.Patient.Headsize = HDR.Patient.Headsize(1:3);
1239  end;
1240  if ~isfield(HDR,'ELEC')
1241  HDR.ELEC.XYZ = repmat(0,HDR.NS,3);
1242  HDR.ELEC.GND = zeros(1,3);
1243  HDR.ELEC.REF = zeros(1,3);
1244  end;
1245  tmp = uint32([hex2dec('00292929'),48*36e5+2^31,15*36e5+2^31,35000]);
1246  if ~isfield(HDR,'REC')
1247  HDR.REC.LOC.RFC1876 = tmp;
1248  elseif ~isfield(HDR.REC,'LOC');
1249  HDR.REC.LOC.RFC1876 = tmp;
1250  elseif ~isfield(HDR.REC.LOC,'RFC1876')
1251  tmp = HDR.REC.LOC;
1252  HDR.REC.LOC.RFC1876 = [hex2dec('00292929'),tmp.Latitude*36e5,tmp.Longitude*36e5,tmp.Altitude*100];
1253  end
1254  if isfield(HDR.REC,'Impedance') && ~isfield(HDR,'Impedance')
1255  HDR.Impedance = HDR.REC.Impedance;
1256  end
1257  if ~isfield(HDR,'Impedance')
1258  HDR.Impedance = repmat(NaN,HDR.NS,1);
1259  end
1260  HDR.REC.Equipment = [1,abs('BIOSIG ')];
1261  if ~isfield(HDR.REC,'Lab')
1262  HDR.REC.Lab = repmat(32,1,8);
1263  end;
1264  if ~isfield(HDR.REC,'IPaddr')
1265  HDR.REC.IPaddr = uint8(zeros(1,6));
1266  end;
1267  if ~isfield(HDR.REC,'Technician')
1268  HDR.REC.Technician = repmat(32,1,8);
1269  end;
1270 
1271  if ~isfield(HDR,'NRec')
1272  HDR.NRec=-1;
1273  end;
1274  if ~isfield(HDR,'Dur')
1275  if HDR.NS>0,
1276  fprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.Dur not defined\n');
1277  end;
1278  HDR.Dur=NaN;
1279  end;
1280  if ~isfield(HDR,'NS')
1281  HDR.ErrMsg = sprintf('Error SOPEN (GDF/EDF/BDF)-W: HDR.NS not defined\n');
1282  HDR.ErrNum = HDR.ErrNum + 128;
1283  return;
1284  end;
1285  if ~isfield(HDR,'SampleRate')
1286  HDR.SampleRate = NaN;
1287  end;
1288  if ~isnan(HDR.Dur) && ~isnan(HDR.SampleRate) && ~isfield(HDR,'SPR'),
1289  HDR.SPR = HDR.SampleRate*HDR.Dur;
1290  end
1291 
1292  if ~isfield(HDR,'AS')
1293  HDR.AS.SPR = repmat(NaN,1,HDR.NS);
1294  end;
1295  if ~isfield(HDR.AS,'SPR')
1296  HDR.AS.SPR = repmat(NaN,1,HDR.NS);
1297  end;
1298  if isfield(HDR,'SPR')
1299  HDR.AS.SPR(isnan(HDR.AS.SPR)) = HDR.SPR;
1300  elseif all(~isnan(HDR.AS.SPR))
1301  HDR.SPR = 1;
1302  for k=1:HDR.NS
1303  if HDR.AS.SPR(k),
1304  HDR.SPR = lcm(HDR.SPR,HDR.AS.SPR(k));
1305  end;
1306  end;
1307  else
1308  warning('either HDR.SPR or HDR.AS.SPR must be defined');
1309  end;
1310  if ~isfield(HDR.AS,'SampleRate')
1311  HDR.AS.SampleRate = HDR.SampleRate*HDR.AS.SPR/HDR.SPR;
1312  end;
1313 
1314  if ~HDR.NS,
1315  elseif ~isnan(HDR.Dur) && any(isnan(HDR.AS.SPR)) && ~any(isnan(HDR.AS.SampleRate))
1316  HDR.AS.SPR = HDR.AS.SampleRate * HDR.Dur;
1317  elseif ~isnan(HDR.Dur) && ~any(isnan(HDR.AS.SPR)) && any(isnan(HDR.AS.SampleRate))
1318  HDR.SampleRate = HDR.Dur * HDR.AS.SPR;
1319  elseif isnan(HDR.Dur) && ~any(isnan(HDR.AS.SPR)) && ~any(isnan(HDR.AS.SampleRate))
1320  HDR.Dur = HDR.AS.SPR(:) ./ HDR.AS.SampleRate(:);
1321  if all((HDR.Dur(1)-HDR.Dur)<5*eps)
1322  HDR.Dur = HDR.Dur(1);
1323  else
1324  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF): SPR and SampleRate do not fit\n');
1325  end;
1326  elseif ~isnan(HDR.Dur) && ~any(isnan(HDR.AS.SPR)) && ~any(isnan(HDR.AS.SampleRate))
1327  %% thats ok,
1328  else
1329  fprintf(HDR.FILE.stderr,'ERROR SOPEN (GDF/EDF/BDF): more than 1 of HDR.Dur, HDR.SampleRate, HDR.AS.SPR undefined.\n');
1330  return;
1331  end;
1332 
1333  %if (abs(HDR.VERSION(1))==255) && strcmp(HDR.VERSION(2:8),'BIOSEMI'),
1334  if (HDR.VERSION == -1),
1335  HDR.GDFTYP=255+24+zeros(1,HDR.NS);
1336  %elseif strcmp(HDR.VERSION,'0 '),
1337  elseif HDR.VERSION == 0,
1338  HDR.GDFTYP=3+zeros(1,HDR.NS);
1339  %elseif strcmp(HDR.VERSION(1:3),'GDF'),
1340  elseif (HDR.VERSION>0),
1341  if HDR.NS == 0;
1342  HDR.GDFTYP = 3;
1343  elseif ~isfield(HDR,'GDFTYP'),
1344  HDR.ErrMsg = sprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.GDFTYP not defined\n');
1345  HDR.ErrNum = HDR.ErrNum + 128;
1346  % fclose(HDR.FILE.FID); return;
1347  elseif length(HDR.GDFTYP)==1,
1348  HDR.GDFTYP = HDR.GDFTYP(ones(HDR.NS,1));
1349  elseif length(HDR.GDFTYP)>=HDR.NS,
1350  HDR.GDFTYP = HDR.GDFTYP(1:HDR.NS);
1351  end;
1352  else
1353  fprintf(HDR.FILE.stderr,'Error SOPEN (GDF/EDF/BDF): invalid VERSION %s\n ',HDR.VERSION);
1354  return;
1355  end;
1356  [tmp,HDR.THRESHOLD]=gdfdatatype(HDR.GDFTYP);
1357 
1358  if (HDR.NS>0), % header 2
1359  % Check all fields of Header2
1360  Label = repmat(' ',HDR.NS,16);
1361  if isfield(HDR,'Label')
1362  if ischar(HDR.Label)
1363  sz = min([HDR.NS,16],size(HDR.Label));
1364  Label(1:sz(1),1:sz(2)) = HDR.Label(1:sz(1),1:sz(2));
1365  elseif iscell(HDR.Label)
1366  for k=1:min(HDR.NS,length(HDR.Label))
1367  tmp = [HDR.Label{k},' '];
1368  sz = min(16,length(tmp));
1369  Label(k,1:sz)=tmp(1:sz);
1370  end;
1371  end;
1372  else
1373  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.Label not defined\n');
1374  end;
1375 
1376  if ~isfield(HDR,'Transducer')
1377  HDR.Transducer=repmat({' '},HDR.NS,1); %char(32+zeros(HDR.NS,80));
1378  elseif ischar(HDR.Transducer)
1379  HDR.Transducer = cellstr(HDR.Transducer);
1380  end;
1381  Transducer = char(HDR.Transducer);
1382  tmp = min(80,size(Transducer,2));
1383  Transducer = [Transducer, repmat(' ',size(Transducer,1),80-tmp)];
1384  Transducer = Transducer(:,1:80);
1385 
1386  if ~isfield(HDR,'Filter')
1387  HDR.Filter.LowPass = repmat(NaN,1,HDR.NS);
1388  HDR.Filter.HighPass = repmat(NaN,1,HDR.NS);
1389  HDR.Filter.Notch = repmat(NaN,1,HDR.NS);
1390  else
1391  if ~isfield(HDR.Filter,'LowPass')
1392  HDR.Filter.LowPass = repmat(NaN,1,HDR.NS);
1393  elseif (numel(HDR.Filter.LowPass)==1)
1394  HDR.Filter.LowPass = repmat(HDR.Filter.LowPass,1,HDR.NS);
1395  elseif (numel(HDR.Filter.LowPass)~=HDR.NS)
1396  fprintf(HDR.FILE.stderr,'SOPEN (GDF) WRITE: HDR.Filter.LowPass has incorrrect number of fields!\n')
1397  end;
1398  if ~isfield(HDR.Filter,'HighPass')
1399  HDR.Filter.HighPass = repmat(NaN,1,HDR.NS);
1400  elseif (numel(HDR.Filter.HighPass)==1)
1401  HDR.Filter.HighPass = repmat(HDR.Filter.HighPass,1,HDR.NS);
1402  elseif (numel(HDR.Filter.HighPass)~=HDR.NS)
1403  fprintf(HDR.FILE.stderr,'SOPEN (GDF) WRITE: HDR.Filter.HighPass has incorrrect number of fields!\n')
1404  end;
1405  if ~isfield(HDR.Filter,'Notch')
1406  HDR.Filter.Notch = repmat(NaN,1,HDR.NS);
1407  elseif (numel(HDR.Filter.Notch)==1)
1408  HDR.Filter.Notch = repmat(HDR.Filter.Notch,1,HDR.NS);
1409  elseif (numel(HDR.Filter.Notch)~=HDR.NS)
1410  fprintf(HDR.FILE.stderr,'SOPEN (GDF) WRITE: HDR.Filter.Notch has incorrrect number of fields!\n')
1411  end;
1412  end;
1413  if ~isfield(HDR,'PreFilt')
1414  HDR.PreFilt = char(32+zeros(HDR.NS,80));
1415  if isfield(HDR,'Filter'),
1416  if isfield(HDR.Filter,'LowPass') && isfield(HDR.Filter,'HighPass') && isfield(HDR.Filter,'Notch'),
1417  if any(length(HDR.Filter.LowPass) == [1,HDR.NS]) && any(length(HDR.Filter.HighPass) == [1,HDR.NS]) && any(length(HDR.Filter.Notch) == [1,HDR.NS])
1418  PreFilt = {};
1419  for k = 1:HDR.NS,
1420  k1 = min(k,length(HDR.Filter.LowPass));
1421  k2 = min(k,length(HDR.Filter.HighPass));
1422  k3 = min(k,length(HDR.Filter.Notch));
1423  PreFilt{k,1} = sprintf('LP: %5.f Hz; HP: %5.2f Hz; Notch: %i',HDR.Filter.LowPass(k1),HDR.Filter.HighPass(k2),HDR.Filter.Notch(k3));
1424  end;
1425  HDR.PreFilt = char(PreFilt);
1426  end;
1427  end
1428  end
1429  elseif size(HDR.PreFilt,1)<HDR.NS,
1430  HDR.PreFilt = repmat(HDR.PreFilt,HDR.NS,1);
1431  end;
1432  tmp = min(80,size(HDR.PreFilt,2));
1433  HDR.PreFilt = [HDR.PreFilt(1:HDR.NS,1:tmp), char(32+zeros(HDR.NS,80-tmp))];
1434 
1435  if isfield(HDR,'PhysDimCode')
1436  HDR.PhysDimCode = HDR.PhysDimCode(1:HDR.NS);
1437  end;
1438  PhysDim = char(32+zeros(HDR.NS,8));
1439  if ~isfield(HDR,'PhysDim')
1440  HDR.PhysDim=repmat({' '},HDR.NS,1);
1441  PhysDim = char(32+zeros(HDR.NS,8));
1442  if HDR.NS>0,
1443  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.PhysDim not defined\n');
1444  end;
1445  else
1446  if iscell(HDR.PhysDim),
1447  % make column
1448  HDR.PhysDim = HDR.PhysDim(:);
1449  end;
1450  if length(HDR.PhysDim)==0,
1451  HDR.PhysDim = repmat({' '},HDR.NS,1);
1452  elseif size(HDR.PhysDim,1)<HDR.NS,
1453  HDR.PhysDim = repmat(HDR.PhysDim,HDR.NS,1);
1454  elseif size(HDR.PhysDim,1)>HDR.NS,
1455  HDR.PhysDim = HDR.PhysDim(1:HDR.NS);
1456  end;
1457  PhysDim = char(HDR.PhysDim); % local copy
1458  if size(PhysDim,1)~=HDR.NS,
1459  PhysDim = char(32+zeros(HDR.NS,8));
1460  end;
1461  end;
1462  tmp = min(8,size(PhysDim,2));
1463  PhysDim = [PhysDim(1:HDR.NS,1:tmp), char(32+zeros(HDR.NS,8-tmp))];
1464 
1465  HDR = physicalunits(HDR);
1466  if ~all(HDR.PhysDimCode>0)
1467  fprintf(HDR.FILE.stderr,'Warning SOPEN: HDR.PhysDimCode of the following channel(s) is(are) not defined:\n');
1468  fprintf(HDR.FILE.stderr,'%i ',find(~HDR.PhysDimCode));
1469  fprintf(HDR.FILE.stderr,'\n');
1470  end;
1471 
1472  if ~isfield(HDR,'PhysMin')
1473  if HDR.NS>0,
1474  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.PhysMin not defined\n');
1475  end
1476  HDR.PhysMin = repmat(nan,HDR.NS,1);
1477  elseif HDR.NS > length(HDR.PhysMin)
1478  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.PhysMin not fully defined\n');
1479  HDR.PhysMin = [HDR.PhysMin(:);repmat(nan,HDR.NS-length(HDR.PhysMin),1)];
1480  else
1481  HDR.PhysMin = HDR.PhysMin(1:HDR.NS);
1482  end;
1483  if ~isfield(HDR,'TOffset')
1484  HDR.TOffset=repmat(nan,HDR.NS,1);
1485  else
1486  HDR.TOffset=[HDR.TOffset(:);repmat(NaN,HDR.NS,1)];
1487  HDR.TOffset=HDR.TOffset(1:HDR.NS);
1488  end;
1489  if ~isfield(HDR,'PhysMax')
1490  if HDR.NS>0,
1491  fprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.PhysMax not defined\n');
1492  end;
1493  HDR.PhysMax=repmat(nan,HDR.NS,1);
1494  else
1495  HDR.PhysMax=HDR.PhysMax(1:HDR.NS);
1496  end;
1497  if ~isfield(HDR,'DigMin')
1498  if HDR.NS>0,
1499  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF)-W: HDR.DigMin not defined\n');
1500  end
1501  HDR.DigMin=repmat(nan,HDR.NS,1);
1502  else
1503  HDR.DigMin=HDR.DigMin(1:HDR.NS);
1504  end;
1505  if ~isfield(HDR,'DigMax')
1506  if HDR.NS>0,
1507  fprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.DigMax not defined\n');
1508  end;
1509  HDR.DigMax=repmat(nan,HDR.NS,1);
1510  else
1511  HDR.DigMax=HDR.DigMax(1:HDR.NS);
1512  end;
1513  HDR.Cal = (HDR.PhysMax(:)-HDR.PhysMin(:))./(HDR.DigMax(:)-HDR.DigMin(:));
1514  HDR.Off = HDR.PhysMin(:) - HDR.Cal(:) .* HDR.DigMin(:);
1515 
1516  flag = isfield(HDR,'ELEC');
1517  if flag,
1518  flag = isfield(HDR.ELEC,'XYZ');
1519  end;
1520 
1521  if ~flag,
1522  HDR.ELEC.XYZ = repmat(NaN,HDR.NS,3);
1523  HDR.ELEC.REF = repmat(NaN,1,3);
1524  HDR.ELEC.GND = repmat(NaN,1,3);
1525  elseif ~isnumeric(HDR.ELEC.XYZ)
1526  fprintf('Warning SOPEN (GDF)-W: HDR.ELEC.LOC must be numeric.\n');
1527  elseif any(size(HDR.ELEC.XYZ)==[HDR.NS,3])
1528  HDR.ELEC.REF = repmat(NaN,1,3);
1529  HDR.ELEC.GND = repmat(NaN,1,3);
1530  elseif any(size(HDR.ELEC.XYZ)==[HDR.NS+1,3])
1531  HDR.ELEC.REF = HDR.ELEC.XYZ(HDR.NS+1,:);
1532  HDR.ELEC.GND = repmat(NaN,1,3);
1533  elseif any(size(HDR.ELEC.XYZ)==[HDR.NS+2,3])
1534  HDR.ELEC.REF = HDR.ELEC.XYZ(HDR.NS+1,:);
1535  HDR.ELEC.GND = HDR.ELEC.XYZ(HDR.NS+2,:);
1536  else
1537  fprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.ELEC.LOC not correctly defined\n');
1538  tmp = [HDR.ELEC.XYZ,repmat(NaN,size(HDR.ELEC.XYZ,1),3)];
1539  tmp = [tmp;repmat(NaN,HDR.NS+2,size(tmp,2))];
1540  HDR.ELEC.XYZ = tmp(1:HDR.NS,1:3);
1541  HDR.ELEC.REF = HDR.ELEC.XYZ(HDR.NS+1,:);
1542  HDR.ELEC.GND = HDR.ELEC.XYZ(HDR.NS+2,:);
1543  end;
1544  if ~isfield(HDR,'Impedance')
1545  HDR.Impedance = repmat(NaN,HDR.NS,1);
1546  elseif ~isnumeric(HDR.Impedance)
1547  fprintf('Warning SOPEN (GDF)-W: HDR.Impedance must be numeric.\n');
1548  elseif (length(HDR.Impedance)~=HDR.NS)
1549  sz = size(HDR.Impedance(:));
1550  tmp = [HDR.Impedance(:),repmat(NaN,sz(1),1);repmat(NaN,HDR.NS,sz(2)+1)];
1551  HDR.Impedance = tmp(1:HDR.NS,1);
1552  end
1553 
1554  ix = find((HDR.DigMax(:)==HDR.DigMin(:)) & (HDR.PhysMax(:)==HDR.PhysMin(:)));
1555  HDR.PhysMax(ix) = 1;
1556  HDR.PhysMin(ix) = 0;
1557  HDR.DigMax(ix) = 1;
1558  HDR.DigMin(ix) = 0;
1559 
1560  if 0, isfield(HDR.AS,'SampleRate')
1561  HDR.AS.SPR = HDR.AS.SampleRate(1:HDR.NS)/HDR.SampleRate * HDR.SPR;
1562  if any(HDR.AS.SPR~=ceil(HDR.AS.SPR)),
1563  fprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.AS.SPR is not integer\n');
1564  end;
1565  elseif ~isfield(HDR.AS,'SPR')
1566  if HDR.NS>0,
1567  fprintf('Warning SOPEN (GDF/EDF/BDF)-W: HDR.AS.SPR not defined\n');
1568  end;
1569  HDR.AS.SPR = repmat(nan,HDR.NS,1);
1570  HDR.ErrMsg = sprintf('Error SOPEN (GDF/EDF/BDF)-W: HDR.AS.SPR not defined\n');
1571  HDR.ErrNum = HDR.ErrNum + 128;
1572  %fclose(HDR.FILE.FID); return;
1573  else
1574  HDR.AS.SPR=reshape(HDR.AS.SPR(1:HDR.NS),HDR.NS,1);
1575  end;
1576 
1577  end; % header 2
1578 
1579  %%%%%% generate Header 3, Tag-Length-Value
1580  TagLenValue = {};
1581  TagLen = 0;
1582  if isfield(HDR,'Manufacturer')
1583  tag = 3;
1584  if ~isfield(HDR.Manufacturer,'Name') HDR.Manufacturer.Name=''; end;
1585  if ~isfield(HDR.Manufacturer,'Model') HDR.Manufacturer.Model=''; end;
1586  if ~isfield(HDR.Manufacturer,'Version') HDR.Manufacturer.Version=''; end;
1587  if ~isfield(HDR.Manufacturer,'SerialNumber') HDR.Manufacturer.SerialNumber=''; end;
1588  TagLenValue{tag} = char([HDR.Manufacturer.Name,0,HDR.Manufacturer.Model,0,HDR.Manufacturer.Version,0,HDR.Manufacturer.SerialNumber]);
1589  TagLen(tag) = length(TagLenValue{tag});
1590  end;
1591 
1592  if 0, isfield(HDR,'ELEC') && isfield(HDR.ELEC,'Orientation') && all(size(HDR.ELEC.Orientation)==[HDR.NS,3])
1593  %% OBSOLETE
1594  tag = 4;
1595  TagLenValue{tag} = HDR.ELEC.Orientation;
1596  TagLen(tag) = 16*HDR.NS;
1597  end;
1598 
1599  %%%%%% generate Header 1, first 256 bytes
1600  HDR.HeadLen=(HDR.NS+1)*256;
1601  if any(TagLen>0) && (HDR.VERSION>2)
1602  HDR.HeadLen = HDR.HeadLen + ceil((sum(TagLen)+4*sum(TagLen>0)+4)/256)*256; %% terminating 0-Tag
1603  end;
1604 
1605  %H1(1:8)=HDR.VERSION; %sprintf('%08i',HDR.VERSION); % 8 Byte Versionsnummer
1606  if isempty(HDR.Patient.Birthday), bd = 'X';
1607  HDR.Patient.Birthday = zeros(1,6);
1608  elseif (~HDR.Patient.Birthday), bd = 'X';
1609  HDR.Patient.Birthday = zeros(1,6);
1610  else bd=datestr(datenum(HDR.Patient.Birthday),'dd-mmm-yyyy');
1611  end;
1612  if HDR.VERSION == -1,
1613  H1 = [255,'BIOSEMI',repmat(32,1,248)];
1614  HDR.PID = [HDR.Patient.Id,' ',GENDER{HDR.Patient.Sex+1}(1),' ',bd,' ',HDR.Patient.Name];
1615  HDR.RID = ['Startdate ',datestr(HDR.T0,'dd-mmm-yyyy')];
1616  elseif HDR.VERSION == 0,
1617  H1 = ['0 ',repmat(32,1,248)];
1618  HDR.PID = [HDR.Patient.Id,' ',GENDER{HDR.Patient.Sex+1}(1),' ',bd,' ',HDR.Patient.Name];
1619  HDR.RID = ['Startdate ',datestr(datenum(HDR.T0),'dd-mmm-yyyy')];
1620  elseif HDR.VERSION > 0,
1621  tmp = sprintf('%5.2f',HDR.VERSION);
1622  H1 = ['GDF',tmp(1:5),repmat(32,1,248)];
1623  HDR.PID = [HDR.Patient.Id,' ',HDR.Patient.Name];
1624  % HDR.RID = 'Hospital_administration_Code Technician_ID [Equipment_ID]'
1625  else
1626  fprintf(HDR.FILE.stderr,'Error SOPEN (GDF) WRITE: invalid version number %f\n',HDR.VERSION);
1627  end;
1628  H1( 8+(1:length(HDR.PID))) = HDR.PID;
1629  H1(88+(1:length(HDR.RID))) = HDR.RID;
1630  %H1(185:192)=sprintf('%-8i',HDR.HeadLen);
1631  HDR.AS.SPR = HDR.AS.SPR(1:HDR.NS);
1632  HDR.AS.spb = sum(HDR.AS.SPR); % Samples per Block
1633  HDR.AS.bi = [0;cumsum(HDR.AS.SPR(:))];
1634  HDR.AS.BPR = ceil(HDR.AS.SPR(:).*GDFTYP_BYTE(HDR.GDFTYP(:)+1)');
1635  while HDR.NS && any(HDR.AS.BPR(:) ~= HDR.AS.SPR(:).*GDFTYP_BYTE(HDR.GDFTYP+1)');
1636  fprintf(2,'\nWarning SOPEN (GDF/EDF/BDF): invalid block configuration in file %s.\n',HDR.FileName);
1637  HDR.SPR,
1638  DIV = 2;
1639  HDR.SPR = HDR.SPR*DIV;
1640  HDR.AS.SPR = HDR.AS.SPR*DIV;
1641  HDR.Dur = HDR.Dur*DIV;
1642  HDR.NRec = HDR.NRec/DIV;
1643  HDR.AS.BPR = ceil(HDR.AS.SPR(:).*GDFTYP_BYTE(HDR.GDFTYP(:)+1)');
1644  end;
1645  HDR.AS.SAMECHANTYP = all(HDR.AS.BPR == (HDR.AS.SPR(:).*GDFTYP_BYTE(HDR.GDFTYP(:)+1)')) && ~any(diff(HDR.GDFTYP));
1646  HDR.AS.spb = sum(HDR.AS.SPR); % Samples per Block
1647  HDR.AS.bi = [0;cumsum(HDR.AS.SPR(:))];
1648  HDR.AS.bpb = sum(ceil(HDR.AS.SPR(:).*GDFTYP_BYTE(HDR.GDFTYP(:)+1)')); % Bytes per Block
1649  HDR.FILE.POS = 0;
1650 
1651  if (HDR.VERSION>=1.9), % do some header checks
1652  if datenum([1850,1,1,0,0,0])>datenum(HDR.Patient.Birthday),
1653  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF) WRITE: HDR.Patient.Birthday is not correctly defined.\n');
1654  end;
1655  elseif (HDR.VERSION == 0)
1656  if sum(HDR.AS.bpb)>61440;
1657  fprintf(HDR.FILE.stderr,'\nWarning SOPEN (EDF): One block exceeds 61440 bytes.\n')
1658  end;
1659  end;
1660 
1661  %%%%% Open File
1662  if ((HDR.NRec<0) && any(HDR.FILE.PERMISSION=='z')),
1663  %% due to a limitation zlib
1664  fprintf(HDR.FILE.stderr,'ERROR SOPEN (GDF/EDF/BDF) "wz": Update of HDR.NRec and writing Eventtable are not possible.\n',HDR.FileName);
1665  fprintf(HDR.FILE.stderr,'\t Solution(s): (1) define exactly HDR.NRec before calling SOPEN(HDR,"wz"); or (2) write to uncompressed file instead.\n');
1666  return;
1667  end;
1668 
1669  if 1,
1670  [HDR.FILE.FID,MESSAGE]=fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
1671  elseif ~any(PERMISSION=='+')
1672  [HDR.FILE.FID,MESSAGE]=fopen(HDR.FileName,'w+b','ieee-le');
1673  else % (arg2=='w+') % may be called only by SDFCLOSE
1674  if HDR.FILE.OPEN==2
1675  [HDR.FILE.FID,MESSAGE]=fopen(HDR.FileName,'r+b','ieee-le');
1676  else
1677  fprintf(HDR.FILE.stderr,'Error SOPEN (GDF/EDF/BDF)-W+: Cannot open %s for write access\n',HDR.FileName);
1678  return;
1679  end;
1680  end;
1681 
1682  if HDR.FILE.FID<0
1683  %fprintf(HDR.FILE.stderr,'Error EDFOPEN: %s\n',MESSAGE);
1684  H1=MESSAGE;H2=[];
1685  HDR.ErrNum = HDR.ErrNum + 32;
1686  fprintf(HDR.FILE.stderr,'Error SOPEN (GDF/EDF/BDF)-W: Could not open %s \n',HDR.FileName);
1687  return;
1688  end;
1689  HDR.FILE.OPEN = 2;
1690 
1691  %if strcmp(HDR.VERSION(1:3),'GDF'),
1692  if (HDR.VERSION > 0), % GDF
1693  if (HDR.VERSION >= 1.90)
1694  H1(85) = mod(HDR.Patient.Medication,3)*64 + mod(HDR.Patient.DrugAbuse,3)*16 + mod(HDR.Patient.AlcoholAbuse,3)*4 + mod(HDR.Patient.Smoking,3);
1695  H1(86) = HDR.Patient.Weight;
1696  H1(87) = HDR.Patient.Height;
1697  H1(88) = bitand(HDR.Patient.Sex,3) + bitand(HDR.Patient.Handedness,3)*4 + bitand(HDR.Patient.Impairment.Visual,3)*16;
1698  if all(H1(153:156)==32)
1699  c = fwrite(HDR.FILE.FID,abs(H1(1:152)),'uint8');
1700  c = fwrite(HDR.FILE.FID,HDR.REC.LOC.RFC1876,'uint32');
1701  else
1702  c = fwrite(HDR.FILE.FID,abs(H1(1:156)),'uint8');
1703  c = fwrite(HDR.FILE.FID,HDR.REC.LOC.RFC1876(2:4),'uint32');
1704  end;
1705  if length(HDR.T0) > 2,
1706  HDR.T0 = datenum(HDR.T0);
1707  end;
1708  if length(HDR.Patient.Birthday) > 2,
1709  HDR.Patient.Birthday = datenum(HDR.Patient.Birthday);
1710  end;
1711  tmp = [HDR.T0, HDR.Patient.Birthday];
1712  tmp = floor([rem(tmp,1)*2^32;tmp]);
1713  c = fwrite(HDR.FILE.FID,tmp,'uint32');
1714  c = fwrite(HDR.FILE.FID,[HDR.HeadLen/256,0,0,0],'uint16');
1715  c = fwrite(HDR.FILE.FID,'b4om2.39','uint8'); % EP_ID=ones(8,1)*32;
1716  if (HDR.VERSION < 2.1)
1717  tmp = [HDR.REC.IPaddr, zeros(1,2)];
1718  else
1719  tmp = zeros(1,6);
1720  end;
1721  c=fwrite(HDR.FILE.FID,tmp(6:-1:1),'uint8'); % IP address, v2.1+: reserved
1722  if HDR.NS>0,
1723  c=fwrite(HDR.FILE.FID,HDR.Patient.Headsize(1:3),'uint16'); % circumference, nasion-inion, left-right mastoid in [mm]
1724  c=fwrite(HDR.FILE.FID,HDR.ELEC.REF(1:3),'float32'); % [X,Y,Z] position of reference electrode
1725  c=fwrite(HDR.FILE.FID,HDR.ELEC.GND(1:3),'float32'); % [X,Y,Z] position of ground electrode
1726  else
1727  fwrite(HDR.FILE.FID,zeros(3,1),'uint16');
1728  fwrite(HDR.FILE.FID,zeros(6,1),'float32');
1729  end;
1730  else
1731  Equipment = [HDR.REC.Equipment, ' '];
1732  Hospital = [HDR.REC.Hospital, ' '];
1733  Technician = [HDR.REC.Technician,' '];
1734 
1735  H1(169:184) = sprintf('%04i%02i%02i%02i%02i%02i%02i',floor(HDR.T0),floor(100*rem(HDR.T0(6),1)));
1736  c=fwrite(HDR.FILE.FID,H1(1:184),'uint8');
1737  c=fwrite(HDR.FILE.FID,[HDR.HeadLen,0],'int32');
1738  c=fwrite(HDR.FILE.FID,Equipment(1:8),'uint8'); % EP_ID=ones(8,1)*32;
1739  c=fwrite(HDR.FILE.FID,Hospital(1:8),'uint8'); % Lab_ID=ones(8,1)*32;
1740  c=fwrite(HDR.FILE.FID,Technician(1:8),'uint8'); % T_ID=ones(8,1)*32;
1741  c=fwrite(HDR.FILE.FID,ones(20,1)*32,'uint8'); %
1742  end;
1743 
1744  %c=fwrite(HDR.FILE.FID,HDR.NRec,'int64');
1745  c=fwrite(HDR.FILE.FID,[HDR.NRec,0],'int32');
1746  if (HDR.VERSION > 2.20)
1747  fwrite(HDR.FILE.FID,HDR.Dur,'float64');
1748  else
1749  [n,d]=rat(HDR.Dur);
1750  fwrite(HDR.FILE.FID,[n d], 'uint32');
1751  end;
1752  c=fwrite(HDR.FILE.FID,[HDR.NS,0],'uint16');
1753  else
1754  H1(168+(1:16))=sprintf('%02i.%02i.%02i%02i.%02i.%02i',floor(rem(HDR.T0([3 2 1 4 5 6]),100)));
1755  H1(185:192)=sprintf('%-8i',HDR.HeadLen);
1756  H1(237:244)=sprintf('%-8i',HDR.NRec);
1757  if (HDR.Dur==ceil(HDR.Dur))
1758  tmp = sprintf('%-8i',HDR.Dur);
1759  else
1760  tmp = sprintf('%-8f',HDR.Dur);
1761  end;
1762  H1(245:252)=tmp(1:8);
1763  if length(tmp)~=8,
1764  tmp = str2double(tmp);
1765  tmp = (HDR.Dur-tmp)/HDR.Dur;
1766  if abs(tmp)>1e-10,
1767  fprintf(HDR.FILE.stderr,'Warning SOPEN(EDF write): Duration field truncated, error %e (%s instead of %-8f),\n',tmp,H1(245:252),HDR.Dur);
1768  end;
1769  end;
1770  H1(253:256)=sprintf('%-4i',HDR.NS);
1771  H1(abs(H1)==0)=char(32);
1772 
1773  c=fwrite(HDR.FILE.FID,abs(H1),'uint8');
1774  end;
1775  %%%%%% generate Header 2, NS*256 bytes
1776  if HDR.NS>0,
1777  %if ~strcmp(HDR.VERSION(1:3),'GDF');
1778  if ~(HDR.VERSION > 0);
1779  sPhysMax=char(32+zeros(HDR.NS,8));
1780  sPhysMin=char(32+zeros(HDR.NS,8));
1781  for k=1:HDR.NS,
1782  tmp=sprintf('%-8g',HDR.PhysMin(k));
1783  lt=length(tmp);
1784  if lt<9
1785  sPhysMin(k,1:lt)=tmp;
1786  else
1787  if any(upper(tmp)=='E') || any(find(tmp=='.')>8),
1788  fprintf(HDR.FILE.stderr,'Error SOPEN (GDF/EDF/BDF)-W: PhysMin(%i) does not fit into header\n', k);
1789  else
1790  sPhysMin(k,:)=tmp(1:8);
1791  end;
1792  end;
1793  tmp=sprintf('%-8g',HDR.PhysMax(k));
1794  lt=length(tmp);
1795  if lt<9
1796  sPhysMax(k,1:lt)=tmp;
1797  else
1798  if any(upper(tmp)=='E') || any(find(tmp=='.')>8),
1799  fprintf(HDR.FILE.stderr,'Error SOPEN (GDF/EDF/BDF)-W: PhysMin(%i) does not fit into header\n', k);
1800  else
1801  sPhysMax(k,:)=tmp(1:8);
1802  end;
1803  end;
1804  end;
1805  c1 = str2double(cellstr(sPhysMax));
1806  c2 = str2double(cellstr(sPhysMin));
1807  e = ((HDR.PhysMax(:)-HDR.PhysMin(:))-(c1-c2))./(HDR.PhysMax(:)-HDR.PhysMin(:));
1808  if any(abs(e)>1e-8)
1809  fprintf(HDR.FILE.stderr,'Warning SOPEN (EDF-Write): relative scaling error is %e (due to roundoff in PhysMax/Min)\n',max(abs(e)))
1810  end
1811 
1812  idx1=cumsum([0 H2idx]);
1813  idx2=HDR.NS*idx1;
1814  h2=char(32*ones(HDR.NS,256));
1815  size(h2);
1816  h2(:,idx1(1)+1:idx1(2))=Label;
1817  h2(:,idx1(2)+1:idx1(3))=Transducer;
1818  h2(:,idx1(3)+1:idx1(4))=PhysDim;
1819  %h2(:,idx1(4)+1:idx1(5))=sPhysMin;
1820  %h2(:,idx1(5)+1:idx1(6))=sPhysMax;
1821  h2(:,idx1(4)+1:idx1(5))=sPhysMin;
1822  h2(:,idx1(5)+1:idx1(6))=sPhysMax;
1823  h2(:,idx1(6)+1:idx1(7))=reshape(sprintf('%-8i',HDR.DigMin)',8,HDR.NS)';
1824  h2(:,idx1(7)+1:idx1(8))=reshape(sprintf('%-8i',HDR.DigMax)',8,HDR.NS)';
1825  h2(:,idx1(8)+1:idx1(9))=HDR.PreFilt;
1826  h2(:,idx1(9)+1:idx1(10))=reshape(sprintf('%-8i',HDR.AS.SPR)',8,HDR.NS)';
1827  h2(abs(h2)==0)=char(32);
1828  for k=1:length(H2idx);
1829  c=fwrite(HDR.FILE.FID,abs(h2(:,idx1(k)+1:idx1(k+1)))','uint8');
1830  end;
1831  else
1832  fwrite(HDR.FILE.FID, abs(Label)','uint8');
1833  fwrite(HDR.FILE.FID, abs(Transducer)','uint8');
1834  if (HDR.VERSION < 1.9)
1835  fwrite(HDR.FILE.FID, abs(PhysDim)','uint8');
1836  fwrite(HDR.FILE.FID, HDR.PhysMin,'float64');
1837  fwrite(HDR.FILE.FID, HDR.PhysMax,'float64');
1838 
1839  if 0, exist('OCTAVE_VERSION','builtin'), % Octave does not support INT64 yet.
1840  fwrite(HDR.FILE.FID, [HDR.DigMin(:),-(HDR.DigMin(:)<0)]','int32');
1841  fwrite(HDR.FILE.FID, [HDR.DigMax(:),-(HDR.DigMax(:)<0)]','int32');
1842  else
1843  fwrite(HDR.FILE.FID, HDR.DigMin, 'int64');
1844  fwrite(HDR.FILE.FID, HDR.DigMax, 'int64');
1845  end;
1846  fwrite(HDR.FILE.FID, abs(HDR.PreFilt)','uint8');
1847  fwrite(HDR.FILE.FID, HDR.AS.SPR,'uint32');
1848  fwrite(HDR.FILE.FID, HDR.GDFTYP,'uint32');
1849  fwrite(HDR.FILE.FID,32*ones(32,HDR.NS),'uint8');
1850  else
1851  fwrite(HDR.FILE.FID, abs(PhysDim(1:HDR.NS,1:6))','uint8');
1852  fwrite(HDR.FILE.FID, HDR.PhysDimCode(1:HDR.NS),'uint16');
1853  fwrite(HDR.FILE.FID, HDR.PhysMin(1:HDR.NS),'float64');
1854  fwrite(HDR.FILE.FID, HDR.PhysMax(1:HDR.NS),'float64');
1855 
1856  fwrite(HDR.FILE.FID, HDR.DigMin(1:HDR.NS), 'float64');
1857  fwrite(HDR.FILE.FID, HDR.DigMax(1:HDR.NS), 'float64');
1858 
1859  if (HDR.VERSION < 2.22)
1860  fwrite(HDR.FILE.FID, abs(HDR.PreFilt(1:HDR.NS,1:68))','uint8');
1861  else
1862  fwrite(HDR.FILE.FID, abs(HDR.PreFilt(1:HDR.NS,1:64))','uint8');
1863  fwrite(HDR.FILE.FID, HDR.TOffset(1:HDR.NS), 'float32');
1864  end;
1865  fwrite(HDR.FILE.FID, HDR.Filter.LowPass(1:HDR.NS),'float32');
1866  fwrite(HDR.FILE.FID, HDR.Filter.HighPass(1:HDR.NS),'float32');
1867  fwrite(HDR.FILE.FID, HDR.Filter.Notch(1:HDR.NS),'float32');
1868  fwrite(HDR.FILE.FID, HDR.AS.SPR(1:HDR.NS),'uint32');
1869  fwrite(HDR.FILE.FID, HDR.GDFTYP(1:HDR.NS),'uint32');
1870  fwrite(HDR.FILE.FID, HDR.ELEC.XYZ(1:HDR.NS,:)','float32');
1871  if (HDR.VERSION < 2.19)
1872  fwrite(HDR.FILE.FID, max(0,min(255,round(log2(HDR.Impedance(1:HDR.NS))*8)')),'uint8');
1873  fwrite(HDR.FILE.FID,32*ones(19,HDR.NS),'uint8');
1874  else
1875  tmp = repmat(NaN,5,HDR.NS);
1876  ch = find(bitand(HDR.PhysDimCode, hex2dec('ffe0'))==4256); % channel with voltage data
1877  if ~isempty(ch),
1878  tmp(1,ch) = HDR.Impedance(ch);
1879  end;
1880  ch = find(bitand(HDR.PhysDimCode, hex2dec('ffe0'))==4288); % channel with impedance data
1881  if isfield(HDR,'fZ') && ~isempty(ch)
1882  tmp(1,ch) = HDR.fZ(ch); % probe frequency
1883  end;
1884  fwrite(HDR.FILE.FID, tmp, 'float32');
1885  end
1886  end;
1887  end;
1888  end;
1889 
1890  if (HDR.VERSION>2)
1891  %%%%%% GDF2: generate Header 3, Tag-Length-Value
1892  for tag=find(TagLen>0)
1893  fwrite(HDR.FILE.FID, tag+TagLen(tag)*256, 'uint32');
1894  switch tag
1895  case 3
1896  fwrite(HDR.FILE.FID, TagLenValue{tag}, 'uint8');
1897  case 4 %% OBSOLETE
1898  % c=fwrite(HDR.FILE.FID, HDR.ELEC.Orientation, 'float32');
1899  % c=c+fwrite(HDR.FILE.FID, HDR.ELEC.Area, 'float32');
1900  fwrite(HDR.FILE.FID, zeros(4*HDR.NS-c), 'float32');
1901  end;
1902  end;
1903  if any(TagLen>0)
1904  fwrite(HDR.FILE.FID, 0, 'uint32'); %% terminating 0-tag
1905  end;
1906  end;
1907 
1908  tmp = ftell(HDR.FILE.FID);
1909  if tmp ~= HDR.HeadLen,
1910  fwrite(HDR.FILE.FID, zeros(1,HDR.HeadLen-tmp), 'uint8');
1911  end;
1912  tmp = ftell(HDR.FILE.FID);
1913  if tmp ~= HDR.HeadLen,
1914  fprintf(1,'Warning SOPEN (GDF/EDF/BDF)-WRITE: incorrect header length %i vs. %i bytes\n',tmp, HDR.HeadLen );
1915  %else fprintf(1,'SOPEN (GDF/EDF/BDF) in write mode: header info stored correctly\n');
1916  end;
1917 
1918  else % if arg2 is not 'r' or 'w'
1919  fprintf(HDR.FILE.stderr,'Warning SOPEN (GDF/EDF/BDF): Incorrect 2nd argument. \n');
1920  end;
1921 
1922  if HDR.ErrNum>0
1923  fprintf(HDR.FILE.stderr,'ERROR %i SOPEN (GDF/EDF/BDF)\n',HDR.ErrNum);
1924  end;
1925 
1926 
1927 elseif strcmp(HDR.TYPE,'EVENT') && any(lower(HDR.FILE.PERMISSION)=='w'),
1928  %%% Save event file in GDF-format
1929  HDR.TYPE = 'GDF';
1930  HDR.NS = 0;
1931  HDR.NRec = 0;
1932  if any(isnan(HDR.T0))
1933  HDR.T0 = clock;
1934  end;
1935  HDR = sopen(HDR,'w');
1936  HDR = sclose(HDR);
1937  HDR.TYPE = 'EVENT';
1938 
1939 
1940 elseif strcmp(HDR.TYPE,'BKR'),
1941  HDR = bkropen(HDR);
1942  HDR.GDFTYP = repmat(3,1,HDR.NS);
1943  %%% Get trigger information from BKR data
1944 
1945 
1946 elseif strmatch(HDR.TYPE,{'CNT';'AVG';'EEG'},'exact')
1947  if any(HDR.FILE.PERMISSION=='r');
1948  if isempty(strfind(MODE,'32'))
1949  [HDR,H1,h2] = cntopen(HDR);
1950  else
1951  [HDR,H1,h2] = cntopen(HDR,'32bit');
1952  end;
1953 
1954  % support of OVERFLOWDETECTION
1955  if ~isfield(HDR,'THRESHOLD'),
1956  if HDR.FLAG.OVERFLOWDETECTION,
1957  fprintf(2,'WARNING SOPEN(CNT): OVERFLOWDETECTION might not work correctly. See also EEG2HIST and read \n');
1958  fprintf(2,' http://dx.doi.org/10.1016/S1388-2457(99)00172-8 (A. Schlögl et al. Quality Control ... Clin. Neurophysiol. 1999, Dec; 110(12): 2165 - 2170).\n');
1959  fprintf(2,' A copy is available here, too: http://pub.ist.ac.at/~schloegl/publications/neurophys1999_2165.pdf \n');
1960  end;
1961  [datatyp,limits,datatypes,numbits,GDFTYP]=gdfdatatype(HDR.GDFTYP);
1962  HDR.THRESHOLD = repmat(limits,HDR.NS,1);
1963  end;
1964 
1965  elseif any(HDR.FILE.PERMISSION=='w');
1966  % check header information
1967  if ~isfield(HDR,'NS'),
1968  HDR.NS = 0;
1969  end;
1970  if ~isfinite(HDR.NS) || (HDR.NS<0)
1971  fprintf(HDR.FILE.stderr,'Error SOPEN CNT-Write: HDR.NS not defined\n');
1972  return;
1973  end;
1974  if ~isfield(HDR,'SPR'),
1975  HDR.SPR = 0;
1976  end;
1977  if ~isfinite(HDR.SPR)
1978  HDR.SPR = 0;
1979  end;
1980  type = 2;
1981  if strmatch(HDR.TYPE,'EEG'), type = 1;
1982  elseif strmatch(HDR.TYPE,'AVG'), type = 0;
1983  end;
1984 
1985  if ~isfield(HDR,'PID')
1986  HDR.PID = char(repmat(32,1,20));
1987  elseif numel(HDR.PID)>20,
1988  HDR.PID = HDR.PID(1:20);
1989  else
1990  HDR.PID = [HDR.PID(:)',repmat(32,1,20-length(HDR.PID(:)))];
1991  %HDR.PID = [HDR.PID,repmat(32,1,20-length(HDR.PID))];
1992  end;
1993 
1994  if ~isfield(HDR,'Label')
1995  HDR.Label = int2str((1:HDR.NS)');
1996  elseif iscell(HDR.Label),
1997  HDR.Label = char(HDR.Label);
1998  end;
1999  if size(HDR.Label,2)>10,
2000  HDR.Label = HDR.Label(:,1:10);
2001  elseif size(HDR.Label,2)<10,
2002  HDR.Label = [HDR.Label,repmat(32,HDR.NS,10-size(HDR.Label,2))];
2003  end;
2004 
2005  if ~isfield(HDR,'Calib')
2006  HDR.Cal = ones(HDR.NS,1);
2007  e.sensitivity = ones(HDR.NS,1)*204.8;
2008  HDR.Off = zeros(HDR.NS,1);
2009  else
2010  HDR.Cal = diag(HDR.Calib(2:end,:));
2011  e.sensitivity = ones(HDR.NS,1)*204.8;
2012  HDR.Off = round(HDR.Calib(1,:)'./HDR.Cal);
2013  end;
2014 
2015  % open file
2016  if any(HDR.FILE.PERMISSION=='z') && (HDR.SPR<=0),
2017  fprintf(HDR.FILE.stderr,'ERROR SOPEN (CNT) "wz": Update of HDR.SPR is not possible.\n',HDR.FileName);
2018  fprintf(HDR.FILE.stderr,'\t Solution(s): (1) define exactly HDR.SPR before calling SOPEN(HDR,"wz"); or (2) write to uncompressed file instead.\n');
2019  return;
2020  end;
2021  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2022  if HDR.FILE.FID < 0,
2023  return;
2024  end;
2025  HDR.FILE.OPEN = 2;
2026  if any([HDR.SPR] <= 0);
2027  HDR.FILE.OPEN = 3;
2028  end;
2029 
2030  % write fixed header
2031  fwrite(HDR.FILE.FID,'Version 3.0','uint8');
2032  fwrite(HDR.FILE.FID,zeros(2,1),'uint32');
2033  fwrite(HDR.FILE.FID,type,'uint8');
2034  fwrite(HDR.FILE.FID,HDR.PID,'uint8');
2035 
2036  fwrite(HDR.FILE.FID,repmat(0,1,900-ftell(HDR.FILE.FID)),'uint8')
2037 
2038  % write variable header
2039  for k = 1:HDR.NS,
2040  count = fwrite(HDR.FILE.FID,HDR.Label(k,:),'uint8');
2041  count = fwrite(HDR.FILE.FID,zeros(5,1),'uint8');
2042  count = fwrite(HDR.FILE.FID, 0, 'uint16');
2043  count = fwrite(HDR.FILE.FID,zeros(2,1),'uint8');
2044 
2045  count = fwrite(HDR.FILE.FID,zeros(7,1),'float');
2046  count = fwrite(HDR.FILE.FID,HDR.Off(k),int16);
2047  count = fwrite(HDR.FILE.FID,zeros(2,1),'uint8');
2048  count = fwrite(HDR.FILE.FID,[zeros(2,1),e.sensitivity(k)],'float');
2049  count = fwrite(HDR.FILE.FID,zeros(3,1),'uint8');
2050  count = fwrite(HDR.FILE.FID,zeros(4,1),'uint8');
2051  count = fwrite(HDR.FILE.FID,zeros(1,1),'uint8');
2052  count = fwrite(HDR.FILE.FID,HDR.Cal(k),'int16');
2053  end;
2054 
2055  HDR.HeadLen = ftell(HDR.FILE.FID);
2056  if HDR.HeadLen ~= (900+75*HDR.NS),
2057  fprintf(HDR.FILE.stderr,'Error SOPEN CNT-Write: Headersize does not fit\n');
2058  end;
2059  end;
2060 
2061 
2062 elseif strcmp(HDR.TYPE,'EPL'), % San Diego EPL system
2063  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2064  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing EPL format not well tested, yet.\n');
2065  HDR.EPL.H1 = fread(HDR.FILE.FID,[1,64],'uint16');
2066  HDR.NS = HDR.EPL.H1(3);
2067  HDR.Label = char(fread(HDR.FILE.FID,[4,32],'uint8')');
2068  HDR.EPL.H2 = char(fread(HDR.FILE.FID,[1,256],'uint8'));
2069  ix = strfind(HDR.EPL.H2,' ');
2070  %HDR.Patient.Name = HDR.EPL.H2(1:ix(2)); % do not support clear text name
2071  tmp = str2double(HDR.EPL.H2(ix(2)+1:ix(3)-1),'/'); % dd/mm/yy format
2072  HDR.T0(1:3)= tmp([3,2,1]) + [2000,0,0];
2073  HDR.HeadLen= ftell(HDR.FILE.FID);
2074  HDR.SPR = 256;
2075  HDR.AS.bpb = HDR.NS*2*(HDR.SPR+8);
2076  HDR.NRec = (HDR.FILE.size-HDR.HeadLen)/HDR.AS.bpb;
2077  HDR.SampleRate = 1e5/HDR.EPL.H1(10);
2078  HDR.Cal = HDR.EPL.H1(6)*HDR.EPL.H1(7)*10;
2079  HDR.PhysDim= repmat({'uV'},HDR.NS,1);
2080  if (HDR.Cal==0)
2081  HDR.Cal = 1/50000;
2082  HDR.FLAG.OVERFLOWDETECTION = 0;
2083  fprintf(HDR.FILE.stderr,'Warning SOPEN (EPL): calibration information in file %s is missing. Assume Gain=50000.\n',HDR.FileName);
2084  end;
2085  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
2086  HDR.delay = HDR.EPL.H1(8)*1e-3;
2087  HDR.EPL.cprecis = HDR.EPL.H1(19); %channel precision*256.pts
2088  HDR.Filter.HighPass = 0.01;
2089  HDR.Filter.LowPass = 100;
2090  HDR.Dur = HDR.SPR/HDR.SampleRate;
2091  HDR.FILE.POS = 0;
2092  HDR.FILE.OPEN = 1;
2093 
2094  fid = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.log']),[HDR.FILE.PERMISSION,'b'],'ieee-le');
2095  if (fid>0),
2096  % read log file
2097  ev1 = fread(fid,[4,inf],'uint16')';
2098  fclose(fid);
2099  ev1(:,2) = ev1(:,2:3)*[2^16;1];
2100  ev1(:,3) = floor(ev1(:,4)/256);
2101  ev1(:,4) = rem(ev1(:,4),256);
2102  HDR.EPL.ev1 = ev1;
2103  HDR.EVENT.POS = ev1(ev1(:,1)<2^15,2);
2104  HDR.EVENT.TYP = ev1(ev1(:,1)<2^15,1);
2105  else
2106  fprintf(HDR.FILE.stderr,'Warning SOPEN (EPL): log-file not found, use the mark track for reading the event information - some Event positions might be off by 1 sample.\n');
2107  % read mark track
2108  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
2109  [ev2, count] = fread(HDR.FILE.FID,inf,'256*uint16=>uint16',HDR.NS*HDR.SPR*2);
2110  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
2111 
2112  ev2(1:256:end)= 0; % remove the "record number" (1st word of each segment) from the "mark track"
2113  HDR.EVENT.POS = find((ev2>0) & (ev2<2^15)); % identify all events, remove deleted events (i.e. high bit ='1')
2114  HDR.EVENT.TYP = ev2(HDR.EVENT.POS);
2115  end;
2116 
2117 
2118 elseif strcmp(HDR.TYPE,'ePrime'),
2119  HDR.FILE.FID = fopen(HDR.FileName,HDR.FILE.PERMISSION);
2120  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing ePrime format not well tested, yet.\n');
2121  fseek(HDR.FILE.FID,0,'bof');
2122  hdrline = fgetl(HDR.FILE.FID);
2123  c = 1; fname={};
2124  [fname{1}, r]=strtok(hdrline,char([9,10,13]));
2125  while ~isempty(r)
2126  c = c+1;
2127  [fname{c}, r]=strtok(r,char([9,10,13]));
2128  end;
2129  s = fread(HDR.FILE.FID,[1,inf],'uint8=>char');
2130  fclose(HDR.FILE.FID);
2131  HDR.FILE.OPEN = 0;
2132  HDR.NS = 0;
2133  HDR.SPR = 1;
2134  HDR.NRec= 0;
2135  s(s==13) = [];
2136  while any(s(1)==[10,13]), s(1)=[]; end;
2137 
2138  try
2139  [N,V,S] = str2array(s,char(9),char(10));
2140  catch
2141  [N,V,S] = str2double(s,char(9),char(10));
2142  end
2143 
2144  c = strmatch('Subject',fname);
2145  if ~V(1,c)
2146  HDR.Patient.Id = num2str(N(1,c));
2147  else
2148  HDR.Patient.Id = S{1,c};
2149  end;
2150 
2151  c = strmatch('Display.RefreshRate',fname);
2152  if all(N(1,c)==N(:,c))
2153  HDR.EVENT.SampleRate = N(1,c);
2154  else
2155  fprintf(HDR.FILE.stderr,'Warning SOPEN (ePrime): could not identify display rate\n');
2156  end;
2157 
2158  t = [S{2,strmatch('SessionDate',fname)}, ' ', S{2,strmatch('SessionTime',fname)}];
2159  t(t==':' | t=='-')=' ';
2160  try
2161  T0 = str2double(t,' ');
2162  HDR.T0 = T0([3,1,2,4,5,6]);
2163  end;
2164 
2165  OnsetTime = N(:,strmatch('PictureTarget.OnsetTime',fname));
2166  HDR.EVENT.POS = OnsetTime;
2167  OnsetDelay = N(:,strmatch('PictureTarget.OnsetDelay',fname));
2168  t = S(:,strmatch('Stimulus',fname));
2169  [HDR.EVENT.Desc,I,HDR.EVENT.TYP] = unique(t);
2170  HDR.EVENT.DUR = N(:,strmatch('PictureTarget.RT',fname));
2171  HDR.EVENT.CHN = zeros(size(HDR.EVENT.POS));
2172 
2173  HDR.ePrime.N = N;
2174  HDR.ePrime.S = S;
2175 
2176 elseif strcmp(HDR.TYPE,'FEF'), % FEF/Vital format included
2177  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],HDR.Endianity);
2178  status = fseek(HDR.FILE.FID,32,'bof'); % skip preamble
2179 
2180  if exist('fefopen','file') && ~status,
2181  HDR = fefopen(HDR);
2182  end;
2183 
2184  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing Vital/FEF format not completed yet. Contact <Biosig-general@lists.sourceforge.net> if you are interested in this feature.\n');
2185  HDR.FILE.FID = -1;
2186  return;
2187 
2188 
2189 elseif strcmp(HDR.TYPE,'SCP'), %
2190  HDR = scpopen(HDR,CHAN);
2191  HDR.GDFTYP = repmat(5,1,HDR.NS);
2192  if HDR.ErrNum,
2193  fclose(HDR.FILE.FID);
2194  HDR.FILE.OPEN = 0;
2195  return;
2196  end;
2197 
2198 
2199 elseif strcmp(HDR.TYPE,'EBS'),
2200  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
2201 
2202  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing EBS format not completed yet. Contact <Biosig-general@lists.sourceforge.net> if you are interested in this feature.\n');
2203 
2204  %%%%% (1) Fixed Header (32 bytes) %%%%%
2205  HDR.VERSION = fread(HDR.FILE.FID,[1,8],'uint8'); %
2206  if ~strcmp(char(HDR.VERSION(1:3)),'EBS')
2207  fprintf(HDR.FILE.stderr,'Error LOADEBS: %s not an EBS-File',HDR.FileName);
2208  if any(HDR.VERSION(4:8)~=hex2dec(['94';'0a';'13';'1a';'0d'])');
2209  fprintf(HDR.FILE.stderr,'Warning SOPEN EBS: %s may be corrupted',HDR.FileName);
2210  end;
2211  end;
2212  HDR.EncodingId = fread(HDR.FILE.FID,1,'int32'); %
2213  HDR.NS = fread(HDR.FILE.FID,1,'uint32'); % Number of Channels
2214  HDR.SPR=fread(HDR.FILE.FID,1,'int64') % Data Length
2215  LenData=fread(HDR.FILE.FID,1,'int64') % Data Length
2216 
2217  %%%%% (2) LOAD Variable Header %%%%%
2218  tag=fread(HDR.FILE.FID,1,'int32'); % Tag field
2219  fid = HDR.FILE.FID;
2220  while (tag~=0),
2221  l =fread(fid,1,'int32'); % length of value field
2222  [tag,l],
2223  %val=char(fread(HDR.FILE.FID,l,'uint16')'); % depends on Tag field
2224  if tag==hex2dec('00000002'), %IGNORE
2225  elseif tag==hex2dec('00000004') HDR.Patient.Name = fread(fid,2*l,'uint16=>char');
2226  elseif tag==hex2dec('00000006') HDR.Patient.Id = fread(fid,l,'uint32');
2227  elseif tag==hex2dec('00000008') HDR.Patient.Birthday = fread(fid,l,'uint32');
2228  elseif tag==hex2dec('0000000a') HDR.Patient.Sex = fread(fid,l,'uint32');
2229  elseif tag==hex2dec('0000000c') HDR.SHORT_DESCRIPTION = fread(fid,2*l,'uint16=>char');
2230  elseif tag==hex2dec('0000000e') HDR.DESCRIPTION = fread(fid,2*l,'uint16=>char');
2231  elseif tag==hex2dec('00000010') HDR.SampleRate = str2double(fread(fid,4*l,'uint8=>char'));
2232  elseif tag==hex2dec('00000012') HDR.INSTITUTION = fread(fid,l,'uint32');
2233  elseif tag==hex2dec('00000014') HDR.PROCESSING_HISTORY = fread(fid,2*l,'uint16=>char');
2234  elseif tag==hex2dec('00000016') HDR.LOCATION_DIAGRAM = fread(fid,2*l,'uint16=>char');
2235 
2236  elseif tag==hex2dec('00000001') HDR.PREFERRED_INTEGER_RANGE = fread(fid,2*l,'uint16=>char');; %reshape(reshape(val,HDR.NS,numel(val)/HDR.NS),2,numel(val));
2237  elseif tag==hex2dec('00000003')
2238  [val,c] = fread(fid,4*l,'uint8=>char');
2239  %val = char(reshape(val(1:16*(HDR.NS)),16,HDR.NS))'
2240  %HDR.Cal = str2double(cellstr(val(:,1:8)));
2241  %HDR.PhysDim = cellstr(val(:,[10,12]));
2242 
2243  elseif tag==hex2dec('00000005')
2244  [val,c] = fread(fid,2*l,'uint16=>char');
2245  val = reshape(val(1:8*floor(2*l/8)),8,floor(2*l/8))'
2246  HDR.Label = val;
2247 
2248  elseif tag==hex2dec('00000007') HDR.CHANNEL_GROUPS = fread(fid,2*l,'uint16=>char')';
2249  elseif tag==hex2dec('00000009') HDR.EVENTS = fread(fid,2*l,'uint16=>char')';
2250  elseif tag==hex2dec('0000000b')
2251  t = fread(fid,4*l,'uint8=>char')';
2252  t2 = repmat(' ',1,20);
2253  t2([1:4,6:7,9:10,13:14,16:17,19:20]) = t([1:8,10:15]);
2254  HDR.T0 = str2double(t2,' ');
2255 
2256  elseif tag==hex2dec('0000000d') HDR.CHANNEL_LOCATIONS = fread(fid,2*l,'uint16=>char')';
2257  elseif tag==hex2dec('0000000f')
2258  t = fread(fid,4*l,'uint8=>char');
2259  t = reshape(t(1:28*floor(numel(t)/28)),28,floor(numel(t)/28))';
2260  HDR.Filter.LowPass = str2double(cellstr(t(:,5:8)));
2261  HDR.Filter.HighPass = str2double(cellstr(t(:,17:20)));
2262  else
2263  break;
2264  end;
2265  tag=fread(fid,1,'int32'); % Tag field
2266  end;
2267  %if ~tag, fseek(fid,-4,'cof'); end;
2268 
2269  %%%%% (3) Encoded Signal Data 4*d bytes%%%%%
2270  HDR.data = fread(fid,[HDR.NS,inf],'int16')';
2271  HDR.HeadLen = ftell(fid);
2272  fclose(HDR.FILE.FID);
2273 
2274 
2275 elseif strcmp(HDR.TYPE,'rhdE'),
2276  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2277 
2278  %fseek(HDR.FILE.FID,4,'bof'); % skip 4 bytes ID
2279  %HDR.HeadLen = fread(HDR.FILE.FID,1,'int32'); % Length of Header ?
2280  %HDR.H2 = fread(HDR.FILE.FID,5,'int32');
2281  %HDR.NS = fread(HDR.FILE.FID,1,'int32'); % ? number of channels
2282  %HDR.H3 = fread(HDR.FILE.FID,5,'int32');
2283  tmp = fread(HDR.FILE.FID,10,'int32');
2284  HDR.HeadLen = tmp(2); % Length of Header ?
2285  HDR.H2 = tmp;
2286  HDR.NS = tmp(8); % ? number of channels
2287  HDR.NRec = (HDR.FILE.size-HDR.HeadLen)/1024;
2288 
2289  fprintf(1,'Warning SOPEN HolterExcel2: is under construction.\n');
2290 
2291  if (nargout>1), % just for testing
2292  H1 = fread(HDR.FILE.FID,[1,inf],'uint8')';
2293  end;
2294  fclose(HDR.FILE.FID);
2295 
2296 
2297 elseif strcmp(HDR.TYPE,'alpha') && any(HDR.FILE.PERMISSION=='r'),
2298  HDR.FILE.FID = -1; % make sure SLOAD does not call SREAD;
2299 
2300  %%%
2301 
2302  % The header files are text files (not binary).
2303  try
2304  PERMISSION = 'rt'; % MatLAB default is binary, force Mode='rt';
2305  fid = fopen(fullfile(HDR.FILE.Path,'head'),PERMISSION);
2306  catch
2307  PERMISSION = 'r'; % Octave 2.1.50 default is text, but does not support Mode='rt',
2308  fid = fopen(fullfile(HDR.FILE.Path,'head'),PERMISSION);
2309  end;
2310 
2311  cfiles = {'alpha.alp','eog','mkdef','r_info','rawhead','imp_res','sleep','../s_info'};
2312  %%,'marker','digin','montage','measure','cal_res'
2313 
2314  HDR.alpha = [];
2315  for k = 1:length(cfiles),
2316  [cf,tmp]=strtok(cfiles{k},'./');
2317  fid = fopen(fullfile(HDR.FILE.Path,cfiles{k}),PERMISSION);
2318  if fid>0,
2319  S = {};
2320  state = 0;
2321  flag.rawhead = strcmp(cf,'rawhead');
2322  flag.sleep = strcmp(cf,'sleep');
2323  [s] = fgetl(fid);
2324  while ischar(s), %~feof(fid),
2325  [tag,s] = strtok(s,'= ');
2326  s(find(s=='='))=' ';
2327  [VAL,s1] = strtok(s,' ');
2328  [val,status] = str2double(VAL);
2329  if (state==0),
2330  try;
2331  if any(status),
2332  S=setfield(S,tag,VAL);
2333  else
2334  S=setfield(S,tag,val);
2335  end;
2336  end;
2337 
2338  if (flag.rawhead && strncmp(tag,'DispFlags',9) && (S.Version < 411.89))
2339  state = 1;
2340  k1 = 0;
2341  elseif (flag.rawhead && strncmp(tag,'Sec2Marker',9) && (S.Version > 411.89))
2342  state = 1;
2343  k1 = 0;
2344  elseif (flag.sleep && strncmp(tag,'SleepType',9))
2345  state = 3;
2346  k1 = 0;
2347  end;
2348  elseif (state==1) % rawhead: channel info
2349  k1 = k1+1;
2350  HDR.Label{k1} = [tag,' '];
2351  [num,status,sa] = str2double(s);
2352  XY(k1,1:2) = num(4:5);
2353  CHANTYPE{k1} = sa{3};
2354  HDR.alpha.chanidx(k1) = num(2);
2355  if (k1==S.ChanCount);
2356  [tmp,HDR.alpha.chanorder] = sort(HDR.alpha.chanidx);
2357  HDR.Label = HDR.Label(HDR.alpha.chanorder);
2358  XY = XY(HDR.alpha.chanorder,:);
2359  tmp = sum(XY.^2,2);
2360  HDR.ELEC.XYZ = [XY,sqrt(max(tmp)-tmp)];
2361  CHANTYPE = CHANTYPE(HDR.alpha.chanorder);
2362  state = 2;
2363  k1 = 0;
2364  HDR.alpha.chantyp.num = [];
2365  end;
2366  elseif (state==2) % rawhead: info on channel type
2367  k1 = k1+1;
2368  [num,status,sa] = str2double(s,',');
2369  chantyp.s{k1} = s;
2370  chantyp.tag{k1} = tag;
2371  elseif (state==3) % sleep: scoreing
2372  k1 = k1+1;
2373  scoring(k1) = val;
2374  end
2375  [s] = fgetl(fid);
2376  end;
2377  fclose(fid);
2378  HDR.alpha=setfield(HDR.alpha,cf,S);
2379  end;
2380  end;
2381  HDR.VERSION = HDR.alpha.rawhead.Version;
2382  if isfield(HDR.alpha,'rawhead')
2383  HDR.Bits = HDR.alpha.rawhead.BitsPerValue;
2384  HDR.NS = HDR.alpha.rawhead.ChanCount;
2385  HDR.SampleRate = HDR.alpha.rawhead.SampleFreq;
2386  HDR.SPR = HDR.alpha.rawhead.SampleCount;
2387  HDR.Filter.Notch = HDR.alpha.rawhead.NotchFreq;
2388  if HDR.Bits == 12; HDR.GDFTYP = HDR.Bits+255;
2389  elseif HDR.Bits == 16; HDR.GDFTYP = 3;
2390  elseif HDR.Bits == 32; HDR.GDFTYP = 5;
2391  else fprintf(HDR.FILE.stderr,'Error SOPEN(alpha): invalid header information.\n'); return;
2392  end;
2393  [datatyp, limits, datatypes] = gdfdatatype(HDR.GDFTYP);
2394  % THRESHOLD for Overflow detection
2395  if ~isfield(HDR,'THRESHOLD')
2396  HDR.THRESHOLD = repmat(limits, HDR.NS, 1);
2397  end;
2398  HDR.NRec = 1;
2399 
2400  % channel-specific settings
2401  ix = zeros(1,HDR.NS);
2402  for k = 1:HDR.NS,
2403  ix(k) = strmatch(CHANTYPE{k},chantyp.tag,'exact');
2404  end;
2405 
2406  chantyp.s = chantyp.s(ix);
2407  for k = 1:HDR.NS,
2408  HDR.Filter.HighPass(k) = num(1);
2409  HDR.Filter.LowPass(k) = num(2);
2410  [num,status,sa] = str2double(chantyp.s{k},',');
2411  if strcmp(sa{5},'%%');
2412  sa{5}='%';
2413  end;
2414  HDR.PhysDim{k}=[deblank(sa{5}),' '];
2415  end;
2416  HDR.PhysDim = char(HDR.PhysDim);
2417  else
2418  fprintf(HDR.FILE.stderr,'Error SOPEN (alpha): couldnot open RAWHEAD\n');
2419  end;
2420  if isfield(HDR.alpha,'sleep')
2421  HDR.alpha.sleep.scoring = scoring;
2422  end;
2423  if isfield(HDR.alpha,'r_info')
2424  HDR.REC.Recording = HDR.alpha.r_info.RecId;
2425  HDR.REC.Hospital = HDR.alpha.r_info.Laboratory;
2426  tmp = [HDR.alpha.r_info.RecDate,' ',HDR.alpha.r_info.RecTime];
2427  tmp(tmp=='.') = ' ';
2428  [tmp,status]=str2double(tmp);
2429  if ~any(status)
2430  HDR.T0 = tmp([3,2,1,4:6]);
2431  end;
2432  end;
2433  if isfield(HDR.alpha,'s_info')
2434  % HDR.Patient.Name = [HDR.alpha.s_info.LastName,', ',HDR.alpha.s_info.FirstName];
2435  HDR.Patient.Sex = HDR.alpha.s_info.Gender;
2436  HDR.Patient.Handedness = HDR.alpha.s_info.Handedness;
2437  tmp = HDR.alpha.s_info.BirthDay;
2438  tmp(tmp=='.')=' ';
2439  t0 = str2double(tmp);
2440  age = [HDR.T0(1:3)-t0([3,2,1])]*[365.25;30;1]; % days
2441  if (age<100)
2442  HDR.Patient.Age = sprintf('%i day',age);
2443  elseif (age<1000)
2444  HDR.Patient.Age = sprintf('%4.1f month',age/30);
2445  else
2446  HDR.Patient.Age = sprintf('%4.1f year(s)',age/365.25);
2447  end;
2448  end;
2449 
2450  fid = fopen(fullfile(HDR.FILE.Path,'cal_res'),PERMISSION);
2451  if fid < 0,
2452  fprintf(HDR.FILE.stderr,'Warning SOPEN alpha-trace: could not open CAL_RES. Data is uncalibrated.\n');
2453  HDR.FLAG.UCAL = 1;
2454  else
2455  k = 0;
2456  while (k<2) %% skip first 2 lines
2457  [s] = fgetl(fid);
2458  if ~strncmp(s,'#',1), %% comment lines do not count
2459  k=k+1;
2460  end;
2461  end;
2462  [s] = fread(fid,[1,inf],'uint8');
2463  fclose(fid);
2464 
2465  HDR.Cal = ones(HDR.NS,1);
2466  HDR.Off = ones(HDR.NS,1);
2467  s(s=='=') = ',';
2468  [val,status,strarray]=str2double(s);
2469  if 0, %try,
2470  HDR.Cal = val(HDR.alpha.chanorder,3);
2471  HDR.Off = val(HDR.alpha.chanorder,4);
2472  else %catch
2473  %%%% FIXME:
2474  for k = 1:size(val,1),
2475  if val(k,1)>0,
2476  ch = val(k,1);
2477  else
2478  ch = k; %strmatch(strarray{k,1},HDR.Label);
2479  end;
2480  HDR.Cal(ch,1) = val(k, 3);
2481  HDR.Off(ch,1) = val(k, 4);
2482  end;
2483  end;
2484 % HDR.Label2 = char(strarray(HDR.alpha.chanorder,1));
2485  OK = strmatch('no',strarray(:,2));
2486 
2487  HDR.FLAG.UCAL = ~isempty(OK);
2488  if ~isempty(OK),
2489  fprintf(HDR.FILE.stderr,'Warning SOPEN (alpha): calibration not valid for some channels\n');
2490  end;
2491 % HDR.Cal(OK) = NaN;
2492  HDR.Calib = sparse([-HDR.Off';eye(HDR.NS*[1,1])])*sparse(1:HDR.NS,1:HDR.NS,HDR.Cal);
2493  end;
2494 
2495  fid = fopen(fullfile(HDR.FILE.Path,'marker'),PERMISSION);
2496  if fid > 0,
2497  k = 0;
2498  while (k<1) %% skip first 2 lines
2499  [s] = fgetl(fid);
2500  if ~strncmp(s,'#',1), %% comment lins do not count
2501  k=k+1;
2502  end;
2503  end;
2504  [s] = fread(fid,[1,inf],'uint8');
2505  fclose(fid);
2506 
2507  s(s=='=') = ',';
2508  [val,status,strarray]=str2double(s,', ');
2509  HDR.EVENT.POS = val(:,3);
2510  [HDR.EVENT.CodeDesc,tmp,HDR.EVENT.TYP] = unique(strarray(:,1));
2511  ix = strmatch('off',strarray(:,2));
2512  HDR.EVENT.TYP(ix) = HDR.EVENT.TYP(ix)+hex2dec('8000');
2513  end;
2514 
2515  fid = fopen(fullfile(HDR.FILE.Path,'montage'),PERMISSION);
2516  if fid > 0,
2517  K = 0;
2518  while ~feof(fid),
2519  s = fgetl(fid);
2520  [tag,s] = strtok(s,' =');
2521  [val1,r] = strtok(s,' =,');
2522  if strncmp(tag,'Version',7),
2523  elseif strncmp(tag,'Montage',7),
2524  K = K+1;
2525  Montage{K,1} = s(4:end);
2526  k = 0;
2527  elseif strncmp(tag,'Trace',5),
2528  k = k+1;
2529  trace{k,K} = s(4:end);
2530  [num,status,str] = str2double(s(4:end),[32,34,44]);
2531  if strcmpi(str{3},'xxx')
2532  Label{k,K} = str{2};
2533  else
2534  Label{k,K} = [str{2},'-',str{3}];
2535  end;
2536  elseif strncmp(tag,'RefType',7),
2537  end;
2538  end;
2539  fclose(fid);
2540  HDR.alpha.montage.Montage = Montage;
2541  HDR.alpha.montage.Label = Label;
2542  HDR.alpha.montage.trace = trace;
2543  end;
2544 
2545  fid = fopen(fullfile(HDR.FILE.Path,'digin'),PERMISSION);
2546  if 1,
2547  elseif fid < 0,
2548  fprintf(HDR.FILE.stderr,'Warning SOPEN alpha-trace: couldnot open DIGIN - no event information included\n');
2549  else
2550  [s] = fgetl(fid); % read version
2551 
2552  k = 0; POS = []; DUR = []; TYP = []; IO = [];
2553  while ~feof(fid),
2554  [s] = fgetl(fid);
2555  if ~isnumeric(s),
2556  [timestamp,s] = strtok(s,'=');
2557  [type,io] = strtok(s,'=,');
2558  timestamp = str2double(timestamp);
2559  if ~isnan(timestamp),
2560  k = k + 1;
2561  POS(k) = timestamp;
2562  TYP(k) = hex2dec(type);
2563  DUR(k) = 0;
2564  if (k>1) && (TYP(k)==0),
2565  DUR(k-1) = POS(k)-POS(k-1);
2566  end;
2567  else
2568  fprintf(HDR.FILE.stderr,'Warning SOPEN: alpha: invalid Event type\n');
2569  end;
2570  if length(io)>1,
2571  IO(k) = io(2);
2572  end;
2573  end;
2574  end;
2575  fclose(fid);
2576  HDR.EVENT.N = k;
2577  HDR.EVENT.POS = POS(:);
2578  HDR.EVENT.DUR = DUR(:);
2579  HDR.EVENT.TYP = TYP(:);
2580  HDR.EVENT.IO = IO(:);
2581  HDR.EVENT.CHN = zeros(HDR.EVENT.N,1);
2582  end;
2583  if all(abs(HDR.alpha.rawhead.Version - [407.1, 407.11, 409.5, 413.2]) > 1e-6);
2584  fprintf(HDR.FILE.stderr,'Warning SLOAD: Format ALPHA Version %6.2f not tested yet.\n',HDR.VERSION);
2585  end;
2586 
2587  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,'rawdata'),'rb');
2588  if HDR.FILE.FID > 0,
2589  HDR.VERSION2 = fread(HDR.FILE.FID,1,'int16');
2590  HDR.NS = fread(HDR.FILE.FID,1,'int16');
2591  HDR.Bits = fread(HDR.FILE.FID,1,'int16');
2592  HDR.AS.bpb = HDR.NS*HDR.Bits/8;
2593  HDR.SPR = 1;
2594  if rem(HDR.AS.bpb,1),
2595  HDR.AS.bpb = HDR.AS.bpb*2; %HDR.NS*HDR.Bits/8;
2596  HDR.SPR = 2;
2597  end;
2598  HDR.FILE.OPEN = 1;
2599  HDR.FILE.POS = 0;
2600  HDR.HeadLen = ftell(HDR.FILE.FID);
2601  fseek(HDR.FILE.FID,0,'eof');
2602  HDR.NRec = (ftell(HDR.FILE.FID)-HDR.HeadLen)/HDR.AS.bpb;
2603  HDR.AS.endpos = HDR.NRec;
2604  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
2605  end;
2606 
2607 
2608 elseif strcmp(HDR.TYPE,'DEMG'),
2609  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2610  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
2611  % read header
2612  fseek(HDR.FILE.FID,4,'bof'); % skip first 4 bytes, should contain 'DEMG'
2613  HDR.VERSION = fread(HDR.FILE.FID,1,'uint16');
2614  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
2615  HDR.SampleRate = fread(HDR.FILE.FID,1,'uint32');
2616  HDR.SPR = fread(HDR.FILE.FID,1,'uint32');
2617  HDR.NRec = 1;
2618 
2619  HDR.Bits = fread(HDR.FILE.FID,1,'uint8');
2620  HDR.PhysMin = fread(HDR.FILE.FID,1,'int8');
2621  HDR.PhysMax = fread(HDR.FILE.FID,1,'int8');
2622  if HDR.VERSION==1,
2623  HDR.GDFTYP = 'float32';
2624  HDR.Cal = 1;
2625  HDR.Off = 0;
2626  HDR.AS.bpb = 4*HDR.NS;
2627  elseif HDR.VERSION==2,
2628  HDR.GDFTYP = 'uint16';
2629  HDR.Cal = (HDR.PhysMax-HDR.PhysMin)/(2^HDR.Bits-1);
2630  HDR.Off = HDR.PhysMin;
2631  HDR.AS.bpb = 2*HDR.NS;
2632  else
2633  fprintf(HDR.FILE.stderr,'Error SOPEN DEMG: invalid version number.\n');
2634  fclose(HDR.FILE.FID);
2635  HDR.FILE.FID=-1;
2636  return;
2637  end;
2638  HDR.Calib = sparse([ones(1,HDR.NS),2:HDR.NS+1],[1:HDR.NS,1:HDR.NS],ones(HDR.NS,1)*[HDR.Off,HDR.Cal],HDR.NS+1,HDR.NS);
2639  HDR.HeadLen = ftell(HDR.FILE.FID);
2640  HDR.FILE.POS = 0;
2641  HDR.FILE.OPEN = 1;
2642  %HDR.Filter.LowPass = 450; % default values
2643  %HDR.Filter.HighPass = 20; % default values
2644 
2645  else
2646  fprintf(HDR.FILE.stderr,'Warning SOPEN DEMG: writing not implemented, yet.\n');
2647  end;
2648 
2649 
2650 elseif strcmp(HDR.TYPE,'ACQ'),
2651  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2652 
2653  %-------- Fixed Header
2654  ItemHeaderLen = fread(HDR.FILE.FID,1,'uint16');
2655  HDR.VERSION = fread(HDR.FILE.FID,1,'uint32');
2656  HDR.ACQ.ExtItemHeaderLen = fread(HDR.FILE.FID,1,'uint32');
2657 
2658  HDR.NS = fread(HDR.FILE.FID,1,'int16');
2659  HDR.ACQ.HorizAxisType = fread(HDR.FILE.FID,1,'int16');
2660  HDR.ACQ.CurChannel = fread(HDR.FILE.FID,1,'int16');
2661  HDR.ACQ.SampleTime = fread(HDR.FILE.FID,1,'float64')/1000;
2662  HDR.SampleRate = 1/HDR.ACQ.SampleTime;
2663  HDR.TimeOffset = fread(HDR.FILE.FID,1,'float64')/1000;
2664  HDR.TimeScale = fread(HDR.FILE.FID,1,'float64');
2665  HDR.ACQ.TimeCursor1 = fread(HDR.FILE.FID,1,'float64');
2666  HDR.ACQ.TimeCursor2 = fread(HDR.FILE.FID,1,'float64');
2667  HDR.ACQ.rcWindow = fread(HDR.FILE.FID,1,'float64');
2668  HDR.ACQ.MeasurementType = fread(HDR.FILE.FID,6,'int16');
2669  HDR.ACQ.HiLite = fread(HDR.FILE.FID,2,'uint8');
2670  HDR.FirstTimeOffset = fread(HDR.FILE.FID,1,'float64');
2671 
2672  fseek(HDR.FILE.FID,HDR.ACQ.ExtItemHeaderLen,'bof');
2673 
2674  % -------- Variable Header
2675 
2676  % -------- Per Channel data section
2677  HDR.Off = zeros(HDR.NS,1);
2678  HDR.Cal = ones(HDR.NS,1);
2679  HDR.ChanHeaderLen = zeros(HDR.NS,1);
2680  offset = ftell(HDR.FILE.FID);
2681  for k = 1:HDR.NS;
2682  fseek(HDR.FILE.FID,offset+sum(HDR.ChanHeaderLen),'bof');
2683  HDR.ChanHeaderLen(k) = fread(HDR.FILE.FID,1,'uint32');
2684  HDR.ChanSel(k) = fread(HDR.FILE.FID,1,'int16');
2685  HDR.Label{k} = char(fread(HDR.FILE.FID,[1,40],'uint8'));
2686  rgbColor = fread(HDR.FILE.FID,4,'int8');
2687  DispChan = fread(HDR.FILE.FID,2,'int8');
2688  HDR.Off(k) = fread(HDR.FILE.FID,1,'float64');
2689  HDR.Cal(k) = fread(HDR.FILE.FID,1,'float64');
2690  HDR.PhysDim{k} = char(fread(HDR.FILE.FID,[1,20],'uint8'));
2691  HDR.ACQ.BufLength(k) = fread(HDR.FILE.FID,1,'int32');
2692  HDR.AmpGain(k) = fread(HDR.FILE.FID,1,'float64');
2693  HDR.AmpOff(k) = fread(HDR.FILE.FID,1,'float64');
2694  HDR.ACQ.ChanOrder = fread(HDR.FILE.FID,1,'int16');
2695  HDR.ACQ.DispSize = fread(HDR.FILE.FID,1,'int16');
2696 
2697  if HDR.VERSION >= 34,
2698  fseek(HDR.FILE.FID,10,'cof');
2699  end;
2700  if HDR.VERSION >= 38, % version of Acq 3.7.0-3.7.2 (Win 98, 98SE, NT, Me, 2000) and above
2701  HDR.Description(k,1:128) = fread(HDR.FILE.FID,[1,128],'uint8');
2702  HDR.ACQ.VarSampleDiv(k) = fread(HDR.FILE.FID,1,'uint16');
2703  else
2704  HDR.ACQ.VarSampleDiv(k) = 1;
2705  end;
2706  if HDR.VERSION >= 39, % version of Acq 3.7.3 or above (Win 98, 98SE, 2000, Me, XP)
2707  HDR.ACQ.VertPrecision(k) = fread(HDR.FILE.FID,1,'uint16');
2708  end;
2709  end;
2710  HDR.Calib = [HDR.Off(:).';diag(HDR.Cal)];
2711  HDR.SPR = HDR.ACQ.VarSampleDiv(1);
2712  for k = 2:length(HDR.ACQ.VarSampleDiv);
2713  HDR.SPR = lcm(HDR.SPR,HDR.ACQ.VarSampleDiv(k));
2714  end;
2715  HDR.NRec = floor(min(HDR.ACQ.BufLength.*HDR.ACQ.VarSampleDiv/HDR.SPR));
2716  HDR.AS.SPR = HDR.SPR./HDR.ACQ.VarSampleDiv';
2717  HDR.AS.spb = sum(HDR.AS.SPR); % Samples per Block
2718  HDR.AS.bi = [0;cumsum(HDR.AS.SPR(:))];
2719  HDR.ACQ.SampleRate = 1./(HDR.AS.SPR*HDR.ACQ.SampleTime);
2720  HDR.SampleRate = 1/HDR.ACQ.SampleTime;
2721  HDR.Dur = HDR.SPR*HDR.ACQ.SampleTime;
2722 
2723  %-------- foreign data section
2724  ForeignDataLength = fread(HDR.FILE.FID,1,'int16');
2725  HDR.ACQ.ForeignDataID = fread(HDR.FILE.FID,1,'uint16');
2726  HDR.ACQ.ForeignData = fread(HDR.FILE.FID,[1,ForeignDataLength-4],'uint8');
2727  %fseek(HDR.FILE.FID,ForeignDataLength-2,'cof');
2728 
2729  %-------- per channel data type section
2730  offset3 = 0;
2731  HDR.AS.bpb = 0;
2732  for k = 1:HDR.NS,
2733  sz = fread(HDR.FILE.FID,1,'uint16');
2734  HDR.AS.bpb = HDR.AS.bpb + HDR.AS.SPR(k)*sz;
2735  offset3 = offset3 + HDR.ACQ.BufLength(k) * sz;
2736 % ftell(HDR.FILE.FID),
2737  typ = fread(HDR.FILE.FID,1,'uint16');
2738  if ~any(typ==[1,2])
2739  fprintf(HDR.FILE.stderr,'Warning SOPEN (ACQ): invalid or unknonw data type in file %s.\n',HDR.FileName);
2740  end;
2741  HDR.GDFTYP(k) = 31-typ*14; % 1 = int16; 2 = double
2742  end;
2743  HDR.AS.BPR = ceil(HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)');
2744  while any(HDR.AS.BPR ~= HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)');
2745  fprintf(2,'\nError SOPEN (ACQ): block configuration in file %s not supported.\n',HDR.FileName);
2746  end;
2747 
2748  % prepare SREAD for different data types
2749  n = 0;
2750  typ = [-1;HDR.GDFTYP(:)];
2751  for k = 1:HDR.NS;
2752  if (typ(k) == typ(k+1)),
2753  HDR.AS.c(n) = HDR.AS.c(n) + HDR.AS.SPR(k);
2754  HDR.AS.c2(n) = HDR.AS.c2(n) + HDR.AS.BPR(k);
2755  else
2756  n = n + 1;
2757  HDR.AS.c(n) = HDR.AS.SPR(k);
2758  HDR.AS.c2(n) = HDR.AS.BPR(k);
2759  HDR.AS.TYP(n) = HDR.GDFTYP(k);
2760  end;
2761  end;
2762 
2763  HDR.HeadLen = HDR.ACQ.ExtItemHeaderLen + sum(HDR.ChanHeaderLen) + ForeignDataLength + 4*HDR.NS;
2764  HDR.FILE.POS = 0;
2765  HDR.FILE.OPEN = 1;
2766  HDR.AS.endpos = HDR.HeadLen + offset3;
2767  fseek(HDR.FILE.FID,HDR.AS.endpos,'bof');
2768 
2769  %-------- Markers Header section
2770  len = fread(HDR.FILE.FID,1,'uint32');
2771  EVENT.N = fread(HDR.FILE.FID,1,'uint32');
2772  HDR.EVENT.POS = repmat(nan, EVENT.N ,1);
2773  HDR.EVENT.TYP = repmat(nan, EVENT.N ,1);
2774 
2775  for k = 1:EVENT.N,
2776  %HDR.Event(k).Sample = fread(HDR.FILE.FID,1,'int32');
2777  HDR.EVENT.POS(k) = fread(HDR.FILE.FID,1,'int32');
2778  tmp = fread(HDR.FILE.FID,4,'uint16');
2779  HDR.Event(k).selected = tmp(1);
2780  HDR.Event(k).TextLocked = tmp(2);
2781  HDR.Event(k).PositionLocked = tmp(3);
2782  textlen = tmp(4);
2783  HDR.Event(k).Text = fread(HDR.FILE.FID,textlen,'uint8');
2784  end;
2785  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
2786 
2787 
2788 elseif strncmp(HDR.TYPE,'AKO',3),
2789  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2790  HDR.Header = fread(HDR.FILE.FID,[1,46],'uint8');
2791  warning('support of AKO format not completed');
2792  HDR.Patient.Id = char(HDR.Header(17:24));
2793  HDR.SampleRate = 128; % ???
2794  HDR.NS = 1;
2795  HDR.NRec = 1;
2796  HDR.Calib = [-127;1];
2797  [HDR.data,HDR.SPR] = fread(HDR.FILE.FID,inf,'uint8');
2798  fclose(HDR.FILE.FID);
2799  HDR.FILE.POS = 0;
2800  HDR.TYPE = 'native';
2801 
2802 
2803 elseif strcmp(HDR.TYPE,'ALICE4'),
2804  fprintf(HDR.FILE.stderr,'Warning SOPEN: Support of ALICE4 format not completeted. \n\tCalibration, filter setttings and SamplingRate are missing\n');
2805  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2806  [s,c] = fread(HDR.FILE.FID,[1,408],'uint8');
2807  HDR.NS = s(55:56)*[1;256];
2808  HDR.SampleRate = 100;
2809  HDR.Patient.Id = char(s(143:184));
2810  HDR.Patient.Sex = char(s(185));
2811  HDR.Patient.Date = char(s(187:194));
2812  [H2,c] = fread(HDR.FILE.FID,[118,HDR.NS],'uint8');
2813  HDR.Label = char(H2(1:12,:)');
2814  HDR.HeadLen = ftell(HDR.FILE.FID);
2815  HDR.AS.bpb = HDR.NS*HDR.SampleRate + 5;
2816  [a,count] = fread(HDR.FILE.FID,[HDR.AS.bpb,floor((HDR.FILE.size-HDR.HeadLen)/HDR.AS.bpb)],'uint8');
2817  fclose(HDR.FILE.FID);
2818  count = ceil(count/HDR.AS.bpb);
2819  HDR.data = repmat(NaN,100*count,HDR.NS);
2820  for k = 1:HDR.NS,
2821  HDR.data(:,k)=reshape(a(k*HDR.SampleRate+[1-HDR.SampleRate:0],:),HDR.SampleRate*count,1);
2822  end
2823  HDR.SPR = size(HDR.data,1);
2824 
2825  HDR.NRec = 1;
2826  HDR.FLAG.UCAL = 1;
2827  HDR.TYPE = 'native';
2828  HDR.FILE.POS = 0;
2829 
2830 
2831 elseif strcmp(HDR.TYPE,'ATES'),
2832  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2833  HDR.Header = fread(HDR.FILE.FID,[1,128],'uint8');
2834  tmp = fread(HDR.FILE.FID,1,'int16');
2835  HDR.FLAG.Monopolar = logical(tmp);
2836  HDR.SampleRate = fread(HDR.FILE.FID,1,'int16');
2837  HDR.Cal = fread(HDR.FILE.FID,1,'float32');
2838  type = fread(HDR.FILE.FID,1,'float32');
2839  if type==2,
2840  HDR.GDFTYP = 'int16';
2841  else
2842  error('ATES: unknown type');
2843  end;
2844  HDR.ATES.Mask = fread(HDR.FILE.FID,2,'uint32');
2845  HDR.DigMax = fread(HDR.FILE.FID,1,'uint16');
2846  HDR.Filter.Notch = fread(HDR.FILE.FID,1,'uint16');
2847  HDR.SPR = fread(HDR.FILE.FID,1,'uint32');
2848  HDR.ATES.MontageName = fread(HDR.FILE.FID,8,'uint8');
2849  HDR.ATES.MontageComment = fread(HDR.FILE.FID,31,'uint8');
2850  HDR.NS = fread(HDR.FILE.FID,1,'int16');
2851  fclose(HDR.FILE.FID);
2852 
2853 
2854 elseif strcmp(HDR.TYPE,'BLSC1'),
2855  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2856  HDR.Header = fread(HDR.FILE.FID,[1,3720],'uint8'); % ???
2857  HDR.data = fread(HDR.FILE.FID,[32,inf],'ubit8'); % ???
2858  %HDR.NS = 32;
2859  %HDR.SPR = 24063;
2860  fclose(HDR.FILE.FID);
2861  fprintf(2,'Error SOPEN: Format BLSC not supported (yet).\n');
2862  return;
2863 
2864  H1 = HDR.Header;
2865  fclose(HDR.FILE.FID);
2866 
2867 
2868 elseif strncmp(HDR.TYPE,'BLSC2',5),
2869  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
2870  HDR.Header = fread(HDR.FILE.FID,[1,3720],'uint8'); % ???
2871  %HDR.data = fread(HDR.FILE.FID,[32,inf],'ubit8'); % ???
2872  H1 = HDR.Header;
2873  HDR.HeadLen= H1(2)*128;
2874  if strcmp(HDR.TYPE,'BLSC2-128'),
2875  H1 = HDR.Header(129:end);
2876  HDR.HeadLen = H1(2)*128;
2877  end;
2878  HDR.VERSION= H1(3:4)*[1;256]/100;
2879  T0 = char(H1(25:34));
2880  T0(T0=='-') = ' ';
2881  T0 = str2double(T0);
2882  HDR.T0 = T0([3,2,1]);
2883  HDR.NS = H1(347);
2884  HDR.SPR = 1;
2885  HDR.SampleRate = 128;
2886  HDR.GDFTYP = 2; % uint8
2887  AmpType = H1(6);
2888  HDR.Filter.LF = H1(319:323);
2889  HDR.Filter.HF = H1(314:328);
2890  RefPos = char(H1(336:341));
2891  GndPos = char(H1(342:346));
2892  NormFlag = H1(348);
2893  ReCount = H1(353:354)*[1;256]; % EEG record count
2894  NoSets = H1(355:356)*[1;256]; % Number of EEG channels
2895  ReCount = H1(357:358)*[1;256]; % Number of Channels in an EEG set
2896 
2897  if (HDR.HeadLen >= 2.34)
2898 % HDR.Label = cellstr(reshape(char(H1(1861:1986)),6,21));
2899  end;
2900 
2901  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2902  %codetab; % Loading the Code Table
2903  %load codetab
2904 gain_code=[10 24;
2905  50 25;
2906  75 26;
2907  100 27;
2908  150 28;
2909  200 29;
2910  300 31;
2911  500 17;
2912  750 18;
2913  1000 19;
2914  1500 20;
2915  2000 21;
2916  2500 22;
2917  3000 23;
2918  5000 9;
2919  7500 10;
2920  10000 11;
2921  15000 12;
2922  20000 13;
2923  25000 14;
2924  30000 15;
2925  50000 1;
2926  75000 2;
2927  100000 3;
2928  150000 4;
2929  200000 5;
2930  250000 6;
2931  300000 7];
2932 
2933  lpf_code=[ 30 100 150 300 500 750 1000 70 300 1000 1500 3000 5000 7500 10000 700];
2934  hpf_code=[.1 .3 1 3 10 30 100 300 inf];
2935 
2936  CV = H1(426:446);
2937  DC = H1(447:467)-128;
2938  SENS = H1(468:469)*[1;256];
2939  CALUV = H1(470:471)*[1;256];
2940  GAIN = H1(603:634);
2941 
2942  for k=1:length(GAIN),
2943  gain(k)=gain_code(find(gain_code(:,2)==GAIN(k)),1);
2944  end;
2945 
2946  if AmpType==0 %External Amplifier
2947  HDR.Cal = (2*CALUV./CV)*(SENS/10);
2948  HDR.Off = -(128+DC)*HDR.Cal;
2949  %Voltage=((ADV'-128)-(DC-128))*(2*CALUV/CV)*(SENS/10);
2950  else %Internal Amplifier
2951  ch = 1:HDR.NS; %1:min(length(CV),length(gain));
2952  HDR.Cal = (200./CV(ch)).*(20000./gain(ch));
2953  HDR.Off = -(128+DC(ch).*gain(ch)/300000).*HDR.Cal;
2954  %for k=(1:NoChan),
2955  % Voltage(:,k)=((ADV(k,:)'-128)-((DC(k)-128)*gain(k)/300000))*((200/CV(k))*(20000/gain(k)));
2956  %end;
2957  end;
2958 
2959  HDR.Calib = [HDR.Off; diag(HDR.Cal)];
2960  HDR.PhysDimCode = zeros(HDR.NS,1);
2961  fprintf(2,'Warning SOPEN: Format BLSC not well tested.\n');
2962  HDR.NRec = (HDR.FILE.size-HDR.HeadLen)/HDR.NS;
2963  HDR.AS.bpb = HDR.NS;
2964  HDR.FILE.POS = 0;
2965  HDR.FILE.OPEN = 1;
2966  HDR.TYPE = 'BLSC2';
2967  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
2968 
2969  fn = fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.CMT']);
2970  fid = fopen(fn,'rb');
2971  if (fid>0)
2972  [CMT,c] = fread(fid,[1,inf],'uint8');
2973  CMT = reshape(CMT(27:end),70,(c-26)/70)';
2974  HDR.EVENT.T = CMT(:,[55:58,63:66])*sparse([7,8,6,5,1,2,3,4],[1,1,2,3,4,5,6,6],[1,256,1,1,1,1,1,.01]);
2975  HDR.EVENT.CMT = CMT;
2976  fclose(fid);
2977  end;
2978 
2979 
2980 elseif strcmp(HDR.TYPE,'LEXICORE'),
2981 
2982  warning('LOADLEXI is experimental and not well tested. ')
2983  %% The solution is based on a single data file, with the comment:
2984  %% "It was used to create a QEEG. It might have been collected
2985  %% on an older Lexicore - I don't know. That was 4 years ago [in 2005]."
2986 
2987  fid = fopen(HDR.FileName,'rb','ieee-le');
2988  HDR.H1 = fread(fid,[1,128],'uint8')';
2989  HDR.data = fread(fid,[24,inf],'int16')';
2990  fclose(fid);
2991 
2992  [HDR.NRec]=size(HDR.data,1);
2993  HDR.NS = 20;
2994  HDR.SPR = 1;
2995  HDR.LEXICORE.status = HDR.data(:,21:24);
2996  s = HDR.data(:,1:20);
2997 
2998  HDR.data = s;
2999  HDR.TYPE = 'native';
3000 
3001  %% unkwown parameters
3002  HDR.SampleRate = NaN;
3003  HDR.FLAG.UCAL = 1; % data is not scaled
3004  HDR.PhysDimCode = zeros(1,HDR.NS);
3005  HDR.Cal = ones(1,HDR.NS);
3006  HDR.Off = zeros(1,HDR.NS);
3007  HDR.Calib = sparse([HDR.Off;diag(HDR.Cal)]);
3008  HDR.Label = repmat({' '},HDR.NS,1);
3009  HDR.EVENT.TYP = [];
3010  HDR.EVENT.POS = [];
3011 
3012 
3013 elseif strcmp(HDR.TYPE,'MicroMed TRC'),
3014  % MicroMed Srl, *.TRC format
3015  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3016  HDR.dat = fread(HDR.FILE.FID,[1,inf],'*uint8');
3017  HDR.Patient.Name = char(HDR.dat(192+[1:42]));
3018  fclose(HDR.FILE.FID);
3019 
3020 
3021 elseif strncmp(HDR.TYPE,'NXA',3),
3022  % Nexstim TMS-compatible EEG system called eXimia
3023  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3024  warning('support of NXA format not completed');
3025  HDR.SampleRate = 1450; % ???
3026  HDR.NS = 64;
3027  HDR.NRec = 1;
3028  HDR.Cal = ones(HDR.NS,1);
3029  HDR.Cal(5:64) = 0.076294; %EEG
3030  HDR.Cal(4) = 0.381470; %EOG
3031  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
3032  HDR.GDFTYP = 3;
3033  HDR.Label = [{'TRIG1';'TRIG2';'TRIG3';'EOG'};cellstr(repmat('EEG',60,1))];
3034  HDR.PhysDimCode = repmat(4275,HDR.NS,1); % uV
3035  [HDR.data] = fread(HDR.FILE.FID,[HDR.NS,inf],'int16')';
3036  HDR.SPR = size(HDR.data,1);
3037  fclose(HDR.FILE.FID);
3038  HDR.FILE.POS = 0;
3039  HDR.TYPE = 'native';
3040 
3041 
3042 elseif strcmp(HDR.TYPE,'RigSys'), % thanks to J. Chen
3043  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3044  [thdr,count] = fread(HDR.FILE.FID,[1,1024],'uint8');
3045  thdr = char(thdr);
3046  HDR.RigSys.H1 = thdr;
3047  empty_char = NaN;
3048  STOPFLAG = 1;
3049  while (STOPFLAG && ~isempty(thdr));
3050  [tline, thdr] = strtok(thdr,[13,10,0]);
3051  [tag, value] = strtok(tline,'=');
3052  value = strtok(value,'=');
3053  if strcmp(tag,'FORMAT ISSUE'),
3054  HDR.VERSION = value;
3055  elseif strcmp(tag,'EMPTY HEADER CHARACTER'),
3056  [t,v]=strtok(value);
3057  if strcmp(t,'ASCII')
3058  empty_char = str2double(v);
3059  STOPFLAG = 0;
3060  else
3061  fprintf(HDR.FILE.stderr,'Warning SOPEN (RigSys): Couldnot identify empty character');;
3062  end;
3063  end;
3064  end
3065  if ~isfield(HDR,'VERSION')
3066  fprintf(HDR.FILE.stderr,'Error SOPEN (RigSys): could not open file %s. Specification not known.\n',HDR.FileName);
3067  HDR.TYPE = 'unknown';
3068  fclose(HDR.FILE.FID);
3069  return;
3070  end;
3071  [thdr,H1] = strtok(thdr,empty_char);
3072  while ~isempty(thdr);
3073  [tline, thdr] = strtok(thdr,[13,10,0]);
3074  [tag, value] = strtok(tline,'=');
3075  value = strtok(value,'=');
3076  if 0,
3077  elseif strcmp(tag,'HEADER SIZE'),
3078  HDR.RigSys.H1size = str2double(value);
3079  if count == HDR.RigSys.H1size,
3080  elseif count < HDR.RigSys.H1size,
3081  tmp = fread(HDR.FILE.FID,[1,HDR.RigSys.H1size-count],'uint8');
3082  thdr = [thdr,char(tmp)];
3083  elseif count > HDR.RigSys.H1size,
3084  status = fseek(HDR.FILE.FID,HDR.RigSys.H1size);
3085  end;
3086  elseif strcmp(tag,'CHANNEL HEADER SIZE'),
3087  HDR.RigSys.H2size = str2double(value);
3088  elseif strcmp(tag,'FRAME HEADER SIZE'),
3089  HDR.RigSys.H3size = str2double(value);
3090  elseif strcmp(tag,'NCHANNELS'),
3091  HDR.NS = str2double(value);
3092  elseif strcmp(tag,'SAMPLE INTERVAL'),
3093  HDR.SampleRate = 1/str2double(value);
3094  elseif strcmp(tag,'HISTORY LENGTH'),
3095  HDR.AS.endpos = str2double(value);
3096  elseif strcmp(tag,'REFERENCE TIME'),
3097  HDR.RigSys.TO=value;
3098  HDR.T0(1:6) = round(datevec(value)*1e4)*1e-4;
3099  end
3100  end;
3101  HDR.HeadLen = HDR.RigSys.H1size+HDR.RigSys.H1size*HDR.NS;
3102 
3103  [H1,c] = fread(HDR.FILE.FID,[HDR.RigSys.H2size,HDR.NS],'uint8');
3104  for chan=1:HDR.NS,
3105  [thdr] = strtok(char(H1(:,chan)'),empty_char);
3106  while ~isempty(thdr);
3107  [tline, thdr] = strtok(thdr,[13,10,0]);
3108  [tag, value] = strtok(tline,'=');
3109  value = strtok(value,'=');
3110  if strcmp(tag,'FULL SCALE'),
3111  HDR.Gain(chan,1) = str2double(value);
3112  elseif strcmp(tag,'UNITS'),
3113  HDR.PhysDim{chan} = [value,' '];
3114  elseif strcmp(tag,'OFFSET'),
3115  HDR.Off(chan) = str2double(value);
3116  elseif 0, strcmp(tag,'CHANNEL DESCRIPTION'),
3117  HDR.Label{chan} = [value,' '];
3118  elseif strcmp(tag,'CHANNEL NAME'),
3119  HDR.Label{chan} = [value,' '];
3120  elseif strcmp(tag,'SAMPLES PER BLOCK'),
3121  HDR.AS.SPR(chan) = str2double(value);
3122  elseif strcmp(tag,'BYTES PER SAMPLE'),
3123  HDR.Bits(chan) = str2double(value)*8;
3124  end;
3125  end;
3126  end;
3127  fhsz = HDR.RigSys.H3size*8/HDR.Bits(1);
3128  s = fread(HDR.FILE.FID,[1024*HDR.NS+fhsz,inf],'int16');
3129  fclose(HDR.FILE.FID);
3130  HDR.RigSys.FrameHeaders=s(1:12,:);
3131 
3132  for k=1:HDR.NS,
3133  if k==1, HDR.SPR = HDR.AS.SPR(1);
3134  else HDR.SPR = lcm(HDR.SPR, HDR.AS.SPR(1));
3135  end;
3136  end;
3137  HDR.AS.bi = [0;cumsum(HDR.AS.SPR(:))];
3138  HDR.NRec = size(s,2);
3139  HDR.FLAG.TRIGGERED = 0;
3140  HDR.data = zeros(HDR.MAXSPR*HDR.NRec,HDR.NS);
3141  for k = 1:HDR.NS,
3142  tmp = s(fhsz+[HDR.AS.bi(k)+1:HDR.AS.bi(k+1)],:);
3143  HDR.data(:,k) = rs(tmp(:),1,HDR.MAXSPR/HDR.AS.SPR(k));
3144  end;
3145  HDR.data = HDR.data(1:HDR.AS.endpos,:);
3146  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Gain(:)./16384);
3147 
3148  HDR.FILE.POS = 0;
3149  HDR.TYPE = 'native';
3150 
3151 
3152 elseif strcmp(HDR.TYPE,'SND'),
3153  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],HDR.Endianity);
3154  if HDR.FILE.FID < 0,
3155  return;
3156  end;
3157 
3158  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
3159  HDR.FILE.OPEN = 1;
3160  fseek(HDR.FILE.FID,4,'bof');
3161  HDR.HeadLen = fread(HDR.FILE.FID,1,'uint32');
3162  datlen = fread(HDR.FILE.FID,1,'uint32');
3163  HDR.FILE.TYPE = fread(HDR.FILE.FID,1,'uint32');
3164  HDR.SampleRate = fread(HDR.FILE.FID,1,'uint32');
3165  HDR.NS = fread(HDR.FILE.FID,1,'uint32');
3166  HDR.Label = repmat({' '},HDR.NS,1);
3167  [tmp,count] = fread(HDR.FILE.FID, [1,HDR.HeadLen-24],'uint8');
3168  HDR.INFO = char(tmp);
3169 
3170  elseif ~isempty(findstr(HDR.FILE.PERMISSION,'w')), %%%%% WRITE
3171  if ~isfield(HDR,'NS'),
3172  HDR.NS = 0;
3173  end;
3174  if ~isfield(HDR,'SPR'),
3175  HDR.SPR = 0;
3176  end;
3177  if ~isfinite(HDR.NS)
3178  HDR.NS = 0;
3179  end;
3180  if ~isfinite(HDR.SPR)
3181  HDR.SPR = 0;
3182  end;
3183  if any(HDR.FILE.PERMISSION=='z') && any([HDR.SPR,HDR.NS] <= 0),
3184  fprintf(HDR.FILE.stderr,'ERROR SOPEN (SND) "wz": Update of HDR.SPR and HDR.NS are not possible.\n',HDR.FileName);
3185  fprintf(HDR.FILE.stderr,'\t Solution(s): (1) define exactly HDR.SPR and HDR.NS before calling SOPEN(HDR,"wz"); or (2) write to uncompressed file instead.\n');
3186  fclose(HDR.FILE.FID)
3187  return;
3188  end;
3189  HDR.FILE.OPEN = 2;
3190  if any([HDR.SPR,HDR.NS] <= 0);
3191  HDR.FILE.OPEN = 3;
3192  end;
3193  if ~isfield(HDR,'INFO')
3194  HDR.INFO = HDR.FileName;
3195  end;
3196  len = length(HDR.INFO);
3197  if len == 0;
3198  HDR.INFO = 'INFO';
3199  else
3200  HDR.INFO = [HDR.INFO,repmat(' ',1,mod(4-len,4))];
3201  end;
3202  HDR.HeadLen = 24+length(HDR.INFO);
3203  if ~isfield(HDR.FILE,'TYPE')
3204  HDR.FILE.TYPE = 6; % default float32
3205  end;
3206  end;
3207 
3208  if HDR.FILE.TYPE==1,
3209  HDR.GDFTYP = 'uint8';
3210  HDR.Bits = 8;
3211  elseif HDR.FILE.TYPE==2,
3212  HDR.GDFTYP = 'int8';
3213  HDR.Bits = 8;
3214  elseif HDR.FILE.TYPE==3,
3215  HDR.GDFTYP = 'int16';
3216  HDR.Bits = 16;
3217  elseif HDR.FILE.TYPE==4,
3218  HDR.GDFTYP = 'bit24';
3219  HDR.Bits = 24;
3220  elseif HDR.FILE.TYPE==5,
3221  HDR.GDFTYP = 'int32';
3222  HDR.Bits = 32;
3223  elseif HDR.FILE.TYPE==6,
3224  HDR.GDFTYP = 'float32';
3225  HDR.Bits = 32;
3226  elseif HDR.FILE.TYPE==7,
3227  HDR.GDFTYP = 'float64';
3228  HDR.Bits = 64;
3229 
3230  elseif HDR.FILE.TYPE==11,
3231  HDR.GDFTYP = 'uint8';
3232  HDR.Bits = 8;
3233  elseif HDR.FILE.TYPE==12,
3234  HDR.GDFTYP = 'uint16';
3235  HDR.Bits = 16;
3236  elseif HDR.FILE.TYPE==13,
3237  HDR.GDFTYP = 'ubit24';
3238  HDR.Bits = 24;
3239  elseif HDR.FILE.TYPE==14,
3240  HDR.GDFTYP = 'uint32';
3241  HDR.Bits = 32;
3242 
3243  else
3244  fprintf(HDR.FILE.stderr,'Error SOPEN SND-format: datatype %i not supported\n',HDR.FILE.TYPE);
3245  return;
3246  end;
3247  [d,l,d1,b,HDR.GDFTYP] = gdfdatatype(HDR.GDFTYP);
3248  HDR.AS.bpb = HDR.NS*HDR.Bits/8;
3249 
3250  % Calibration
3251  if any(HDR.FILE.TYPE==[2:5]),
3252  HDR.Cal = 2^(1-HDR.Bits);
3253  else
3254  HDR.Cal = 1;
3255  end;
3256  HDR.Off = 0;
3257  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
3258 
3259  %%%%% READ
3260  if HDR.FILE.OPEN == 1;
3261  % check file length
3262  fseek(HDR.FILE.FID,0,1);
3263  len = ftell(HDR.FILE.FID);
3264  if len ~= (datlen+HDR.HeadLen),
3265  fprintf(HDR.FILE.stderr,'Warning SOPEN SND-format: header information does not fit file length \n');
3266  datlen = len - HDR.HeadLen;
3267  end;
3268  fseek(HDR.FILE.FID,HDR.HeadLen,-1);
3269  HDR.SPR = datlen/HDR.AS.bpb;
3270  HDR.Dur = HDR.SPR/HDR.SampleRate;
3271 
3272 
3273  %%%%% WRITE
3274  elseif HDR.FILE.OPEN > 1;
3275  datlen = HDR.SPR * HDR.AS.bpb;
3276  fwrite(HDR.FILE.FID,[hex2dec('2e736e64'),HDR.HeadLen,datlen,HDR.FILE.TYPE,HDR.SampleRate,HDR.NS],'uint32');
3277  fwrite(HDR.FILE.FID,HDR.INFO,'uint8');
3278 
3279  end;
3280  HDR.FILE.POS = 0;
3281  HDR.NRec = 1;
3282 
3283 
3284 elseif strcmp(HDR.TYPE,'Delta'),
3285  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
3286  if any(HDR.FILE.PERMISSION=='r'), %%%%% READ
3287  warning('Support for Delta/NihonKohden Format is not implemented yet. ')
3288  HDR.HeadLen = hex2dec('304');
3289  HDR.H1 = fread(HDR.FILE.FID,[1,HDR.HeadLen],'uint8');
3290  HDR.Patient.Id = char(HDR.H1(314:314+80));
3291 
3292  if 1,
3293  HDR.NS = 36;
3294  HDR.SampleRate = 256;
3295  HDR.NRec = 1;
3296  HDR.SPR = 137216;
3297  HDR.data = fread(HDR.FILE.FID,[HDR.NS,HDR.SPR],'int16');
3298  HDR.EventTablePos = HDR.NRec*HDR.SPR*HDR.NS*2+HDR.HeadLen;
3299  end;
3300  tmp = fread(HDR.FILE.FID,[1,inf],'uint8');
3301 
3302  %%%%% identify events
3303  %ix = [strfind(char(HDR.ev),'TEST'),
3304  ix = strfind(char(tmp),'trigger');
3305  HDR.EVENT.TYP = tmp(ix-4)';
3306  HDR.EVENT.POS = [tmp(ix-12)',tmp(ix-11)',tmp(ix-10)',tmp(ix-9)']*(256.^[0:3]');
3307 
3308  fclose(HDR.FILE.FID);
3309  end;
3310 
3311 elseif strcmp(HDR.TYPE,'Sigma'), % SigmaPLpro
3312  fprintf(HDR.FILE.stdout,'Warning SOPEN: SigmaPLpro format is experimental only.\n')
3313  fprintf(HDR.FILE.stdout,'\t Assuming Samplerate and scaling factors are fixed to 128 Hz and 1, respectively.\n')
3314 
3315  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3316  if any(HDR.FILE.PERMISSION=='r'), %%%%% READ
3317  fseek(HDR.FILE.FID,16,'bof');
3318  HDR.XXX.S1 = fread(HDR.FILE.FID,[1,4],'uint32');
3319  for k = 1:5,
3320  line = fgets(HDR.FILE.FID);
3321  [tag,r]=strtok(line,['=',10,13]);
3322  [val]=strtok(r,['=',10,13]);
3323  if strcmp(tag,'Name'),
3324  elseif strcmp(tag,'Vorname'),
3325  elseif strcmp(tag,'GebDat'),
3326  val(val=='.')=' ';
3327  tmp = str2double(val);
3328  HDR.Patient.Birthday = [tmp([3,2,1]),12,0,0];
3329  elseif strcmp(tag,'ID'),
3330  HDR.Patient.ID = val;
3331  end;
3332  end;
3333  HDR.SampleRate = 128;
3334  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
3335  len = fread(HDR.FILE.FID,1,'uint8');
3336  val = fread(HDR.FILE.FID,[1,len],'uint8=>char');
3337  fseek(HDR.FILE.FID,148,'bof');
3338  for k1=1:HDR.NS
3339  ch = fread(HDR.FILE.FID,1,'uint16');
3340  HDR.Filter.Notch(k1) = fread(HDR.FILE.FID,1,'int16') ~= 0;
3341  for k2=1:4
3342  len = fread(HDR.FILE.FID,1,'uint8');
3343  val = fread(HDR.FILE.FID,[1,len],'uint8=>char');
3344  XXX.Val(k1,k2)=str2double(val);
3345  end;
3346  HDR.Off(k1) = fread(HDR.FILE.FID,1,'int16');
3347  for k2=5:8
3348  len = fread(HDR.FILE.FID,1,'uint8');
3349  val = fread(HDR.FILE.FID,[1,len],'uint8=>char');
3350  XXX.Val(k1,k2)=str2double(val);
3351  end;
3352  val = fread(HDR.FILE.FID,4,'int16');
3353  HDR.ELEC.XYZ(k1,1:2)=val(1:2);
3354  refxy(k1,:) = val(3:4);
3355  len = fread(HDR.FILE.FID,1,'uint8');
3356  val = fread(HDR.FILE.FID,[1,19],'uint8=>char');
3357  HDR.Label{k1}=val(1:len);
3358  len = fread(HDR.FILE.FID,1,'uint8');
3359  val = fread(HDR.FILE.FID,[1,7],'uint8=>char');
3360  HDR.PhysDim{k1}=val(1:len);
3361  len = fread(HDR.FILE.FID,1,'uint8');
3362  val = fread(HDR.FILE.FID,[1,8],'uint8=>char');
3363  end;
3364  HDR.XXX.Val = XXX.Val;
3365  HDR.AS.SampleRate = XXX.Val(:,1);
3366  HDR.Filter.LowPass = XXX.Val(:,2);
3367  HDR.Filter.HighPass = XXX.Val(:,3);
3368  HDR.Filter.HighPass = XXX.Val(:,3);
3369  HDR.Impedance = XXX.Val(:,7);
3370  HDR.Cal = XXX.Val(:,8);
3371  HDR.Off = HDR.Off(:)'.*HDR.Cal(:)';
3372  if all(refxy(:,1)==refxy(1,1)) && all(refxy(:,2)==refxy(1,2))
3373  HDR.ELEC.REF = refxy(1,1:2);
3374  end;
3375 
3376  HDR.GDFTYP = repmat(3,1,HDR.NS);
3377  HDR.FILE.POS = 0;
3378  HDR.FILE.OPEN= 1;
3379  HDR.SPR = 1;
3380  HDR.NRec = (HDR.FILE.size-HDR.HeadLen)/(2*HDR.NS);
3381  end;
3382 
3383 
3384 elseif strncmp(HDR.TYPE,'EEG-1100',8),
3385  try
3386  [s,H] = mexSLOAD(HDR.FileName,ReRefMx);
3387  H.data = s;
3388  H.TYPE = 'native';
3389  H.FILE.stderr = HDR.FILE.stderr;
3390  H.FILE.PERMISSION = HDR.FILE.PERMISSION;
3391  H.FLAG.FORCEALLCHANNEL = HDR.FLAG.FORCEALLCHANNEL;
3392  H.FLAG.TRIGGERED = 0;
3393  H.FILE.POS = 0;
3394  H.FLAG.OUTPUT = HDR.FLAG.OUTPUT;
3395  H.FILE.OPEN = HDR.FILE.OPEN;
3396  H.FILE.FID = HDR.FILE.FID;
3397  HDR = H;
3398 
3399  catch
3400  fprintf(HDR.FILE.stderr,'Warning SOPEN: family of Nihon-Kohden 1100 format is implemented only fully in libbiosig.\n');
3401  fprintf(HDR.FILE.stderr,'You need to have mexSLOAD installed in order to load file %s,\n',HDR.FileName);
3402  fprintf(HDR.FILE.stderr,' or you get only some limited header information');
3403 
3404  %% TODO: use mexSOPEN and SREAD.M together in order to avoid the need to load the whole data section
3405 
3406  H = mexSSOPEN(HDR.FileName);
3407  %% This will do some parts, but the internal fields needed by SREAD() and channel selection need still be defined.
3408 
3409  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3410  if any(HDR.FILE.PERMISSION=='r'), %%%%% READ
3411  [H1,count] = fread(HDR.FILE.FID,[1,6160],'uint8');
3412  % HDR.Patient.Name = char(H1(79+(1:32)));
3413  if count < 6160,
3414  fclose(HDR.FILE.FID);
3415  return;
3416  end;
3417  HDR.T0(1:6) = str2double({H1(65:68),H1(69:70),H1(71:72),H1(6148:6149),H1(6150:6151),H1(6152:6153)});
3418  if strcmp(HDR.FILE.Ext,'LOG')
3419  [s,c] = fread(HDR.FILE.FID,[1,inf],'uint8');
3420  s = char([H1(1025:end),s]);
3421  K = 0;
3422  [t1,s] = strtok(s,0);
3423  while ~isempty(s),
3424  K = K + 1;
3425  [HDR.EVENT.x{K},s] = strtok(s,0);
3426  end
3427  end;
3428  fclose(HDR.FILE.FID);
3429  end;
3430  end
3431 
3432 
3433 elseif strcmp(HDR.TYPE,'GTF'), % Galileo EBNeuro EEG Trace File
3434  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3435 
3436  % read 3 header blocks
3437  HDR.GTF.H1 = fread(HDR.FILE.FID,[1,512],'uint8');
3438  HDR.GTF.H2 = fread(HDR.FILE.FID,[1,15306],'int8');
3439  HDR.GTF.H3 = fread(HDR.FILE.FID,[1,8146],'uint8');
3440  HDR.GTF.messages = fread(HDR.FILE.FID,[3600,1],'int8');
3441  HDR.GTF.states = fread(HDR.FILE.FID,[3600,1],'int8');
3442 
3443  HDR.GTF.L1 = char(reshape(HDR.GTF.H3(1:650),65,10)');
3444  HDR.GTF.L2 = char(reshape(HDR.GTF.H3(650+(1:20*16)),16,20)');
3445  HDR.GTF.L3 = reshape(HDR.GTF.H3(1070+32*3+(1:232*20)),232,20)';
3446 
3447  HDR.Label = char(reshape(HDR.GTF.H3(1071:1070+32*3),3,32)'); % channel labels
3448 
3449  [H.i8, count] = fread(HDR.FILE.FID,inf,'int8');
3450  fclose(HDR.FILE.FID);
3451 
3452  [t,status] = str2double(char([HDR.GTF.H1(35:36),32,HDR.GTF.H1(37:39)]));
3453  if ~any(status) && all(t>0)
3454  HDR.NS = t(1);
3455  HDR.SampleRate = t(2);
3456  else
3457  fprintf(2,'ERROR SOPEN (%s): Invalid GTF header.\n',HDR.FileName);
3458  HDR.TYPE = 'unknown';
3459  return;
3460  end
3461 
3462  % convert messages, states and annotations into EVENT's
3463  ix = find(HDR.GTF.messages<-1);
3464  ann.POS = ix*HDR.SampleRate;
3465  ann.TYP = -HDR.GTF.messages(ix)-1;
3466  ann.Desc = [repmat('A: ',length(ix),1),HDR.GTF.L1(ann.TYP,:)];
3467  ix = find(HDR.GTF.messages>-1);
3468  msg.POS = ix*HDR.SampleRate;
3469  msg.TYP = 1+HDR.GTF.messages(ix);
3470  msg.Desc = [repmat('M: ',length(ix),1),HDR.GTF.L2(msg.TYP,:)];
3471  ix = find((HDR.GTF.states>9) & (HDR.GTF.states<20));
3472  sts.POS = ix*HDR.SampleRate;
3473  sts.TYP = HDR.GTF.states(ix)+1;
3474  % ix = find((HDR.GTF.states==20)); % Calibration ???
3475 
3476  sts.Desc = [repmat('S: ',length(ix),1),HDR.GTF.L2(sts.TYP,:)];
3477  HDR.EVENT.POS = [ann.POS(:); msg.POS(:); sts.POS(:)];
3478  HDR.EVENT.TYP = [ann.TYP(:); msg.TYP(:)+10; sts.TYP(:)+10];
3479  HDR.EVENT.Desc = cellstr(char(ann.Desc,msg.Desc,sts.Desc));
3480 
3481  HDR.GTF.ann = ann;
3482  HDR.GTF.msg = msg;
3483  HDR.GTF.sts = sts;
3484 
3485  HDR.Dur = 10;
3486  HDR.SPR = HDR.Dur*HDR.SampleRate;
3487  HDR.Bits = 8;
3488  HDR.GDFTYP = repmat(1,HDR.NS,1);
3489  HDR.TYPE = 'native';
3490  if ~isfield(HDR.THRESHOLD'),
3491  HDR.THRESHOLD = repmat([-127,127],HDR.NS,1); % support of overflow detection
3492  end;
3493  HDR.FILE.POS = 0;
3494  HDR.Label = HDR.Label(1:HDR.NS,:);
3495 
3496  HDR.AS.bpb = (HDR.SampleRate*240+2048);
3497  HDR.GTF.Preset = HDR.GTF.H3(8134)+1; % Preset
3498 
3499  t2 = (0:floor(count/HDR.AS.bpb)-1)*HDR.AS.bpb;
3500  HDR.NRec = length(t2);
3501  [s2,sz] = trigg(H.i8,t2+2048,1,HDR.SampleRate*240);
3502  HDR.data = reshape(s2,[HDR.NS,sz(2)/HDR.NS*HDR.NRec])';
3503 
3504  [s4,sz] = trigg(H.i8,t2+1963,0,1);
3505  sz(sz==1)= [];
3506  x = reshape(s4,sz)';
3507  HDR.GTF.timestamp = (x+(x<0)*256)*[1;256]; % convert from 2*int8 in 1*uint16
3508 
3509  [s4,sz] = trigg(H.i8,t2,1,2048);
3510  sz(sz==1)= []; if length(sz)<2,sz = [sz,1]; end;
3511  s4 = reshape(s4,sz);
3512 
3513  tau = [0.01, 0.03, 0.1, 0.3, 1];
3514  LowPass = [30, 70];
3515 
3516  %% Scaling
3517  Sens = [.5, .7, 1, 1.4, 2, 5, 7, 10, 14, 20, 50, 70, 100, 140, 200];
3518  x = reshape(s4(13:6:1932,:),32,HDR.NRec*HDR.Dur);
3519  Cal = Sens(x(1:HDR.NS,:)+1)'/4;
3520  HDR.data = HDR.data.*Cal(ceil((1:HDR.SampleRate*HDR.NRec*HDR.Dur)/HDR.SampleRate),:);
3521  HDR.PhysDim = 'uV';
3522 
3523 
3524 elseif strcmp(HDR.TYPE,'MatrixMarket'),
3525  if (HDR.FILE.PERMISSION=='r')
3526  fid = fopen(HDR.FileName,HDR.FILE.PERMISSION,'ieee-le');
3527  K = 0;
3528  status = 0;
3529  while ~feof(fid);
3530  line = fgetl(fid);
3531  if length(line)<3,
3532  ;
3533  elseif all(line(1:2)=='%') && isspace(line(3)),
3534  if strncmp(line,'%% LABELS',9)
3535  status = 1;
3536  elseif strncmp(line,'%% ENDLABEL',11)
3537  status = 0;
3538  elseif status,
3539  k=3;
3540  while (isspace(line(k))) k=k+1; end;
3541  [t,r] = strtok(line(k:end),char([9,32]));
3542  ch = str2double(t);
3543  k = 1;
3544  while (isspace(r(k))) k=k+1; end;
3545  r = r(k:end);
3546  k = length(r);
3547  while (isspace(r(k))) k=k-1; end;
3548  HDR.Label{ch} = r(1:k);
3549  end;
3550  elseif (line(1)=='%')
3551  ;
3552  else
3553  [n,v,sa] = str2double(line);
3554  K = K+1;
3555  if (K==1)
3556  HDR.Calib = sparse([],[],[],n(1),n(2),n(3));
3557  else
3558  HDR.Calib(n(1),n(2))=n(3);
3559  end;
3560  end;
3561  end;
3562  fclose(fid);
3563  HDR.FILE.FID = fid;
3564 
3565  elseif (HDR.FILE.PERMISSION=='w')
3566  fid = fopen(HDR.FileName,HDR.FILE.PERMISSION,'ieee-le');
3567 
3568  [I,J,V] = find(HDR.Calib);
3569  fprintf(fid,'%%%%MatrixMarket matrix coordinate real general\n');
3570  fprintf(fid,'%% generated on %04i-%02i-%02i %02i:%02i:%02.0f\n',clock);
3571  fprintf(fid,'%% Spatial Filter for EEG/BioSig data\n%%\n');
3572  if isfield(HDR,'Label')
3573  fprintf(fid,'%%%% LABELS [for channels in target file]\n');
3574  for k = 1:length(HDR.Label),
3575  fprintf(fid,'%%%%\t%i\t%s\n', k, HDR.Label{k});
3576  end;
3577  fprintf(fid,'%%%% ENDLABELS\n');
3578  end
3579  if isfield(HDR,'NumberOfSamplesUsed')
3580  %%% used when matrix contain correction coefficients for e.g. eog artifacts, then this value
3581  %%% should contain the number of samples used for estimating these correction coefficients.
3582  %%% It can be used for quality control, whether the coefficients are reliable or not.
3583  fprintf(fid,'%%%% NumberOfSamplesUsed: %i\n',HDR.NumberOfSamplesUsed);
3584  end;
3585  fprintf(fid,'%%\n%%============================================\n%i %i %i\n',size(HDR.Calib),length(V));
3586  for k = 1:length(V),
3587  fprintf(fid,'%2i %2i %.18e\n',I(k),J(k),V(k));
3588  end;
3589  fclose(fid);
3590 
3591  end;
3592 
3593 
3594 elseif strcmp(HDR.TYPE,'MFER'),
3595  HDR = mwfopen(HDR,[HDR.FILE.PERMISSION,'b']);
3596  if (HDR.FRAME.N ~= 1),
3597  fprintf(HDR.FILE.stderr,'Error SOPEN (MFER): files with more than one frame not implemented, yet.\n');
3598  fclose(HDR.FILE.FID);
3599  HDR.FILE.FID =-1;
3600  HDR.FILE.OPEN = 0;
3601  end
3602 
3603 
3604 elseif strcmp(HDR.TYPE,'MPEG'),
3605  % http://www.dv.co.yu/mpgscript/mpeghdr.htm
3606  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3607  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
3608  % read header
3609  try,
3610  tmp = fread(HDR.FILE.FID,1,'ubit11');
3611  catch
3612  fprintf(HDR.FILE.stderr,'Error 1003 SOPEN: datatype UBIT11 not implented. Header cannot be read.\n');
3613  return;
3614  end;
3615  HDR.MPEG.syncword = tmp;
3616  HDR.MPEG.ID = fread(HDR.FILE.FID,1,'ubit2');
3617  HDR.MPEG.layer = fread(HDR.FILE.FID,1,'ubit2');
3618  HDR.MPEG.protection_bit = fread(HDR.FILE.FID,1,'ubit1');
3619  HDR.MPEG.bitrate_index = fread(HDR.FILE.FID,1,'ubit4');
3620  HDR.MPEG.sampling_frequency_index = fread(HDR.FILE.FID,1,'ubit2');
3621  HDR.MPEG.padding_bit = fread(HDR.FILE.FID,1,'ubit1');
3622  HDR.MPEG.privat_bit = fread(HDR.FILE.FID,1,'ubit1');
3623  HDR.MPEG.mode = fread(HDR.FILE.FID,1,'ubit2');
3624  HDR.MPEG.mode_extension = fread(HDR.FILE.FID,1,'ubit2');
3625  HDR.MPEG.copyright = fread(HDR.FILE.FID,1,'ubit1');
3626  HDR.MPEG.original_home = fread(HDR.FILE.FID,1,'ubit1');
3627  HDR.MPEG.emphasis = fread(HDR.FILE.FID,1,'ubit2');
3628 
3629  switch HDR.MPEG.ID, %Layer
3630  case 0,
3631  HDR.VERSION = 2.5;
3632  case 1,
3633  HDR.VERSION = -1;% reserved
3634  case 2,
3635  HDR.VERSION = 2;
3636  case 3,
3637  HDR.VERSION = 1;
3638  end;
3639 
3640  tmp = [32,32,32,32,8; 64,48,40,48,16; 96,56,48,56,24; 128,64,56,64,32; 160,80,64,80,40; 192,96,80,96,48; 224,112,96,112,56; 256,128,112,128,64; 288,160,128,144,80; 320,192 160,160,96; 352,224,192,176,112; 384,256,224, 192,128; 416,320,256,224,144; 448,384,320,256,160];
3641  tmp = [tmp,tmp(:,5)];
3642  if HDR.MPEG.bitrate_index==0,
3643  HDR.bitrate = NaN;
3644  elseif HDR.MPEG.bitrate_index==15,
3645  fclose(HDR.FILE.FID);
3646  fprintf(HDR.FILE.stderr,'SOPEN: corrupted MPEG file %s ',HDR.FileName);
3647  return;
3648  else
3649  HDR.bitrate = tmp(HDR.MPEG.bitrate_index,floor(HDR.VERSION)*3+HDR.MPEG.layer-3);
3650  end;
3651 
3652  switch HDR.MPEG.sampling_frequency_index,
3653  case 0,
3654  HDR.SampleRate = 44.100;
3655  case 1,
3656  HDR.SampleRate = 48.000;
3657  case 2,
3658  HDR.SampleRate = 32.000;
3659  otherwise,
3660  HDR.SampleRate = NaN;
3661  end;
3662  HDR.SampleRate_units = 'kHz';
3663  HDR.SampleRate = HDR.SampleRate*(2^(1-ceil(HDR.VERSION)));
3664 
3665  switch 4-HDR.MPEG.layer, %Layer
3666  case 1,
3667  HDR.SPR = 384;
3668  slot = 32*HDR.MPEG.padding_bit; % bits, 4 bytes
3669  HDR.FrameLengthInBytes = (12*HDR.bitrate/HDR.SampleRate+slot)*4;
3670  case {2,3},
3671  HDR.SampleRate = 1152;
3672  slot = 8*HDR.MPEG.padding_bit; % bits, 1 byte
3673  HDR.FrameLengthInBytes = 144*HDR.bitrate/HDR.SampleRate+slot;
3674  end;
3675 
3676  if ~HDR.MPEG.protection_bit,
3677  HDR.MPEG.error_check = fread(HDR.FILE.FID,1,'uint16');
3678  end;
3679 
3680  HDR.MPEG.allocation = fread(HDR.FILE.FID,[1,32],'ubit4');
3681  HDR.MPEG.NoFB = sum(HDR.MPEG.allocation>0);
3682  HDR.MPEG.idx = find(HDR.MPEG.allocation>0);
3683  HDR.MPEG.scalefactor = fread(HDR.FILE.FID,[1,HDR.MPEG.NoFB],'ubit6');
3684  for k = HDR.MPEG.idx,
3685  HDR.MPEG.temp(1:12,k) = fread(HDR.FILE.FID,[12,1],['ubit',int2str(HDR.MPEG.allocation(k))]);
3686  end;
3687  fprintf(HDR.FILE.stderr,'Warning SOPEN: MPEG not ready for use (%s)\n',HDR.FileName);
3688  HDR.FILE.OPEN = 1;
3689  end;
3690  HDR.FILE.OPEN = 0;
3691  fclose(HDR.FILE.FID);
3692  HDR.FILE.FID = -1;
3693  return;
3694 
3695 
3696 elseif strcmp(HDR.TYPE,'QTFF'),
3697  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
3698  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
3699  HDR.FILE.OPEN = 1;
3700  offset = 0;
3701  while ~feof(HDR.FILE.FID),
3702  tagsize = fread(HDR.FILE.FID,1,'uint32'); % which size
3703  if ~isempty(tagsize),
3704  offset = offset + tagsize;
3705  tag = char(fread(HDR.FILE.FID,[1,4],'uint8'));
3706  if tagsize==0,
3707  tagsize=inf; %tagsize-8;
3708  elseif tagsize==1,
3709  tagsize=fread(HDR.FILE.FID,1,'uint64');
3710  end;
3711 
3712  if tagsize <= 8,
3713  elseif strcmp(tag,'free'),
3714  val = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3715  HDR.MOV.free = val;
3716  elseif strcmp(tag,'skip'),
3717  val = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3718  HDR.MOV.skip = val;
3719  elseif strcmp(tag,'wide'),
3720  %val = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3721  %HDR.MOV.wide = val;
3722  elseif strcmp(tag,'pnot'),
3723  val = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3724  HDR.MOV.pnot = val;
3725  elseif strcmp(tag,'moov'),
3726  offset2 = 8;
3727  while offset2 < tagsize,
3728  tagsize2 = fread(HDR.FILE.FID,1,'uint32'); % which size
3729  if tagsize2==0,
3730  tagsize2 = inf;
3731  elseif tagsize2==1,
3732  tagsize2=fread(HDR.FILE.FID,1,'uint64');
3733  end;
3734  offset2 = offset2 + tagsize2;
3735  tag2 = char(fread(HDR.FILE.FID,[1,4],'uint8'));
3736  if tagsize2 <= 8,
3737  elseif strcmp(tag2,'mvhd'),
3738  HDR.MOOV.Version = fread(HDR.FILE.FID,1,'uint8');
3739  HDR.MOOV.Flags = fread(HDR.FILE.FID,3,'uint8');
3740  HDR.MOOV.Times = fread(HDR.FILE.FID,5,'uint32');
3741  HDR.T0 = datevec(HDR.MOOV.Times(1)/(3600*24))+[1904,0,0,0,0,0];
3742  HDR.MOOV.prefVol = fread(HDR.FILE.FID,1,'uint16');
3743  HDR.MOOV.reserved = fread(HDR.FILE.FID,10,'uint8');
3744  HDR.MOOV.Matrix = fread(HDR.FILE.FID,[3,3],'int32')';
3745  HDR.MOOV.Matrix(:,1:2) = HDR.MOOV.Matrix(:,1:2)/2^16;
3746  HDR.MOOV.Preview = fread(HDR.FILE.FID,5,'uint32');
3747  elseif strcmp(tag2,'trak'),
3748  HDR.MOOV.trak = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3749  elseif strcmp(tag2,'cmov'),
3750  HDR.MOOV.cmov = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3751  elseif strcmp(tag2,'free'),
3752  HDR.MOOV.free = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3753  elseif strcmp(tag2,'clip'),
3754  HDR.MOOV.clip = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3755  elseif strcmp(tag2,'udta'),
3756  HDR.MOOV.udta = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3757  elseif strcmp(tag2,'ctab'),
3758  HDR.MOOV.ctab = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3759  else
3760  end;
3761  end;
3762  %HDR.MOV.moov = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3763 
3764  elseif strcmp(tag,'mdat'),
3765  HDR.HeadLen = ftell(HDR.FILE.FID);
3766  offset2 = 8;
3767  while offset2 < tagsize,
3768  tagsize2 = fread(HDR.FILE.FID,1,'uint32'); % which size
3769  tag2 = char(fread(HDR.FILE.FID,[1,4],'uint8'));
3770  if tagsize2==0,
3771  tagsize2 = inf;
3772  elseif tagsize2==1,
3773  tagsize2 = fread(HDR.FILE.FID,1,'uint64');
3774  end;
3775  offset2 = offset2 + tagsize2;
3776  if tagsize2 <= 8,
3777  elseif strcmp(tag2,'mdat'),
3778  HDR.MDAT.mdat = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3779  elseif strcmp(tag2,'wide'),
3780  HDR.MDAT.wide = fread(HDR.FILE.FID,[1,tagsize2],'uint8');
3781  elseif strcmp(tag2,'clip'),
3782  HDR.MDAT.clip = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3783  elseif strcmp(tag2,'udta'),
3784  HDR.MDAT.udta = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3785  elseif strcmp(tag2,'ctab'),
3786  HDR.MDAT.ctab = fread(HDR.FILE.FID,[1,tagsize2-8],'uint8');
3787  else
3788  end;
3789  end;
3790  %HDR.MOV.mdat = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3791  else
3792  val = fread(HDR.FILE.FID,[1,tagsize-8],'uint8');
3793  fprintf(HDR.FILE.stderr,'Warning SOPEN Type=MOV: unknown Tag %s.\n',tag);
3794  end;
3795  fseek(HDR.FILE.FID,offset,'bof');
3796  end;
3797  end;
3798  end;
3799  %fclose(HDR.FILE.FID);
3800 
3801 
3802 elseif strcmp(HDR.TYPE,'ASF') ,
3803  if exist('asfopen','file'),
3804  HDR = asfopen(HDR,[HDR.FILE.PERMISSION,'b']);
3805  else
3806  fprintf(1,'SOPEN ASF-File: Microsoft claims that its illegal to implement the ASF format.\n');
3807  fprintf(1,' Anyway Microsoft provides the specification at http://www.microsoft.com/windows/windowsmedia/format/asfspec.aspx \n');
3808  fprintf(1,' So, you can implement it and use it for your own purpose.\n');
3809  end;
3810 
3811 
3812 elseif strcmp(HDR.TYPE,'MIDI') || strcmp(HDR.TYPE,'RMID') ,
3813  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],HDR.Endianity);
3814 
3815  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
3816 
3817  [tmp,c] = fread(HDR.FILE.FID,[1,4+12*strcmp(HDR.TYPE,'RMID') ],'uint8');
3818  tmp = char(tmp(c+(-3:0)));
3819  if ~strcmpi(tmp,'MThd'),
3820  fprintf(HDR.FILE.stderr,'Warning SOPEN (MIDI): file %s might be corrupted 1\n',HDR.FileName);
3821  end;
3822 
3823  while ~feof(HDR.FILE.FID),
3824  tag = char(tmp);
3825  tagsize = fread(HDR.FILE.FID,1,'uint32'); % which size
3826  filepos = ftell(HDR.FILE.FID);
3827 
3828  if 0,
3829 
3830  %%%% MIDI file format
3831  elseif strcmpi(tag,'MThd');
3832  [tmp,c] = fread(HDR.FILE.FID,[1,tagsize/2],'uint16');
3833  HDR.MIDI.Format = tmp(1);
3834  HDR.NS = tmp(2);
3835  if tmp(3)<2^15,
3836  HDR.SampleRate = tmp(3);
3837  else
3838  tmp4 = floor(tmp(3)/256);
3839  if tmp>127,
3840  tmp4 = 256-tmp4;
3841  HDR.SampleRate = (tmp4*rem(tmp(3),256));
3842  end
3843  end;
3844  CurrentTrack = 0;
3845 
3846  elseif strcmpi(tag,'MTrk');
3847  [tmp,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8');
3848  CurrentTrack = CurrentTrack + 1;
3849  HDR.MIDI.Track{CurrentTrack} = tmp;
3850  k = 1;
3851  while 0,k<c,
3852  deltatime = 1;
3853  while tmp(k)>127,
3854  deltatime = mod(tmp(k),128) + deltatime*128;
3855  k = k+1;
3856  end;
3857  deltatime = tmp(k) + deltatime*128;
3858  k = k+1;
3859  status_byte = tmp(k);
3860  k = k+1;
3861 
3862  if any(floor(status_byte/16)==[8:11]), % Channel Mode Message
3863  databyte = tmp(k:k+1);
3864  k = k+2;
3865 
3866  elseif any(floor(status_byte/16)==[12:14]), % Channel Voice Message
3867  databyte = tmp(k);
3868  k = k+1;
3869 
3870  elseif any(status_byte==hex2dec(['F0';'F7'])) % Sysex events
3871  len = 1;
3872  while tmp(k)>127,
3873  len = mod(tmp(1),128) + len*128
3874  k = k+1;
3875  end;
3876  len = tmp(k) + len*128;
3877  data = tmp(k+(1:len));
3878 
3879  % System Common Messages
3880  elseif status_byte==240, % F0
3881  elseif status_byte==241, % F1
3882  while tmp(k)<128,
3883  k = k+1;
3884  end;
3885  elseif status_byte==242, % F2
3886  k = k + 1;
3887  elseif status_byte==243, % F3
3888  k = k + 1;
3889  elseif status_byte==244, % F4
3890  elseif status_byte==245, % F5
3891  elseif status_byte==246, % F6
3892  elseif status_byte==247, % F7
3893  elseif status_byte==(248:254), % F7:FF
3894 
3895  elseif (status_byte==255) % Meta Events
3896  type = tmp(k);
3897  k = k+1;
3898  len = 1;
3899  while tmp(k)>127,
3900  len = mod(tmp(1),128) + len*128
3901  k = k+1;
3902  end;
3903  len = tmp(k) + len*128;
3904  data = tmp(k+1:min(k+len,length(tmp)));
3905  if 0,
3906  elseif type==0, HDR.MIDI.SequenceNumber = data;
3907  elseif type==1, HDR.MIDI.TextEvent = char(data);
3908  elseif type==2, HDR.Copyright = char(data);
3909  elseif type==3, HDR.MIDI.SequenceTrackName = char(data);
3910  elseif type==4, HDR.MIDI.InstrumentNumber = char(data);
3911  elseif type==5, HDR.MIDI.Lyric = char(data);
3912  elseif type==6, HDR.EVENT.POS = data;
3913  elseif type==7, HDR.MIDI.CuePoint = char(data);
3914  elseif type==32,MDR.MIDI.ChannelPrefix = data;
3915  elseif type==47,MDR.MIDI.EndOfTrack = k;
3916 
3917  end;
3918  else
3919  end;
3920  end;
3921 
3922  elseif ~isempty(tagsize)
3923  fprintf(HDR.FILE.stderr,'Warning SOPEN (MIDI): unknown TAG in %s: %s(%i) \n',HDR.FileName,tag,tagsize);
3924  [tmp,c] = fread(HDR.FILE.FID,[1,min(100,tagsize)],'uint8');
3925  fprintf(HDR.FILE.stderr,'%s\n',char(tmp));
3926  end,
3927 
3928  if ~isempty(tagsize)
3929  status = fseek(HDR.FILE.FID,filepos+tagsize,'bof');
3930  if status,
3931  fprintf(HDR.FILE.stderr,'Warning SOPEN (MIDI): fseek failed. Probably tagsize larger than end-of-file and/or file corrupted\n');
3932  fseek(HDR.FILE.FID,0,'eof');
3933  end;
3934  end;
3935  [tmp,c] = fread(HDR.FILE.FID,[1,4],'uint8');
3936  end;
3937 
3938  HDR.FILE.POS = 0;
3939  HDR.FILE.OPEN = 1;
3940  HDR.NRec = 1;
3941  end;
3942 
3943 
3944 elseif strmatch(HDR.TYPE,['AIF';'IIF';'WAV';'AVI']),
3945  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
3946  if strcmp(HDR.TYPE,'AIF')
3947  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
3948  else
3949  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
3950  end;
3951 
3952  tmp = char(fread(HDR.FILE.FID,[1,4],'uint8'));
3953  if ~strcmpi(tmp,'FORM') && ~strcmpi(tmp,'RIFF')
3954  fprintf(HDR.FILE.stderr,'Warning SOPEN AIF/WAV-format: file %s might be corrupted 1\n',HDR.FileName);
3955  end;
3956  tagsize = fread(HDR.FILE.FID,1,'uint32'); % which size
3957  tagsize0 = tagsize + rem(tagsize,2);
3958  tmp = char(fread(HDR.FILE.FID,[1,4],'uint8'));
3959  if ~strncmpi(tmp,'AIF',3) && ~strncmpi(tmp,'WAVE',4) && ~strncmpi(tmp,'AVI ',4),
3960  % not (AIFF or AIFC or WAVE)
3961  fprintf(HDR.FILE.stderr,'Warning SOPEN AIF/WAF-format: file %s might be corrupted 2\n',HDR.FileName);
3962  end;
3963 
3964  [tmp,c] = fread(HDR.FILE.FID,[1,4],'uint8');
3965  while ~feof(HDR.FILE.FID),
3966  tag = char(tmp);
3967  tagsize = fread(HDR.FILE.FID,1,'uint32'); % which size
3968  tagsize0= tagsize + rem(tagsize,2);
3969  filepos = ftell(HDR.FILE.FID);
3970 
3971  %%%% AIF - section %%%%%
3972  if strcmpi(tag,'COMM')
3973  if tagsize<18,
3974  fprintf(HDR.FILE.stderr,'Error SOPEN AIF: incorrect tag size\n');
3975  return;
3976  end;
3977  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
3978  HDR.SPR = fread(HDR.FILE.FID,1,'uint32');
3979  HDR.AS.endpos = HDR.SPR;
3980  HDR.Bits = fread(HDR.FILE.FID,1,'uint16');
3981  %HDR.GDFTYP = ceil(HDR.Bits/8)*2-1; % unsigned integer of approbriate size;
3982  if HDR.Bits == 8;
3983  HDR.GDFTYP = 'uint8';
3984  elseif HDR.Bits == 16;
3985  HDR.GDFTYP = 'uint16';
3986  elseif HDR.Bits == 32;
3987  HDR.GDFTYP = 'uint32';
3988  else
3989  HDR.GDFTYP = ['ubit', int2str(HDR.Bits)];
3990  end;
3991  HDR.Cal = 2^(1-HDR.Bits);
3992  HDR.Off = 0;
3993  HDR.AS.bpb = ceil(HDR.Bits/8)*HDR.NS;
3994 
3995  % HDR.SampleRate; % construct Extended 80bit IEEE 754 format
3996  tmp = fread(HDR.FILE.FID,1,'int16');
3997  sgn = sign(tmp);
3998  if tmp(1)>= 2^15; tmp(1)=tmp(1)-2^15; end;
3999  e = tmp - 2^14 + 1;
4000  tmp = fread(HDR.FILE.FID,2,'uint32');
4001  HDR.SampleRate = sgn * (tmp(1)*(2^(e-31))+tmp(2)*2^(e-63));
4002  HDR.Dur = HDR.SPR/HDR.SampleRate;
4003  HDR.FILE.TYPE = 0;
4004 
4005  if tagsize>18,
4006  [tmp,c] = fread(HDR.FILE.FID,[1,4],'uint8');
4007  HDR.AIF.CompressionType = char(tmp);
4008  [tmp,c] = fread(HDR.FILE.FID,[1,tagsize-18-c],'uint8');
4009  HDR.AIF.CompressionName = tmp;
4010 
4011  if strcmpi(HDR.AIF.CompressionType,'NONE');
4012  elseif strcmpi(HDR.AIF.CompressionType,'fl32');
4013  HDR.GDFTYP = 'uint16';
4014  HDR.Cal = 1;
4015  elseif strcmpi(HDR.AIF.CompressionType,'fl64');
4016  HDR.GDFTYP = 'float64';
4017  HDR.Cal = 1;
4018  elseif strcmpi(HDR.AIF.CompressionType,'alaw');
4019  HDR.GDFTYP = 'uint8';
4020  HDR.AS.bpb = HDR.NS;
4021  %HDR.FILE.TYPE = 1;
4022  fprintf(HDR.FILE.stderr,'Warning SOPEN AIFC-format: data not scaled because of CompressionType ALAW\n');
4023  HDR.FLAG.UCAL = 1;
4024  elseif strcmpi(HDR.AIF.CompressionType,'ulaw');
4025  HDR.GDFTYP = 'uint8';
4026  HDR.AS.bpb = HDR.NS;
4027  HDR.FILE.TYPE = 1;
4028 
4029  %%%% other compression types - currently not supported, probably obsolete
4030  %elseif strcmpi(HDR.AIF.CompressionType,'DWVW');
4031  %elseif strcmpi(HDR.AIF.CompressionType,'GSM');
4032  %elseif strcmpi(HDR.AIF.CompressionType,'ACE2');
4033  %elseif strcmpi(HDR.AIF.CompressionType,'ACE8');
4034  %elseif strcmpi(HDR.AIF.CompressionType,'ima4');
4035  %elseif strcmpi(HDR.AIF.CompressionType,'MAC3');
4036  %elseif strcmpi(HDR.AIF.CompressionType,'MAC6');
4037  %elseif strcmpi(HDR.AIF.CompressionType,'Qclp');
4038  %elseif strcmpi(HDR.AIF.CompressionType,'QDMC');
4039  %elseif strcmpi(HDR.AIF.CompressionType,'rt24');
4040  %elseif strcmpi(HDR.AIF.CompressionType,'rt29');
4041  else
4042  fprintf(HDR.FILE.stderr,'Warning SOPEN AIFC-format: CompressionType %s is not supported\n', HDR.AIF.CompressionType);
4043  end;
4044  end;
4045 
4046  elseif strcmpi(tag,'SSND');
4047  HDR.AIF.offset = fread(HDR.FILE.FID,1,'int32');
4048  HDR.AIF.blocksize= fread(HDR.FILE.FID,1,'int32');
4049  HDR.AIF.SSND.tagsize = tagsize-8;
4050 
4051  HDR.HeadLen = filepos+8;
4052  %HDR.AIF.sounddata= fread(HDR.FILE.FID,tagsize-8,'uint8');
4053 
4054  elseif strcmpi(tag,'FVER');
4055  if tagsize<4,
4056  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: incorrect tag size\n');
4057  return;
4058  end;
4059  HDR.AIF.TimeStamp = fread(HDR.FILE.FID,1,'uint32');
4060 
4061  elseif strcmp(tag,'DATA') && strcmp(HDR.TYPE,'AIF') ; % AIF uses upper case, there is a potential conflict with WAV using lower case data
4062  HDR.AIF.DATA = fread(HDR.FILE.FID,[1,tagsize],'uint8');
4063 
4064  elseif strcmpi(tag,'INST'); % not sure if this is ok !
4065  %HDR.AIF.INST = fread(HDR.FILE.FID,[1,tagsize],'uint8');
4066  %HDR.AIF.INST.notes = fread(HDR.FILE.FID,[1,6],'uint8');
4067  HDR.AIF.INST.baseNote = fread(HDR.FILE.FID,1,'uint8');
4068  HDR.AIF.INST.detune = fread(HDR.FILE.FID,1,'uint8');
4069  HDR.AIF.INST.lowNote = fread(HDR.FILE.FID,1,'uint8');
4070  HDR.AIF.INST.highNote = fread(HDR.FILE.FID,1,'uint8');
4071  HDR.AIF.INST.lowvelocity = fread(HDR.FILE.FID,1,'uint8');
4072  HDR.AIF.INST.highvelocity = fread(HDR.FILE.FID,1,'uint8');
4073  HDR.AIF.INST.gain = fread(HDR.FILE.FID,1,'int16');
4074 
4075  HDR.AIF.INST.sustainLoop_PlayMode = fread(HDR.FILE.FID,1,'uint8');
4076  HDR.AIF.INST.sustainLoop = fread(HDR.FILE.FID,2,'uint16');
4077  HDR.AIF.INST.releaseLoop_PlayMode = fread(HDR.FILE.FID,1,'uint8');
4078  HDR.AIF.INST.releaseLoop = fread(HDR.FILE.FID,2,'uint16');
4079 
4080  elseif strcmpi(tag,'MIDI');
4081  HDR.AIF.MIDI = fread(HDR.FILE.FID,[1,tagsize],'uint8');
4082 
4083  elseif strcmpi(tag,'AESD');
4084  HDR.AIF.AESD = fread(HDR.FILE.FID,[1,tagsize],'uint8');
4085 
4086  elseif strcmpi(tag,'APPL');
4087  HDR.AIF.APPL = fread(HDR.FILE.FID,[1,tagsize],'uint8');
4088 
4089  elseif strcmpi(tag,'COMT');
4090  HDR.AIF.COMT = fread(HDR.FILE.FID,[1,tagsize],'uint8');
4091 
4092  elseif strcmpi(tag,'ANNO');
4093  HDR.AIF.ANNO = char(fread(HDR.FILE.FID,[1,tagsize],'uint8'));
4094 
4095  elseif strcmpi(tag,'(c) ');
4096  [HDR.Copyright,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4097 
4098  %%%% WAV - section %%%%%
4099  elseif strcmpi(tag,'fmt ')
4100  if tagsize<14,
4101  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: incorrect tag size\n');
4102  return;
4103  end;
4104  HDR.WAV.Format = fread(HDR.FILE.FID,1,'uint16');
4105  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
4106  HDR.SampleRate = fread(HDR.FILE.FID,1,'uint32');
4107  HDR.WAV.AvgBytesPerSec = fread(HDR.FILE.FID,1,'uint32');
4108  HDR.WAV.BlockAlign = fread(HDR.FILE.FID,1,'uint16');
4109  if HDR.WAV.Format==1, % PCM format
4110  HDR.Bits = fread(HDR.FILE.FID,1,'uint16');
4111  HDR.Off = 0;
4112  HDR.Cal = 2^(1-8*ceil(HDR.Bits/8));
4113  if HDR.Bits<=8,
4114  HDR.GDFTYP = 'uint8';
4115  HDR.Off = 1;
4116  %HDR.Cal = HDR.Cal*2;
4117  elseif HDR.Bits<=16,
4118  HDR.GDFTYP = 'int16';
4119  elseif HDR.Bits<=24,
4120  HDR.GDFTYP = 'bit24';
4121  elseif HDR.Bits<=32,
4122  HDR.GDFTYP = 'int32';
4123  end;
4124  else
4125  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: format type %i not supported\n',HDR.WAV.Format);
4126  fclose(HDR.FILE.FID);
4127  return;
4128  end;
4129  if tagsize>16,
4130  HDR.WAV.cbSize = fread(HDR.FILE.FID,1,'uint16');
4131  end;
4132 
4133  elseif strcmp(tag,'data') && strcmp(HDR.TYPE,'WAV') ; % AIF uses upper case, there is a potential conflict with WAV using lower case data
4134  HDR.HeadLen = filepos;
4135  if HDR.WAV.Format == 1,
4136  HDR.AS.bpb = HDR.NS * ceil(HDR.Bits/8);
4137  HDR.SPR = tagsize/HDR.AS.bpb;
4138  HDR.Dur = HDR.SPR/HDR.SampleRate;
4139 
4140  else
4141  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: format type %i not supported\n',HDR.WAV.Format);
4142  end;
4143 
4144  elseif strcmpi(tag,'fact');
4145  if tagsize<4,
4146  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: incorrect tag size\n');
4147  return;
4148  end;
4149  [HDR.RIFF.FACT,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4150 
4151  elseif strcmpi(tag,'disp');
4152  if tagsize<8,
4153  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: incorrect tag size\n');
4154  return;
4155  end;
4156  [tmp,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4157  HDR.RIFF.DISP = char(tmp);
4158  if ~all(tmp(1:8)==[0,1,0,0,0,0,1,1])
4159  HDR.RIFF.DISPTEXT = char(tmp(5:length(tmp)));
4160  end;
4161 
4162  elseif strcmpi(tag,'list');
4163  if tagsize<4,
4164  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: incorrect tag size\n');
4165  return;
4166  end;
4167 
4168  if ~isfield(HDR,'RIFF');
4169  HDR.RIFF.N1 = 1;
4170  elseif ~isfield(HDR.RIFF,'N');
4171  HDR.RIFF.N1 = 1;
4172  else
4173  HDR.RIFF.N1 = HDR.RIFF.N1+1;
4174  end;
4175 
4176  %HDR.RIFF.list = char(tmp);
4177  [tag,c1] = fread(HDR.FILE.FID,[1,4],'uint8');
4178  tag = char(tag);
4179  [val,c2] = fread(HDR.FILE.FID,[1,tagsize-4],'uint8');
4180  HDR.RIFF = setfield(HDR.RIFF,tag,char(val));
4181  if 1,
4182  elseif strcmp(tag,'INFO'),
4183  HDR.RIFF.INFO=val;
4184  elseif strcmp(tag,'movi'),
4185  HDR.RIFF.movi = val;
4186  elseif strcmp(tag,'hdrl'),
4187  HDR.RIFF.hdr1 = val;
4188 
4189  elseif 0,strcmp(tag,'mdat'),
4190  %HDR.RIFF.mdat = val;
4191  else
4192  fprintf(HDR.FILE.stderr,'Warning SOPEN Type=RIFF: unknown Tag %s.\n',tag);
4193  end;
4194  % AVI audio video interleave format
4195  elseif strcmpi(tag,'movi');
4196  if tagsize<4,
4197  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4198  return;
4199  end;
4200  [HDR.RIFF.movi,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4201 
4202  elseif strcmp(tag,'idx1');
4203  if tagsize<4,
4204  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4205  return;
4206  end;
4207  [HDR.RIFF.idx1,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4208 
4209  elseif strcmpi(tag,'junk');
4210  if tagsize<4,
4211  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4212  return;
4213  end;
4214  [HDR.RIFF.junk,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4215 
4216  elseif strcmpi(tag,'MARK');
4217  if tagsize<4,
4218  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4219  return;
4220  end;
4221  [HDR.RIFF.MARK,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4222 
4223  elseif strcmpi(tag,'AUTH');
4224  if tagsize<4,
4225  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4226  return;
4227  end;
4228  [HDR.RIFF.AUTH,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4229 
4230  elseif strcmpi(tag,'NAME');
4231  if tagsize<4,
4232  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4233  return;
4234  end;
4235  [HDR.RIFF.NAME,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4236 
4237  elseif strcmpi(tag,'afsp');
4238  if tagsize<4,
4239  fprintf(HDR.FILE.stderr,'Error SOPEN AVI: incorrect tag size\n');
4240  return;
4241  end;
4242  [HDR.RIFF.afsp,c] = fread(HDR.FILE.FID,[1,tagsize],'uint8=>char');
4243 
4244  elseif ~isempty(tagsize)
4245  fprintf(HDR.FILE.stderr,'Warning SOPEN AIF/WAV: unknown TAG in %s: %s(%i) \n',HDR.FileName,tag,tagsize);
4246  [tmp,c] = fread(HDR.FILE.FID,[1,min(100,tagsize)],'uint8');
4247  fprintf(HDR.FILE.stderr,'%s\n',char(tmp));
4248  end;
4249 
4250  if ~isempty(tagsize)
4251  status = fseek(HDR.FILE.FID,filepos+tagsize0,'bof');
4252  if status,
4253  fprintf(HDR.FILE.stderr,'Warning SOPEN (WAF/AIF/AVI): fseek failed. Probably tagsize larger than end-of-file and/or file corrupted\n');
4254  fseek(HDR.FILE.FID,0,'eof');
4255  end;
4256  end;
4257  [tmp,c] = fread(HDR.FILE.FID,[1,4],'uint8');
4258  end;
4259 
4260  if strncmpi(char(tmp),'AIF',3),
4261  if HDR.AIF.SSND.tagsize~=HDR.SPR*HDR.AS.bpb,
4262  fprintf(HDR.FILE.stderr,'Warning SOPEN AIF: Number of samples do not fit %i vs %i\n',tmp,HDR.SPR);
4263  end;
4264  end;
4265 
4266  if ~isfield(HDR,'HeadLen')
4267  fprintf(HDR.FILE.stderr,'Warning SOPEN AIF/WAV: missing data section\n');
4268  else
4269  status = fseek(HDR.FILE.FID, HDR.HeadLen, 'bof');
4270  end;
4271 
4272  if isnan(HDR.NS), return; end;
4273  [d,l,d1,b,HDR.GDFTYP] = gdfdatatype(HDR.GDFTYP);
4274 
4275  % define Calib: implements S = (S+.5)*HDR.Cal - HDR.Off;
4276  HDR.Calib = [repmat(.5,1,HDR.NS);eye(HDR.NS)] * diag(repmat(HDR.Cal,1,HDR.NS));
4277  HDR.Calib(1,:) = HDR.Calib(1,:) - HDR.Off;
4278  HDR.Label = repmat({' '},HDR.NS,1);
4279 
4280  HDR.FILE.POS = 0;
4281  HDR.FILE.OPEN = 1;
4282  HDR.NRec = 1;
4283 
4284 
4285  elseif ~isempty(findstr(HDR.FILE.PERMISSION,'w')), %%%%% WRITE
4286  if any(HDR.FILE.PERMISSION=='z'),
4287  fprintf(HDR.FILE.stderr,'WARNING SOPEN (AIF/WAV/IIF,AVI) "wz": Writing to gzipped AIF file not supported (yet).\n');
4288  HDR.FILE.PERMISSION = 'w';
4289  end;
4290  if strcmp(HDR.TYPE,'AIF')
4291  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
4292  else
4293  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
4294  end;
4295  HDR.FILE.OPEN = 3;
4296  if strcmp(HDR.TYPE,'AIF')
4297  fwrite(HDR.FILE.FID,'FORM','uint8');
4298  fwrite(HDR.FILE.FID,0,'uint32');
4299  fwrite(HDR.FILE.FID,'AIFFCOMM','uint8');
4300  fwrite(HDR.FILE.FID,18,'uint32');
4301  fwrite(HDR.FILE.FID,HDR.NS,'uint16');
4302  fwrite(HDR.FILE.FID,HDR.SPR,'uint32');
4303  fwrite(HDR.FILE.FID,HDR.Bits,'uint16');
4304 
4305  %HDR.GDFTYP = ceil(HDR.Bits/8)*2-1; % unsigned integer of appropriate size;
4306  HDR.GDFTYP = ['ubit', int2str(HDR.Bits)];
4307  HDR.Cal = 2^(1-HDR.Bits);
4308  HDR.AS.bpb = ceil(HDR.Bits/8)*HDR.NS;
4309 
4310  [f,e] = log2(HDR.SampleRate);
4311  tmp = e + 2^14 - 1;
4312  if tmp<0, tmp = tmp + 2^15; end;
4313  fwrite(HDR.FILE.FID,tmp,'uint16');
4314  fwrite(HDR.FILE.FID,[bitshift(abs(f),31),bitshift(abs(f),63)],'uint32');
4315 
4316  HDR.AS.bpb = HDR.NS * ceil(HDR.Bits/8);
4317  tagsize = HDR.SPR*HDR.AS.bpb + 8;
4318  HDR.Dur = HDR.SPR/HDR.SampleRate;
4319  HDR.AS.endpos = HDR.SPR;
4320 
4321  if 0; isfield(HDR.AIF,'INST'); % does not work yet
4322  fwrite(HDR.FILE.FID,'SSND','uint8');
4323  fwrite(HDR.FILE.FID,20,'uint32');
4324 
4325  fwrite(HDR.FILE.FID,HDR.AIF.INST.baseNote,'uint8');
4326  fwrite(HDR.FILE.FID,HDR.AIF.INST.detune,'uint8');
4327  fwrite(HDR.FILE.FID,HDR.AIF.INST.lowNote,'uint8');
4328  fwrite(HDR.FILE.FID,HDR.AIF.INST.highNote,'uint8');
4329  fwrite(HDR.FILE.FID,HDR.AIF.INST.lowvelocity,'uint8');
4330  fwrite(HDR.FILE.FID,HDR.AIF.INST.highvelocity,'uint8');
4331  fwrite(HDR.FILE.FID,HDR.AIF.INST.gain,'int16');
4332 
4333  fwrite(HDR.FILE.FID,HDR.AIF.INST.sustainLoop_PlayMode,'uint8');
4334  fwrite(HDR.FILE.FID,HDR.AIF.INST.sustainLoop,'uint16');
4335  fwrite(HDR.FILE.FID,HDR.AIF.INST.releaseLoop_PlayMode,'uint8');
4336  fwrite(HDR.FILE.FID,HDR.AIF.INST.releaseLoop,'uint16');
4337  end;
4338 
4339  fwrite(HDR.FILE.FID,'SSND','uint8');
4340  HDR.WAV.posis = [4, ftell(HDR.FILE.FID)];
4341  fwrite(HDR.FILE.FID,[tagsize,0,0],'uint32');
4342 
4343  HDR.HeadLen = ftell(HDR.FILE.FID);
4344 
4345  elseif strcmp(HDR.TYPE,'WAV'),
4346  fwrite(HDR.FILE.FID,'RIFF','uint8');
4347  fwrite(HDR.FILE.FID,0,'uint32');
4348  fwrite(HDR.FILE.FID,'WAVEfmt ','uint8');
4349  fwrite(HDR.FILE.FID,16,'uint32');
4350  fwrite(HDR.FILE.FID,[1,HDR.NS],'uint16');
4351  fwrite(HDR.FILE.FID,[HDR.SampleRate,HDR.Bits/8*HDR.NS*HDR.SampleRate],'uint32');
4352  fwrite(HDR.FILE.FID,[HDR.Bits/8*HDR.NS,HDR.Bits],'uint16');
4353 
4354  if isfield(HDR,'Copyright'),
4355  fwrite(HDR.FILE.FID,'(c) ','uint8');
4356  if rem(length(HDR.Copyright),2),
4357  HDR.Copyright(length(HDR.Copyright)+1)=' ';
4358  end;
4359  fwrite(HDR.FILE.FID,length(HDR.Copyright),'uint32');
4360  fwrite(HDR.FILE.FID,HDR.Copyright,'uint8');
4361  end;
4362 
4363  HDR.Off = 0;
4364  HDR.Cal = 2^(1-8*ceil(HDR.Bits/8));
4365  if HDR.Bits<=8,
4366  HDR.GDFTYP = 'uint8';
4367  HDR.Off = 1;
4368  %HDR.Cal = HDR.Cal*2;
4369  elseif HDR.Bits<=16,
4370  HDR.GDFTYP = 'int16';
4371  elseif HDR.Bits<=24,
4372  HDR.GDFTYP = 'bit24';
4373  elseif HDR.Bits<=32,
4374  HDR.GDFTYP = 'int32';
4375  end;
4376 
4377  HDR.AS.bpb = HDR.NS * ceil(HDR.Bits/8);
4378  tagsize = HDR.SPR*HDR.AS.bpb;
4379  HDR.Dur = HDR.SPR/HDR.SampleRate;
4380  HDR.AS.endpos = HDR.SPR;
4381 
4382  fwrite(HDR.FILE.FID,'data','uint8');
4383  HDR.WAV.posis=[4,ftell(HDR.FILE.FID)];
4384  fwrite(HDR.FILE.FID,tagsize,'uint32');
4385 
4386  if rem(tagsize,2)
4387  fprintf(HDR.FILE.stderr,'Error SOPEN WAV: data section has odd number of samples.\n. This violates the WAV specification\n');
4388  fclose(HDR.FILE.FID);
4389  HDR.FILE.OPEN = 0;
4390  return;
4391  end;
4392 
4393  HDR.HeadLen = ftell(HDR.FILE.FID);
4394  end;
4395  end;
4396 
4397 
4398 elseif strcmp(HDR.TYPE,'FLAC'),
4399  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
4400 
4401  if HDR.FILE.FID > 0,
4402  HDR.magic = fread(HDR.FILE.FID,[1,4],'uint8');
4403 
4404  % read METADATA_BLOCK
4405  % read METADATA_BLOCK_HEADER
4406  tmp = fread(HDR.FILE.FID,[1,4],'uint8')
4407  while (tmp(1)<128),
4408  BLOCK_TYPE = mod(tmp(1),128);
4409  LEN = tmp(2:4)*2.^[0;8;16];
4410  POS = ftell(HDR.FILE.FID);
4411  if (BLOCK_TYPE == 0), % STREAMINFO
4412  minblksz = fread(HDR.FILE.FID,1,'uint16')
4413  maxblksz = fread(HDR.FILE.FID,1,'uint16')
4414  minfrmsz = 2.^[0,8,16]*fread(HDR.FILE.FID,3,'uint8')
4415  maxfrmsz = 2.^[0,8,16]*fread(HDR.FILE.FID,3,'uint8')
4416  %Fs = fread(HDR.FILE.FID,3,'ubit20')
4417  elseif (BLOCK_TYPE == 1), % PADDING
4418  elseif (BLOCK_TYPE == 2), % APPLICATION
4419  HDR.FLAC.Reg.Appl.ID = fread(HDR.FILE.FID,1,'uint32')
4420  elseif (BLOCK_TYPE == 3), % SEEKTABLE
4421  HDR.EVENT.N = LEN/18;
4422  for k = 1:LEN/18,
4423  HDR.EVENT.POS(k) = 2.^[0,32]*fread(HDR.FILE.FID,2,'uint32');
4424  HDR.EVENT.DUR(k) = 2.^[0,32]*fread(HDR.FILE.FID,2,'uint32');
4425  HDR.EVENT.nos(k) = fread(HDR.FILE.FID,1,'uint16');
4426 
4427  end;
4428  elseif (BLOCK_TYPE == 4), % VORBIS_COMMENT
4429  elseif (BLOCK_TYPE == 5), % CUESHEET
4430  else % reserved
4431  end;
4432 
4433  fseek(HDR.FILE.FID, POS+LEN,'bof');
4434  tmp = fread(HDR.FILE.FID,[1,4],'uint8')
4435  end;
4436 
4437  % read METADATA_BLOCK_DATA
4438 
4439  % read METADATA_BLOCK_DATA
4440  % read METADATA_BLOCK_STREAMINFO
4441  % read METADATA_BLOCK_PADDING
4442  % read METADATA_BLOCK_APPLICATION
4443  % read METADATA_BLOCK_SEEKTABLE
4444  % read METADATA_BLOCK_COMMENT
4445  % read METADATA_BLOCK_CUESHEET
4446 
4447  % read FRAME
4448  % read FRAME_HEADER
4449  % read FRAME_SUBFRAME
4450  % read FRAME_SUBFRAME_HEADER
4451  % read FRAME_HEADER
4452 
4453  fclose(HDR.FILE.FID)
4454 
4455  fprintf(HDR.FILE.stderr,'Warning SOPEN: FLAC not ready for use\n');
4456  return;
4457  end;
4458 
4459 
4460 elseif strcmp(HDR.TYPE,'OGG'),
4461  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
4462 
4463  if HDR.FILE.FID > 0,
4464  % chunk header
4465  tmp = fread(HDR.FILE.FID,1,'uint8');
4466  QualityIndex = mod(tmp(1),64);
4467  if (tmp(1)<128), % golden frame
4468  tmp = fread(HDR.FILE.FID,2,'uint8');
4469  HDR.VERSION = tmp(1);
4470  HDR.VP3.Version = floor(tmp(2)/8);
4471  HDR.OGG.KeyFrameCodingMethod = floor(mod(tmp(2),8)/4);
4472  end;
4473 
4474  % block coding information
4475  % coding mode info
4476  % motion vectors
4477  % DC coefficients
4478  % DC coefficients
4479  % 1st AC coefficients
4480  % 2nd AC coefficients
4481  % ...
4482  % 63rd AC coefficient
4483 
4484  fclose(HDR.FILE.FID);
4485  fprintf(HDR.FILE.stderr,'Warning SOPEN: OGG not ready for use\n');
4486  return;
4487  end;
4488 
4489 
4490 elseif strcmp(HDR.TYPE,'Persyst'),
4491  if any(HDR.FILE.PERMISSION=='r');
4492  [HDR.FILE.FID] = fopen(HDR.FileName,['rb']);
4493  if HDR.FILE.FID < 0,
4494  HDR.ErrNum = [32,HDR.ErrNum];
4495  return;
4496  end;
4497  [H1,count] = fread(HDR.FILE.FID, [1,inf], 'uint8=>char');
4498  fclose(HDR.FILE.FID);
4499 
4500  HDR.EVENT.N = 0;
4501  HDR.NS = 0;
4502  HDR.Endianity ='ieee-le';
4503  HDR.FLAG.OVERFLOWDETECTION = 0;
4504  flag_interleaved = 1;
4505  flag_nk = 0;
4506  status = 0;
4507  line = H1;
4508  Desc = {};
4509  HDR.EVENT.POS = [];
4510  HDR.EVENT.DUR = [];
4511  HDR.EVENT.CHN = [];
4512  HDR.EVENT.TYP = [];
4513  while (~isempty(line))
4514  [line,H1] = strtok(H1,char([10,13]));
4515  if strcmp(line,'[FileInfo]')
4516  status = 1;
4517  elseif strcmp(line,'[ChannelMap]')
4518  status = 2;
4519 %% HDR.AS.bpb = HDR.NS* %% todo
4520  HDR.PhysDimCode = zeros(HDR.NS,1); % unknown
4521  elseif strcmp(line,'[Sheets]')
4522  status = 3;
4523  elseif strcmp(line,'[Comments]')
4524  status = 4;
4525  elseif strcmp(line,'[Patient]')
4526  status = 5;
4527  elseif strcmp(line,'[SampleTimes]')
4528  status = 6;
4529  elseif isempty(line)
4530  ; %% ignore
4531  elseif isempty(line)
4532  status = -1;
4533  else
4534  switch (status)
4535  case {1}
4536  [tag,val]=strtok(line,'=');
4537  val = val(2:end);
4538  switch (tag)
4539  case {'File'}
4540  val(val=='\')='/';
4541  ix = find(val=='/');
4542  if isempty(ix), ix = 0; end;
4543  datfile = val(ix(end)+1:end);
4544  case {'FileType'}
4545  flag_interleaved = strcmp(val,'Interleaved');
4546  flag_NK = strcmp(val,'NihonKohden');
4547  case {'SamplingRate'}
4548  HDR.SampleRate = str2double(val);
4549  HDR.EVENT.SampleRate = HDR.SampleRate;
4550  case {'Calibration'}
4551  HDR.Cal = str2double(val);
4552  case {'WaveformCount'}
4553  HDR.NS = str2double(val);
4554  case {'DataType'}
4555  switch (val)
4556  case {'0'}
4557  HDR.GDFTYP = 3;
4558  HDR.AS.bpb = 2*HDR.NS;
4559  case {'4'}
4560  HDR.GDFTYP = 3;
4561  HDR.AS.bpb = 2*HDR.NS;
4562  HDR.Endianity = 'ieee-be';
4563  case {'6'}
4564  HDR.GDFTYP = 1;
4565  HDR.AS.bpb = HDR.NS;
4566  otherwise
4567 
4568  end;
4569  end;
4570  case {2}
4571  [tag,val]=strtok(line,'=');
4572  ch = str2double(val(2:end));
4573  HDR.Label{ch} = tag;
4574  case {3}
4575  case {4}
4576  HDR.EVENT.N = HDR.EVENT.N + 1;
4577  [pos,ll]=strtok(line,',');
4578  [dur,ll]=strtok(ll,',');
4579  [ign,ll]=strtok(ll,',');
4580  [ign,ll]=strtok(ll,',');
4581  Desc{HDR.EVENT.N} = ll(2:end);
4582  HDR.EVENT.POS(HDR.EVENT.N) = str2double(pos)*HDR.EVENT.SampleRate;
4583  HDR.EVENT.DUR(HDR.EVENT.N) = str2double(dur)*HDR.EVENT.SampleRate;
4584  case {5}
4585  [tag,val]=strtok(line,'=');
4586  val = val(2:end);
4587  switch (tag)
4588  case {'First'}
4589  FirstName = val;
4590  case {'MI'}
4591  MiddleName = val;
4592  case {'Last'}
4593  SurName = val;
4594  case {'Hand'}
4595  HDR.Patient.Handedness = any(val(1)=='rR') + any(val(1)=='lL') * 2;
4596  case {'Sex'}
4597  HDR.Patient.Sex = any(val(1)=='mM') + any(val(1)=='fF') * 2;
4598  case {'BirthDate'}
4599  val(val==47)=' ';
4600  t = str2double(val);
4601  if t(3) < 30, c = 2000;
4602  else c = 1900;
4603  end;
4604  HDR.Patient.Birthday = [t(3)+c,t(1),t(2), 0, 0, 0];
4605  case {'TestDate'}
4606  val(val=='/')=' ';
4607  t = str2double(val);
4608  if t(3) < 80, c = 2000;
4609  else c = 1900;
4610  end;
4611  HDR.T0(1:3) = [t(3)+c,t(1),t(2)];
4612  case {'TestTime'}
4613  val(val==':')=' ';
4614  t = str2double(val);
4615  HDR.T0(4:6) = t;
4616  case {'ID'}
4617  HDR.Patient.Id = val;
4618  %case {'Physician'}
4619  % This is not really needed
4620  % HDR.REC.Doctor = val;
4621  case {'Technician'}
4622  HDR.REC.Technician = val;
4623  case {'Medications'}
4624  HDR.Patient.Medication = val;
4625  end;
4626  case {6}
4627  end;
4628  end;
4629  end;
4630 
4631  if (flag_nk)
4632  HDR = sopen(fullfile(HDR.FILE.Path,datfile));
4633  end;
4634  HDR.FILE.POS = 0;
4635  HDR.FILE.Ext = '.dat';
4636  fid = fopen(fullfile(HDR.FILE.Path,datfile),'r', HDR.Endianity);
4637  if HDR.GDFTYP==3,
4638  s = fread(fid,inf,'int16');
4639  elseif HDR.GDFTYP==1
4640  s = fread(fid,inf,'int8');
4641  end
4642  fclose(fid);
4643 
4644  if flag_interleaved,
4645  HDR.data = reshape(s,HDR.NS,[])';
4646  else
4647  HDR.data = reshape(s,[],HDR.NS);
4648  end;
4649  HDR.data = HDR.data*HDR.Cal;
4650 
4651  HDR.SPR = 1;
4652  HDR.NRec = size(HDR.data,1);
4653  HDR.TYPE = 'native';
4654  HDR.DigMax = max(HDR.data);
4655  HDR.DigMin = min(HDR.data);
4656  HDR.PhysMax = HDR.Cal*HDR.DigMax;
4657  HDR.PhysMin = HDR.Cal*HDR.DigMin;
4658 
4659  HDR.Calib = sparse(2:HDR.NS+1, 1:HDR.NS, HDR.Cal);
4660 
4661  [HDR.EVENT.CodeDesc, j, HDR.EVENT.TYP] = unique(Desc);
4662  HDR.EVENT.CHN = zeros(size(HDR.EVENT.POS));
4663  end
4664 
4665 
4666 elseif strcmp(HDR.TYPE,'RMF'),
4667  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
4668 
4669  if HDR.FILE.FID > 0,
4670  fclose(HDR.FILE.FID)
4671 
4672  fprintf(HDR.FILE.stderr,'Warning SOPEN: RMF not ready for use\n');
4673  return;
4674  end;
4675 
4676 
4677 elseif strcmp(HDR.TYPE,'EGI'),
4678  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
4679 
4680  HDR.VERSION = fread(HDR.FILE.FID,1,'uint32');
4681 
4682  if ~(HDR.VERSION >= 2 & HDR.VERSION <= 7),
4683  % fprintf(HDR.FILE.stderr,'EGI Simple Binary Versions 2-7 supported only.\n');
4684  end;
4685 
4686  HDR.T0 = fread(HDR.FILE.FID,[1,6],'uint16');
4687  millisecond = fread(HDR.FILE.FID,1,'uint32');
4688  HDR.T0(6) = HDR.T0(6) + millisecond/1000;
4689 
4690  HDR.SampleRate = fread(HDR.FILE.FID,1,'uint16');
4691  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
4692  HDR.gain = fread(HDR.FILE.FID,1,'uint16');
4693  HDR.Bits = fread(HDR.FILE.FID,1,'uint16');
4694  HDR.DigMax = 2^HDR.Bits;
4695  HDR.PhysMax = fread(HDR.FILE.FID,1,'uint16');
4696  if ( HDR.Bits ~= 0 && HDR.PhysMax ~= 0 )
4697  HDR.Cal = repmat(HDR.PhysMax/HDR.DigMax,1,HDR.NS);
4698  else
4699  HDR.Cal = ones(1,HDR.NS);
4700  end;
4701  HDR.Off = zeros(1,HDR.NS);
4702  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal,HDR.NS+1,HDR.NS);
4703  HDR.PhysDim = 'uV';
4704  for k=1:HDR.NS,
4705  HDR.Label{k}=sprintf('# %3i',k);
4706  end;
4707 
4708  HDR.categories = 0;
4709  HDR.EGI.catname= {};
4710 
4711  if any(HDR.VERSION==[2,4,6]),
4712  HDR.NRec = fread(HDR.FILE.FID, 1 ,'int32');
4713  HDR.EGI.N = fread(HDR.FILE.FID,1,'int16');
4714  HDR.SPR = 1;
4715  HDR.FLAG.TRIGGERED = logical(0);
4716  HDR.AS.spb = HDR.NS+HDR.EGI.N;
4717  HDR.AS.endpos = HDR.SPR*HDR.NRec;
4718  HDR.Dur = 1/HDR.SampleRate;
4719  elseif any(HDR.VERSION==[3,5,7]),
4720  HDR.EGI.categories = fread(HDR.FILE.FID,1,'uint16');
4721  if (HDR.EGI.categories),
4722  for i=1:HDR.EGI.categories,
4723  catname_len(i) = fread(HDR.FILE.FID,1,'uint8');
4724  HDR.EGI.catname{i} = char(fread(HDR.FILE.FID,catname_len(i),'uint8'))';
4725  end
4726  end
4727  HDR.NRec = fread(HDR.FILE.FID,1,'int16');
4728  HDR.SPR = fread(HDR.FILE.FID,1,'int32');
4729  HDR.EGI.N = fread(HDR.FILE.FID,1,'int16');
4730  HDR.FLAG.TRIGGERED = logical(1);
4731  HDR.AS.spb = HDR.SPR*(HDR.NS+HDR.EGI.N);
4732  HDR.AS.endpos = HDR.NRec*HDR.SPR;
4733  HDR.Dur = HDR.SPR/HDR.SampleRate;
4734  else
4735  fprintf(HDR.FILE.stderr,'Invalid EGI version %i\n',HDR.VERSION);
4736  return;
4737  end
4738 
4739  % get datatype from version number
4740  if any(HDR.VERSION==[2,3]),
4741  HDR.GDFTYP = 3; % 'int16';
4742  elseif any(HDR.VERSION==[4,5]),
4743  HDR.GDFTYP = 16; % 'float32';
4744  elseif any(HDR.VERSION==[6,7]),
4745  HDR.GDFTYP = 17; % 'float64';
4746  else
4747  error('Unknown data format');
4748  end
4749  HDR.AS.bpb = HDR.AS.spb*GDFTYP_BYTE(HDR.GDFTYP+1) + 6*HDR.FLAG.TRIGGERED;
4750 
4751  tmp = fread(HDR.FILE.FID,[4,HDR.EGI.N],'uint8=>char');
4752  HDR.EVENT.CodeDesc = cellstr(tmp');
4753 
4754  HDR.HeadLen = ftell(HDR.FILE.FID);
4755  HDR.FILE.POS = 0;
4756  HDR.FILE.OPEN = 1;
4757 
4758  % extract event information
4759  if (HDR.EGI.N>0),
4760  if HDR.FLAG.TRIGGERED,
4761  fseek(HDR.FILE.FID,HDR.HeadLen + 6 + HDR.NS*GDFTYP_BYTE(HDR.GDFTYP+1),'bof');
4762  typ = [int2str(HDR.EGI.N),'*',gdfdatatype(HDR.GDFTYP),'=>',gdfdatatype(HDR.GDFTYP)]
4763  [s,count] = fread(HDR.FILE.FID,inf, typ, 6+HDR.NS*GDFTYP_BYTE(HDR.GDFTYP+1));
4764  else
4765  fseek(HDR.FILE.FID,HDR.HeadLen + HDR.NS*GDFTYP_BYTE(HDR.GDFTYP+1),'bof');
4766  typ = [int2str(HDR.EGI.N),'*',gdfdatatype(HDR.GDFTYP),'=>',gdfdatatype(HDR.GDFTYP)];
4767  [s,count] = fread(HDR.FILE.FID,inf, typ, HDR.NS*GDFTYP_BYTE(HDR.GDFTYP+1));
4768  end;
4769 
4770  s = reshape(s, HDR.EGI.N, length(s)/HDR.EGI.N)';
4771  POS = [];
4772  CHN = [];
4773  DUR = [];
4774  TYP = [];
4775  for k = 1:HDR.EGI.N,
4776  ix = find(diff(s(:,k)));
4777  ix = diff(double([s(:,k);s(1,k)]==s(1,k))); % labels
4778  POS = [POS; find(ix>0)+1];
4779  TYP = [TYP; repmat(k,sum(ix>0),1)];
4780  CHN = [CHN; repmat(0,sum(ix>0),1)];
4781  DUR = [DUR; find(ix>0)-find(ix<0)];
4782  end
4783  HDR.EVENT.POS = POS;
4784  HDR.EVENT.TYP = TYP;
4785  HDR.EVENT.CHN = CHN;
4786  HDR.EVENT.DUR = DUR;
4787  end;
4788  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
4789 
4790 
4791 elseif strcmp(HDR.TYPE,'TEAM'), % Nicolet TEAM file format
4792  % implementation of this format is not finished yet.
4793 
4794  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
4795  %%%%% X-Header %%%%%
4796  HDR.VERSION = fread(HDR.FILE.FID,1,'int16');
4797  HDR.NS = fread(HDR.FILE.FID,1,'int16');
4798  HDR.NRec = fread(HDR.FILE.FID,1,'int16');
4799  HDR.TEAM.Length = fread(HDR.FILE.FID,1,'int32');
4800  HDR.TEAM.NSKIP = fread(HDR.FILE.FID,1,'int32');
4801  HDR.SPR = fread(HDR.FILE.FID,1,'int32');
4802  HDR.Samptype = fread(HDR.FILE.FID,1,'int16');
4803  if HDR.Samptype==2, HDR.GDFTYP = 'int16';
4804  elseif HDR.Samptype==4, HDR.GDFTYP = 'float32';
4805  else
4806  fprintf(HDR.FILE.stderr,'Error SOPEN TEAM-format: invalid file\n');
4807  fclose(HDR.FILE.FID);
4808  return;
4809  end;
4810  HDR.XLabel = fread(HDR.FILE.FID,[1,8],'uint8');
4811  HDR.X0 = fread(HDR.FILE.FID,1,'float');
4812  HDR.TEAM.Xstep = fread(HDR.FILE.FID,1,'float');
4813  HDR.SampleRate = 1/HDR.TEAM.Xstep;
4814  tmp = fread(HDR.FILE.FID,[1,6],'uint8');
4815  tmp(1) = tmp(1) + 1980;
4816  HDR.T0 = tmp([4,5,6,1,2,3]);
4817 
4818  HDR.EVENT.N = fread(HDR.FILE.FID,1,'int16');
4819  HDR.TEAM.Nsegments = fread(HDR.FILE.FID,1,'int16');
4820  HDR.TEAM.SegmentOffset = fread(HDR.FILE.FID,1,'int32');
4821  HDR.XPhysDim = fread(HDR.FILE.FID,[1,8],'uint8');
4822  HDR.TEAM.RecInfoOffset = fread(HDR.FILE.FID,1,'int32');
4823  status = fseek(HDR.FILE.FID,256,'bof');
4824  %%%%% Y-Header %%%%%
4825  for k = 1:HDR.NS,
4826  HDR.Label{k} = char(fread(HDR.FILE.FID,[1,7],'uint8'));
4827  HDR.PhysDim{k} = char(fread(HDR.FILE.FID,[1,7],'uint8'));
4828  HDR.Off(1,k) = fread(HDR.FILE.FID,1,'float');
4829  HDR.Cal(1,k) = fread(HDR.FILE.FID,1,'float');
4830  HDR.PhysMax(1,k) = fread(HDR.FILE.FID,1,'float');
4831  HDR.PhysMin(1,k) = fread(HDR.FILE.FID,1,'float');
4832  status = fseek(HDR.FILE.FID,2,'cof');
4833  end;
4834  HDR.HeadLen = 256+HDR.NS*32;
4835 
4836  % Digital (event) information
4837  HDR.TEAM.DigitalOffset = 256 + 32*HDR.NS + HDR.NS*HDR.NRec*HDR.SPR*HDR.Samptype;
4838  status = fseek(HDR.FILE.FID,HDR.TEAM.DigitalOffset,'bof');
4839  if HDR.TEAM.DigitalOffset < HDR.TEAM.SegmentOffset,
4840  HDR.EventLabels = char(fread(HDR.FILE.FID,[16,HDR.EVENT.N],'uint8')');
4841 
4842  % Events could be detected in this way
4843  % HDR.Events = zeros(HDR.SPR*HDR.NRec,1);
4844  % for k = 1:ceil(HDR.EVENT.N/16)
4845  % HDR.Events = HDR.Events + 2^(16*k-16)*fread(HDR.FILE.FID,HDR.SPR*HDR.NRec,'uint16');
4846  % end;
4847  end;
4848 
4849  % Segment information block entries
4850  if HDR.TEAM.Nsegments,
4851  fseek(HDR.FILE.FID,HDR.TEAM.SegmentOffset,'bof');
4852  for k = 1:HDR.TEAM.Nsegments,
4853  HDR.TEAM.NSKIP(k) = fread(HDR.FILE.FID,1,'int32');
4854  HDR.SPR(k) = fread(HDR.FILE.FID,1,'int32');
4855  HDR.X0(k) = fread(HDR.FILE.FID,1,'float');
4856  HDR.Xstep(k) = fread(HDR.FILE.FID,1,'float');
4857  status = fseek(HDR.FILE.FID,8,'cof');
4858  end;
4859  end;
4860 
4861  % Recording information block entries
4862  if HDR.TEAM.RecInfoOffset,
4863  status = fseek(HDR.FILE.FID,HDR.TEAM.RecInfoOffset,'bof');
4864  blockinformation = fread(HDR.FILE.FID,[1,32],'uint8');
4865  for k = 1:HDR.NRec,
4866  HDR.TRIGGER.Time(k) = fread(HDR.FILE.FID,1,'double');
4867  HDR.TRIGGER.Date(k,1:3) = fread(HDR.FILE.FID,[1,3],'uint8');
4868  fseek(HDR.FILE.FID,20,'cof');
4869  end;
4870  HDR.TRIGGER.Date(k,1) = HDR.TRIGGER.Date(k,1) + 1900;
4871  end;
4872  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing Nicolet TEAM file format not completed yet. Contact <Biosig-general@lists.sourceforge.net> if you are interested in this feature.\n');
4873  fclose(HDR.FILE.FID);
4874 
4875 
4876 elseif strcmp(HDR.TYPE,'UFF5b'), % implementation of this format is not finished yet.
4877  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
4878  HDR.FILE.FID = fopen(HDR.FileName,'rt');
4879  fclose(HDR.FILE.FID);
4880  end;
4881 
4882 elseif strcmp(HDR.TYPE,'UFF58b'), % implementation of this format is not finished yet.
4883  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
4884  HDR.FILE.FID = fopen(HDR.FileName,'r','ieee-le');
4885  tline = fgetl(HDR.FILE.FID); % line 1
4886  tline = fgetl(HDR.FILE.FID); % line 2
4887  if strncmp(tline,' 58b 1 1',19)
4888  HDR.Endianity = 'vax';
4889  elseif strncmp(tline,' 58b 1 2',19)
4890  HDR.Endianity = 'ieee-le';
4891  HDR.GDFTYP = 16;
4892  elseif strncmp(tline,' 58b 2 2',19)
4893  HDR.Endianity = 'ieee-be';
4894  elseif 0, strncmp(tline,' 58b 1 3',19)
4895  HDR.Endianity = 'ibm370';
4896  else
4897  HDR.Endianity = ''; % not supported;
4898  fprintf(HDR.FILE.stderr,'ERROR SOPEN(UFF): binary format (IBM370, DEC/VMS) not supported, yet.');
4899  fclose(fid);
4900  return;
4901  end;
4902  [HDR.UFF.NoLines,v,str] = str2double(tline(20:31));
4903  [HDR.UFF.NoBytes,v,str] = str2double(tline(32:43));
4904  for k = 1:HDR.UFF.NoLines,
4905  tline = fgetl(HDR.FILE.FID); %line k+2
4906  if strncmp(tline,'NONE',4)
4907  elseif strncmp(tline,'@',1)
4908  elseif strcmp(tline([3,7,13,16]),'--::')
4909  HDR.T0 = datevec(datenum(tline));
4910  else
4911  end;
4912  end;
4913  HDR.HeadLen = ftell(HDR.FILE.FID);
4914  if ~strcmp(HDR.Endianity,'ieee-le')
4915  fclose(HDR.FILE.FID);
4916  HDR.FILE.FID = fopen(HDR.FileName,'r',HDR.Endianity);
4917  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
4918  end;
4919  HDR.data = fread(HDR.FILE.FID,[2,HDR.UFF.NoBytes/8],'float32')'
4920  HDR.Calib = [1;sqrt(-1)];
4921  fclose(HDR.FILE.FID);
4922  fprintf(HDR.FILE.stderr, 'WARNING SOPEN(UFF58): support for UFF58 format not complete.\n');
4923  end;
4924 
4925 
4926 elseif strcmp(HDR.TYPE,'WFT'), % implementation of this format is not finished yet.
4927 
4928  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
4929  [s,c] = fread(HDR.FILE.FID,1536,'uint8');
4930  [tmp,s] = strtok(s,char([0,32]));
4931  Nic_id0 = str2double(tmp);
4932  [tmp,s] = strtok(s,char([0,32]));
4933  Niv_id1 = str2double(tmp);
4934  [tmp,s] = strtok(s,char([0,32]));
4935  Nic_id2 = str2double(tmp);
4936  [tmp,s] = strtok(s,char([0,32]));
4937  User_id = str2double(tmp);
4938  [tmp,s] = strtok(s,char([0,32]));
4939  HDR.HeadLen = str2double(tmp);
4940  [tmp,s] = strtok(s,char([0,32]));
4941  HDR.FILE.Size = str2double(tmp);
4942  [tmp,s] = strtok(s,char([0,32]));
4943  HDR.VERSION = str2double(tmp);
4944  [tmp,s] = strtok(s,char([0,32]));
4945  HDR.WFT.WaveformTitle = str2double(tmp);
4946  [tmp,s] = strtok(s,char([0,32]));
4947  HDR.T0(1) = str2double(tmp);
4948  [tmp,s] = strtok(s,char([0,32]));
4949  HDR.T0(1,2) = str2double(tmp);
4950  [tmp,s] = strtok(s,char([0,32]));
4951  HDR.T0(1,3) = str2double(tmp);
4952  [tmp,s] = strtok(s,char([0,32]));
4953  tmp = str2double(tmp);
4954  HDR.T0(1,4:6) = [floor(tmp/3600000),floor(rem(tmp,3600000)/60000),rem(tmp,60000)];
4955  [tmp,s] = strtok(s,char([0,32]));
4956  HDR.SPR = str2double(tmp);
4957  [tmp,s] = strtok(s,char([0,32]));
4958  HDR.Off = str2double(tmp);
4959  [tmp,s] = strtok(s,char([0,32]));
4960  HDR.Cal = str2double(tmp);
4961 
4962  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
4963 
4964  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing Nicolet WFT file format not completed yet. Contact <Biosig-general@lists.sourceforge.net> if you are interested in this feature.\n');
4965  fclose(HDR.FILE.FID);
4966 
4967 
4968 elseif strcmp(HDR.TYPE,'WG1'),
4969  if ~isempty(findstr(HDR.FILE.PERMISSION,'r')), %%%%% READ
4970  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],HDR.Endianity);
4971  HDR.VERSION = dec2hex(fread(HDR.FILE.FID,1,'uint32'));
4972  if strcmp(HDR.VERSION,'AFFE5555')
4973  error('This version of WG1 format is not supported, yet')
4974 
4975  elseif any(strcmp(HDR.VERSION,{'DADAFEFA','AFFEDADA'}))
4976  HDR.WG1.MachineId = fread(HDR.FILE.FID,1,'uint32');
4977  HDR.WG1.Day = fread(HDR.FILE.FID,1,'uint32');
4978  HDR.WG1.millisec = fread(HDR.FILE.FID,1,'uint32');
4979  HDR.T0 = datevec(HDR.WG1.Day - 15755 - hex2dec('250000'));
4980  HDR.T0(1) = HDR.T0(1) + 1970;
4981  HDR.T0(4) = floor(HDR.WG1.millisec/3600000);
4982  HDR.T0(5) = mod(floor(HDR.WG1.millisec/60000),60);
4983  HDR.T0(6) = mod(HDR.WG1.millisec/1000,60);
4984  dT = fread(HDR.FILE.FID,1,'uint32');
4985  HDR.SampleRate = 1e6/dT;
4986  HDR.WG1.pdata = fread(HDR.FILE.FID,1,'uint16');
4987  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
4988  HDR.WG1.poffset = fread(HDR.FILE.FID,1,'uint16');
4989  HDR.WG1.pad1 = fread(HDR.FILE.FID,38,'uint8');
4990  HDR.Cal = repmat(NaN,HDR.NS,1);
4991  HDR.ChanSelect = repmat(NaN,HDR.NS,1);
4992  for k=1:HDR.NS,
4993  HDR.Label{k} = char(fread(HDR.FILE.FID,[1,8],'uint8'));
4994  HDR.Cal(k,1) = fread(HDR.FILE.FID,1,'uint32')/1000;
4995  tmp = fread(HDR.FILE.FID,[1,2],'uint16');
4996  HDR.ChanSelect(k) = tmp(1)+1;
4997  end;
4998  %HDR.Calib = sparse(2:HDR.NS+1,HDR.ChanSelect,HDR.Cal);
4999  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
5000  HDR.PhysDimCode = zeros(HDR.NS,1);
5001 
5002  status = fseek(HDR.FILE.FID,7*256,'bof');
5003  HDR.WG1.neco1 = fread(HDR.FILE.FID,1,'uint32');
5004  HDR.Patient.Id = fread(HDR.FILE.FID,[1,12],'uint8');
5005  HDR.Patient.LastName = fread(HDR.FILE.FID,[1,20],'uint8');
5006  HDR.Patient.text1 = fread(HDR.FILE.FID,[1,20],'uint8');
5007  HDR.Patient.FirstName = fread(HDR.FILE.FID,[1,20],'uint8');
5008  HDR.Patient.Sex = fread(HDR.FILE.FID,[1,2],'uint8');
5009  HDR.Patient.vata = fread(HDR.FILE.FID,[1,8],'uint8');
5010  HDR.Patient.text2 = fread(HDR.FILE.FID,[1,14],'uint8');
5011  HDR.WG1.Datum = fread(HDR.FILE.FID,1,'uint32');
5012  HDR.WG1.mstime = fread(HDR.FILE.FID,1,'uint32');
5013  HDR.WG1.nic = fread(HDR.FILE.FID,[1,4],'uint32');
5014  HDR.WG1.neco3 = fread(HDR.FILE.FID,1,'uint32');
5015 
5016  status = fseek(HDR.FILE.FID,128,'cof');
5017  HDR.HeadLen = ftell(HDR.FILE.FID);
5018  HDR.FILE.OPEN = 1;
5019  HDR.FILE.POS = 0;
5020 
5021  HDR.WG1.szBlock = 256;
5022  HDR.WG1.szOffset = 128;
5023  HDR.WG1.szExtra = HDR.WG1.pdata-(HDR.NS+HDR.WG1.poffset);
5024  szOneRec = HDR.WG1.szOffset*4+(HDR.NS+HDR.WG1.szExtra)*HDR.WG1.szBlock;
5025  HDR.AS.bpb = szOneRec;
5026  HDR.WG1.szRecs = floor((HDR.FILE.size-HDR.HeadLen)/HDR.AS.bpb);
5027  HDR.WG1.szData = HDR.WG1.szBlock*HDR.WG1.szRecs;
5028  HDR.WG1.unknownNr = 11;
5029  conv = round(19*sinh((0:127)/19));
5030  conv = [conv, HDR.WG1.unknownNr, -conv(end:-1:2)];
5031  HDR.WG1.conv = conv;
5032  HDR.NRec = HDR.WG1.szRecs;
5033  HDR.SPR = HDR.WG1.szBlock;
5034  HDR.Dur = HDR.SPR/HDR.SampleRate;
5035  HDR.AS.endpos = HDR.NRec*HDR.SPR;
5036  end
5037 
5038  %----- load event information -----
5039  eventFile = fullfile(HDR.FILE.Path,[HDR.FILE.Name, '.wg2']);
5040  if ~exist(eventFile,'file')
5041  eventFile = fullfile(HDR.FILE.Path,[HDR.FILE.Name, '.WG2']);
5042  end;
5043  if exist(eventFile,'file')
5044  fid= fopen(eventFile,'r');
5045  nr = 1;
5046  [s,c] = fread(fid,1,'uint32');
5047  while ~feof(fid)
5048  HDR.EVENT.POS(nr,1) = s;
5049  pad = fread(fid,3,'uint32');
5050  len = fread(fid,1,'uint8');
5051  tmp = char(fread(fid,[1,47], 'uint8'));
5052  Desc{nr,1} = tmp(1:len);
5053  % find string between quotation marks
5054  % HDR.EVENT.Desc{nr}=regexpi(Event,'(?<=\'').*(?=\'')','match','once');
5055  [s,c] = fread(fid,1,'uint32');
5056  nr = nr+1;
5057  end;
5058  [HDR.EVENT.CodeDesc, CodeIndex, HDR.EVENT.TYP] = unique(Desc);
5059  fclose(fid);
5060  end;
5061  end;
5062 
5063 
5064 elseif strcmp(HDR.TYPE,'LDR'),
5065  HDR = openldr(HDR,[HDR.FILE.PERMISSION,'t']);
5066 
5067 
5068 elseif strcmp(HDR.TYPE,'SMA'), % under constructions
5069  try % MatLAB default is binary, force Mode='rt';
5070  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'t'],'ieee-le');
5071  catch % Octave 2.1.50 default is text, but does not support Mode='rt',
5072  HDR.FILE.FID = fopen(HDR.FileName,HDR.FILE.PERMISSION,'ieee-le');
5073  end
5074  numbegin=0;
5075  HDR.H1 = '';
5076  delim = char([abs('"='),10,13]);
5077  while ~numbegin,
5078  line = fgetl(HDR.FILE.FID);
5079  HDR.H1 = [HDR.H1, line];
5080  if strncmp('"NCHAN%"',line,8)
5081  [tmp,line] = strtok(line,'=');
5082  [tmp,line] = strtok(line,delim);
5083  HDR.NS = str2double(char(tmp));
5084  end
5085  if strncmp('"NUM.POINTS"',line,12)
5086  [tmp,line] = strtok(line,'=');
5087  [tmp,line] = strtok(line,delim);
5088  HDR.SPR = str2double(tmp);
5089  end
5090  if strncmp('"ACT.FREQ"',line,10)
5091  [tmp,line] = strtok(line,'=');
5092  [tmp,line] = strtok(line,delim);
5093  HDR.SampleRate= str2double(tmp);
5094  end
5095  if strncmp('"DATE$"',line,7)
5096  [tmp,line] = strtok(line,'=');
5097  [date,line] = strtok(line,delim);
5098  [tmp,date]=strtok(date,'-');
5099  HDR.T0(3) = str2double(tmp);
5100  [tmp,date]=strtok(date,'-');
5101  HDR.T0(2) = str2double(tmp);
5102  [tmp,date]=strtok(date,'-');
5103  HDR.T0(1) = str2double(tmp);
5104  end
5105  if strncmp('"TIME$"',line,7)
5106  [tmp,line] = strtok(line,'=');
5107  [time,line] = strtok(line,delim);
5108  [tmp,date]=strtok(time,':');
5109  HDR.T0(4) = str2double(tmp);
5110  [tmp,date]=strtok(date,':');
5111  HDR.T0(5) = str2double(tmp);
5112  [tmp,date]=strtok(date,':');
5113  HDR.T0(6) = str2double(tmp);
5114  end;
5115  if strncmp('"UNITS$[]"',line,10)
5116  [tmp,line] = strtok(char(line),'=');
5117  for k=1:HDR.NS,
5118  [tmp,line] = strtok(line,[' ,',delim]);
5119  HDR.PhysDim(k,1:length(tmp)) = tmp;
5120  end;
5121  end
5122  if strncmp('"CHANNEL.RANGES[]"',line,18)
5123  [tmp,line] = strtok(line,'= ');
5124  [tmp,line] = strtok(line,'= ');
5125  for k=1:HDR.NS,
5126  [tmp,line] = strtok(line,[' ',delim]);
5127  [tmp1, tmp]=strtok(tmp,'(),');
5128  HDR.PhysMin(k,1)=str2double(tmp1);
5129  [tmp2, tmp]=strtok(tmp,'(),');
5130  HDR.PhysMax(k,1)=str2double(tmp2);
5131  end;
5132  end
5133  if strncmp('"CHAN$[]"',line,9)
5134  [tmp,line] = strtok(line,'=');
5135  for k=1:HDR.NS,
5136  [tmp,line] = strtok(line,[' ,',delim]);
5137  HDR.Label{k,1} = char(tmp);
5138  end;
5139  end
5140  if 0,strncmp('"CHANNEL.LABEL$[]"',line,18)
5141  [tmp,line] = strtok(line,'=');
5142  for k=1:HDR.NS,
5143  [HDR.Label{k,1},line] = strtok(line,delim);
5144  end;
5145  end
5146  if strncmp(line,'"TR"',4)
5147  HDR.H1 = HDR.H1(1:length(HDR.H1)-length(line));
5148  line = fgetl(HDR.FILE.FID); % get the time and date stamp line
5149  tmp=fread(HDR.FILE.FID,1,'uint8'); % read sync byte hex-AA char
5150  if tmp~=hex2dec('AA');
5151  fprintf(HDR.FILE.stderr,'Error SOPEN type=SMA: Sync byte is not "AA"\n');
5152  end;
5153  numbegin=1;
5154  end
5155  end
5156 
5157  %%%%%%%%%%%%%%%%%%% check file length %%%%%%%%%%%%%%%%%%%%
5158 
5159  HDR.FILE.POS= 0;
5160  HDR.HeadLen = ftell(HDR.FILE.FID); % Length of Header
5161 
5162  fclose(HDR.FILE.FID);
5163  %% PERMISSION = PERMISSION(PERMISSION~='t'); % open in binary mode
5164  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
5165 
5166  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
5167  %[HDR.AS.endpos,HDR.HeadLen,HDR.NS,HDR.SPR,HDR.NS*HDR.SPR*4,HDR.AS.endpos-HDR.HeadLen - HDR.NS*HDR.SPR*4]
5168  HDR.AS.endpos = HDR.NS*HDR.SPR*4 - HDR.HeadLen;
5169  if HDR.FILE.size-HDR.HeadLen ~= HDR.NS*HDR.SPR*4;
5170  fprintf(HDR.FILE.stderr,'Warning SOPEN TYPE=SMA: Header information does not fit size of file\n');
5171  fprintf(HDR.FILE.stderr,'\tProbably more than one data segment - this is not supported in the current version of SOPEN\n');
5172  end
5173  HDR.AS.bpb = HDR.NS*4;
5174  HDR.AS.endpos = (HDR.AS.endpos-HDR.HeadLen)/HDR.AS.bpb;
5175  HDR.Dur = 1/HDR.SampleRate;
5176  HDR.NRec = 1;
5177 
5178  if ~isfield(HDR,'SMA')
5179  HDR.SMA.EVENT_CHANNEL= 1;
5180  HDR.SMA.EVENT_THRESH = 2.3;
5181  end;
5182  HDR.Filter.T0 = zeros(1,length(HDR.SMA.EVENT_CHANNEL));
5183 
5184 
5185 elseif strcmp(HDR.TYPE,'RDF'), % UCSD ERPSS acqusition software DIGITIZE
5186  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
5187 
5188  status = fseek(HDR.FILE.FID,4,-1);
5189  HDR.FLAG.compressed = fread(HDR.FILE.FID,1,'uint16');
5190  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
5191  status = fseek(HDR.FILE.FID,552,-1);
5192  HDR.SampleRate = fread(HDR.FILE.FID,1,'uint16');
5193  status = fseek(HDR.FILE.FID,580,-1);
5194  HDR.Label = char(fread(HDR.FILE.FID,[8,HDR.NS],'uint8')');
5195 
5196  cnt = 0;
5197  ev_cnt = 0;
5198  ev = [];
5199 
5200  % first pass, scan data
5201  totalsize = 0;
5202  tag = fread(HDR.FILE.FID,1,'uint32');
5203  while ~feof(HDR.FILE.FID) %& ~status,
5204  if tag == hex2dec('f0aa55'),
5205  cnt = cnt + 1;
5206  HDR.Block.Pos(cnt) = ftell(HDR.FILE.FID);
5207 
5208  % Read nchans and block length
5209  tmp = fread(HDR.FILE.FID,34,'uint16');
5210 
5211  %fseek(HDR.FILE.FID,2,0);
5212  nchans = tmp(2); %fread(HDR.FILE.FID,1,'uint16');
5213  %fread(HDR.FILE.FID,1,'uint16');
5214  block_size = 2^tmp(3); %fread(HDR.FILE.FID,1,'uint16');
5215  blocksize2 = tmp(4);
5216  %ndupsamp = fread(HDR.FILE.FID,1,'uint16');
5217  %nrun = fread(HDR.FILE.FID,1,'uint16');
5218  %err_detect = fread(HDR.FILE.FID,1,'uint16');
5219  %nlost = fread(HDR.FILE.FID,1,'uint16');
5220  HDR.EVENT.N = tmp(9); %fread(HDR.FILE.FID,1,'uint16');
5221  %fseek(HDR.FILE.FID,50,0);
5222 
5223  % Read events
5224  HDR.EVENT.POS = repmat(nan,HDR.EVENT.N,1);
5225  HDR.EVENT.TYP = repmat(nan,HDR.EVENT.N,1);
5226  for i = 1:HDR.EVENT.N,
5227  tmp = fread(HDR.FILE.FID,2,'uint8');
5228  %cond_code = fread(HDR.FILE.FID,1,'uint8');
5229  ev_code = fread(HDR.FILE.FID,1,'uint16');
5230  ev_cnt = ev_cnt + 1;
5231  tmp2.sample_offset = tmp(1) + (cnt-1)*128;
5232  tmp2.cond_code = tmp(2);
5233  tmp2.event_code = ev_code;
5234  if ~exist('OCTAVE_VERSION','builtin'),
5235  ev{ev_cnt} = tmp2;
5236  end;
5237  HDR.EVENT.POS(ev_cnt) = tmp(1) + (cnt-1)*128;
5238  HDR.EVENT.TYP(ev_cnt) = ev_code;
5239  end;
5240  status = fseek(HDR.FILE.FID,4*(110-HDR.EVENT.N)+2*nchans*block_size,0);
5241  else
5242  [tmp, c] = fread(HDR.FILE.FID,3,'uint16');
5243  if (c > 2),
5244  nchans = tmp(2); %fread(HDR.FILE.FID,1,'uint16');
5245  block_size = 2^tmp(3); %fread(HDR.FILE.FID,1,'uint16');
5246 
5247  %fseek(HDR.FILE.FID,62+4*(110-HDR.EVENT.N)+2*nchans*block_size,0);
5248  sz = 62 + 4*110 + 2*nchans*block_size;
5249  status = -(sz>=(2^31));
5250  if ~status,
5251  status = fseek(HDR.FILE.FID, sz, 0);
5252  end;
5253  end;
5254  end
5255  tag = fread(HDR.FILE.FID,1,'uint32');
5256  end
5257  HDR.NRec = cnt;
5258 
5259  HDR.Events = ev;
5260  HDR.HeadLen = 0;
5261  HDR.FLAG.TRIGGERED = 1;
5262  HDR.FILE.POS = 0;
5263  HDR.SPR = block_size;
5264  HDR.AS.bpb = HDR.SPR*HDR.NS*2;
5265  HDR.Dur = HDR.SPR/HDR.SampleRate;
5266  HDR.PhysDimCode = zeros(1,HDR.NS);
5267 
5268 
5269 elseif strcmp(HDR.TYPE,'LABVIEW'),
5270  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
5271 
5272  tmp = fread(HDR.FILE.FID,8,'uint8');
5273  HDR.VERSION = char(fread(HDR.FILE.FID,[1,8],'uint8'));
5274  HDR.AS.endpos = fread(HDR.FILE.FID,1,'int32'); % 4 first bytes = total header length
5275 
5276  HDR.HeadLen = fread(HDR.FILE.FID,1,'int32'); % 4 first bytes = total header length
5277  HDR.NS = fread(HDR.FILE.FID,1,'int32'); % 4 next bytes = channel list string length
5278  HDR.AS.endpos2 = fread(HDR.FILE.FID,1,'int32'); % 4 first bytes = total header length
5279 
5280  HDR.ChanList = fread(HDR.FILE.FID,HDR.NS,'uint8'); % channel string
5281 
5282  fclose(HDR.FILE.FID);
5283  %HDR.FILE.OPEN = 1;
5284  HDR.FILE.FID = -1;
5285 
5286  return;
5287 
5288  %%%%% READ HEADER from Labview 5.1 supplied VI "create binary header"
5289 
5290  HDR.HeadLen = fread(HDR.FILE.FID,1,'int32'); % 4 first bytes = total header length
5291  HDR.NS = fread(HDR.FILE.FID,1,'int32'); % 4 next bytes = channel list string length
5292  HDR.ChanList = fread(HDR.FILE.FID,HDR.NS,'uint8'); % channel string
5293 
5294  % Number of channels = 1 + ord(lastChann) - ord(firstChann):
5295  HDR.LenN = fread(HDR.FILE.FID,1,'int32'); % Hardware config length
5296  HDR.HWconfig = fread(HDR.FILE.FID,HDR.LenN,'uint8'); % its value
5297  HDR.SampleRate = fread(HDR.FILE.FID,1,'float32');
5298  HDR.InterChannelDelay = fread(HDR.FILE.FID,1,'float32');
5299  tmp=fread(HDR.FILE.FID,[1,HDR.HeadLen - ftell(HDR.FILE.FID)],'uint8'); % read rest of header
5300  [HDR.Date,tmp]= strtok(tmp,9) ; % date is the first 10 elements of this tmp array (strip out tab)
5301  [HDR.Time,tmp]= strtok(tmp,9); % and time is the next 8 ones
5302  % HDR.T0 = [yyyy mm dd hh MM ss]; %should be Matlab date/time format like in clock()
5303  HDR.Description= char(tmp); % description is the rest of elements.
5304 
5305  % Empirically determine the number of bytes per multichannel point:
5306  HDR.HeadLen = ftell(HDR.FILE.FID) ;
5307  dummy10 = fread(HDR.FILE.FID,[HDR.NS,1],'int32');
5308  HDR.AS.bpb = (ftell(HDR.FILE.FID) - HDR.HeadLen); % hope it's an int !
5309 
5310  tmp = fseek(HDR.FILE.FID,0,'eof');
5311  HDR.AS.endpos = (ftell(HDR.FILE.FID) - HDR.HeadLen)/HDR.AS.bpb;
5312  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
5313 
5314  HDR.Cal = 1;
5315 
5316 
5317 elseif strcmp(HDR.TYPE,'RG64'),
5318  fid = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
5319 
5320  HDR.IDCODE=char(fread(fid,[1,4],'uint8')); %
5321  if ~strcmp(HDR.IDCODE,'RG64')
5322  fprintf(HDR.FILE.stderr,'\nError LOADRG64: %s not a valid RG64 - header file\n',HDR.FileName);
5323  HDR.TYPE = 'unknown';
5324  fclose(fid);
5325  return;
5326  end; %end;
5327 
5328  tmp = fread(fid,2,'int32');
5329  HDR.VERSION = tmp(1)+tmp(2)/100;
5330  HDR.NS = fread(fid,1,'int32');
5331  HDR.SampleRate = fread(fid,1,'int32');
5332  HDR.SPR = fread(fid,1,'int32')/HDR.NS;
5333  AMPF = fread(fid,64,'int32');
5334  fclose(fid);
5335 
5336  HDR.HeadLen = 0;
5337  HDR.PhysDim = 'uV';
5338  HDR.Cal = (5E6/2048)./AMPF;
5339  HDR.AS.endpos = HDR.SPR;
5340  HDR.AS.bpb = HDR.NS*2;
5341  HDR.GDFTYP = 'int16';
5342 
5343  EXT = HDR.FILE.Ext;
5344  if upper(EXT(2))~='D',
5345  EXT(2) = EXT(2) - 'H' + 'D';
5346  end;
5347  FILENAME=fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.',EXT]);
5348 
5349  HDR.FILE.FID=fopen(FILENAME,[HDR.FILE.PERMISSION,'b'],'ieee-le');
5350  if HDR.FILE.FID<0,
5351  fprintf(HDR.FILE.stderr,'\nError LOADRG64: data file %s not found\n',FILENAME);
5352  return;
5353  end;
5354 
5355  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal(1:HDR.NS),HDR.NS+1,HDR.NS);
5356  HDR.FILE.POS = 0;
5357  HDR.FILE.OPEN= 1;
5358 
5359 
5360 elseif strcmp(HDR.TYPE,'DDF'),
5361 
5362  % implementation of this format is not finished yet.
5363  fprintf(HDR.FILE.stderr,'Warning SOPEN: Implementing DASYLAB format not completed yet. Contact <Biosig-general@lists.sourceforge.net> if you are interested in this feature.\n');
5364  %HDR.FILE.FID = -1;
5365  %return;
5366 
5367  if any(HDR.FILE.PERMISSION=='r'),
5368  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
5369  HDR.FILE.OPEN = 1;
5370  HDR.FILE.POS = 0;
5371  %HDR.ID = fread(HDR.FILE.FID,5,'uint8');
5372  ds=fread(HDR.FILE.FID,[1,128],'uint8');
5373  HDR.ID = char(ds(1:5));
5374  DataSource = ds;
5375  k = 0;
5376  while ~(any(ds==26)),
5377  ds = fread(HDR.FILE.FID,[1,128],'uint8');
5378  DataSource = [DataSource,ds];
5379  k = k+1;
5380  end;
5381  pos = find(ds==26)+k*128;
5382  DataSource = char(DataSource(6:pos));
5383  HDR.DDF.Source = DataSource;
5384  while ~isempty(DataSource),
5385  [ds,DataSource] = strtok(char(DataSource),[10,13]);
5386  [field,value] = strtok(ds,'=');
5387  if strfind(field,'SAMPLE RATE');
5388  [tmp1,tmp2] = strtok(value,'=');
5389  HDR.SampleRate = str2double(tmp1);
5390  elseif strfind(field,'DATA CHANNELS');
5391  HDR.NS = str2double(value);
5392  elseif strfind(field,'START TIME');
5393  Time = value;
5394  elseif strfind(field,'DATA FILE');
5395  HDR.FILE.DATA = value;
5396  end;
5397  end;
5398  fseek(HDR.FILE.FID,pos,'bof'); % position file identifier
5399  if 0;%DataSource(length(DataSource))~=26,
5400  fprintf(1,'Warning: DDF header seems to be incorrenct. Contact <alois.schloegl@ist.ac.at> Subject: BIOSIG/DATAFORMAT/DDF \n');
5401  end;
5402  HDR.DDF.CPUidentifier = fread(HDR.FILE.FID,[1,2],'uint8=>char');
5403  HDR.HeadLen(1) = fread(HDR.FILE.FID,1,'uint16');
5404  tmp = fread(HDR.FILE.FID,1,'uint16');
5405  if tmp == 0, HDR.GDFTYP = 'uint16'; % streamer format (data are raw data in WORD=UINT16)
5406  elseif tmp == 1, HDR.GDFTYP = 'float32'; % Universal Format 1 (FLOAT)
5407  elseif tmp == 2, HDR.GDFTYP = 'float64'; % Universal Format 2 (DOUBLE)
5408  elseif tmp <= 1000, % reserved
5409  else % unused
5410  end;
5411  HDR.FILE.Type = tmp;
5412  HDR.VERSION = fread(HDR.FILE.FID,1,'uint16');
5413  HDR.HeadLen(2) = fread(HDR.FILE.FID,1,'uint16'); % second global Header
5414  HDR.HeadLen(3) = fread(HDR.FILE.FID,1,'uint16'); % size of channel Header
5415  fread(HDR.FILE.FID,1,'uint16'); % size of a block Header
5416  tmp = fread(HDR.FILE.FID,1,'uint16');
5417  if tmp ~= isfield(HDR.FILE,'DATA')
5418  fprintf(1,'Warning: DDF header seems to be incorrenct. Contact <alois.schloegl@ist.ac.at> Subject: BIOSIG/DATAFORMAT/DDF \n');
5419  end;
5420  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
5421  HDR.Delay = fread(HDR.FILE.FID,1,'double');
5422  HDR.StartTime = fread(HDR.FILE.FID,1,'uint32'); % might be incorrect
5423 
5424  % it looks good so far.
5425  % fseek(HDR.FILE.FID,HDR.HeadLen(1),'bof');
5426  if HDR.FILE.Type==0,
5427  % second global header
5428  fread(HDR.FILE.FID,1,'uint16') % overall number of bytes in this header
5429  fread(HDR.FILE.FID,1,'uint16') % number of analog channels
5430  fread(HDR.FILE.FID,1,'uint16') % number of counter channels
5431  fread(HDR.FILE.FID,1,'uint16') % number of digital ports
5432  fread(HDR.FILE.FID,1,'uint16') % number of bits in each digital port
5433  fread(HDR.FILE.FID,1,'uint16') % original blocksize when data was stored
5434  fread(HDR.FILE.FID,1,'uint32') % sample number of the first sample (when cyclic buffer not activated, always zero
5435  fread(HDR.FILE.FID,1,'uint32') % number of samples per channel
5436 
5437  % channel header
5438  for k = 1:HDR.NS,
5439  fread(HDR.FILE.FID,1,'uint16') % number of bytes in this hedader
5440  fread(HDR.FILE.FID,1,'uint16') % channel type 0: analog, 1: digital, 2: counter
5441  HDR.Label = char(fread(HDR.FILE.FID,[24,16],'uint8')'); %
5442  tmp = fread(HDR.FILE.FID,1,'uint16') % dataformat 0 UINT, 1: INT
5443  HDR.GDFTYP(k) = 3 + (~tmp);
5444  HDR.Cal(k) = fread(HDR.FILE.FID,1,'double'); %
5445  HDR.Off(k) = fread(HDR.FILE.FID,1,'double'); %
5446  end;
5447 
5448  elseif HDR.FILE.Type==1,
5449  % second global header
5450  HDR.pos1 = ftell(HDR.FILE.FID);
5451  tmp = fread(HDR.FILE.FID,1,'uint16'); % size of this header
5452  if (tmp~=HDR.HeadLen(2)),
5453  fprintf(HDR.FILE.stderr,'Error SOPEN DDF: error in header of file %s\n',HDR.FileName);
5454  end;
5455  HDR.U1G.NS = fread(HDR.FILE.FID,1,'uint16'); % number of channels
5456  HDR.FLAG.multiplexed = fread(HDR.FILE.FID,1,'uint16'); % multiplexed: 0=no, 1=yes
5457  HDR.DDF.array = fread(HDR.FILE.FID,[1,16],'uint16'); % array of channels collected on each input channel
5458 
5459  % channel header
5460  for k = 1:HDR.NS,
5461  filepos = ftell(HDR.FILE.FID);
5462  taglen = fread(HDR.FILE.FID,1,'uint16'); % size of this header
5463  ch = fread(HDR.FILE.FID,1,'uint16'); % channel number
5464  HDR.DDF.MAXSPR(ch+1)= fread(HDR.FILE.FID,1,'uint16'); % maximum size of block in samples
5465  HDR.DDF.delay(ch+1) = fread(HDR.FILE.FID,1,'double'); % time delay between two samples
5466  HDR.DDF.ChanType(ch+1) = fread(HDR.FILE.FID,1,'uint16'); % channel type
5467  HDR.DDF.ChanFlag(ch+1) = fread(HDR.FILE.FID,1,'uint16'); % channel flag
5468  unused = fread(HDR.FILE.FID,2,'double'); % must be 0.0 for future extension
5469  tmp = fgets(HDR.FILE.FID); % channel unit
5470  HDR.PhysDim{k} = [tmp,' ']; % channel unit
5471  tmp = fgets(HDR.FILE.FID); % channel name
5472  HDR.Label{k} = [tmp,' ']; % channel name
5473  fseek(HDR.FILE.FID,filepos+taglen,'bof');
5474  end;
5475 
5476  % channel header
5477  for k = 1:HDR.NS,
5478  fread(HDR.FILE.FID,[1,4],'uint8');
5479  fread(HDR.FILE.FID,1,'uint16'); % overall number of bytes in this header
5480  HDR.BlockStartTime = fread(HDR.FILE.FID,1,'uint32'); % might be incorrect
5481  unused = fread(HDR.FILE.FID,2,'double'); % must be 0.0 for future extension
5482  ch = fread(HDR.FILE.FID,1,'uint32'); % channel number
5483  end;
5484  fseek(HDR.FILE.FID,HDR.pos1+sum(HDR.HeadLen(2:3)),'bof');
5485 
5486  elseif HDR.FILE.Type==2,
5487  % second global header
5488  pos = ftell(HDR.FILE.FID);
5489  HeadLen = fread(HDR.FILE.FID,1,'uint16'); % size of this header
5490  fread(HDR.FILE.FID,1,'uint16'); % number of channels
5491  fseek(HDR.FILE.FID, pos+HeadLen ,'bof');
5492 
5493  % channel header
5494  for k = 1:HDR.NS,
5495  pos = ftell(HDR.FILE.FID);
5496  HeadLen = fread(HDR.FILE.FID,1,'uint16'); % size of this header
5497  HDR.DDF.Blocksize(k) = fread(HDR.FILE.FID,1,'uint16'); %
5498  HDR.DDF.Delay(k) = fread(HDR.FILE.FID,1,'double'); %
5499  HDR.DDF.chantyp(k) = fread(HDR.FILE.FID,1,'uint16'); %
5500  HDR.FLAG.TRIGGER(k) = ~~fread(HDR.FILE.FID,1,'uint16');
5501  fread(HDR.FILE.FID,1,'uint16');
5502  HDR.Cal(k) = fread(HDR.FILE.FID,1,'double');
5503  end;
5504  else
5505 
5506  end;
5507  %ftell(HDR.FILE.FID),
5508  tag=fread(HDR.FILE.FID,[1,4],'uint8');
5509  end;
5510  return;
5511 
5512 
5513 elseif strcmp(HDR.TYPE,'MIT')
5514  if any(HDR.FILE.PERMISSION=='r'),
5515  HDR.FileName = fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.',HDR.FILE.Ext]);
5516 
5517  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
5518  if HDR.FILE.FID<0,
5519  fprintf(HDR.FILE.stderr,'Error SOPEN: Couldnot open file %s\n',HDR.FileName);
5520  return;
5521  end;
5522 
5523  fid = HDR.FILE.FID;
5524  z = fgetl(fid);
5525  while strncmp(z,'#',1) || isempty(z),
5526  z = fgetl(fid);
5527  end;
5528  tmpfile = strtok(z,' /');
5529  if ~strcmpi(HDR.FILE.Name,tmpfile),
5530  fprintf(HDR.FILE.stderr,'Error: RecordName %s does not fit filename %s\n',tmpfile,HDR.FILE.Name);
5531  fclose(HDR.FILE.FID)
5532  return;
5533  end;
5534 
5535  %A = sscanf(z, '%*s %d %d %d',[1,3]);
5536  t = z;
5537  k = 0;
5538  while ~isempty(t)
5539  k = k + 1;
5540  [s,t] = strtok(t,[9,10,13,32]);
5541  Z{k} = s;
5542  if any(s==':'),
5543  t0 = str2double(s,':');
5544  HDR.T0(3+(1:length(t0))) = t0;
5545  elseif sum(s=='/')==2,
5546  HDR.T0([3,2,1])=str2double(s,'/');
5547  end;
5548  end;
5549  HDR.NS = str2double(Z{2}); % number of signals
5550 
5551  if k>2,
5552  [tmp,tmp1] = strtok(Z{3},'/');
5553  HDR.SampleRate = str2double(tmp); % sample rate of data
5554  end;
5555 
5556  [tmp,z1] = strtok(Z{1},'/');
5557  if ~isempty(z1)
5558  %%%%%%%%%% Multi-Segment files %%%%%%%
5559  fprintf(HDR.FILE.stderr,'Error SOPEN (MIT) %s: multi-segment files not supported.\n',tmpfile);
5560 
5561  return;
5562 
5563  HDR.FLAG.TRIGGERED = 1;
5564  z1 = strtok(z1,'/');
5565  HDR.NRec = str2double(z1);
5566 
5567  HDR.EVENT.TYP = repmat(hex2dec('0300'),HDR.NRec,1);
5568  HDR.EVENT.POS = repmat(NaN,HDR.NRec,1);
5569  HDR.EVENT.DUR = repmat(NaN,HDR.NRec,1);
5570  HDR.EVENT.CHN = repmat(0,HDR.NRec,1);
5571  count = 0;
5572  for k = 1:HDR.NRec;
5573  [s,t] = strtok(fgetl(fid));
5574  [hdr] = sopen(fullfile(HDR.FILE.Path,[s,'.hea']),'r',CHAN);
5575  [s,hdr] = sread(hdr);
5576  hdr = sclose(hdr);
5577  if k==1,
5578  HDR.data = repmat(s,HDR.NRec,1);
5579  else
5580  HDR.data(count+1:count+size(s,1),:) = s;
5581  end;
5582  HDR.EVENT.POS(k) = count;
5583  HDR.EVENT.DUR(k) = size(s,1);
5584  count = count + size(s,1);
5585  end;
5586  HDR.Label = hdr.Label;
5587  HDR.PhysDim = hdr.PhysDim;
5588  HDR.SPR = size(s,1);
5589  HDR.NS = hdr.NS;
5590  HDR.Calib = (hdr.Calib>0);
5591  HDR.FLAG.TRIGGERED = 1;
5592  HDR.FILE.POS = 0;
5593  HDR.TYPE = 'native';
5594 
5595  else
5596 
5597  [tmp,z] = strtok(z);
5598  [tmp,z] = strtok(z);
5599  %HDR.NS = str2double(Z{2}); % number of signals
5600  [tmp,z] = strtok(z);
5601  [tmp,z] = strtok(z,' ()');
5602  HDR.NRec = str2double(tmp); % length of data
5603  HDR.SPR = 1;
5604 
5605  HDR.MIT.gain = zeros(1,HDR.NS);
5606  HDR.MIT.zerovalue = repmat(NaN,1,HDR.NS);
5607  HDR.MIT.firstvalue = repmat(NaN,1,HDR.NS);
5608  for k = 1:HDR.NS,
5609  z = fgetl(fid);
5610  [HDR.FILE.DAT{k,1},z]=strtok(z);
5611  for k0 = 1:7,
5612  [tmp,z] = strtok(z);
5613  if k0 == 1,
5614  [tmp, tmp1] = strtok(tmp,'x:+');
5615  [tmp, status] = str2double(tmp);
5616  HDR.MIT.dformat(k,1) = tmp;
5617  HDR.AS.SPR(k) = 1;
5618  if isempty(tmp1)
5619  elseif tmp1(1)=='x'
5620  HDR.AS.SPR(k) = str2double(tmp1(2:end));
5621  elseif tmp1(1)==':'
5622  fprintf(HDR.FILE.stderr,'Warning SOPEN: skew information in %s is ignored.\n', HDR.FileName);
5623  end
5624  elseif k0==2,
5625  % EC13*.HEA files have special gain values like "200(23456)/uV".
5626  [tmp, tmp2] = strtok(tmp,'/');
5627  tmp2 = [tmp2(2:end),' '];
5628  HDR.PhysDim(k,1:length(tmp2)) = tmp2;
5629  [tmp, tmp1] = strtok(tmp,' ()');
5630  [tmp, status] = str2double(tmp);
5631  if isempty(tmp), tmp = 0; end; % gain
5632  if isnan(tmp), tmp = 0; end;
5633  HDR.MIT.gain(1,k) = tmp;
5634  elseif k0==3,
5635  [tmp, status] = str2double(tmp);
5636  if isempty(tmp), tmp = NaN; end;
5637  if isnan(tmp), tmp = NaN; end;
5638  HDR.Bits(1,k) = tmp;
5639  elseif k0==4,
5640  [tmp, status] = str2double(tmp);
5641  if isempty(tmp), tmp = 0; end;
5642  if isnan(tmp), tmp = 0; end;
5643  HDR.MIT.zerovalue(1,k) = tmp;
5644  elseif k0==5,
5645  [tmp, status] = str2double(tmp);
5646  if isempty(tmp), tmp = NaN; end;
5647  if isnan(tmp), tmp = NaN; end;
5648  HDR.MIT.firstvalue(1,k) = tmp; % first integer value of signal (to test for errors)
5649  else
5650 
5651  end;
5652  end;
5653  HDR.Label{k} = strtok(z,[9,10,13,32]);
5654  end;
5655 
5656  HDR.MIT.gain(HDR.MIT.gain==0) = 200; % default gain
5657  HDR.Calib = sparse([HDR.MIT.zerovalue; eye(HDR.NS)]*diag(1./HDR.MIT.gain(:)));
5658 
5659  z = char(fread(fid,[1,inf],'uint8'));
5660  ix1 = [strfind(upper(z),'AGE:')+4, strfind(upper(z),'AGE>:')+5];
5661  if ~isempty(ix1),
5662  [tmp,z]=strtok(z(ix1(1):length(z)));
5663  HDR.Patient.Age = str2double(tmp);
5664  end;
5665  ix1 = [strfind(upper(z),'SEX:')+4, strfind(upper(z),'SEX>:')+5];
5666  if ~isempty(ix1),
5667  [HDR.Patient.Sex,z]=strtok(z(ix1(1):length(z)));
5668  end;
5669  ix1 = [strfind(upper(z),'BMI:')+4, strfind(upper(z),'BMI>:')+5];
5670  if ~isempty(ix1),
5671  [tmp,z]=strtok(z(ix1(1):length(z)));
5672  HDR.Patient.BMI = str2double(tmp);
5673  end;
5674  ix1 = [strfind(upper(z),'DIAGNOSIS:')+10; strfind(upper(z),'DIAGNOSIS>:')+11];
5675  if ~isempty(ix1),
5676  [HDR.Patient.Diagnosis,z]=strtok(z(ix1(1):length(z)),char([10,13,abs('#<>')]));
5677  end;
5678  ix1 = [strfind(upper(z),'MEDICATIONS:')+12, strfind(upper(z),'MEDICATIONS>:')+13];
5679  if ~isempty(ix1),
5680  [HDR.Patient.Medication,z]=strtok(z(ix1(1):length(z)),char([10,13,abs('#<>')]));
5681  end;
5682  fclose(fid);
5683 
5684  %------ LOAD ATR FILE ---------------------------------------------------
5685  tmp = fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.atr']);
5686  if ~exist(tmp,'file'),
5687  tmp = fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.ATR']);
5688  end;
5689  if exist(tmp,'file'),
5690  H = sopen(tmp);
5691  HDR.EVENT = H.EVENT;
5692  HDR.EVENT.SampleRate = HDR.SampleRate;
5693  end;
5694 
5695  %------ LOAD BINARY DATA --------------------------------------------------
5696  if ~HDR.NS,
5697  return;
5698  end;
5699  if all(HDR.MIT.dformat==HDR.MIT.dformat(1)),
5700  HDR.VERSION = HDR.MIT.dformat(1);
5701  else
5702  fprintf(HDR.FILE.stderr,'Error SOPEN: different DFORMATs not supported.\n');
5703  HDR.FILE.FID = -1;
5704  return;
5705  end;
5706 
5707  GDFTYP = repmat(NaN,HDR.NS,1);
5708  GDFTYP(HDR.MIT.dformat==80) = 2;
5709  GDFTYP(HDR.MIT.dformat==16) = 3;
5710  GDFTYP(HDR.MIT.dformat==24) = 255+24;
5711  GDFTYP(HDR.MIT.dformat==32) = 5;
5712  GDFTYP(HDR.MIT.dformat==61) = 3;
5713  GDFTYP(HDR.MIT.dformat==160)= 4;
5714  GDFTYP(HDR.MIT.dformat==212)= 255+12;
5715  GDFTYP(HDR.MIT.dformat==310)= 255+10;
5716  GDFTYP(HDR.MIT.dformat==311)= 255+10;
5717  if ~any(isnan(GDFTYP)), HDR.GDFTYP = GDFTYP; end;
5718  HDR.RID = HDR.FILE(1).Name;
5719  HDR.PID = '';
5720 
5721  HDR.AS.spb = sum(HDR.AS.SPR);
5722  if 0,
5723 
5724  elseif HDR.VERSION == 212,
5725  HDR.AS.bpb = HDR.AS.spb*3/2;
5726  elseif HDR.VERSION == 310,
5727  HDR.AS.bpb = HDR.AS.spb/3*4;
5728  elseif HDR.VERSION == 311,
5729  HDR.AS.bpb = HDR.AS.spb/3*4;
5730  elseif HDR.VERSION == 8,
5731  HDR.AS.bpb = HDR.AS.spb;
5732  elseif HDR.VERSION == 80,
5733  HDR.AS.bpb = HDR.AS.spb;
5734  elseif HDR.VERSION == 160,
5735  HDR.AS.bpb = HDR.AS.spb;
5736  elseif HDR.VERSION == 16,
5737  HDR.AS.bpb = HDR.AS.spb;
5738  elseif HDR.VERSION == 61,
5739  HDR.AS.bpb = HDR.AS.spb;
5740  end;
5741  if HDR.AS.bpb==round(HDR.AS.bpb),
5742  d = 1;
5743  else
5744  [HDR.AS.bpb,d] = rat(HDR.AS.bpb);
5745  HDR.NRec = HDR.NRec/d;
5746  HDR.AS.SPR = HDR.AS.SPR*d;
5747  HDR.AS.spb = HDR.AS.spb*d;
5748  end;
5749  HDR.AS.bi = [0;cumsum(HDR.AS.SPR(:))];
5750  HDR.SPR = HDR.AS.SPR(1);
5751  for k = 2:HDR.NS,
5752  HDR.SPR = lcm(HDR.SPR,HDR.AS.SPR(k));
5753  end;
5754  HDR.AS.SampleRate = HDR.SampleRate*HDR.AS.SPR/d;
5755  HDR.SampleRate = HDR.SampleRate*HDR.SPR/d;
5756  HDR.Dur = HDR.SPR/HDR.SampleRate;
5757 
5758  if HDR.VERSION ==61,
5759  MACHINE_FORMAT='ieee-be';
5760  else
5761  MACHINE_FORMAT='ieee-le';
5762  end;
5763 
5764  DAT = char(HDR.FILE.DAT);
5765  if all(all(DAT == DAT(ones(size(DAT,1),1),:))),
5766  % single DAT-file: only this provides high performance
5767  HDR.FILE.DAT = DAT(1,:);
5768 
5769  tmpfile = fullfile(HDR.FILE.Path,HDR.FILE.DAT);
5770  if ~exist(tmpfile,'file'),
5771  HDR.FILE.DAT = upper(HDR.FILE.DAT);
5772  tmpfile = fullfile(HDR.FILE.Path,HDR.FILE.DAT);
5773  end;
5774  if ~exist(tmpfile,'file'),
5775  HDR.FILE.DAT = lower(HDR.FILE.DAT);
5776  tmpfile = fullfile(HDR.FILE.Path,HDR.FILE.DAT);
5777  end;
5778  HDR.FILE.FID = fopen(tmpfile,'rb',MACHINE_FORMAT);
5779  if HDR.FILE.FID<0,
5780  fprintf(HDR.FILE.stderr,'Error SOPEN: Couldnot open file %s\n',tmpfile);
5781  return;
5782  end;
5783 
5784  HDR.FILE.OPEN = 1;
5785  HDR.FILE.POS = 0;
5786  HDR.HeadLen = 0;
5787  status = fseek(HDR.FILE.FID,0,'eof');
5788  tmp = ftell(HDR.FILE.FID);
5789  try
5790  HDR.AS.endpos = tmp/HDR.AS.bpb;
5791  catch
5792  fprintf(HDR.FILE.stderr,'Warning 2003 SOPEN: FTELL does not return numeric value (Octave > 2.1.52).\nHDR.AS.endpos not completed.\n');
5793  end;
5794  status = fseek(HDR.FILE.FID,0,'bof');
5795 
5796  HDR.InChanSelect = 1:HDR.NS;
5797  FLAG_UCAL = HDR.FLAG.UCAL;
5798  HDR.FLAG.UCAL = 1;
5799  S = NaN;
5800  [S,HDR] = sread(HDR,HDR.SPR/HDR.SampleRate); % load 1st sample
5801  if (HDR.VERSION>0) && (any(S(1,:) - HDR.MIT.firstvalue)),
5802  fprintf(HDR.FILE.stderr,'Warning SOPEN MIT-ECG: First values of header and datablock do not fit in file %s.\n\tHeader:\t',HDR.FileName);
5803  fprintf(HDR.FILE.stderr,'\t%5i',HDR.MIT.firstvalue);
5804  fprintf(HDR.FILE.stderr,'\n\tData 1:\t');
5805  fprintf(HDR.FILE.stderr,'\t%5i',S(1,:));
5806  fprintf(HDR.FILE.stderr,'\n');
5807  end;
5808  HDR.FLAG.UCAL = FLAG_UCAL ;
5809  fseek(HDR.FILE.FID,0,'bof'); % reset file pointer
5810 
5811  else
5812  % Multi-DAT files
5813  [i,j,k]=unique(HDR.FILE.DAT);
5814  for k1 = 1:length(j),
5815  ix = (k==k1);
5816  f = fullfile(HDR.FILE.Path,HDR.FILE.DAT{j(k1)});
5817  hdr.FILE.FID = fopen(f,'rb');
5818  if hdr.FILE.FID>0,
5819  hdr.FILE.stderr = HDR.FILE.stderr;
5820  hdr.FILE.stdout = HDR.FILE.stdout;
5821  hdr.FILE.POS = 0;
5822  hdr.NS = sum(ix);
5823  hdr.InChanSelect = 1:hdr.NS;
5824  hdr.MIT.dformat = HDR.MIT.dformat(ix);
5825  %hdr.Calib = HDR.Calib(:,ix);
5826  hdr.AS.spb = sum(HDR.AS.SPR(ix));
5827  hdr.SampleRate = HDR.SampleRate;
5828  hdr.TYPE = 'MIT';
5829  hdr.SPR = HDR.SPR;
5830  hdr.AS.SPR = HDR.AS.SPR(ix);
5831  hdr.FLAG = HDR.FLAG;
5832  hdr.FLAG.UCAL = 1;
5833 
5834  if all(hdr.MIT.dformat(1)==hdr.MIT.dformat),
5835  hdr.VERSION = hdr.MIT.dformat(1);
5836  else
5837  fprintf(hdr.FILE.stderr,'different DFORMATs not supported.\n');
5838  hdr.FILE.FID = -1;
5839  return;
5840  end;
5841  if 0,
5842 
5843  elseif hdr.VERSION == 212,
5844  if mod(hdr.AS.spb,2)
5845  hdr.AS.spb = hdr.AS.spb*2;
5846  end
5847  hdr.AS.bpb = hdr.AS.spb*3/2;
5848  elseif hdr.VERSION == 310,
5849  if mod(hdr.AS.spb,3)
5850  hdr.AS.spb = hdr.AS.spb*2/3;
5851  end
5852  hdr.AS.bpb = hdr.AS.spb*2;
5853  elseif hdr.VERSION == 311,
5854  if mod(hdr.AS.spb,3)
5855  hdr.AS.spb = hdr.AS.spb*3;
5856  end
5857  hdr.AS.bpb = hdr.AS.spb*4;
5858  elseif hdr.VERSION == 8,
5859  hdr.AS.bpb = hdr.AS.spb;
5860  elseif hdr.VERSION == 80,
5861  hdr.AS.bpb = hdr.AS.spb;
5862  elseif hdr.VERSION == 160,
5863  hdr.AS.bpb = hdr.AS.spb;
5864  elseif hdr.VERSION == 16,
5865  hdr.AS.bpb = hdr.AS.spb;
5866  elseif hdr.VERSION == 61,
5867  hdr.AS.bpb = hdr.AS.spb;
5868  end;
5869  [s,hdr] = sread(hdr);
5870  fclose(hdr.FILE.FID);
5871  else
5872  s = [];
5873  end;
5874 
5875  if k1==1,
5876  HDR.data = s;
5877  else
5878  n = [size(s,1),size(HDR.data,1)];
5879  if any(n~=n(1)),
5880  fprintf(HDR.FILE.stderr,'Warning SOPEN MIT-ECG(%s): lengths of %s (%i) and %s (%i) differ\n',HDR.FileName,HDR.FILE.DAT{j(k1-1)},n(1),HDR.FILE.DAT{j(k1)},n(2));
5881  end;
5882  n = min(n);
5883  HDR.data = [HDR.data(1:n,:),s(1:n,:)];
5884  end;
5885  end;
5886  HDR.FILE.POS = 0;
5887  HDR.TYPE = 'native';
5888  end;
5889  end;
5890 
5891  elseif any(HDR.FILE.PERMISSION=='w'),
5892 
5893  fn = fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.hea']);
5894  fid = fopen(fn,'wt','ieee-le');
5895  fprintf(fid, '%s %i %f %i %02i:%02i:%02i %02i/%02i/%04i',HDR.FILE.Name,HDR.NS,HDR.SampleRate,HDR.NRec*HDR.SPR,HDR.T0([4:6,3,2,1]));
5896  if ~isfield(HDR,'GDFTYP')
5897  HDR.GDFTYP=repmat(3,1,HDR.NS); % int16
5898  end;
5899  for k = 1:HDR.NS,
5900  if 0,
5901  elseif HDR.GDFTYP(k)==2,
5902  HDR.MIT.dformat = 80;
5903  elseif HDR.GDFTYP(k)==3,
5904  HDR.MIT.dformat = 16;
5905  elseif HDR.GDFTYP(k)==4,
5906  HDR.MIT.dformat = 160;
5907  else
5908  error('SOPEN (MIT write): dataformat not supported');
5909  end;
5910  ical = (HDR.DigMax(k)-HDR.DigMin(k))/(HDR.PhysMax(k)-HDR.PhysMin(k));
5911  off = HDR.DigMin(k) - ical*HDR.PhysMin(k);
5912  fprintf(fid,'\n%s %i %f(%f)',[HDR.FILE.Name,'.dat'],HDR.MIT.dformat,ical,off);
5913 
5914  if isfield(HDR,'PhysDim')
5915  physdim = HDR.PhysDim(k,:);
5916  physdim(physdim<33) = []; % remove any whitespace
5917  fprintf(fid,'/%s ',physdim);
5918  end;
5919  if isfield(HDR,'Label')
5920  fprintf(fid,'%s ',HDR.Label(k,:));
5921  end;
5922  end;
5923  fclose(fid);
5924  HDR.Cal = (HDR.PhysMax-HDR.PhysMin)./(HDR.DigMax-HDR.DigMin);
5925  HDR.Off = HDR.PhysMin - HDR.Cal .* HDR.DigMin;
5926 
5927  HDR.FileName = fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.dat']);
5928  HDR.FILE.FID = fopen(HDR.FileName,'wb','ieee-le');
5929  HDR.FILE.OPEN = 2;
5930  end;
5931 
5932 
5933 elseif strcmp(HDR.TYPE,'MIT-ATR'),
5934  tmp = dir(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.hea']));
5935  if isempty(tmp)
5936  tmp = dir(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.HEA']));
5937  end;
5938  if isempty(tmp)
5939  fprintf(HDR.FILE.stderr,'Warning SOPEN: no corresponing header file found for MIT-ATR EVENT file %s.\n',HDR.FileName);
5940  end;
5941 
5942  %------ LOAD ATTRIBUTES DATA ----------------------------------------------
5943  fid = fopen(HDR.FileName,'rb','ieee-le');
5944  if fid<0,
5945  A = 0; c = 0;
5946  else
5947  [A,c] = fread(fid, inf, 'uint16');
5948  fclose(fid);
5949  end;
5950 
5951  EVENTTABLE = repmat(NaN,c,3);
5952  Desc = repmat({''},ceil(c),1);
5953  FLAG63 = 0;
5954  K = 0;
5955  i = 1;
5956  ch = 0;
5957  accu = 0;
5958 
5959  tmp = floor(A(:)/1024);
5960  annoth = tmp;
5961  L = A(:) - tmp*1024;
5962  tmp = floor(A(:)/256);
5963  t0 = char([A(:)-256*tmp, tmp])';
5964  while ((i<=size(A,1)) && (A(i)>0)),
5965  a = annoth(i);
5966  if a==0, % end of file
5967 
5968  elseif a<50,
5969  K = K + 1;
5970  accu = accu + L(i);
5971  EVENTTABLE(K,:) = [a,accu,ch];
5972  elseif a==59, % SKIP
5973  if (L(i)==0),
5974  accu = accu + (2.^[0,16])*[A(i+2);A(i+1)];
5975  i = i + 2;
5976  else
5977  accu = accu + L(i);
5978  end;
5979  %elseif a==60, % NUM
5980  %[60,L,A(i)]
5981  % nothing to do!
5982  %elseif a==61, % SUB
5983  %[61,L,A(i)]
5984  % nothing to do!
5985  elseif a==62, % CHN
5986  ch = L(i);
5987  elseif a==63, % AUX
5988  c = ceil(L(i)/2);
5989  t = t0(:,i+1:i+c)';
5990  Desc{K} = t(:)';
5991  FLAG63 = 1;
5992  i = i + c;
5993  end;
5994  i = i + 1;
5995  end;
5996  HDR.EVENT.TYP = EVENTTABLE(1:K,1); % + hex2dec('0540');
5997  HDR.EVENT.POS = EVENTTABLE(1:K,2);
5998  HDR.EVENT.CHN = EVENTTABLE(1:K,3);
5999  HDR.EVENT.DUR = zeros(K,1);
6000  if FLAG63, HDR.EVENT.Desc = Desc(1:K); end;
6001  HDR.TYPE = 'EVENT';
6002 
6003 
6004 elseif strcmp(HDR.TYPE,'TMS32'), % Portilab/TMS32/Poly5 format
6005  if any(HDR.FILE.PERMISSION=='r'),
6006  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
6007  HDR.ID = fread(HDR.FILE.FID,31,'uint8');
6008  HDR.VERSION = fread(HDR.FILE.FID,1,'int16'); % 31
6009  [tmp,c] = fread(HDR.FILE.FID,81,'uint8'); % 33
6010  HDR.SampleRate = fread(HDR.FILE.FID,1,'int16'); % 114
6011  HDR.TMS32.StorageRate = fread(HDR.FILE.FID,1,'int16'); % 116
6012  HDR.TMS32.StorageType = fread(HDR.FILE.FID,1,'uint8'); % 118
6013  HDR.NS = fread(HDR.FILE.FID,1,'int16'); % 119
6014  HDR.AS.endpos = fread(HDR.FILE.FID,1,'int32'); % 121
6015  tmp = fread(HDR.FILE.FID,1,'int32'); % 125
6016  tmp = fread(HDR.FILE.FID,[1,7],'int16'); % 129
6017  HDR.T0 = tmp([1:3,5:7]);
6018  HDR.NRec = fread(HDR.FILE.FID,1,'int32'); % 143
6019  HDR.SPR = fread(HDR.FILE.FID,1,'uint16'); % 147
6020  HDR.AS.bpb = fread(HDR.FILE.FID,1,'uint16')+86; % 149
6021  HDR.FLAG.DeltaCompression = fread(HDR.FILE.FID,1,'int16'); % 151
6022  tmp = fread(HDR.FILE.FID,64,'uint8'); % 153
6023  HDR.HeadLen = 217 + HDR.NS*136;
6024  HDR.FILE.OPEN = 1;
6025  HDR.FILE.POS = 0;
6026 
6027  aux = 0;
6028  for k=1:HDR.NS,
6029  c = fread(HDR.FILE.FID,[1,1],'uint8');
6030  tmp = fread(HDR.FILE.FID,[1,40],'uint8=>char');
6031  if strncmp(tmp,'(Lo)',4);
6032  %Label(k-aux,1:c-5) = tmp(6:c);
6033  HDR.Label{k-aux} = deblank(tmp(6:c));
6034  HDR.GDFTYP(k-aux) = 16;
6035  elseif strncmp(tmp,'(Hi) ',5) ;
6036  aux = aux + 1;
6037  else
6038  HDR.Label{k-aux} = deblank(tmp(1:c));
6039  HDR.GDFTYP(k-aux) = 3;
6040  end;
6041 
6042  tmp = fread(HDR.FILE.FID,[1,4],'uint8');
6043  c = fread(HDR.FILE.FID,[1,1],'uint8');
6044  tmp = fread(HDR.FILE.FID,[1,10],'uint8=>char');
6045  HDR.PhysDim{k-aux} = deblank(tmp(1:c));
6046 
6047  HDR.PhysMin(k-aux,1) = fread(HDR.FILE.FID,1,'float32');
6048  HDR.PhysMax(k-aux,1) = fread(HDR.FILE.FID,1,'float32');
6049  HDR.DigMin(k-aux,1) = fread(HDR.FILE.FID,1,'float32');
6050  HDR.DigMax(k-aux,1) = fread(HDR.FILE.FID,1,'float32');
6051  HDR.TMS32.SI(k) = fread(HDR.FILE.FID,1,'int16');
6052  tmp = fread(HDR.FILE.FID,62,'uint8');
6053  end;
6054  HDR.NS = HDR.NS-aux;
6055  HDR.Cal = (HDR.PhysMax-HDR.PhysMin)./(HDR.DigMax-HDR.DigMin);
6056  HDR.Off = HDR.PhysMin - HDR.Cal .* HDR.DigMin;
6057  HDR.Calib = sparse([HDR.Off';(diag(HDR.Cal))]);
6058  end;
6059 
6060 elseif strcmp(HDR.TYPE,'TMSiLOG'),
6061  if any(HDR.FILE.PERMISSION=='r'),
6062  %fid = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
6063  %H1 = fread(fid,[1,inf],'uint8=>char');
6064  %fclose(fid);
6065  %getfiletype read whole header file into HDR.H1
6066  GDFTYP = 0;
6067  HDR.SPR = 1;
6068  HDR.NRec = 1;
6069  [line,r] = strtok(HDR.H1,[13,10]);
6070  ix = find(line=='=');
6071  while ~isempty(ix)
6072  tag = line(1:ix-1);
6073  val = deblank(line(ix+1:end));
6074  if strcmp(tag,'DateTime')
6075  val(val=='/' | val=='-' | val==':') = ' ';
6076  HDR.T0 = str2double(val);
6077  elseif strcmp(tag,'Format')
6078  if strcmp(val,'Int16') GDFTYP = 3;
6079  elseif strcmp(val,'Int32') GDFTYP = 5;
6080  elseif strcmp(val,'Float32') GDFTYP = 16;
6081  elseif strcmp(val,'Ascii') GDFTYP = -1;
6082  % else val,abs(val),
6083  end;
6084  elseif strcmp(tag,'Length')
6085  duration = str2double(val);
6086  elseif strcmp(tag,'Signals')
6087  HDR.NS = str2double(val);
6088  elseif strncmp(tag,'Signal',6)
6089  ch = str2double(tag(7:10));
6090  HDR.NS = str2double(val);
6091  if strcmp(tag(12:end),'Name')
6092  HDR.Label{ch}=val;
6093  elseif strcmp(tag(12:end),'UnitName')
6094  HDR.PhysDim{ch}=val;
6095  elseif strcmp(tag(12:end),'Resolution')
6096  HDR.Cal(ch)=str2double(val);
6097  elseif strcmp(tag(12:end),'StoreRate')
6098  HDR.AS.SampleRate(ch)=str2double(val);
6099  HDR.AS.SPR = HDR.AS.SampleRate(ch)*duration;
6100  HDR.SPR = lcm(HDR.SPR, HDR.AS.SPR);
6101  elseif strcmp(tag(12:end),'File')
6102  HDR.TMSi.FN{ch}=val;
6103  elseif strcmp(tag(12:end),'Index')
6104  end;
6105  end;
6106  [line,r]=strtok(r,[13,10]);
6107  ix = find(line=='=');
6108  end;
6109 
6110  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
6111  HDR.SampleRate = HDR.SPR/duration;
6112  HDR.GDFTYP = repmat(GDFTYP,1,HDR.NS);
6113  HDR.TMSi.FN = unique(HDR.TMSi.FN);
6114  if length(HDR.TMSi.FN)==1,
6115  if (GDFTYP>0)
6116  fid = fopen(fullfile(HDR.FILE.Path,HDR.TMSi.FN{1}),'rb');
6117  tmp = fread(fid,[1,3],'int16');
6118  switch tmp(3)
6119  case {16}
6120  GDFTYP=3;
6121  case {32}
6122  GDFTYP=5;
6123  case {32+256}
6124  GDFTYP=16;
6125  end;
6126  HDR.data = fread(fid, [HDR.NS,inf], gdfdatatype(GDFTYP))';
6127  fclose(fid);
6128 
6129  elseif (GDFTYP==-1)
6130  fid = fopen(fullfile(HDR.FILE.Path,HDR.TMSi.FN{1}),'rt');
6131  line = fgetl(fid);
6132  line = fgetl(fid);
6133  line = fgetl(fid);
6134  tmp = fread(fid,[1,inf],'uint8=>char');
6135  fclose(fid);
6136  [n,v,sa] = str2double(tmp);
6137  HDR.data = n(:,2:end);
6138  end;
6139  end
6140  HDR.TYPE = 'native';
6141  end;
6142 
6143 
6144 elseif 0, strcmp(HDR.TYPE,'DAQ'),
6145  HDR = daqopen(HDR,[HDR.FILE.PERMISSION,'b']);
6146 
6147 
6148 elseif strcmp(HDR.TYPE,'MAT4') && any(HDR.FILE.PERMISSION=='r'),
6149  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],HDR.MAT4.opentyp);
6150  k=0; NB=0;
6151  %type = fread(HDR.FILE.FID,4,'uint8'); % 4-byte header
6152  type = fread(HDR.FILE.FID,1,'uint32'); % 4-byte header
6153  while ~isempty(type),
6154  type = sprintf('%04i',type)';
6155  type = type - abs('0');
6156  k = k + 1;
6157  [mrows,c] = fread(HDR.FILE.FID,1,'uint32'); % tag, datatype
6158  ncols = fread(HDR.FILE.FID,1,'uint32'); % tag, datatype
6159  imagf = fread(HDR.FILE.FID,1,'uint32'); % tag, datatype
6160  namelen = fread(HDR.FILE.FID,1,'uint32'); % tag, datatype
6161  if namelen>HDR.FILE.size,
6162  % fclose(HDR.FILE.FID);
6163  HDR.ErrNum = -1;
6164  HDR.ErrMsg = sprintf('Error SOPEN (MAT4): Could not open %s\n',HDR.FileName);
6165  return;
6166  end;
6167  [name,c] = fread(HDR.FILE.FID,namelen,'uint8');
6168 
6169  if imagf,
6170  HDR.ErrNum=-1;
6171  fprintf(HDR.FILE.stderr,'Warning %s: Imaginary data not tested\n',mfilename);
6172  end;
6173  if type(4)==2,
6174  HDR.ErrNum=-1;
6175  fprintf(HDR.FILE.stderr,'Error %s: sparse data not supported\n',mfilename);
6176  elseif type(4)>2,
6177  type(4)=rem(type(4),2);
6178  end;
6179 
6180  dt=type(3);
6181  if dt==0, SIZOF=8; TYP = 'float64';
6182  elseif dt==6, SIZOF=1; TYP = 'uint8';
6183  elseif dt==4, SIZOF=2; TYP = 'uint16';
6184  elseif dt==3, SIZOF=2; TYP = 'int16';
6185  elseif dt==2, SIZOF=4; TYP = 'int32';
6186  elseif dt==1, SIZOF=4; TYP = 'float32';
6187  else
6188  fprintf(HDR.FILE.stderr,'Error %s: unknown data type\n',mfilename);
6189  end;
6190 
6191  HDR.Var(k).Name = char(name(1:length(name)-1)');
6192  HDR.Var(k).Size = [mrows,ncols];
6193  HDR.Var(k).SizeOfType = SIZOF;
6194  HDR.Var(k).Type = [type;~~imagf]';
6195  HDR.Var(k).TYP = TYP;
6196  HDR.Var(k).Pos = ftell(HDR.FILE.FID);
6197 
6198  c=0;
6199  %% find the ADICHT data channels
6200  if strfind(HDR.Var(k).Name,'data_block'),
6201  HDR.ADI.DB(str2double(HDR.Var(k).Name(11:length(HDR.Var(k).Name))))=k;
6202  elseif strfind(HDR.Var(k).Name,'ticktimes_block'),
6203  HDR.ADI.TB(str2double(HDR.Var(k).Name(16:length(HDR.Var(k).Name))))=k;
6204  end;
6205 
6206  tmp1=ftell(HDR.FILE.FID);
6207 
6208  % skip next block
6209  tmp=(prod(HDR.Var(k).Size)-c)*HDR.Var(k).SizeOfType*(1+(~~imagf));
6210  fseek(HDR.FILE.FID,tmp,0);
6211 
6212  tmp2=ftell(HDR.FILE.FID);
6213  if (tmp2-tmp1) < tmp, % if skipping the block was not successful
6214  HDR.ErrNum = -1;
6215  HDR.ErrMsg = sprintf('file %s is corrupted',HDR.FileName);
6216  fprintf(HDR.FILE.stderr,'Error SOPEN: MAT4 (ADICHT) file %s is corrupted\n',HDR.FileName);
6217  return;
6218  end;
6219 
6220  %type = fread(HDR.FILE.FID,4,'uint8'); % 4-byte header
6221  type = fread(HDR.FILE.FID,1,'uint32'); % 4-byte header
6222  end;
6223  HDR.FILE.OPEN = 1;
6224  HDR.FILE.POS = 0;
6225 
6226 
6227  if isfield(HDR,'ADI')
6228  HDR.TYPE = 'ADI', % ADICHT-data, converted into a Matlab 4 file
6229 
6230  fprintf(HDR.FILE.stderr,'Format not tested yet. \nFor more information contact <Biosig-general@lists.sourceforge.net> Subject: Biosig/Dataformats \n',HDR.FILE.PERMISSION);
6231 
6232  %% set internal sampling rate to 1000Hz (default). Set HDR.iFs=[] if no resampling should be performed
6233  HDR.iFs = []; %1000;
6234  HDR.NS = HDR.Var(HDR.ADI.DB(1)).Size(1);
6235  HDR.ADI.comtick = [];
6236  HDR.ADI.comTick = [];
6237  HDR.ADI.comtext = [];
6238  HDR.ADI.comchan = [];
6239  HDR.ADI.comblok = [];
6240  HDR.ADI.index = [];
6241  HDR.ADI.range = [];
6242  HDR.ADI.scale = [];
6243  HDR.ADI.titles = [];
6244 
6245  HDR.ADI.units = [];
6246 
6247  for k=1:length(HDR.ADI.TB),
6248  [HDR,t1] = matread(HDR,['ticktimes_block' int2str(k)],[1 2]); % read first and second element of timeblock
6249  [HDR,t2] = matread(HDR,['ticktimes_block' int2str(k)],HDR.Var(HDR.ADI.DB(k)).Size(2)); % read last element of timeblock
6250  HDR.ADI.ti(k,1:2) = [t1(1),t2];
6251  HDR.SampleRate(k) = round(1/diff(t1));
6252 
6253  [HDR,tmp] = matread(HDR,['comtick_block' int2str(k)]); % read first and second element of timeblock
6254  HDR.ADI.comtick = [HDR.ADI.comtick;tmp];
6255  %HDR.ADI.comTick = [HDR.ADI.comTick;tmp/HDR.SampleRate(k)+HDR.ADI.ti(k,1)];
6256  [HDR,tmp] = matread(HDR,['comchan_block' int2str(k)]); % read first and second element of timeblock
6257  HDR.ADI.comchan = [HDR.ADI.comchan;tmp];
6258  [HDR,tmp] = matread(HDR,['comtext_block' int2str(k)]); % read first and second element of timeblock
6259  tmp2 = size(HDR.ADI.comtext,2)-size(tmp,2);
6260  if tmp2>=0,
6261  HDR.ADI.comtext = [HDR.ADI.comtext;[tmp,zeros(size(tmp,1),tmp2)]];
6262  else
6263  HDR.ADI.comtext = [[HDR.ADI.comtext,zeros(size(HDR.ADI.comtext,1),-tmp2)];tmp];
6264  end;
6265  HDR.ADI.comblok=[HDR.ADI.comblok;repmat(k,size(tmp,1),1)];
6266 
6267  [HDR,tmp] = matread(HDR,['index_block' int2str(k)]); % read first and second element of timeblock
6268  if isempty(tmp),
6269  HDR.ADI.index{k} = 1:HDR.NS;
6270  else
6271  HDR.NS=length(tmp); %
6272  HDR.ADI.index{k} = tmp;
6273  end;
6274  [HDR,tmp] = matread(HDR,['range_block' int2str(k)]); % read first and second element of timeblock
6275  HDR.ADI.range{k} = tmp;
6276  [HDR,tmp] = matread(HDR,['scale_block' int2str(k)]); % read first and second element of timeblock
6277  HDR.ADI.scale{k} = tmp;
6278  [HDR,tmp] = matread(HDR,['titles_block' int2str(k)]); % read first and second element of timeblock
6279  HDR.ADI.titles{k} = tmp;
6280 
6281  [HDR,tmp] = matread(HDR,['units_block' int2str(k)]); % read first and second element of timeblock
6282  HDR.ADI.units{k} = char(tmp);
6283  if k==1;
6284  HDR.PhysDim = char(sparse(find(HDR.ADI.index{1}),1:sum(HDR.ADI.index{1}>0),1)*HDR.ADI.units{1}); % for compatibility with the EDF toolbox
6285  elseif any(size(HDR.ADI.units{k-1})~=size(tmp))
6286  fprintf(HDR.FILE.stderr,'Warning MATOPEN: Units are different from block to block\n');
6287  elseif any(any(HDR.ADI.units{k-1}~=tmp))
6288  fprintf(HDR.FILE.stderr,'Warning MATOPEN: Units are different from block to block\n');
6289  end;
6290  HDR.PhysDim = char(sparse(find(HDR.ADI.index{k}),1:sum(HDR.ADI.index{k}>0),1)*HDR.ADI.units{k}); % for compatibility with the EDF toolbox
6291  %HDR.PhysDim=HDR.ADI.PhysDim;
6292  end;
6293  HDR.T0 = datevec(datenum(1970,1,1)+HDR.ADI.ti(1,1)/24/3600);
6294  for k=1:size(HDR.ADI.comtext,1),
6295  HDR.ADI.comtime0(k)=HDR.ADI.comtick(k)./HDR.SampleRate(HDR.ADI.comblok(k))'+HDR.ADI.ti(HDR.ADI.comblok(k),1)-HDR.ADI.ti(1,1);
6296  end;
6297 
6298  % Test if timeindex is increasing
6299  tmp = size(HDR.ADI.ti,1);
6300  if ~all(HDR.ADI.ti(2:tmp,2)>HDR.ADI.ti(1:tmp-1,1)),
6301  HDR.ErrNum=-1;
6302  fprintf(HDR.FILE.stderr,'Warning MATOPEN: Time index are not monotonic increasing !!!\n');
6303  return;
6304  end;
6305  % end of ADI-Mode
6306  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,ones(1,HDR.NS));
6307  else
6308  fclose(HDR.FILE.FID);
6309  HDR.FILE.FID = -1;
6310  return;
6311  end;
6312 
6313 
6314 elseif strcmp(HDR.TYPE,'BCI2002b');
6315  % BCI competition 2002, dataset b (EEG synchronized imagined movement task) provided by Allen Osman, University of Pennsylvania).
6316  HDR.NS = 59;
6317  HDR.GDFTYP = 16; % float32
6318  if any(HDR.FILE.PERMISSION=='r'),
6319  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path, 'alldata.bin'),[HDR.FILE.PERMISSION,'b'],'ieee-be');
6320  HDR.data = fread(HDR.FILE.FID,[HDR.NS,inf],'float32')';
6321  fclose(HDR.FILE.FID);
6322  HDR.SPR = size(HDR.data,1);
6323  HDR.NRec = 1;
6324  HDR.SampleRate = 100; % Hz
6325  HDR.FILE.POS = 0;
6326  if ~isfield(HDR,'THRESHOLD')
6327  HDR.THRESHOLD = repmat([-125,124.93],HDR.NS,1)
6328  end;
6329 
6330  x1 = load(fullfile(HDR.FILE.Path, 'lefttrain.events'));
6331  x2 = load(fullfile(HDR.FILE.Path, 'righttrain.events'));
6332  x3 = load(fullfile(HDR.FILE.Path, 'test.events'));
6333  x = [x1; x2; x3];
6334  HDR.EVENT.POS = x(:,1);
6335  HDR.EVENT.TYP = (x(:,2)==5)*hex2dec('0301') + (x(:,2)==6)*hex2dec('0302') + (x(:,2)==7)*hex2dec('030f');
6336 
6337  HDR.TYPE = 'native';
6338 
6339  tmp = HDR.FILE.Path;
6340  if tmp(1)~='/',
6341  tmp = fullfile(pwd,tmp);
6342  end;
6343  while ~isempty(tmp)
6344  if exist(fullfile(tmp,'sensorlocations.txt'))
6345  fid = fopen(fullfile(tmp,'sensorlocations.txt'));
6346  s = fread(fid,[1,inf],'uint8=>char');
6347  fclose(fid);
6348  [NUM, STATUS,STRARRAY] = str2double(s);
6349  HDR.Label = STRARRAY(:,1);
6350  HDR.ELEC.XYZ = NUM(:,2:4);
6351  tmp = '';
6352  end;
6353  tmp = fileparts(tmp);
6354  end;
6355  end;
6356 
6357 
6358 elseif strcmp(HDR.TYPE,'BCI2003_Ia+b');
6359  % BCI competition 2003, dataset 1a+b (Tuebingen)
6360  data = load('-ascii',HDR.FileName);
6361  if strfind(HDR.FileName,'Testdata'),
6362  HDR.Classlabel = repmat(NaN,size(data,1),1);
6363  else
6364  HDR.Classlabel = data(:,1);
6365  data = data(:,2:end);
6366  end;
6367 
6368  HDR.NRec = length(HDR.Classlabel);
6369  HDR.FLAG.TRIGGERED = HDR.NRec>1;
6370  HDR.PhysDim = 'µV';
6371  HDR.SampleRate = 256;
6372 
6373  if strfind(HDR.FILE.Path,'a34lkt')
6374  HDR.INFO='BCI competition 2003, dataset 1a (Tuebingen)';
6375  HDR.Dur = 3.5;
6376  HDR.Label = {'A1-Cz';'A2-Cz';'C3f';'C3p';'C4f';'C4p'};
6377  HDR.TriggerOffset = -2; %[s]
6378  end;
6379 
6380  if strfind(HDR.FILE.Path,'egl2ln')
6381  HDR.INFO='BCI competition 2003, dataset 1b (Tuebingen)';
6382  HDR.Dur = 4.5;
6383  HDR.Label = {'A1-Cz';'A2-Cz';'C3f';'C3p';'vEOG';'C4f';'C4p'};
6384  HDR.TriggerOffset = -2; %[s]
6385  end;
6386  HDR.SPR = HDR.SampleRate*HDR.Dur;
6387  HDR.NS = length(HDR.Label);
6388  HDR.data = reshape(permute(reshape(data, [HDR.NRec, HDR.SPR, HDR.NS]),[2,1,3]),[HDR.SPR*HDR.NRec,HDR.NS]);
6389  HDR.TYPE = 'native';
6390  HDR.FILE.POS = 0;
6391 
6392 
6393 elseif strcmp(HDR.TYPE,'BCI2003_III');
6394  % BCI competition 2003, dataset III (Graz)
6395  tmp = load(HDR.FileName);
6396  HDR.data = [tmp*50;repmat(NaN,100,size(tmp,2))];
6397  if strcmp(HDR.FILE.Name,'x_train'),
6398  tmp = fullfile(HDR.FILE.Path,'y_train');
6399  if exist(tmp,'file')
6400  HDR.Classlabel = load(tmp);
6401  end;
6402  elseif strcmp(HDR.FILE.Name,'x_test'),
6403  HDR.Classlabel = repmat(NaN,140,1);
6404  end;
6405 
6406  %elseif isfield(tmp,'x_train') && isfield(tmp,'y_train') && isfield(tmp,'x_test');
6407  HDR.INFO = 'BCI competition 2003, dataset 3 (Graz)';
6408  HDR.Label = {'C3a-C3p'; 'Cza-Czp'; 'C4a-C4p'};
6409  HDR.SampleRate = 128;
6410  HDR.NRec = length(HDR.Classlabel);
6411  HDR.FLAG.TRIGGERED = 1;
6412  HDR.Dur = 9;
6413  HDR.NS = 3;
6414  HDR.SPR = size(HDR.data,1);
6415 
6416  sz = [HDR.NS, HDR.SPR, HDR.NRec];
6417  HDR.data = reshape(permute(reshape(HDR.data,sz([2,1,3])),[2,1,3]),sz(1),sz(2)*sz(3))';
6418  HDR.TYPE = 'native';
6419  HDR.FILE.POS = 0;
6420 
6421 
6422 elseif strncmp(HDR.TYPE,'MAT',3),
6423  status = warning;
6424  warning('off');
6425  tmp = whos('-file',HDR.FileName);
6426  tmp = load('-mat',HDR.FileName);
6427  warning(status);
6428 
6429  HDR.FILE.FID = 0;
6430  flag.bci2002a = isfield(tmp,'x') && isfield(tmp,'y') && isfield(tmp,'z') && isfield(tmp,'fs') && isfield(tmp,'elab');
6431  if flag.bci2002a,
6432  flag.bci2002a = all(size(tmp.y) == [1501,27,516]);
6433  end;
6434  flag.tfm = isfield(tmp,'HRV') || isfield(tmp,'BPV') || isfield(tmp,'BPVsBP'); % TFM BeatToBeat Matlab export
6435  if flag.tfm && isfield(tmp,'HRV'),
6436  flag.tfm = (isfield(tmp.HRV,'HF_RRI') && isfield(tmp.HRV,'LF_RRI') && isfield(tmp.HRV,'PSD_RRI') && isfield(tmp.HRV,'VLF_RRI'));
6437  end
6438  if flag.tfm && isfield(tmp,'BPV'),
6439  flag.tfm = flag.tfm + 2*((isfield(tmp.BPV,'HF_dBP') && isfield(tmp.BPV,'LF_dBP') && isfield(tmp.BPV,'PSD_dBP') && isfield(tmp.BPV,'VLF_dBP')));
6440  end
6441  if flag.tfm && isfield(tmp,'BPVsBP'),
6442  flag.tfm = flag.tfm + 4*((isfield(tmp.BPVsBP,'HF_sBP') && isfield(tmp.BPVsBP,'LF_sBP') && isfield(tmp.BPVsBP,'PSD_sBP') && isfield(tmp.BPVsBP,'VLF_sBP')));
6443  end;
6444  flag.bbci = isfield(tmp,'bbci') && isfield(tmp,'nfo');
6445  flag.bcic2008_1 = isfield(tmp,'cnt') && isfield(tmp,'nfo') && isfield(tmp,'mrk');
6446  flag.bcic2008_3 = isfield(tmp,'test_data') && isfield(tmp,'training_data') && isfield(tmp,'Info');
6447  flag.bcic2008_4 = isfield(tmp,'test_data') && isfield(tmp,'train_data') && isfield(tmp,'train_dg');
6448  if flag.bbci
6449  flag.bbci = isfield(tmp,'mnt') && isfield(tmp,'mrk') && isfield(tmp,'dat') && isfield(tmp,'fs_orig') && isfield(tmp,'mrk_orig');
6450  if ~(flag.bbci),
6451  warning('identification of bbci data may be not correct');
6452  end;
6453  end;
6454  flag.fieldtrip = isfield(tmp,'data');
6455  if flag.fieldtrip,
6456  flag.fieldtrip = isfield(tmp.data,'cfg') && isfield(tmp.data,'hdr') && isfield(tmp.data,'label') && isfield(tmp.data,'fsample');
6457  end;
6458  flag.brainvision = isfield(tmp,'Channels') && isfield(tmp,'ChannelCount') && isfield(tmp,'Markers') && isfield(tmp,'MarkerCount') && isfield(tmp,'SampleRate') && isfield(tmp,'SegmentCount') && isfield(tmp,'t');
6459 
6460  if isfield(tmp,'HDR'),
6461  H = HDR;
6462  HDR = tmp.HDR;
6463  HDR.FILE = H.FILE;
6464  HDR.FileName = H.FileName;
6465  if isfield(HDR,'data');
6466  HDR.TYPE = 'native';
6467  end;
6468  if ~isfield(HDR,'FLAG')
6469  HDR.FLAG.OVERFLOWDETECTION=0;
6470  end;
6471  if ~isfield(HDR.FLAG,'UCAL')
6472  HDR.FLAG.UCAL = 0;
6473  end;
6474  if ~isfield(HDR.FLAG,'TRIGGERED')
6475  HDR.FLAG.TRIGGERED=0;
6476  end;
6477  if ~isfield(HDR,'SampleRate')
6478  HDR.SampleRate = NaN;
6479  end;
6480  if ~isfield(HDR,'EVENT')
6481  HDR.EVENT.POS = [];
6482  HDR.EVENT.TYP = [];
6483  HDR.EVENT.CHN = [];
6484  HDR.EVENT.DUR = [];
6485  end;
6486  if ~isfield(HDR,'PhysDim') && ~isfield(HDR,'PhysDimCode')
6487  HDR.PhysDimCode = zeros(HDR.NS,1);
6488  end;
6489 
6490  elseif flag.brainvision,
6491  %% BrainVision Matlab export
6492  HDR.SPR = length(tmp.t);
6493  HDR.NS = tmp.ChannelCount;
6494  HDR.SampleRate = tmp.SampleRate;
6495  HDR.NRec= tmp.SegmentCount;
6496  HDR.Label = {tmp.Channels.Name}';
6497  HDR.data = zeros(HDR.SPR,HDR.NS);
6498  R=[tmp.Channels.Radius]'; Theta = [tmp.Channels.Theta]'*pi/180; Phi = [tmp.Channels.Phi]'*pi/180;
6499  HDR.ELEC.XYZ = R(:,ones(1,3)).*[sin(Theta).*cos(Phi),sin(Theta).*sin(Phi),cos(Theta)];
6500  HDR.PhysDimCode = repmat(4275,1,HDR.NS); % uV
6501  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1);
6502  HDR.GDFTYP = repmat(17,1,HDR.NS);
6503  for k = 1:HDR.NS,
6504  HDR.data(:,k) = getfield(tmp,tmp.Channels(k).Name);
6505  end;
6506 
6507  ch = strmatch('Status',HDR.Label);
6508  if 0,ch,
6509  HDR.BDF.ANNONS = round(2^24 + HDR.data(:,ch));
6510  HDR = bdf2biosig_events(HDR, FLAG.BDF.status2event);
6511  else
6512  % HDR.EVENT.N = tmp.MarkerCount;
6513  HDR.EVENT.POS = [tmp.Markers(:).Position]';
6514  HDR.EVENT.DUR = [tmp.Markers(:).Points]';
6515  HDR.EVENT.CHN = [tmp.Markers(:).ChannelNumber]';
6516  HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
6517  ix = strmatch('New Segment',{tmp.Markers.Type}');
6518  HDR.EVENT.TYP(ix) = hex2dec('7ffe');
6519  ix = HDR.EVENT.TYP==0;
6520  [HDR.EVENT.CodeDesc, CodeIndex, HDR.EVENT.TYP(ix)] = unique({tmp.Markers(ix).Description});
6521  end;
6522  HDR.TYPE = 'native';
6523  clear tmp;
6524 
6525  elseif flag.bcic2008_1, %isfield(tmp,'cnt') && isfield(tmp,'mrk') && isfield(tmp,'nfo')
6526  HDR.SampleRate = tmp.nfo.fs;
6527  HDR.NRec = 1;
6528  HDR.Label = tmp.nfo.clab';
6529  HDR.EVENT.POS = tmp.mrk.pos';
6530  if isfield(tmp.nfo,'className')
6531  HDR.EVENT.CodeDesc = tmp.nfo.className;
6532  end;
6533  if isfield(tmp.mrk,'y')
6534  [u,i,HDR.Classlabel] = unique(tmp.mrk.y);
6535  HDR.EVENT.TYP = HDR.Classlabel(:);
6536  HDR.TRIG = tmp.mrk.pos';
6537  elseif isfield(tmp.mrk,'toe')
6538  HDR.EVENT.TYP = tmp.mrk.toe';
6539  HDR.Classlabel = tmp.mrk.toe;
6540  else
6541  HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
6542  end;
6543 
6544  HDR.data = tmp.cnt;
6545  [HDR.SPR,HDR.NS] = size(HDR.data);
6546  HDR.Calib = sparse(2:HDR.NS+1, 1:HDR.NS, 0.1);
6547  HDR.PhysDimCode = repmat(4275,HDR.NS,1); % uV
6548 
6549  if (CHAN==0), CHAN=1:HDR.NS; end;
6550  [tmp0,HDR.THRESHOLD,tmp1,HDR.bits,HDR.GDFTYP] = gdfdatatype(class(HDR.data));
6551  HDR.THRESHOLD = repmat(HDR.THRESHOLD,HDR.NS,1);
6552  HDR.TYPE = 'native';
6553 
6554 
6555  elseif flag.bcic2008_3,
6556  HDR.NS = 10;
6557  HDR.Label = tmp.Info.MEGChannelPosition;
6558  HDR.Filter.LowPass = 100;
6559  HDR.Filter.HighPass = 0.3;
6560  HDR.SampleRate = 400;
6561  HDR.data = cat(1,cat(1,tmp.training_data{:}),tmp.test_data);
6562  [N,HDR.SPR,HDR.NS]=size(HDR.data);
6563  HDR.Classlabel = [ceil((1:160)'/40);repmat(NaN,size(tmp.test_data,1),1)];
6564  HDR.TRIG = [0:N-1]*HDR.SPR+1;
6565  %HDR.data = reshape(permute(HDR.data,[2,1,3]),
6566  return;
6567 
6568 
6569  elseif flag.bcic2008_4,
6570  HDR.SampleRate = 1000;
6571  HDR.NRec = 1;
6572  HDR.NS = 62+5;
6573  HDR.data = [tmp.train_data,tmp.train_dg;repmat(NaN,1000,HDR.NS);tmp.test_data,repmat(NaN,size(tmp.test_data,1),5)];
6574  [HDR.SPR,HDR.NS] = size(HDR.data);
6575  HDR.Label = cellstr(num2str([1:HDR.NS]'));
6576 
6577  HDR.Calib = sparse(2:HDR.NS+1, 1:HDR.NS, 1);
6578  HDR.PhysDimCode = repmat(0,HDR.NS,1); % unknown
6579  HDR.TYPE = 'native';
6580 
6581 
6582  elseif isfield(tmp,'mnt') && isfield(tmp,'mrk') && isfield(tmp,'cnt')
6583  HDR.SampleRate = tmp.cnt.fs;
6584  HDR.NRec = 1;
6585  HDR.Label = tmp.cnt.clab';
6586  HDR.EVENT.POS = tmp.mrk.pos';
6587  if isfield(tmp.mrk,'className')
6588  HDR.EVENT.CodeDesc = tmp.mrk.className;
6589  end;
6590  if isfield(tmp.mrk,'y')
6591  [t,HDR.Classlabel] = max(tmp.mrk.y,[],1);
6592  HDR.EVENT.TYP = HDR.Classlabel(:);
6593  HDR.TRIG = tmp.mrk.pos';
6594  elseif isfield(tmp.mrk,'toe')
6595  HDR.EVENT.TYP = tmp.mrk.toe';
6596  HDR.Classlabel = tmp.mrk.toe;
6597  else
6598  HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
6599  end;
6600  HDR.data = tmp.cnt.x;
6601  [HDR.SPR,HDR.NS] = size(HDR.data);
6602  if (CHAN==0), CHAN=1:HDR.NS; end;
6603  [tmp0,HDR.THRESHOLD,tmp1,HDR.bits,HDR.GDFTYP] = gdfdatatype(class(HDR.data));
6604  HDR.THRESHOLD = repmat(HDR.THRESHOLD,HDR.NS,1);
6605  HDR.TYPE = 'native';
6606  HDR.PhysDimCode = repmat(4275,HDR.NS,1);
6607  HDR.PhysDim = repmat('uV',HDR.NS,1);
6608 
6609  if isfield(tmp.cnt,'hdr')
6610  % BNI header
6611  HDR.H1 = tmp.cnt.hdr;
6612  HDR = bni2hdr(HDR);
6613  end;
6614 
6615 
6616  elseif flag.bbci,
6617  HDR.SampleRate = tmp.nfo.fs;
6618  HDR.NRec = tmp.nfo.nEpochs;
6619  HDR.SPR = tmp.nfo.T;
6620  HDR.Label = tmp.dat.clab';
6621  if isfield(tmp,'mrk_orig'),
6622  HDR.EVENT.POS = round([tmp.mrk_orig.pos]./[tmp.mrk_orig.fs]*tmp.mrk.fs)';
6623  % HDR.EVENT.Desc = {tmp.mrk_orig.desc};
6624  % HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
6625  [HDR.EVENT.CodeDesc, CodeIndex, HDR.EVENT.TYP] = unique({tmp.mrk_orig.desc});
6626  HDR.EVENT.CHN = zeros(size(HDR.EVENT.POS));
6627  HDR.EVENT.DUR = ones(size(HDR.EVENT.POS));
6628  HDR = bv2biosig_events(HDR);
6629  elseif isfield(tmp,'mrk');
6630  HDR.EVENT.POS = tmp.mrk.pos';
6631  HDR.EVENT.TYP = tmp.mrk.toe';
6632  if isfield(tmp.mrk,'toe')
6633  HDR.EVENT.TYP = tmp.mrk.toe';
6634  HDR.Classlabel = tmp.mrk.toe;
6635  else
6636  HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
6637  end;
6638  end;
6639  HDR.NS = length(HDR.Label);
6640  HDR.Cal = tmp.dat.resolution;
6641  if (CHAN==0), CHAN=1:HDR.NS; end;
6642 % HDR.data = repmat(NaN,HDR.SPR*HDR.NRec,HDR.NS);
6643  for k = 1:length(CHAN),
6644  HDR.data(:,CHAN(k)) = getfield(tmp,['ch',int2str(CHAN(k))]);
6645  end
6646  [tmp0,HDR.THRESHOLD,tmp1,HDR.bits,HDR.GDFTYP]=gdfdatatype(class(tmp.ch1));
6647  HDR.THRESHOLD = repmat(HDR.THRESHOLD,HDR.NS,1);
6648 
6649  HDR.TYPE = 'native';
6650  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
6651  HDR.PhysDimCode = repmat(4275,HDR.NS,1);
6652  HDR.PhysDim = repmat('uV',HDR.NS,1);
6653 
6654 
6655  elseif flag.bci2002a,
6656  [HDR.SPR, HDR.NS, HDR.NRec] = size(tmp.y);
6657  HDR.Label = tmp.elab;
6658  HDR.SampleRate = tmp.fs;
6659  HDR.data = reshape(permute(tmp.y,[1,3,2]),[HDR.SPR*HDR.NRec,HDR.NS]);
6660  HDR.Transducer = repmat({'Ag/AgCl electrodes'},3,1);
6661  HDR.Filter.Lowpass = 200;
6662  HDR.Filter.HighPass = 0.05;
6663  HDR.TYPE = 'native';
6664 
6665  HDR.FLAG.TRIGGERED = logical(1);
6666  HDR.EVENT.POS = [0:HDR.NRec-1]'*HDR.SPR;
6667  HDR.EVENT.TYP = [(tmp.z==-1)*hex2dec('0301') + (tmp.z==1)*hex2dec('0302') + (tmp.z==0)*hex2dec('030f')]';
6668  HDR.EVENT.POS(isnan(tmp.z)) = [];
6669  HDR.EVENT.TYP(isnan(tmp.z)) = [];
6670  HDR.Classlabel = mod(HDR.EVENT.TYP,256);
6671  HDR.Classlabel(HDR.Classlabel==15) = NaN; % unknown/undefined cue
6672  HDR.TRIG = HDR.EVENT.POS;
6673 
6674 
6675  elseif isfield(tmp,'y'), % Guger, Mueller, Scherer
6676  HDR.NS = size(tmp.y,2);
6677  HDR.NRec = 1;
6678  if ~isfield(tmp,'SampleRate')
6679  %fprintf(HDR.FILE.stderr,['Samplerate not known in ',HDR.FileName,'. 125Hz is chosen']);
6680  HDR.SampleRate=125;
6681  else
6682  HDR.SampleRate=tmp.SampleRate;
6683  end;
6684  fprintf(HDR.FILE.stderr,'Sensitivity not known in %s.\n',HDR.FileName);
6685  HDR.data = tmp.y;
6686  HDR.TYPE = 'native';
6687 
6688 
6689  elseif ( isfield(tmp,'cnt') || isfield(tmp,'X') ) && isfield(tmp,'nfo')
6690  if isfield(tmp,'cnt')
6691  HDR.data = tmp.cnt;
6692  [HDR.SPR,HDR.NS] = size(tmp.cnt);
6693  HDR.INFO='BCI competition 2005, dataset IV (Berlin)';
6694  HDR.Filter.LowPass = 0.05;
6695  HDR.Filter.HighPass = 200;
6696  HDR.Cal = 0.1;
6697  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,.1);
6698  elseif isfield(tmp,'X'),
6699  HDR.data = tmp.X;
6700  [HDR.SPR,HDR.NS] = size(tmp.X);
6701  HDR.INFO='BCI competition 2005, dataset V (IDIAP)';
6702  HDR.Filter.LowPass = 0;
6703  HDR.Filter.HighPass = 256;
6704  if isfield(tmp,'Y'),
6705  HDR.Classlabel = tmp.Y(:);
6706  else
6707  HDR.Classlabel = repmat(NaN,size(tmp.X,1),1);
6708  end;
6709  HDR.Cal = 1;
6710  else
6711 
6712  end;
6713 
6714  HDR.PhysDim = 'uV';
6715  HDR.SampleRate = tmp.nfo.fs;
6716  %HDR.Dur = HDR.SPR/HDR.SampleRate;
6717  if isfield(tmp,'mrk')
6718  HDR.TRIG = tmp.mrk.pos;
6719  HDR.EVENT.POS = tmp.mrk.pos(:);
6720  HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
6721  HDR.EVENT.CHN = zeros(size(HDR.EVENT.POS));
6722  if ~isempty(strfind(HDR.INFO,'Berlin')),cuelen=3.5;
6723  elseif ~isempty(strfind(HDR.INFO,'IDIAP')),cuelen=20;
6724  end;
6725  HDR.EVENT.DUR = repmat(cuelen*HDR.SampleRate,size(HDR.EVENT.POS));
6726  if isfield(tmp.mrk,'y'),
6727  HDR.Classlabel = tmp.mrk.y;
6728  else
6729  HDR.Classlabel = repmat(NaN,size(HDR.TRIG));
6730  end;
6731  if isfield(tmp.mrk,'className'),
6732  HDR.EVENT.TeegType = tmp.mrk.className;
6733  HDR.EVENT.TYP(isnan(HDR.Classlabel)) = hex2dec('030f'); % unknown/undefined
6734  ix = strmatch('left',tmp.mrk.className);
6735  if ~isempty(ix),
6736  HDR.EVENT.TYP(HDR.Classlabel==ix) = hex2dec('0301'); % left
6737  end;
6738  ix = strmatch('right',tmp.mrk.className);
6739  if ~isempty(ix),
6740  HDR.EVENT.TYP(HDR.Classlabel==ix) = hex2dec('0302'); % right
6741  end;
6742  ix = strmatch('foot',tmp.mrk.className);
6743  if ~isempty(ix),
6744  HDR.EVENT.TYP(HDR.Classlabel==ix) = hex2dec('0303'); % foot
6745  end;
6746  ix = strmatch('tongue',tmp.mrk.className);
6747  if ~isempty(ix),
6748  HDR.EVENT.TYP(HDR.Classlabel==ix) = hex2dec('0304'); % tongue
6749  end;
6750  end;
6751  end;
6752  HDR.Label = tmp.nfo.clab';
6753  z2=sum([tmp.nfo.xpos,tmp.nfo.ypos].^2,2);
6754  HDR.ELEC.XYZ = [tmp.nfo.xpos,tmp.nfo.ypos,sqrt(max(z2)-z2)];
6755  HDR.NRec = 1;
6756  HDR.FILE.POS = 0;
6757  HDR.TYPE = 'native';
6758  clear tmp;
6759 
6760 
6761  elseif isfield(tmp,'Signal') && isfield(tmp,'Flashing') && isfield(tmp,'StimulusCode')
6762  HDR.INFO = 'BCI competition 2005, dataset II (Albany)';
6763  HDR.SampleRate = 240;
6764  HDR.Filter.LowPass = 60;
6765  HDR.Filter.HighPass = 0.1;
6766  [HDR.NRec,HDR.SPR,HDR.NS] = size(tmp.Signal);
6767  HDR.BCI2000.Flashing = tmp.Flashing;
6768  HDR.BCI2000.StimulusCode = tmp.StimulusCode;
6769  if isfield(tmp,'TargetChar')
6770  HDR.BCI2000.TargetChar = tmp.TargetChar;
6771  end;
6772  if isfield(tmp,'StimulusType')
6773  HDR.BCI2000.StimulusType = tmp.StimulusType;
6774  end;
6775 
6776  HDR.FILE.POS = 0;
6777  HDR.TYPE = 'native';
6778  HDR.data = reshape(tmp.Signal,[HDR.NRec*HDR.SPR, HDR.NS]);
6779  clear tmp;
6780 
6781 
6782  elseif isfield(tmp,'run') && isfield(tmp,'trial') && isfield(tmp,'sample') && isfield(tmp,'signal') && isfield(tmp,'TargetCode');
6783  HDR.INFO = 'BCI competition 2002/2003, dataset 2a (Albany)';
6784  HDR.SampleRate = 160;
6785  HDR.NRec = 1;
6786  [HDR.SPR,HDR.NS]=size(tmp.signal);
6787  HDR.data = tmp.signal;
6788  HDR.EVENT.POS = [0;find(diff(tmp.trial)>0)-1];
6789  HDR.EVENT.TYP = ones(length(HDR.EVENT.POS),1)*hex2dec('0300'); % trial onset;
6790 
6791  if 0,
6792  EVENT.POS = [find(diff(tmp.trial)>0);length(tmp.trial)];
6793  EVENT.TYP = ones(length(EVENT.POS),1)*hex2dec('8300'); % trial offset;
6794  HDR.EVENT.POS = [HDR.EVENT.POS; EVENT.POS];
6795  HDR.EVENT.TYP = [HDR.EVENT.TYP; EVENT.TYP];
6796  [HDR.EVENT.POS,ix]=sort(HDR.EVENT.POS);
6797  HDR.EVENT.TYP = HDR.EVENT.TYP(ix);
6798  end;
6799 
6800  HDR.EVENT.N = length(HDR.EVENT.POS);
6801  ix = find((tmp.TargetCode(1:end-1)==0) & (tmp.TargetCode(2:end)>0));
6802  HDR.Classlabel = tmp.TargetCode(ix+1);
6803  HDR.TYPE = 'native';
6804 
6805 
6806  elseif isfield(tmp,'runnr') && isfield(tmp,'trialnr') && isfield(tmp,'samplenr') && isfield(tmp,'signal') && isfield(tmp,'StimulusCode');
6807  HDR.INFO = 'BCI competition 2003, dataset 2b (Albany)';
6808  HDR.SampleRate = 240;
6809  HDR.NRec = 1;
6810  [HDR.SPR,HDR.NS]=size(tmp.signal);
6811  HDR.data = tmp.signal;
6812  HDR.EVENT.POS = [0;find(diff(tmp.trialnr)>0)-1];
6813  HDR.EVENT.TYP = ones(length(HDR.EVENT.POS),1)*hex2dec('0300'); % trial onset;
6814 
6815  if 0,
6816  EVENT.POS = [find(diff(tmp.trial)>0);length(tmp.trial)];
6817  EVENT.TYP = ones(length(EVENT.POS),1)*hex2dec('8300'); % trial offset;
6818  HDR.EVENT.POS = [HDR.EVENT.POS; EVENT.POS];
6819  HDR.EVENT.TYP = [HDR.EVENT.TYP; EVENT.TYP];
6820  [HDR.EVENT.POS,ix]=sort(HDR.EVENT.POS);
6821  HDR.EVENT.TYP = HDR.EVENT.TYP(ix);
6822  end;
6823 
6824  HDR.EVENT.N = length(HDR.EVENT.POS);
6825  ix = find((tmp.StimulusCode(1:end-1)==0) && (tmp.StimulusCode(2:end)>0));
6826  HDR.Classlabel = tmp.StimulusCode(ix+1);
6827  HDR.TYPE = 'native';
6828 
6829 
6830  elseif isfield(tmp,'clab') && isfield(tmp,'x_train') && isfield(tmp,'y_train') && isfield(tmp,'x_test');
6831  HDR.INFO = 'BCI competition 2003, dataset 4 (Berlin)';
6832  HDR.Label = tmp.clab;
6833  HDR.Classlabel = [repmat(nan,size(tmp.x_test,3),1);tmp.y_train';repmat(nan,size(tmp.x_test,3),1)];
6834  HDR.NRec = length(HDR.Classlabel);
6835 
6836  HDR.SampleRate = 1000;
6837  HDR.Dur = 0.5;
6838  HDR.NS = size(tmp.x_test,2);
6839  HDR.SPR = HDR.SampleRate*HDR.Dur;
6840  HDR.FLAG.TRIGGERED = 1;
6841  sz = [HDR.NS,HDR.SPR,HDR.NRec];
6842 
6843  HDR.data = reshape(permute(cat(3,tmp.x_test,tmp.x_train,tmp.x_test),[2,1,3]),sz(1),sz(2)*sz(3))';
6844  HDR.TYPE = 'native';
6845 
6846  elseif isfield(tmp,'x_train') && isfield(tmp,'y_train') && isfield(tmp,'x_test');
6847  HDR.INFO = 'BCI competition 2003, dataset 3 (Graz)';
6848  HDR.Label = {'C3a-C3p'; 'Cza-Czp'; 'C4a-C4p'};
6849  HDR.SampleRate = 128;
6850  HDR.Classlabel = [tmp.y_train-1; repmat(nan,size(tmp.x_test,3),1)];
6851  HDR.data = cat(3, tmp.x_test, tmp.x_train)*50;
6852 
6853  HDR.NRec = length(HDR.Classlabel);
6854  HDR.FLAG.TRIGGERED = 1;
6855  HDR.SampleRate = 128;
6856  HDR.Dur = 9;
6857  HDR.NS = 3;
6858  HDR.SPR = HDR.SampleRate*HDR.Dur;
6859 
6860  sz = [HDR.NS, HDR.SPR, HDR.NRec];
6861  HDR.data = reshape(permute(HDR.data,[2,1,3]),sz(1),sz(2)*sz(3))';
6862  HDR.TYPE = 'native';
6863 
6864 
6865  elseif isfield(tmp,'RAW_SIGNALS') % TFM RAW Matlab export
6866  HDR.Label = fieldnames(tmp.RAW_SIGNALS);
6867  HDR.NS = length(HDR.Label);
6868  HDR.SampleRate = 1000;
6869  ix = repmat(NaN,1,HDR.NS);
6870  for k1 = 1:HDR.NS;
6871  s = getfield(tmp.RAW_SIGNALS,HDR.Label{k1});
6872  for k2 = 1:length(s);
6873  ix(k2,k1) = length(s{k2});
6874  end;
6875  end;
6876  DIV = sum(ix,1);
6877  HDR.TFM.DIV = round(max(DIV)./DIV);
6878  HDR.TFM.ix = ix;
6879 
6880  HDR.data = repmat(NaN, max(HDR.TFM.DIV.*DIV), HDR.NS);
6881  for k1 = 1:HDR.NS;
6882  s = getfield(tmp.RAW_SIGNALS,HDR.Label{k1});
6883  s2= rs(cat(2,s{:})',1,HDR.TFM.DIV(k1));
6884  HDR.data(1:size(s2,1),k1) = s2;
6885  end;
6886  clear tmp s s2;
6887  HDR.EVENT.POS = cumsum(ix(:,min(find(HDR.TFM.DIV==1))));
6888  HDR.EVENT.TYP = repmat(1,size(HDR.EVENT.POS));
6889  HDR.TFM.SampleRate = HDR.SampleRate./HDR.TFM.DIV;
6890  HDR.TYPE = 'native';
6891  HDR.NRec = 1;
6892 
6893 
6894  elseif isfield(tmp,'BeatToBeat') % TFM BeatToBeat Matlab export
6895  HDR.Label = fieldnames(tmp.BeatToBeat);
6896  HDR.NS = length(HDR.Label);
6897  HDR.SampleRate = NaN;
6898  ix = [];
6899  for k1 = 1:HDR.NS,
6900  tmp2 = getfield(tmp.BeatToBeat,HDR.Label{k1});
6901  HDR.data(:,k1)=cat(2,tmp2{:})';
6902  for k2 = 1:length(tmp2);
6903  if (k1==1),
6904  ix(k2) = length(tmp2{k2});
6905  elseif ix(k2) ~= length(tmp2{k2}),
6906  fprintf(2,'Warning TFM BeatToBeat Import: length (%i!=%i) of segment %i:%i does not fit \n',length(tmp2{k2}),ix(k2),k1,k2);
6907  end;
6908  end;
6909  if length(ix)~=length(tmp2)
6910  fprintf(2,'Warning TFM BeatToBeat Import: number of segments (%i!=%1) in channel %i do not fit \n',length(tmp2),length(ix),k1);
6911  end;
6912  end;
6913  HDR.EVENT.POS = [1;cumsum(ix(:))];
6914  HDR.EVENT.TYP = repmat(1,size(HDR.EVENT.POS));
6915  HDR.PhysDim = repmat({''},HDR.NS,1);
6916  HDR.NRec = 1;
6917  HDR.TYPE = 'native';
6918 
6919 
6920  elseif flag.tfm, % other TFM BeatToBeat Matlab export
6921  HDR.NS = 0;
6922  HDR.Label = {};
6923  if bitand(flag.tfm,1)
6924  f = fieldnames(tmp.HRV);
6925  for k1 = 1:length(f),
6926  tmp2 = getfield(tmp.HRV,f{k1});
6927  HDR.data(:,HDR.NS + k1)=cat(2,tmp2{:})';
6928  end;
6929  HDR.Label = [HDR.Label;f];
6930  HDR.NS = HDR.NS + length(f);
6931  end;
6932  if bitand(flag.tfm,2)
6933  f = fieldnames(tmp.BPV);
6934  for k1 = 1:length(f),
6935  tmp2 = getfield(tmp.BPV,f{k1});
6936  HDR.data(:,HDR.NS + k1)=cat(2,tmp2{:})';
6937  end;
6938  HDR.Label = [HDR.Label;f];
6939  HDR.NS = HDR.NS + length(f);
6940  end;
6941  if bitand(flag.tfm,3)
6942  f = fieldnames(tmp.BPVsBP);
6943  for k1 = 1:length(f),
6944  tmp2 = getfield(tmp.BPVsBP,f{k1});
6945  HDR.data(:,HDR.NS + k1)=cat(2,tmp2{:})';
6946  end;
6947  HDR.Label = [HDR.Label;f];
6948  HDR.NS = HDR.NS + length(f);
6949  end;
6950  HDR.PhysDim = repmat({''},HDR.NS,1);
6951  HDR.NRec = 1;
6952  HDR.TYPE = 'native';
6953 
6954 
6955  elseif flag.fieldtrip,
6956  HDR.Label = tmp.data.label;
6957  if isfield(tmp.data,'fsample');
6958  HDR.SampleRate = tmp.data.fsample;
6959  else
6960  HDR.SampleRate = tmp.data.hdr.Fs;
6961  end;
6962  HDR.data = cat(2,tmp.data.trial{:})';
6963  [HDR.NRec,HDR.NS] = size(HDR.data);
6964  HDR.SPR = 1;
6965  HDR.DigMax = double(max(HDR.data));
6966  HDR.DigMin = double(min(HDR.data));
6967  HDR.PhysMax = HDR.DigMax;
6968  HDR.PhysMin = HDR.DigMin;
6969  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1);
6970  HDR.PhysDimCode = zeros(HDR.NS,1);
6971  numtrials = length(tmp.data.trial);
6972  tlen = zeros(numtrials,1);
6973  for k=1:numtrials,
6974  tlen(k) = size(tmp.data.trial{k},2);
6975  end;
6976  HDR.EVENT.TYP = repmat(hex2dec('7ffe'),length(tmp.data.trial),1);
6977  HDR.EVENT.POS = 1+cumsum(tlen);
6978  HDR.EVENT.DUR = tlen;
6979  HDR.EVENT.CHN = zeros(numtrials,1);
6980  HDR.TYPE = 'native';
6981  HDR.FILE.POS = 0;
6982 
6983  fid = -1; % fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.rej']),'r');
6984  if fid>0,
6985  %% FIXME: *.rej info not used.
6986  t = fread(fid,[1,inf],'uint8');
6987  fclose(fid);
6988  t = char(t);
6989  t(t=='-') = ' ';
6990  [n,v,t]=str2double(t);
6991  end;
6992 
6993 
6994  elseif isfield(tmp,'EEG'); % EEGLAB file format
6995  HDR.T0 = 0;
6996  HDR.SPR = tmp.EEG.pnts;
6997  HDR.NS = tmp.EEG.nbchan;
6998  HDR.NRec = tmp.EEG.trials;
6999  HDR.SampleRate = tmp.EEG.srate;
7000  if isfield(tmp.EEG.chanlocs,'X')
7001  HDR.ELEC.XYZ = [[tmp.EEG.chanlocs.X]',[tmp.EEG.chanlocs.Y]',[tmp.EEG.chanlocs.Z]'];
7002  end;
7003 
7004  if isfield(tmp.EEG.chanlocs,'labels')
7005  HDR.Label = {tmp.EEG.chanlocs.labels};
7006  else
7007  HDR.Label = cellstr([repmat('#',HDR.NS,1),int2str([1:HDR.NS]')]);
7008  end
7009  HDR.PhysDimCode = repmat(4275,HDR.NS,1); % uV
7010 
7011  if ischar(tmp.EEG.data) && exist(tmp.EEG.data,'file')
7012  fid = fopen(tmp.EEG.data,'r','ieee-le');
7013  HDR.data = fread(fid,[HDR.NS,HDR.SPR*HDR.NRec],'float32')';
7014  fclose(fid);
7015  HDR.GDFTYP = 16;
7016  elseif isnumeric(tmp.EEG.data)
7017  HDR.data = tmp.EEG.data';
7018  HDR.GDFTYP = 17;
7019  end;
7020 
7021  if isfield(HDR,'data'),
7022  HDR.data = reshape(permute(reshape(HDR.data,[HDR.SPR,HDR.NS,HDR.NRec]),[1,3,2]),[HDR.SPR*HDR.NRec,HDR.NS]);
7023  if isfield(HDR,'Label') && ~isempty(HDR.Label)
7024  HDR.BDF.Status.Channel = strmatch('Status',HDR.Label,'exact');
7025  if length(HDR.BDF.Status.Channel),
7026  HDR.BDF.ANNONS = uint32(HDR.data(:,HDR.BDF.Status.Channel));
7027  end;
7028  end;
7029  end;
7030 
7031  if isfield(tmp.EEG,'event'),
7032  HDR.EVENT.SampleRate = HDR.SampleRate;
7033  HDR.EVENT.POS = round([tmp.EEG.event.latency]');
7034  [HDR.EVENT.CodeDesc, tmp, HDR.EVENT.TYP] = unique({tmp.EEG.event.type}');
7035  elseif isfield(HDR,'BDF') && isfield(HDR.BDF,'ANNONS'),
7036  HDR = bdf2biosig_events(HDR,FLAG.BDF.status2event);
7037  else
7038  % trial onset and offset event
7039  HDR.EVENT.POS = [ [0:HDR.NRec-1]'*HDR.SPR+1; [1:HDR.NRec]'*HDR.SPR ];
7040  HDR.EVENT.TYP = [repmat(hex2dec('0300'),HDR.NRec,1);repmat(hex2dec('8300'),HDR.NRec,1)];
7041 
7042  % cue event
7043  if isfield(tmp.EEG,'xmin')
7044  offset = tmp.EEG.xmin*HDR.SampleRate;
7045  HDR.EVENT.POS = [HDR.EVENT.POS; [0:HDR.NRec-1]'*HDR.SPR - offset]; % timing of cue
7046  HDR.EVENT.TYP = [HDR.EVENT.TYP; repmat(hex2dec('0301'), HDR.NRec,1)]; % this is a hack because info on true classlabels is not available
7047  end;
7048  end;
7049  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1);
7050  % HDR.debugging_info = tmp.EEG;
7051  HDR.TYPE = 'native';
7052 
7053  elseif isfield(tmp,'eeg'); % Scherer
7054  fprintf(HDR.FILE.stderr,'Warning SLOAD: Sensitivity not known in %s,\n',HDR.FileName);
7055  HDR.NS=size(tmp.eeg,2);
7056  HDR.NRec = 1;
7057  if ~isfield(tmp,'SampleRate')
7058  % fprintf(HDR.FILE.stderr,['Samplerate not known in ',HDR.FileName,'. 125Hz is chosen']);
7059  HDR.SampleRate=125;
7060  else
7061  HDR.SampleRate=tmp.SampleRate;
7062  end;
7063  HDR.data = tmp.eeg;
7064  if isfield(tmp,'classlabel'),
7065  HDR.Classlabel = tmp.classlabel;
7066  end;
7067  HDR.TYPE = 'native';
7068 
7069 
7070  elseif isfield(tmp,'data');
7071  if isfield(tmp,'readme') && iscell(tmp.data) ; %Zachary A. Keirn, Purdue University, 1988.
7072  HDR.Label = {'C3'; 'C4'; 'P3'; 'P4'; 'O1'; 'O2'; 'EOG'};
7073  HDR.SampleRate = 250;
7074  HDR.FLAG.TRIGGERED = 1;
7075  HDR.Dur = 10;
7076  HDR.SPR = 2500;
7077  HDR.FILTER.LowPass = 0.1;
7078  HDR.FILTER.HighPass = 100;
7079  HDR.NRec = length(tmp.data);
7080 
7081  x = cat(1,tmp.data{:});
7082  [b,i,CL] = unique({x{:,1}}');
7083  [HDR.EVENT.CodeDesc,i,CL(:,2)] = unique({x{:,2}}');
7084  HDR.Classlabel = CL;
7085  HDR.data = [x{:,4}]';
7086  HDR.NS = size(HDR.data,2);
7087  HDR.Calib= sparse(2:8,1:7,1);
7088  HDR.Cal = ones(HDR.NS,1);
7089  HDR.Off = zeros(HDR.NS,1);
7090  HDR.PhysDimCode = zeros(HDR.NS,1);
7091  HDR.TYPE = 'native';
7092  HDR.THRESHOLD = [-31.4802 28.8094; -29.1794 31.8082; -25.9697 31.4411; -44.8894 29.2010; -31.6907 35.1667; -29.9277 32.6030; -336.5146 261.8502];
7093  if HDR.FLAG.OVERFLOWDETECTION
7094  for k=1:HDR.NS,
7095  HDR.data((HDR.data(:,k)<=HDR.THRESHOLD(k,1)) | (HDR.data(:,k)>=HDR.THRESHOLD(k,2)),k)=NaN;
7096  end;
7097  end;
7098 
7099  else % Mueller, Scherer ?
7100  HDR.NS = size(tmp.data,2);
7101  HDR.NRec = 1;
7102  fprintf(HDR.FILE.stderr,'Warning SLOAD: Sensitivity not known in %s,\n',HDR.FileName);
7103  if ~isfield(tmp,'SampleRate')
7104  fprintf(HDR.FILE.stderr,'Warning SLOAD: Samplerate not known in %s. 125Hz is chosen\n',HDR.FileName);
7105  HDR.SampleRate=125;
7106  else
7107  HDR.SampleRate=tmp.SampleRate;
7108  end;
7109  HDR.data = tmp.data;
7110  if isfield(tmp,'classlabel'),
7111  HDR.Classlabel = tmp.classlabel;
7112  end;
7113  if isfield(tmp,'artifact'),
7114  HDR.ArtifactSelection = zeros(size(tmp.classlabel));
7115  HDR.ArtifactSelection(tmp.artifact)=1;
7116  end;
7117  HDR.TYPE = 'native';
7118  end;
7119 
7120 
7121  elseif isfield(tmp,'EEGdata') && isfield(tmp,'classlabel'); % Telemonitoring Daten (Reinhold Scherer)
7122  HDR.NS = size(tmp.EEGdata,2);
7123  HDR.NRec = 1;
7124  HDR.Classlabel = tmp.classlabel;
7125  if ~isfield(tmp,'SampleRate')
7126  fprintf(HDR.FILE.stderr,'Warning SLOAD: Samplerate not known in %s. 125Hz is chosen\n',HDR.FileName);
7127  HDR.SampleRate=125;
7128  else
7129  HDR.SampleRate=tmp.SampleRate;
7130  end;
7131  HDR.PhysDim = 'µV';
7132  fprintf(HDR.FILE.stderr,'Sensitivity not known in %s. 50µV is chosen\n',HDR.FileName);
7133  HDR.data = tmp.EEGdata*50;
7134  HDR.TYPE = 'native';
7135 
7136 
7137  elseif isfield(tmp,'EEGdata') && isfield(tmp,'EEGdatalabel') && isfield(tmp,'configuration_channel');
7138  %% some gtec data
7139  HDR.NS = size(tmp.EEGdata,1);
7140  HDR.SPR = size(tmp.EEGdata,2);
7141  HDR.NRec = size(tmp.EEGdata,3);
7142  HDR.Classlabel = tmp.EEGdatalabel;
7143  HDR.TRIG = [0:HDR.NRec-1]'*HDR.SPR+1;
7144  fprintf(HDR.FILE.stderr,'Warning SLOAD: Samplerate not known in %s. Samplingrate is normalized to 1.\n',HDR.FileName);
7145  HDR.SampleRate = 1;
7146  % values for samplerate, channel label, physical units etc. not supported.
7147  HDR.PhysDim = 'uV';
7148  HDR.data = reshape(tmp.EEGdata,HDR.NS,HDR.SPR*HDR.NRec)';
7149  HDR.TYPE = 'native';
7150 
7151 
7152  elseif isfield(tmp,'daten'); % EP Daten von Michael Woertz
7153  HDR.NS = size(tmp.daten.raw,2)-1;
7154  HDR.NRec = 1;
7155  if ~isfield(tmp,'SampleRate')
7156  fprintf(HDR.FILE.stderr,'Warning SLOAD: Samplerate not known in %s. 2000Hz is chosen\n',HDR.FileName);
7157  HDR.SampleRate=2000;
7158  else
7159  HDR.SampleRate=tmp.SampleRate;
7160  end;
7161  HDR.PhysDim = 'µV';
7162  fprintf(HDR.FILE.stderr,'Sensitivity not known in %s. 100µV is chosen\n',HDR.FileName);
7163  %signal=tmp.daten.raw(:,1:HDR.NS)*100;
7164  HDR.data = tmp.daten.raw*100;
7165  HDR.TYPE = 'native';
7166 
7167  elseif isfield(tmp,'neun') && isfield(tmp,'zehn') && isfield(tmp,'trig'); % guger,
7168  HDR.NS=3;
7169  HDR.NRec = 1;
7170  if ~isfield(tmp,'SampleRate')
7171  fprintf(HDR.FILE.stderr,'Warning SLOAD: Samplerate not known in %s. 125Hz is chosen\n',HDR.FileName);
7172  HDR.SampleRate=125;
7173  else
7174  HDR.SampleRate=tmp.SampleRate;
7175  end;
7176  fprintf(HDR.FILE.stderr,'Sensitivity not known in %s. \n',HDR.FileName);
7177  HDR.data = [tmp.neun;tmp.zehn;tmp.trig];
7178  HDR.Label = {'Neun','Zehn','TRIG'};
7179  HDR.TYPE = 'native';
7180 
7181 
7182  elseif isfield(tmp,'Recorder1') % Nicolet NRF format converted into Matlab
7183  for k = 1:length(s.Recorder1.Channels.ChannelInfos);
7184  HDR.Label{k} = [s.Recorder1.Channels.ChannelInfos(k).ChannelInfo.Name,' '];
7185  HDR.PhysDim{k} = [s.Recorder1.Channels.ChannelInfos(k).ChannelInfo.YUnits,' '];
7186  end;
7187  signal = [];
7188  T = [];
7189  for k = 1:length(s.Recorder1.Channels.Segments)
7190  tmp = s.Recorder1.Channels.Segments(k).Data;
7191  sz = size(tmp.Samples);
7192  signal = [signal; repmat(nan,100,sz(1)); tmp.Samples'];
7193  T = [T;repmat(nan,100,1);tmp.dX0+(1:sz(2))'*tmp.dXstep ]
7194  fs = 1./tmp.dXstep;
7195  if k==1,
7196  HDR.SampleRate = fs;
7197  elseif HDR.SampleRate ~= fs;
7198  fprintf(2,'Error SLOAD (NRF): different Sampling rates not supported, yet.\n');
7199  end;
7200  end;
7201  HDR.data = signal;
7202  HDR.TYPE = 'native';
7203 
7204 
7205  elseif isfield(tmp,'ECoGdata') && isfield(tmp,'dataset') %Michigan ECoG dataset
7206  HDR.data = tmp.ECoGdata';
7207  HDR.T0 = datevec(datenum(tmp.dataset.filetype.timestamp));
7208  HDR.SampleRate = tmp.dataset.specs.sample_rate;
7209  HDR.Filter.HighPass = tmp.dataset.specs.filters.lowcut;
7210  HDR.Filter.LowPass = tmp.dataset.specs.filters.highcut;
7211  if isfield(tmp.dataset.specs.filters,'notch60');
7212  HDR.FILTER.Notch = tmp.dataset.specs.filters.notch60*60;
7213  end;
7214  HDR.Patient.Sex = tmp.dataset.subject_info.gender;
7215  HDR.Patient.Age = tmp.dataset.subject_info.age;
7216  HDR.Label = tmp.dataset.electrode.names;
7217  HDR.NS = tmp.dataset.electrode.number;
7218 
7219  trigchancode = getfield(tmp.dataset.electrode.options,'TRIGGER');
7220  HDR.AS.TRIGCHAN = find(tmp.dataset.electrode.region==trigchancode);
7221  HDR.TRIG = tmp.dataset.trigger.trigs_all;
7222 
7223  HDR.FLAG.TRIGGERED = 0;
7224  HDR.NRec = 1;
7225  HDR.SPR = size(HDR.data,1);
7226  HDR.Dur = HDR.SPR/HDR.SampleRate;
7227  HDR.TYPE = 'native';
7228  clear tmp;
7229 
7230 
7231  elseif isfield(tmp,'P_C_S'); % G.Tec Ver 1.02, 1.5x data format
7232  HDR.FILE.POS = 0;
7233  if isa(tmp.P_C_S,'data'), %isfield(tmp.P_C_S,'version'); % without BS.analyze
7234  if any(tmp.P_C_S.Version==[1.02, 1.5, 1.52, 3.00]),
7235  else
7236  fprintf(HDR.FILE.stderr,'Warning: PCS-Version is %4.2f.\n',tmp.P_C_S.Version);
7237  end;
7238  HDR.Filter.LowPass = tmp.P_C_S.LowPass;
7239  HDR.Filter.HighPass = tmp.P_C_S.HighPass;
7240  HDR.Filter.Notch = tmp.P_C_S.Notch;
7241  HDR.SampleRate = tmp.P_C_S.SamplingFrequency;
7242  HDR.gBS.Attribute = tmp.P_C_S.Attribute;
7243  HDR.gBS.AttributeName = tmp.P_C_S.AttributeName;
7244  HDR.Label = tmp.P_C_S.ChannelName;
7245  HDR.gBS.EpochingSelect = tmp.P_C_S.EpochingSelect;
7246  HDR.gBS.EpochingName = tmp.P_C_S.EpochingName;
7247  HDR.ELEC.XYZ = [tmp.P_C_S.XPosition; tmp.P_C_S.YPosition; tmp.P_C_S.ZPosition]';
7248 
7249  HDR.data = double(tmp.P_C_S.Data);
7250 
7251  else %if isfield(tmp.P_C_S,'Version'), % with BS.analyze software, ML6.5
7252  if any(tmp.P_C_S.version==[1.02, 1.5, 1.52, 3.00]),
7253  else
7254  fprintf(HDR.FILE.stderr,'Warning: PCS-Version is %4.2f.\n',tmp.P_C_S.version);
7255  end;
7256  HDR.Filter.LowPass = tmp.P_C_S.lowpass;
7257  HDR.Filter.HighPass = tmp.P_C_S.highpass;
7258  HDR.Filter.Notch = tmp.P_C_S.notch;
7259  HDR.SampleRate = tmp.P_C_S.samplingfrequency;
7260  HDR.gBS.Attribute = tmp.P_C_S.attribute;
7261  HDR.gBS.AttributeName = tmp.P_C_S.attributename;
7262  HDR.Label = tmp.P_C_S.channelname;
7263  HDR.gBS.EpochingSelect = tmp.P_C_S.epochingselect;
7264  HDR.gBS.EpochingName = tmp.P_C_S.epochingname;
7265  HDR.ELEC.XYZ = [tmp.P_C_S.xposition; tmp.P_C_S.yposition; tmp.P_C_S.zposition]';
7266 
7267  HDR.data = double(tmp.P_C_S.data);
7268  end;
7269  tmp = []; % free some memory
7270 
7271  sz = size(HDR.data);
7272  HDR.NRec = sz(1);
7273  HDR.SPR = sz(2);
7274  HDR.Dur = sz(2)/HDR.SampleRate;
7275  HDR.NS = sz(3);
7276  HDR.FLAG.TRIGGERED = HDR.NRec>1;
7277 
7278  HDR.data = reshape(permute(HDR.data,[2,1,3]),[sz(1)*sz(2),sz(3)]);
7279 
7280  % Selection of trials with artifacts
7281  ch = strmatch('ARTIFACT',HDR.gBS.AttributeName);
7282  if ~isempty(ch)
7283  HDR.ArtifactSelection = HDR.gBS.Attribute(ch,:);
7284  end;
7285 
7286  % Convert gBS-epochings into BIOSIG - Events
7287  map = zeros(size(HDR.gBS.EpochingName,1),1);
7288  map(strmatch('AUGE',HDR.gBS.EpochingName))=hex2dec('0101');
7289  map(strmatch('EOG',HDR.gBS.EpochingName))=hex2dec('0101');
7290  map(strmatch('MUSKEL',HDR.gBS.EpochingName))=hex2dec('0103');
7291  map(strmatch('MUSCLE',HDR.gBS.EpochingName))=hex2dec('0103');
7292 
7293  map(strmatch('ELECTRODE',HDR.gBS.EpochingName))=hex2dec('0105');
7294 
7295  map(strmatch('SLEEPSTAGE1',HDR.gBS.EpochingName))=hex2dec('0411');
7296  map(strmatch('SLEEPSTAGE2',HDR.gBS.EpochingName))=hex2dec('0412');
7297  map(strmatch('SLEEPSTAGE3',HDR.gBS.EpochingName))=hex2dec('0413');
7298  map(strmatch('SLEEPSTAGE4',HDR.gBS.EpochingName))=hex2dec('0414');
7299  map(strmatch('REM',HDR.gBS.EpochingName))=hex2dec('0415');
7300 
7301  if ~isempty(HDR.gBS.EpochingSelect),
7302  HDR.EVENT.TYP = map([HDR.gBS.EpochingSelect{:,9}]');
7303  HDR.EVENT.POS = [HDR.gBS.EpochingSelect{:,1}]';
7304  HDR.EVENT.CHN = [HDR.gBS.EpochingSelect{:,3}]';
7305  HDR.EVENT.DUR = [HDR.gBS.EpochingSelect{:,4}]';
7306  end;
7307  HDR.TYPE = 'native';
7308 
7309  elseif isfield(tmp,'P_C_DAQ_S');
7310  if ~isempty(tmp.P_C_DAQ_S.data),
7311  HDR.data = double(tmp.P_C_DAQ_S.data{1});
7312 
7313  else
7314  for k = 1:length(tmp.P_C_DAQ_S.daqboard),
7315  [tmppfad,file,ext] = fileparts(tmp.P_C_DAQ_S.daqboard{k}.ObjInfo.LogFileName);
7316  if any(file=='\'),
7317  %% if file was recorded on WIN but analyzed in LINUX
7318  file=file(max(find(file=='\'))+1:end);
7319  end;
7320  file = fullfile(HDR.FILE.Path,[file,ext]);
7321  if exist(file,'file')
7322  HDR.info{k}=daqread(file,'info');
7323  data = daqread(file);
7324  if k==1,
7325  HDR.data = data;
7326  else
7327  len = min(size(data,1),size(HDR.data,1));
7328  HDR.data = [HDR.data(1:len,:), data(1:len,:)];
7329  end;
7330  else
7331  fprintf(HDR.FILE.stderr,'Error SOPEN: data file %s not found\n',file);
7332  return;
7333  end;
7334  end;
7335  end;
7336 
7337  HDR.NS = size(HDR.data,2);
7338  HDR.Cal = tmp.P_C_DAQ_S.sens*(2.^(1-tmp.P_C_DAQ_S.daqboard{1}.HwInfo.Bits));
7339  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
7340  HDR.PhysMax = max(HDR.data);
7341  HDR.PhysMin = min(HDR.data);
7342  HDR.DigMax = HDR.PhysMax;% ./HDR.Cal;
7343  HDR.DigMin = HDR.PhysMin;% ./HDR.Cal;
7344  HDR.Cal = ones(1,HDR.NS);
7345  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1);
7346  HDR.GDFTYP = repmat(16,1,HDR.NS); %% float
7347 
7348  if all(tmp.P_C_DAQ_S.unit==1)
7349  HDR.PhysDimCode=repmat(4275,1,HDR.NS); %% uV
7350  else
7351  HDR.PhysDimCode=zeros(1,HDR.NS); %% [?]
7352  end;
7353 
7354  HDR.SampleRate = tmp.P_C_DAQ_S.samplingfrequency;
7355  sz = size(HDR.data);
7356  if length(sz)==2, sz=[1,sz]; end;
7357  HDR.NRec = sz(1);
7358  HDR.Dur = sz(2)/HDR.SampleRate;
7359  HDR.NS = sz(3);
7360  HDR.FLAG.TRIGGERED = HDR.NRec>1;
7361  HDR.Label = tmp.P_C_DAQ_S.channelname;
7362  HDR.Filter.LowPass = tmp.P_C_DAQ_S.lowpass;
7363  HDR.Filter.HighPass = tmp.P_C_DAQ_S.highpass;
7364  HDR.Filter.Notch = tmp.P_C_DAQ_S.notch;
7365  if isfield(tmp.P_C_DAQ_S,'attribute')
7366  HDR.gBS.Attribute = tmp.P_C_DAQ_S.attribute;
7367  end;
7368  if isfield(tmp.P_C_DAQ_S,'attributename')
7369  HDR.gBS.AttributeName = tmp.P_C_DAQ_S.attributename;
7370  end;
7371  HDR.TYPE = 'native';
7372 
7373 
7374  elseif isfield(tmp,'eventmatrix') && isfield(tmp,'samplerate')
7375  %%% F. Einspieler's Event information
7376  HDR.EVENT.POS = tmp.eventmatrix(:,1);
7377  HDR.EVENT.TYP = tmp.eventmatrix(:,2);
7378  HDR.EVENT.CHN = tmp.eventmatrix(:,3);
7379  HDR.EVENT.DUR = tmp.eventmatrix(:,4);
7380  HDR.SampleRate = tmp.samplerate;
7381  HDR.TYPE = 'EVENT';
7382 
7383 
7384  elseif isfield(tmp,'Electrode')
7385  if isfield(tmp.Electrode,'Theta') && isfield(tmp.Electrode,'Phi')
7386  Theta = tmp.Electrode.Theta(:)*pi/180;
7387  Phi = tmp.Electrode.Phi(:)*pi/180;
7388  HDR.ELEC.XYZ = [ sin(Theta).*cos(Phi), sin(Theta).*sin(Phi),cos(Theta)];
7389  HDR.Label = tmp.Electrode.Acronym(:);
7390  HDR.TYPE = 'ELPOS';
7391  return;
7392  end;
7393 
7394  else
7395  HDR.Calib = 1;
7396  CHAN = 1;
7397  end;
7398  if strcmp(HDR.TYPE,'native'),
7399  if ~isfield(HDR,'NS');
7400  HDR.NS = size(HDR.data,2);
7401  end;
7402  if ~isfield(HDR,'SPR');
7403  HDR.SPR = size(HDR.data,1);
7404  end;
7405  if ~isfield(HDR.FILE,'POS');
7406  HDR.FILE.POS = 0;
7407  end;
7408  end;
7409 
7410 elseif strncmp(HDR.TYPE,'BCI2000',7),
7411  if any(HDR.FILE.PERMISSION=='r'),
7412  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
7413 
7414  [HDR.Header,count] = fread(HDR.FILE.FID,[1,256],'uint8');
7415  [tmp,rr] = strtok(char(HDR.Header),[10,13]);
7416  tmp(tmp=='=') = ' ';
7417  [t,status,sa] = str2double(tmp,[9,32],[10,13]);
7418  if (HDR.VERSION==1) && strcmp(sa{3},'SourceCh') && strcmp(sa{5},'StatevectorLen') && ~any(status([2,4,6]))
7419  HDR.HeadLen = t(2);
7420  HDR.NS = t(4);
7421  HDR.BCI2000.StateVectorLength = t(6);
7422  HDR.GDFTYP = 3; % 'int16';
7423 
7424  elseif (HDR.VERSION==1.1) && strcmp(sa{5},'SourceCh') && strcmp(sa{7},'StatevectorLen') && strcmp(sa{9},'DataFormat') && ~any(status([2:2:8]))
7425  HDR.VERSION = t(2);
7426  HDR.HeadLen = t(4);
7427  HDR.NS = t(6);
7428  HDR.BCI2000.StateVectorLength = t(8);
7429  if strcmp(sa{10},'int16')
7430  HDR.GDFTYP = 3;
7431  elseif strcmp(sa{10},'int32')
7432  HDR.GDFTYP = 5;
7433  elseif strcmp(sa{10},'float32')
7434  HDR.GDFTYP = 16;
7435  elseif strcmp(sa{10},'float64')
7436  HDR.GDFTYP = 17;
7437  elseif strcmp(sa{10},'int24')
7438  HDR.GDFTYP = 255+24;
7439  elseif strcmp(sa{10},'uint16')
7440  HDR.GDFTYP = 4;
7441  elseif strcmp(sa{10},'uint32')
7442  HDR.GDFTYP = 6;
7443  elseif strcmp(sa{10},'uint24')
7444  HDR.GDFTYP = 511+24;
7445  end;
7446  else
7447  HDR.TYPE = 'unknown';
7448  fprintf(HDR.FILE.stderr,'Error SOPEN: file %s does not confirm with BCI2000 format\n',HDR.FileName);
7449  fclose(HDR.FILE.FID);
7450  return;
7451  end;
7452  if count<HDR.HeadLen,
7453  status = fseek(HDR.FILE.FID,0,'bof');
7454  [BCI2000.INFO,count] = fread(HDR.FILE.FID,[1,HDR.HeadLen],'uint8=>char');
7455  elseif count>HDR.HeadLen,
7456  status = fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
7457  BCI2000.INFO = char(HDR.Header(1:HDR.HeadLen));
7458  end
7459  ORIENT = 0;
7460  [tline,rr] = strtok(BCI2000.INFO,[10,13]);
7461  HDR.Label = cellstr([repmat('ch',HDR.NS,1),num2str([1:HDR.NS]')]);
7462  STATUSFLAG = 0;
7463  while length(rr),
7464  tline = tline(1:min([length(tline),strfind(tline,char([47,47]))-1]));
7465 
7466  if ~isempty(strfind(tline,'[ State Vector Definition ]'))
7467  STATUSFLAG = 1;
7468  STATECOUNT = 0;
7469 
7470  elseif ~isempty(strfind(tline,'[ Parameter Definition ]'))
7471  STATUSFLAG = 2;
7472 
7473  elseif strncmp(tline,'[',1)
7474  STATUSFLAG = 3;
7475 
7476  elseif STATUSFLAG==1,
7477  [t,r] = strtok(tline);
7478  val = str2double(r);
7479  %HDR.BCI2000 = setfield(HDR.BCI2000,t,val);
7480  STATECOUNT = STATECOUNT + 1;
7481  HDR.BCI2000.StateVector(STATECOUNT,:) = val;
7482  HDR.BCI2000.StateDef{STATECOUNT,1} = t;
7483 
7484  elseif STATUSFLAG==2,
7485  [tag,r] = strtok(tline,'=');
7486  [val,r] = strtok(r,'=');
7487  if ~isempty(strfind(tag,'SamplingRate'))
7488  [tmp,status] = str2double(val);
7489  HDR.SampleRate = tmp(1);
7490  elseif ~isempty(strfind(tag,'SourceChGain'))
7491  [tmp,status] = str2double(val);
7492  HDR.Cal = tmp(2:tmp(1)+1);
7493  elseif ~isempty(strfind(tag,'SourceChOffset'))
7494  [tmp,status] = str2double(val);
7495  HDR.Off = tmp(2:tmp(1)+1);
7496  elseif ~isempty(strfind(tag,'SourceMin'))
7497  [tmp,status] = str2double(val);
7498  HDR.DigMin = tmp(1);
7499  elseif ~isempty(strfind(tag,'SourceMax'))
7500  [tmp,status] = str2double(val);
7501  HDR.DigMax = tmp(1);
7502  elseif ~isempty(strfind(tag,'NotchFilter'))
7503  [tmp,status] = str2double(val);
7504  if tmp(1)==0, HDR.Filter.Notch = 0;
7505  elseif tmp(1)==1, HDR.Filter.Notch = 50;
7506  elseif tmp(1)==2, HDR.Filter.Notch = 60;
7507  end;
7508  elseif ~isempty(strfind(tag,'TargetOrientation'))
7509  [tmp,status] = str2double(val);
7510  ORIENT = tmp(1);
7511  elseif ~isempty(strfind(tag,'StorageTime'))
7512  ix = strfind(val,'%20');
7513  if length(ix)==4,
7514  val([ix,ix+1,ix+2])=' ';
7515  val(val==':') = ' ';
7516  [n,v,s] = str2double(val);
7517  n(1)=n(7);
7518  n(2)=strmatch(s{2},{'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'});
7519  HDR.T0 = n(1:6);
7520  end;
7521  elseif ~isempty(strfind(tag,'ChannelNames'))
7522  [tmp,status,labels] = str2double(val);
7523  HDR.Label(1:tmp(1))=labels(2:tmp(1)+1);
7524  end;
7525  end;
7526  [tline,rr] = strtok(rr,[10,13]);
7527  end;
7528 
7529  %HDR.PhysDim = 'µV';
7530  HDR.PhysDimCode = repmat(4275,HDR.NS,1); % 'µV';
7531  HDR.Calib = [HDR.Off(1)*ones(1,HDR.NS);eye(HDR.NS)]*HDR.Cal(1);
7532 
7533  % decode State Vector Definition
7534  X = repmat(NaN,1,HDR.BCI2000.StateVectorLength*8);
7535  for k = 1:STATECOUNT,
7536  for k1 = 1:HDR.BCI2000.StateVector(k,1),
7537  X(HDR.BCI2000.StateVector(k,3:4)*[8;1]+k1) = k;
7538  end;
7539  end;
7540  X = X(end:-1:1);
7541  HDR.BCI2000.X = X;
7542 
7543  % convert EVENT information
7544  status = fseek(HDR.FILE.FID,HDR.HeadLen+2*HDR.NS,'bof');
7545  tmp = fread(HDR.FILE.FID,[HDR.BCI2000.StateVectorLength,inf],[int2str(HDR.BCI2000.StateVectorLength),'*uchar'],HDR.NS*2)';
7546  NoS = size(tmp);
7547  POS = [1;1+find(any(diff(tmp,[],1),2))];
7548  tmp = tmp(POS,end:-1:1)'; % compress event information
7549  tmp = dec2bin(tmp(:),8)';
7550  HDR.BCI2000.BINARYSTATUS = reshape(tmp, 8*HDR.BCI2000.StateVectorLength, size(tmp,2)/HDR.BCI2000.StateVectorLength)';
7551  for k = 1:max(X)
7552  HDR.BCI2000.STATE(:,k) = bin2dec(HDR.BCI2000.BINARYSTATUS(:,k==X));
7553  end;
7554 
7555  HDR.EVENT.POS = POS;
7556  HDR.EVENT.TYP = repmat(0,size(HDR.EVENT.POS)); % should be extracted from HDR.BCI2000.STATE
7557  fprintf(2,'Warning SOPEN (BCI2000): HDR.EVENT.TYP information need to be extracted from HDR.BCI2000.STATE\n');
7558  HDR.EVENT.CHN = zeros(size(HDR.EVENT.POS));
7559  HDR.EVENT.DUR = zeros(size(HDR.EVENT.POS));
7560  HDR.EVENT.SampleRate = HDR.SampleRate;
7561 
7562  k = strmatch('TargetCode', HDR.BCI2000.StateDef);
7563  ix = find(diff(HDR.BCI2000.STATE(:,k))>0)+1; %% start of trial ??
7564  HDR.TRIG = POS(ix);
7565  HDR.Classlabel = HDR.BCI2000.STATE(ix,k);
7566 
7567  if ORIENT == 1, %% vertical
7568  cl = hex2dec('030c')*(HDR.Classlabel==1) + hex2dec('0306')*(HDR.Classlabel==2) + hex2dec('0303')*(HDR.Classlabel==3);
7569  HDR.EVENT.TYP(ix) = cl;
7570  else %% horizontal or both
7571  HDR.EVENT.TYP(ix) = HDR.Classlabel + hex2dec('0300');
7572  end;
7573  ix2 = find(diff(HDR.BCI2000.STATE(:,k))<0)+1; %% end of trial ??
7574  ix = ix(1:length(ix2));
7575  HDR.EVENT.DUR(ix) = POS(ix2) - POS(ix);
7576 
7577  % remove all empty events
7578  ix = find(HDR.EVENT.TYP>0);
7579  HDR.EVENT.POS=HDR.EVENT.POS(ix);
7580  HDR.EVENT.TYP=HDR.EVENT.TYP(ix);
7581  HDR.EVENT.DUR=HDR.EVENT.DUR(ix);
7582  HDR.EVENT.CHN=HDR.EVENT.CHN(ix);
7583  HDR.EVENT.N = length(ix);
7584 
7585  k= strmatch('Feedback', HDR.BCI2000.StateDef);
7586  ix = find(diff(HDR.BCI2000.STATE(:,k))>0)+1; %% start of feedback
7587  ix2 = find(diff(HDR.BCI2000.STATE(:,k))<0)+1; %% end of feedback
7588  HDR.EVENT.POS = [HDR.EVENT.POS;POS(ix)];
7589  HDR.EVENT.TYP = [HDR.EVENT.TYP;repmat(hex2dec('030d'),length(ix),1)];
7590  HDR.EVENT.CHN = zeros(length(HDR.EVENT.POS),1);
7591  if length(ix2)==length(ix),
7592  HDR.EVENT.DUR = [HDR.EVENT.DUR;POS(ix2)-POS(ix)];
7593  else
7594  tmp = [POS(ix2);NoS(1)+1];
7595  HDR.EVENT.DUR = [HDR.EVENT.DUR;tmp-POS(ix)];
7596  end;
7597  HDR.EVENT.N = length(HDR.EVENT.POS);
7598 
7599  % finalize header definition
7600  status = fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
7601  HDR.AS.bpb = 2*HDR.NS + HDR.BCI2000.StateVectorLength;
7602  HDR.SPR = (HDR.FILE.size - HDR.HeadLen)/HDR.AS.bpb;
7603  HDR.AS.endpos = HDR.SPR;
7604 
7605  [datatyp,limits,datatypes,numbits,GDFTYP] = gdfdatatype(HDR.GDFTYP);
7606  HDR.BCI2000.GDFTYP = [int2str(HDR.NS),'*',datatypes{1},'=>',datatypes{1}];
7607  HDR.NRec = 1;
7608 
7609  HDR.FILE.OPEN = 1;
7610  HDR.FILE.POS = 0;
7611  end;
7612 
7613 elseif strcmp(HDR.TYPE,'BioSig'),
7614  % this code should match HDR2ASCII in order to do ASCII2HDR
7615  if any(HDR.FILE.PERMISSION=='r'),
7616  fid = fopen(HDR.FileName,'r');
7617  s = fread(fid,[1,inf],'uint8=>char');
7618  fclose(fid);
7619  ix0 = strfind(s,'[Fixed Header]');
7620  ix1 = strfind(s,'[Channel Header]');
7621  ix2 = strfind(s,'[Event Table]');
7622 
7623  HDR.H1 = s(ix0:ix1-1);
7624  HDR.H2 = s(ix1:ix2-1);
7625  HDR.H3 = s(ix2-1:end);
7626 
7627  %%%%%%%%%% fixed header
7628  HDR.H1(HDR.H1=='=') = 9;
7629  [n,v,s]=str2double(HDR.H1,9);
7630  HDR.SampleRate = n(strmatch('SamplingRate',s(:,1)),2);
7631  HDR.NS = n(strmatch('NumberOfChannels',s(:,1)),2);
7632  HDR.SPR = n(strmatch('Number_of_Samples',s(:,1)),2);
7633  HDR.NRec = 1;
7634  HDR.TYPE = s{strmatch('Format',s(:,1)),2};
7635  HDR.FileName = s{strmatch('Filename',s(:,1)),2};
7636 
7637  %%%%%%%%%% variable header
7638  s = HDR.H2;
7639  [tline,s] = strtok(s,[10,13]);
7640  [tline,s] = strtok(s,[10,13]);
7641  [n,v,s]=str2double(s,9,[10,13]);
7642  HDR.Label = s(:,3)';
7643  HDR.LeadIdCode = n(:,2);
7644  HDR.AS.SampleRate = n(:,4);
7645  [datatyp,limits,datatypes,numbits,HDR.GDFTYP]=gdfdatatype(s(:,5));
7646  HDR.THRESHOLD = n(:,6:7);
7647  HDR.Off = n(:,8);
7648  HDR.Cal = n(:,9);
7649  HDR.PhysDim = s(:,10)';
7650  HDR.Filter.HighPass = n(:,11);
7651  HDR.Filter.LowPass = n(:,12);
7652  HDR.Filter.Notch = n(:,13);
7653  HDR.Impedance = n(:,14)*1000;
7654  HDR.ELEC.XYZ = n(:,15:17);
7655 
7656  %%%%%%%%%% event table
7657  s = HDR.H3;
7658  tline = '';
7659  while ~strncmp(tline,'NumberOfEvents',14);
7660  [tline,s] = strtok(s,[10,13]);
7661  end;
7662  [p,v] = strtok(tline,'=');
7663  [p,v] = strtok(v,'=');
7664  N = str2double(p);
7665  ET = repmat(NaN,N,4);
7666  [tline,s] = strtok(s,[10,13]);
7667  for k = 1:N,
7668  [tline,s] = strtok(s,[10,13]);
7669  [typ,tline] = strtok(tline,[9,10,13]);
7670  ET(k,1) = hex2dec(typ(3:end));
7671  [n,v,st] = str2double(tline,[9]);
7672  ET(k,2:4) = n(1:3);
7673  end;
7674  HDR.EVENT.TYP = ET(:,1);
7675  HDR.EVENT.POS = ET(:,2);
7676  HDR.EVENT.CHN = ET(:,3);
7677  HDR.EVENT.DUR = ET(:,4);
7678  % the following is redundant information %
7679  HDR.EVENT.VAL = repmat(NaN,N,1);
7680  ix = find(HDR.EVENT.TYP==hex2dec('7fff'));
7681  HDR.EVENT.VAL(ix)=HDR.EVENT.DUR(ix);
7682  end;
7683 
7684 
7685 elseif strcmp(HDR.TYPE,'CFWB'), % Chart For Windows Binary data, defined by ADInstruments.
7686  CHANNEL_TITLE_LEN = 32;
7687  UNITS_LEN = 32;
7688  if any(HDR.FILE.PERMISSION=='r'),
7689  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
7690 
7691  HDR.FILE.OPEN = 1;
7692  fseek(HDR.FILE.FID,4,'bof');
7693  HDR.VERSION = fread(HDR.FILE.FID,1,'int32');
7694  HDR.Dur = fread(HDR.FILE.FID,1,'double');
7695  HDR.SampleRate = 1/HDR.Dur;
7696  HDR.T0 = fread(HDR.FILE.FID,[1,5],'int32');
7697  tmp = fread(HDR.FILE.FID,2,'double');
7698  HDR.T0(6) = tmp(1);
7699  HDR.CFWB.preTrigger = tmp(2);
7700  HDR.NS = fread(HDR.FILE.FID,1,'int32');
7701  HDR.NRec = fread(HDR.FILE.FID,1,'int32');
7702  HDR.SPR = 1;
7703  HDR.FLAG.TRIGGERED = 0;
7704  HDR.AS.endpos = HDR.NRec*HDR.SPR;
7705 
7706  HDR.FLAG.TimeChannel = fread(HDR.FILE.FID,1,'int32');
7707  tmp = fread(HDR.FILE.FID,1,'int32');
7708  if tmp == 1,
7709  HDR.GDFTYP = 17; %'float64';
7710  HDR.AS.bpb = HDR.NS * 8;
7711  elseif tmp == 2,
7712  HDR.GDFTYP = '16'; %'float32';
7713  HDR.AS.bpb = HDR.NS * 4;
7714  elseif tmp == 3,
7715  HDR.GDFTYP = 3; %'int16';
7716  HDR.AS.bpb = HDR.NS * 2;
7717  end;
7718  for k = 1:HDR.NS,
7719  HDR.Label{k,1} = char(fread(HDR.FILE.FID,[1, CHANNEL_TITLE_LEN],'uint8'));
7720  HDR.PhysDim{k,1} = char(fread(HDR.FILE.FID,[1, UNITS_LEN],'uint8'));
7721  HDR.Cal(k,1) = fread(HDR.FILE.FID,1,'double');
7722  HDR.Off(k,1) = fread(HDR.FILE.FID,1,'double');
7723  HDR.PhysMax(1,k) = fread(HDR.FILE.FID,1,'double');
7724  HDR.PhysMin(1,k) = fread(HDR.FILE.FID,1,'double');
7725  end;
7726 
7727 
7728  elseif any(HDR.FILE.PERMISSION=='w'),
7729  HDR.VERSION = 1;
7730  if ~isfield(HDR,'NS'),
7731  HDR.NS = 0; % unknown channel number ...
7732  fprintf(HDR.FILE.stderr,'Error SOPEN-W CFWB: number of channels HDR.NS undefined.\n');
7733  return;
7734  end;
7735  if ~isfield(HDR,'NRec'),
7736  HDR.NRec = -1; % Unknown - Value will be fixed when file is closed.
7737  end;
7738  HDR.SPR = 1;
7739  if ~isfield(HDR,'SampleRate'),
7740  HDR.SampleRate = 1; % Unknown - Value will be fixed when file is closed.
7741  if isfield(HDR,'Dur')
7742  HDR.SampleRate = 1/HDR.Dur;
7743  else
7744  fprintf(HDR.FILE.stderr,'Warning SOPEN-W CFWB: samplerate undefined.\n');
7745  end;
7746  else
7747  HDR.Dur = 1/HDR.SampleRate;
7748  end;
7749 
7750  if (any(HDR.NRec<0) && any(HDR.FILE.PERMISSION=='z')),
7751  %% due to a limitation zlib
7752  fprintf(HDR.FILE.stderr,'ERROR SOPEN (CFWB) "wz": Update of HDR.SPR not possible.\n',HDR.FileName);
7753  fprintf(HDR.FILE.stderr,'\t Solution(s): (1) define exactly HDR.SPR before calling SOPEN(HDR,"wz"); or (2) write to uncompressed file instead.\n');
7754  return;
7755  end;
7756  if any([HDR.NRec<=0]), % if any unknown, ...
7757  HDR.FILE.OPEN = 3; % ... fix header when file is closed.
7758  end;
7759  if ~isfield(HDR,'CFWB'),
7760  HDR.CFWB.preTrigger = 0; % Unknown - Value will be fixed when file is closed.
7761  end;
7762  if ~isfield(HDR.CFWB,'preTrigger'),
7763  HDR.CFWB.preTrigger = 0; % Unknown - Value will be fixed when file is closed.
7764  end;
7765  if ~isfield(HDR,'FLAG'),
7766  HDR.FLAG.TimeChannel = 0;
7767  else
7768  if ~isfield(HDR.FLAG,'TimeChannel'),
7769  HDR.Flag.TimeChannel = 0;
7770  end;
7771  end;
7772  if strcmp(gdfdatatype(HDR.GDFTYP),'float64');
7773  tmp = 1;
7774  HDR.AS.bpb = HDR.NS * 8;
7775  HDR.Cal = ones(HDR.NS,1);
7776  HDR.Off = zeros(HDR.NS,1);
7777  elseif strcmp(gdfdatatype(HDR.GDFTYP),'float32');
7778  tmp = 2;
7779  HDR.AS.bpb = HDR.NS * 4;
7780  HDR.Cal = ones(HDR.NS,1);
7781  HDR.Off = zeros(HDR.NS,1);
7782  elseif strcmp(gdfdatatype(HDR.GDFTYP),'int16');
7783  tmp = 3;
7784  HDR.AS.bpb = HDR.NS * 2;
7785  end;
7786  HDR.PhysMax = repmat(NaN,HDR.NS,1);
7787  HDR.PhysMin = repmat(NaN,HDR.NS,1);
7788  if ~isfield(HDR,'Cal'),
7789  fprintf(HDR.FILE.stderr,'Warning SOPEN-W CFWB: undefined scaling factor - assume HDR.Cal=1.\n');
7790  HDR.Cal = ones(HDR.NS,1);
7791  end;
7792  if ~isfield(HDR,'Off'),
7793  fprintf(HDR.FILE.stderr,'Warning SOPEN-W CFWB: undefined offset - assume HDR.Off=0.\n');
7794  HDR.Off = zeros(HDR.NS,1);
7795  end;
7796  if ~isfield(HDR,'Label'),
7797  for k = 1:HDR.NS,
7798  Label{k} = sprintf('channel %i',k);
7799  end;
7800  end;
7801  Label = char(HDR.Label); % local copy of Label
7802  Label = [Label, char(repmat(32,size(Label,1),max(0,CHANNEL_TITLE_LEN-size(Label,2))))];
7803  Label = [Label; char(repmat(32,max(0,HDR.NS-size(Label,1)),size(Label,2)))];
7804 
7805  if ~isfield(HDR,'PhysDim'),
7806  HDR.PhysDim = repmat({''},HDR.NS,1);
7807  end;
7808 
7809  if size(HDR.PhysDim,1)==1,
7810  HDR.PhysDim = HDR.PhysDim(ones(HDR.NS,1),:);
7811  end;
7812  if iscell(HDR.PhysDim)
7813  for k = 1:length(HDR.PhysDim),
7814  HDR.PhysDim{k} = [HDR.PhysDim{k},' '];
7815  end;
7816  end
7817  PhysDim = char(HDR.PhysDim); %local copy
7818  PhysDim = [PhysDim, char(repmat(32,size(PhysDim,1),max(0,UNITS_LEN-size(PhysDim,2))))];
7819  PhysDim = [PhysDim; char(repmat(32,max(0,HDR.NS-size(PhysDim,1)),size(PhysDim,2)))];
7820 
7821  %%%%% write fixed header
7822  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
7823  if HDR.FILE.FID<0,
7824  fprintf(HDR.FILE.stderr,'Error SOPEN-W CFWB: could not open file %s .\n',HDR.FileName);
7825  return;
7826  else
7827  HDR.FILE.OPEN = 2;
7828  end;
7829  fwrite(HDR.FILE.FID,'CFWB','uint8');
7830  fwrite(HDR.FILE.FID,HDR.VERSION,'int32');
7831  fwrite(HDR.FILE.FID,HDR.Dur,'double');
7832  fwrite(HDR.FILE.FID,HDR.T0(1:5),'int32');
7833  fwrite(HDR.FILE.FID,HDR.T0(6),'double');
7834  fwrite(HDR.FILE.FID,HDR.CFWB.preTrigger,'double');
7835  fwrite(HDR.FILE.FID,[HDR.NS,HDR.NRec,HDR.Flag.TimeChannel],'int32');
7836  fwrite(HDR.FILE.FID,tmp,'int32');
7837  HDR.HeadLen = ftell(HDR.FILE.FID);
7838  if (HDR.HeadLen~=68),
7839  fprintf(HDR.FILE.stderr,'Error SOPEN CFWB: size of header1 does not fit in file %s\n',HDR.FileName);
7840  end;
7841 
7842  %%%%% write channel header
7843  for k = 1:HDR.NS,
7844  fwrite(HDR.FILE.FID,Label(k,1:32),'uint8');
7845  fwrite(HDR.FILE.FID,PhysDim(k,1:32),'uint8');
7846  fwrite(HDR.FILE.FID,[HDR.Cal(k),HDR.Off(k)],'double');
7847  fwrite(HDR.FILE.FID,[HDR.PhysMax(k),HDR.PhysMin(k)],'double');
7848  end;
7849  %HDR.HeadLen = (68+HDR.NS*96); %
7850  HDR.HeadLen = ftell(HDR.FILE.FID);
7851  if (HDR.HeadLen~=(68+HDR.NS*96))
7852  fprintf(HDR.FILE.stderr,'Error SOPEN CFWB: size of header2 does not fit in file %s\n',HDR.FileName);
7853  end;
7854  end;
7855  HDR.Calib = [HDR.Off';speye(HDR.NS)]*sparse(1:HDR.NS,1:HDR.NS,HDR.Cal);
7856 
7857  HDR.HeadLen = ftell(HDR.FILE.FID);
7858  HDR.FILE.POS = 0;
7859  HDR.AS.endpos = HDR.NRec*HDR.SPR;
7860 
7861 
7862 elseif strcmp(HDR.TYPE,'ISHNE'),
7863  if any(HDR.FILE.PERMISSION=='r'),
7864  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
7865 
7866  fprintf(HDR.FILE.stderr,'Format not tested yet. \nFor more information contact <Biosig-general@lists.sourceforge.net> Subject: Biosig/Dataformats \n',HDR.FILE.PERMISSION);
7867 
7868  HDR.FILE.OPEN = 1;
7869  fseek(HDR.FILE.FID,10,'bof');
7870  HDR.variable_length_block = fread(HDR.FILE.FID,1,'int32');
7871  HDR.SPR = fread(HDR.FILE.FID,1,'int32');
7872  HDR.NRec= 1;
7873  HDR.offset_variable_length_block = fread(HDR.FILE.FID,1,'int32');
7874  HDR.HeadLen = fread(HDR.FILE.FID,1,'int32');
7875  HDR.VERSION = fread(HDR.FILE.FID,1,'int16');
7876  HDR.Patient.Name = char(fread(HDR.FILE.FID,[1,80],'uint8'));
7877  %HDR.Surname = fread(HDR.FILE.FID,40,'uint8');
7878  HDR.Patient.Id = char(fread(HDR.FILE.FID,[1,20],'uint8'));
7879  HDR.Patient.Sex = fread(HDR.FILE.FID,1,'int16');
7880  HDR.Patient.Race = fread(HDR.FILE.FID,1,'int16');
7881  HDR.Patient.Birthday([3:-1:1,4:6]) = [fread(HDR.FILE.FID,[1,3],'int16'),12,0,0];
7882  %HDR.Patient.Surname = char(fread(HDR.FILE.FID,40,'uint8')');
7883  Date = fread(HDR.FILE.FID,[1,3],'int16');
7884  Date2 = fread(HDR.FILE.FID,[1,3],'int16');
7885  Time = fread(HDR.FILE.FID,[1,3],'int16');
7886  HDR.T0 = [Date([3,2,1]),Time];
7887 
7888  HDR.NS = fread(HDR.FILE.FID,1,'int16');
7889  HDR.Lead.Specification = fread(HDR.FILE.FID,12,'int16');
7890  HDR.Lead.Quality = fread(HDR.FILE.FID,12,'int16');
7891 
7892  HDR.Lead.AmplitudeResolution = fread(HDR.FILE.FID,12,'int16');
7893  if any(HDR.Lead.AmplitudeResolution ~= -9)
7894  fprintf(HDR.FILE.stderr,'Warning: AmplitudeResolution and Number of Channels %i do not fit.\n',HDR.NS);
7895  end;
7896 
7897  HDR.ISHNE.PacemakerCode = fread(HDR.FILE.FID,1,'int16');
7898  HDR.ISHNE.TypeOfRecorder = char(fread(HDR.FILE.FID,[1,40],'uint8'));
7899  tmp = fread(HDR.FILE.FID,1,'int16');
7900  if tmp==-9,
7901  HDR.SampleRate = 200;
7902  else
7903  fprintf(HDR.FILE.stderr,'Warning SOPEN (ISHNE): Sample rate not correctly reconstructed!!!\n');
7904  HDR.SampleRate = 1;
7905  end;
7906  HDR.ISHNE.Proprietary_of_ECG = char(fread(HDR.FILE.FID,[1,80],'uint8'));
7907  HDR.ISHNE.Copyright = char(fread(HDR.FILE.FID,[1,80],'uint8'));
7908  HDR.ISHNE.reserved1 = char(fread(HDR.FILE.FID,[1,80],'uint8'));
7909  if ftell(HDR.FILE.FID) ~= HDR.offset_variable_length_block,
7910  fprintf(HDR.FILE.stderr,'Warning: length of fixed header does not fit %i %i \n',ftell(HDR.FILE.FID),HDR.offset_variable_length_block);
7911  HDR.ISHNE.reserved2 = char(fread(HDR.FILE.FID,[1,max(0,HDR.offset_variable_length_block-ftell(HDR.FILE.FID))],'uint8'));
7912  fseek(HDR.FILE.FID,HDR.offset_variable_length_block,'bof');
7913  end;
7914  HDR.VariableHeader = fread(HDR.FILE.FID,[1,HDR.variable_length_block],'uint8');
7915  if ftell(HDR.FILE.FID)~=HDR.HeadLen,
7916  fprintf(HDR.FILE.stderr,'ERROR: length of variable header does not fit %i %i \n',ftell(HDR.FILE.FID),HDR.HeadLen);
7917  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
7918  end;
7919  HDR.PhysDim= 'uV';
7920  HDR.AS.bpb = 2*HDR.NS;
7921 
7922  HDR.Cal = HDR.Lead.AmplitudeResolution(1:HDR.NS)/1000;
7923  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal,HDR.NS+1,HDR.NS);
7924  if HDR.VERSION,
7925  HDR.GDFTYP = 3; % 'int16'
7926  else
7927  %% does not follow the specification (generated with Medilog Darwin software ?)
7928  HDR.GDFTYP = 4; % 'uint16'
7929  HDR.Off = -(2^15)*HDR.Cal;
7930  HDR.Calib(1,:)=HDR.Off';
7931  end;
7932 
7933  HDR.AS.endpos = HDR.SPR;
7934  HDR.FLAG.TRIGGERED = 0; % Trigger Flag
7935  HDR.Label = cellstr([repmat('#',HDR.NS,1),num2str([1:HDR.NS]')]);
7936  HDR.FILE.POS = 0;
7937  else
7938  fprintf(HDR.FILE.stderr,'PERMISSION %s not supported\n',HDR.FILE.PERMISSION);
7939  end;
7940 
7941 
7942 elseif strcmp(HDR.TYPE,'DDT'),
7943  if any(HDR.FILE.PERMISSION=='r'),
7944  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
7945  tmp = fread(HDR.FILE.FID,2,'int32');
7946  HDR.Version = tmp(1);
7947  HDR.HeadLen = tmp(2);
7948  HDR.SampleRate = fread(HDR.FILE.FID,1,'double');
7949  HDR.NS = fread(HDR.FILE.FID,1,'int32');
7950  HDR.T0 = fread(HDR.FILE.FID,[1,6],'int32');
7951  HDR.Gain = fread(HDR.FILE.FID,1,'int32');
7952  HDR.Comment = char(fread(HDR.FILE.FID,[1,128],'uint8'));
7953  tmp = fread(HDR.FILE.FID,[1,256],'uint8');
7954  if HDR.Version == 100,
7955  HDR.Bits = 12;
7956  HDR.Cal = 5/2048*HDR.Gain;
7957  elseif HDR.Version == 101,
7958  HDR.Bits = tmp(1);
7959  HDR.Cal = 5*2^(1-HDR.Bits)/HDR.Gain;
7960  elseif HDR.Version == 102,
7961  HDR.Bits = tmp(1);
7962  ChannelGain = tmp(2:65);
7963  HDR.Cal = 5000*2^(1-HDR.Bits)./(HDR.Gain*ChannelGain);
7964  elseif HDR.Version == 103,
7965  HDR.Bits = tmp(1);
7966  ChannelGain = tmp(2:65);
7967  HDR.PhysMax = tmp(66:67)*[1;256]
7968  HDR.Cal = 5000*2^(1-HDR.Bits)./(HDR.Gain*ChannelGain);
7969  end;
7970  HDR.DigMax(1:HDR.NS) = 2^(HDR.Bits-1)-1;
7971  HDR.DigMin(1:HDR.NS) = -(2^(HDR.Bits-1));
7972  HDR.PhysMax = HDR.DigMax * HDR.Cal;
7973  HDR.PhysMin = HDR.DigMin * HDR.Cal;
7974  HDR.PhysDim = 'mV';
7975  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
7976 
7977  HDR.AS.bpb = 2*HDR.NS;
7978  HDR.GDFTYP = 3;
7979  HDR.SPR = (HDR.FILE.size-HDR.HeadLen)/HDR.AS.bpb;
7980  HDR.NRec = 1;
7981  HDR.AS.endpos = HDR.SPR;
7982  status = fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
7983  HDR.FILE.POS = 0;
7984  HDR.FILE.OPEN = 1;
7985  end;
7986 
7987 
7988 elseif strcmp(HDR.TYPE,'NEX'),
7989  fprintf(HDR.FILE.stderr,'Warning: SOPEN (NEX) is still in testing phase.\n');
7990  if any(HDR.FILE.PERMISSION=='r'),
7991  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
7992  if HDR.FILE.FID<0,
7993  return;
7994  end
7995 
7996  HDR.FILE.POS = 0;
7997  HDR.NEX.magic = fread(HDR.FILE.FID,1,'int32');
7998  HDR.VERSION = fread(HDR.FILE.FID,1,'int32');
7999  HDR.NEX.comment = char(fread(HDR.FILE.FID,[1,256],'uint8'));
8000  HDR.NEX.SampleRate = fread(HDR.FILE.FID, 1, 'double');
8001  HDR.NEX.begintime = fread(HDR.FILE.FID, 1, 'int32');
8002  HDR.NEX.endtime = fread(HDR.FILE.FID, 1, 'int32');
8003  HDR.NEX.NS = fread(HDR.FILE.FID, 1, 'int32');
8004  status = fseek(HDR.FILE.FID, 260, 'cof');
8005 
8006  HDR.EVENT.DUR = [];
8007  HDR.EVENT.CHN = [];
8008 
8009  for k = 1:HDR.NEX.NS,
8010  HDR.NEX.pos0(k) = ftell(HDR.FILE.FID);
8011  HDR.NEX.type(k) = fread(HDR.FILE.FID, 1, 'int32');
8012  HDR.NEX.version(k) = fread(HDR.FILE.FID, 1, 'int32');
8013  Label(k,:) = fread(HDR.FILE.FID, [1 64], 'uint8');
8014  HDR.NEX.offset(k) = fread(HDR.FILE.FID, 1, 'int32');
8015  HDR.NEX.nf(k) = fread(HDR.FILE.FID, 1, 'int32');
8016  reserved(k,:) = char(fread(HDR.FILE.FID, [1 32], 'uint8'));
8017  HDR.NEX.SampleRate(k) = fread(HDR.FILE.FID, 1, 'double');
8018  HDR.NEX.Cal(k) = fread(HDR.FILE.FID, 1, 'double');
8019  HDR.NEX.SPR(k) = fread(HDR.FILE.FID, 1, 'int32');
8020  HDR.NEX.h2(:,k)= fread(HDR.FILE.FID,19,'uint32');
8021  %nm = fread(HDR.FILE.FID, 1, 'int32');
8022  %nl = fread(HDR.FILE.FID, 1, 'int32');
8023 
8024  HDR.NEX.pos(k) = ftell(HDR.FILE.FID);
8025 % fseek(HDR.FILE.FID, HDR.NEX.pos0(k)+208,'bof');
8026  end;
8027  HDR.HeadLen = ftell(HDR.FILE.FID);
8028 
8029  HDR.NEX.Label = char(Label);
8030  HDR.PhysDim = 'mV';
8031  HDR.FILE.POS = 0;
8032  HDR.FILE.OPEN = 1;
8033  HDR.NRec = 1;
8034 
8035  % select AD-channels only,
8036  CH = find(HDR.NEX.type==5);
8037  HDR.AS.chanreduce = cumsum(HDR.NEX.type==5);
8038  HDR.NS = length(CH);
8039  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.NEX.Cal(CH));
8040  HDR.Label = HDR.NEX.Label(CH,:);
8041  HDR.AS.SampleRate = HDR.NEX.SampleRate(CH);
8042  HDR.AS.SPR = HDR.NEX.SPR(CH);
8043  HDR.SPR = 1;
8044  HDR.SampleRate = 1;
8045  for k = 1:HDR.NS,
8046  HDR.SPR = lcm(HDR.SPR,HDR.AS.SPR(k));
8047  HDR.SampleRate = lcm(HDR.SampleRate,HDR.AS.SampleRate(k));
8048  end;
8049  end;
8050 
8051 
8052 elseif strcmp(HDR.TYPE,'PLEXON'),
8053  if any(HDR.FILE.PERMISSION=='r'),
8054  fprintf(HDR.FILE.stderr,'Warning: SOPEN (PLX) is still in testing phase.\n');
8055 
8056  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
8057  if HDR.FILE.FID<0,
8058  return;
8059  end
8060  H1 = fread(HDR.FILE.FID,2,'int32');
8061  HDR.magic = H1(1);
8062  HDR.Version = H1(2);
8063  HDR.PLX.comment = fread(HDR.FILE.FID,128,'uint8');
8064  H1 = fread(HDR.FILE.FID,14,'int32');
8065  HDR.PLX.ADFrequency = H1(1);
8066  HDR.PLX.NumDSPChannels = H1(2);
8067  HDR.PLX.NumEventChannels = H1(3);
8068  HDR.PLX.NumSlowChannels = H1(4);
8069  HDR.PLX.NumPointsWave = H1(5);
8070  HDR.PLX.NumPointsPreThr = H1(6);
8071  %HDR.NS = H1(2);
8072  HDR.EVENT.N = H1(3);
8073  HDR.NS = H1(4);
8074  HDR.PLX.wavlen = H1(5);
8075  HDR.TimeOffset = H1(6);
8076  HDR.T0 = H1(7:12)';
8077  HDR.PLX.fastread = H1(13);
8078  HDR.PLX.WaveFormFreq = H1(14);
8079  HDR.PLX.LastTimeStamp = fread(HDR.FILE.FID,1,'double');
8080  H1 = fread(HDR.FILE.FID,4,'uint8');
8081  H2 = fread(HDR.FILE.FID,3,'uint16');
8082  if HDR.Version>=103,
8083  HDR.PLX.Trodalness = H1(1);
8084  HDR.PLX.DataTrodalness = H1(2);
8085  HDR.PLX.BitsPerSpikeSample = H1(3);
8086  HDR.PLX.BitsPerSlowSample = H1(4);
8087  HDR.PLX.SpikeMaxMagnitudeMV = H2(1);
8088  HDR.PLX.SlowMaxMagnitudeMV = H2(2);
8089  end;
8090  if HDR.Version>=105,
8091  HDR.PLX.SpikePreAmpGain = H2(3);
8092  end;
8093  H1 = fread(HDR.FILE.FID,46,'uint8');
8094 
8095  HDR.PLX.tscount = fread(HDR.FILE.FID,[5,130],'int32');
8096  HDR.PLX.wfcount = fread(HDR.FILE.FID,[5,130],'int32');
8097  HDR.PLX.evcount = fread(HDR.FILE.FID,[1,300],'int32');
8098  HDR.PLX.adcount = fread(HDR.FILE.FID,[1,212],'int32');
8099 
8100  %HDR.PLX.dspHeader = fread(HDR.FILE.FID,[1020,HDR.NS],'uint8');
8101  for k = 1:HDR.PLX.NumDSPChannels,
8102  tmp = fread(HDR.FILE.FID,[32,2],'uint8');
8103  HDR.Spike.Name(k,:) = tmp(:,1)';
8104  HDR.Spike.SIGName(k,:) = tmp(:,2)';
8105  tmp = fread(HDR.FILE.FID,9,'int32');
8106  HDR.Spike.Channel(k) = tmp(1);
8107  HDR.Spike.WFRate(k) = tmp(2);
8108  HDR.Spike.SIG(k) = tmp(3);
8109  HDR.Spike.Ref(k) = tmp(4);
8110  HDR.Spike.Gain(k) = tmp(5);
8111  HDR.Spike.Filter(k) = tmp(6);
8112  HDR.Spike.Threshold(k) = tmp(7);
8113  HDR.Spike.Method(k) = tmp(8);
8114  HDR.Spike.NUnits(k) = tmp(9);
8115  HDR.Spike.template(k,:,:) = fread(HDR.FILE.FID,[5,64],'int16');
8116  tmp = fread(HDR.FILE.FID,6,'int32');
8117  HDR.Spike.Fit(k,:) = tmp(1:5)';
8118  HDR.Spike.SortWidth(k) = tmp(6);
8119  HDR.Spike.Boxes(k,:,:,:) = reshape(fread(HDR.FILE.FID,[40],'int16'),[5,2,4]);
8120  HDR.Spike.SortBeg(k) = fread(HDR.FILE.FID,1,'int32');
8121  HDR.Spike.Comment(k,:) = fread(HDR.FILE.FID,[1,128],'uint8');
8122  tmp = fread(HDR.FILE.FID,11,'int32');
8123  end;
8124  HDR.Spike.Name = deblank(char(HDR.Spike.Name));
8125  HDR.Spike.Comment = deblank(char(HDR.Spike.Comment));
8126  for k = 1:HDR.PLX.NumEventChannels,
8127  HDR.EV.Name(k,:) = fread(HDR.FILE.FID,[1,32],'uint8');
8128  HDR.EV.Channel(k) = fread(HDR.FILE.FID,1,'int32');
8129  HDR.EV.Comment(k,:) = fread(HDR.FILE.FID,[1,128],'uint8');
8130  tmp = fread(HDR.FILE.FID,33,'int32');
8131  end;
8132  HDR.EV.Name = deblank(char(HDR.EV.Name));
8133  HDR.EV.Comment = deblank(char(HDR.EV.Comment));
8134  for k = 1:HDR.PLX.NumSlowChannels,
8135  HDR.Cont.Name(k,:) = fread(HDR.FILE.FID,[1,32],'uint8');
8136  tmp = fread(HDR.FILE.FID,6,'int32');
8137  HDR.Cont.Channel(k) = tmp(1)+1;
8138  HDR.Cont.ADfreq(k) = tmp(2);
8139  HDR.Cont.Gain(k) = tmp(3);
8140  HDR.Cont.Enabled(k) = tmp(4);
8141  HDR.Cont.PreAmpGain(k) = tmp(5);
8142  HDR.Cont.SpikeChannel(k) = tmp(6);
8143  HDR.Cont.Comment(k,:) = fread(HDR.FILE.FID,[1,128],'uint8');
8144  tmp = fread(HDR.FILE.FID,28,'int32');
8145  end;
8146  HDR.Cont.Name = deblank(char(HDR.Cont.Name));
8147  HDR.Cont.Comment = deblank(char(HDR.Cont.Comment));
8148 
8149  HDR.AS.SampleRate = HDR.Cont.ADfreq;
8150  HDR.HeadLen = ftell(HDR.FILE.FID);
8151  HDR.EVENT.SampleRate = HDR.PLX.ADFrequency;
8152  HDR.PhysDim = 'mV';
8153  if HDR.Version<=102,
8154  HDR.Spike.Cal = 3./(2048*HDR.Spike.Gain);
8155  elseif HDR.Version<105
8156  HDR.Spike.Cal = HDR.PLX.SpikeMaxMagnitudeMV*2.^(-HDR.PLX.BitsPerSpikeSample)./(500*HDR.Spike.Gain);
8157  else
8158  HDR.Spike.Cal = HDR.PLX.SpikeMaxMagnitudeMV*2.^(1-HDR.PLX.BitsPerSpikeSample)./(HDR.Spike.Gain*HDR.PLX.SpikePreAmpGain);
8159  end;
8160  if HDR.Version<=101,
8161  HDR.Cal = 5./(2048*HDR.Cont.Gain);
8162  elseif HDR.Version<=102,
8163  HDR.Cal = 5000./(2048*HDR.Cont.Gain.*HDR.Cont.PreAmpGain);
8164  else
8165  HDR.Cal = HDR.PLX.SpikeMaxMagnitudeMV*2^[1-HDR.PLX.BitsPerSlowSample]./(HDR.Cont.Gain.*HDR.Cont.PreAmpGain);
8166  end;
8167 
8168  % transfrom into native format
8169  HDR.Label = HDR.Cont.Name;
8170  HDR.NRec = 1;
8171  HDR.SPR = max(HDR.PLX.adcount);
8172  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
8173  HDR.SampleRate = 1;
8174  for k=1:HDR.NS,
8175  HDR.SampleRate = lcm(HDR.SampleRate,HDR.AS.SampleRate(k));
8176  end;
8177  HDR.FILE.POS = 0;
8178  HDR.FILE.OPEN = 1;
8179 
8180  CH = find(HDR.PLX.adcount>0);
8181  if isempty(ReRefMx) && any(CH) && (max(CH)<150),
8182  HDR.NS = max(CH);
8183  HDR.Label = HDR.Label(1:HDR.NS,:);
8184  end;
8185  end;
8186 
8187 
8188 elseif strcmp(HDR.TYPE,'Nicolet'),
8189  fid = fopen(fullfile(HDR.FILE.Path,HDR.FILE.Name,'.bni'),'rt');
8190  HDR.H1 = char(fread(fid,[1,inf],'uint8=>char'));
8191  fclose(fid);
8192  HDR = bni2hdr(HDR);
8193  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,HDR.FILE.Name,'.eeg'),'r','ieee-le');
8194  status = fseek(HDR.FILE.FID,-4,'eof');
8195  if status,
8196  fprintf(2,'Error SOPEN: file %s\n',HDR.FileName);
8197  return;
8198  end
8199  datalen = fread(fid,1,'uint32');
8200  status = fseek(fid,datalen,'bof');
8201  HDR.H2 = char(fread(fid,[1,1e6],'uint8'));
8202  status = fseek(HDR.FILE.FID,0,'bof');
8203  HDR.SPR = datalen/(2*HDR.NS);
8204  HDR.NRec = 1;
8205  HDR.AS.endpos = HDR.SPR;
8206  HDR.GDFTYP = 3; % int16;
8207  HDR.HeadLen = 0;
8208 
8209 
8210 elseif 0, strcmp(HDR.TYPE,'Nicolet'), %%%%% OBSOLETE? %%%%%%%
8211  if any(HDR.FILE.PERMISSION=='r'),
8212  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
8213  if HDR.FILE.FID<0,
8214  return;
8215  end
8216 
8217  HDR.FILE.POS = 0;
8218  HDR.FILE.OPEN = 1;
8219  HDR.AS.endpos = HDR.SPR;
8220  HDR.AS.bpb = 2*HDR.NS;
8221  HDR.GDFTYP = 'int16';
8222  HDR.HeadLen = 0;
8223  else
8224  fprintf(HDR.FILE.stderr,'PERMISSION %s not supported\n',HDR.FILE.PERMISSION);
8225  end;
8226 
8227 
8228 elseif strncmp(HDR.TYPE,'SEG2',4),
8229  if any(HDR.FILE.PERMISSION=='r'),
8230  HDR.FILE.FID = fopen(HDR.FileName,PERMISSION,HDR.Endianity);
8231 
8232  HDR.FILE.OPEN = 1;
8233  HDR.FILE.POS = 0;
8234  HDR.VERSION = fread(HDR.FILE.FID,1,'int16');
8235  HDR.HeadLen = fread(HDR.FILE.FID,1,'uint16');
8236  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
8237  HDR.SEG2.nsterm = fread(HDR.FILE.FID,1,'uint8'); % number of string terminator
8238  HDR.SEG2.sterm = fread(HDR.FILE.FID,2,'uint8'); % string terminator
8239  HDR.SEG2.nlterm = fread(HDR.FILE.FID,1,'uint8'); % number of line terminator
8240  HDR.SEG2.lterm = fread(HDR.FILE.FID,2,'uint8'); % line terminator
8241  HDR.SEG2.TraceDesc = fread(HDR.FILE.FID,HDR.NS,'uint32');
8242 
8243  % initialize date
8244  HDR.SEG2.blocksize = repmat(nan,HDR.NS,1);
8245  HDR.AS.bpb = repmat(nan,HDR.NS,1);
8246  HDR.AS.spb = repmat(nan,HDR.NS,1);
8247  HDR.SEG2.DateFormatCode = repmat(nan,HDR.NS,1);
8248 
8249  if ftell(HDR.FILE.FID) ~= HDR.HeadLen,
8250  fprintf(HDR.FILE.stderr,'Warning SOPEN TYPE=SEG2: headerlength does not fit.\n');
8251  end;
8252 
8253  optstrings = fread(HDR.FILE.FID,HDR.SEG2.TraceDesc(1)-HDR.Headlen,'uint8');
8254 
8255  id_tmp = fread(HDR.FILE.FID,1,'uint16');
8256  if id_tmp ~=hex2dec('4422')
8257  fprintf(HDR.FILE.stderr,'Error SOPEN TYPE=SEG2: incorrect trace descriptor block ID.\n');
8258  end;
8259 
8260  for k = 1:HDR.NS,
8261  fseek(HDR.FILE.FID,HDR.SEG2.TraceDesc(k),'bof');
8262  HDR.SEG2.blocksize(k) = fread(HDR.FILE.FID,1,'uint16');
8263  HDR.AS.bpb(k) = fread(HDR.FILE.FID,1,'uint32');
8264  HDR.AS.spb(k) = fread(HDR.FILE.FID,1,'uint32');
8265  HDR.SEG2.DateFormatCode(k) = fread(HDR.FILE.FID,1,'uint8');
8266 
8267  fseek(HDR.FILE.FID,32-13,'cof');
8268  %[tmp,c] = fread(HDR.FILE.FID,32-13,'uint8'); % reserved
8269 
8270  optstrings = fread(HDR.FILE.FID,HDR.SEG2.blocksize(k)-32,'uint8');
8271  end;
8272 
8273  fprintf(HDR.FILE.stderr,'Format %s not implemented yet. \nFor more information contact <Biosig-general@lists.sourceforge.net> Subject: Biosig/Dataformats \n',HDR.TYPE);
8274  fclose(HDR.FILE.FID);
8275  HDR.FILE.FID = -1;
8276  HDR.FILE.OPEN = 0;
8277  end;
8278 
8279 
8280 elseif strncmp(HDR.TYPE,'SIGIF',5),
8281  if any(PERMISSION=='r'),
8282  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
8283  HDR.FILE.OPEN = 1;
8284  HDR.FILE.POS = 0;
8285 
8286  HDR.fingerprint=fgetl(HDR.FILE.FID); % 1
8287 
8288  if length(HDR.fingerprint)>6
8289  HDR.VERSION = int2str(HDR.fingerprint(7));
8290  else
8291  HDR.VERSION = 1.1;
8292  end;
8293  HDR.Comment=fgetl(HDR.FILE.FID); % 2
8294  HDR.SignalName=fgetl(HDR.FILE.FID); % 3
8295  HDR.Date=fgetl(HDR.FILE.FID); % 4
8296  HDR.modifDate=fgetl(HDR.FILE.FID); % 5
8297 
8298  [tmp1,tmp] = strtok(HDR.Date,'-/');
8299  HDR.T0 = zeros(1,6);
8300  HDR.T0(1) = str2double(tmp1);
8301  if length(tmp1)<3, HDR.T0(1) = 1900+HDR.T0(1); end;
8302  [tmp1,tmp] = strtok(tmp,'-/');
8303  HDR.T0(2) = str2double(tmp1);
8304  [tmp1,tmp] = strtok(tmp,'-/');
8305  HDR.T0(3) = str2double(tmp1);
8306 
8307  HDR.SIG.Type = fgetl(HDR.FILE.FID); % 6 simultaneous or serial sampling
8308  Source = fgetl(HDR.FILE.FID); % 7 - obsolete
8309  HDR.NS = str2double(fgetl(HDR.FILE.FID)); % 8 number of channels
8310  HDR.NRec = str2double(fgetl(HDR.FILE.FID)); % 9 number of segments
8311  NFrames= str2double(fgetl(HDR.FILE.FID)); % 10 number of frames per segment - obsolete
8312 
8313  %HDR.SPR = str2double(fgetl(HDR.FILE.FID)); % 11 number of samples per frame
8314  HDR.AS.spb = str2double(fgetl(HDR.FILE.FID)); % 11 number of samples per frame
8315  H1.Bytes_per_Sample = str2double(fgetl(HDR.FILE.FID)); % 12 number of bytes per samples
8316  HDR.AS.bpb = HDR.AS.spb * H1.Bytes_per_Sample;
8317  HDR.Sampling_order = str2double(fgetl(HDR.FILE.FID)); % 13
8318  HDR.FLAG.INTEL_format = str2double(fgetl(HDR.FILE.FID)); % 14
8319  HDR.FormatCode = str2double(fgetl(HDR.FILE.FID)); % 15
8320 
8321  HDR.CompressTechnique = fgetl(HDR.FILE.FID); % 16
8322  HDR.SignalType = fgetl(HDR.FILE.FID); % 17
8323 
8324  for k=1:HDR.NS,
8325  chandata = fgetl(HDR.FILE.FID); % 18
8326  [tmp,chandata] = strtok(chandata,' ,;:');
8327  HDR.Label{k} = tmp;
8328  [tmp,chandata] = strtok(chandata,' ,;:');
8329  HDR.Cal(k) = str2double(tmp);
8330 
8331  [tmp,chandata] = strtok(chandata,' ,;:');
8332  HDR.SampleRate(k) = str2double(tmp);
8333 
8334  %[tmp,chandata] = strtok(chandata);
8335  HDR.Variable{k} = chandata;
8336 
8337  while ~isempty(chandata)
8338  [tmp,chandata] = strtok(chandata,' ,;:');
8339  if strcmp(tmp,'G')
8340  [HDR.PhysDim{k},chandata] = strtok(chandata,' ,;:');
8341  end;
8342  end;
8343  end;
8344  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal,HDR.NS+1,HDR.NS);
8345  HDR.Segment_separator = fgetl(HDR.FILE.FID); % 19
8346  %HDR.Segment_separator = hex2dec(fgetl(HDR.FILE.FID));
8347 
8348  HDR.FLAG.TimeStamp = str2double(fgetl(HDR.FILE.FID)); % 20
8349 
8350  if HDR.VERSION>=3,
8351  HDR.FLAG.SegmentLength = str2double(fgetl(HDR.FILE.FID)); % 21
8352  HDR.AppStartMark = fgetl(HDR.FILE.FID); % 22
8353  HDR.AppInfo = fgetl(HDR.FILE.FID); % 23
8354  else
8355  HDR.FLAG.SegmentLength = 0;
8356  end;
8357  HDR.footer = fgets(HDR.FILE.FID,6); % 24
8358 
8359  if ~strcmp(HDR.footer,'oFSvAI')
8360  fprintf(HDR.FILE.stderr,'Warning LOADSIG in %s: Footer not found\n', HDR.FileName);
8361  end;
8362 
8363  if HDR.VERSION<2,
8364  HDR.FLAG.SegmentLength = 0;
8365  end;
8366 
8367  switch HDR.FormatCode,
8368  case 0; HDR.GDFTYP = 4; %'uint16';
8369  case 3; HDR.GDFTYP = 3; %'int16';
8370  HDR.Segment_separator = hex2dec(HDR.Segment_separator([3:4,1:2]));
8371  case 5; HDR.GDFTYP = 16; %'float';
8372  otherwise;
8373  fprintf(HDR.FILE.stderr,'Warning LOADSIG: FormatCode %i not implemented\n',HDR.FormatCode);
8374  end;
8375 
8376  tmp = ftell(HDR.FILE.FID);
8377  if ~HDR.FLAG.INTEL_format,
8378  fclose(HDR.FILE.FID);
8379  HDR.FILE.FID = fopen(HDR.FileName,'rt','ieee-be');
8380  fseek(HDR.FILE.FID,tmp,'bof');
8381  end;
8382  HDR.HeadLen = tmp + HDR.FLAG.TimeStamp*9;
8383 
8384  if ~HDR.NRec, HDR.NRec = inf; end;
8385  k = 0;
8386  while (k < HDR.NRec) && ~feof(HDR.FILE.FID),
8387  k = k+1;
8388  HDR.Block.Pos(k) = ftell(HDR.FILE.FID);
8389  if HDR.FLAG.TimeStamp,
8390  HDR.Frame(k).TimeStamp = fread(HDR.FILE.FID,[1,9],'uint8');
8391  end;
8392 
8393  if HDR.FLAG.SegmentLength,
8394  HDR.Block.Length(k) = fread(HDR.FILE.FID,1,'uint16'); %#26
8395  fseek(HDR.FILE.FID,HDR.Block.Length(k)*H1.Bytes_per_Sample,'cof');
8396  else
8397  tmp = HDR.Segment_separator-1;
8398  count = 0;
8399  data = [];
8400  dat = [];
8401  while ~(any(dat==HDR.Segment_separator));
8402  [dat,c] = fread(HDR.FILE.FID,[HDR.NS,1024],HDR.GDFTYP);
8403  count = count + c;
8404  end;
8405  tmppos = min(find(dat(:)==HDR.Segment_separator));
8406  HDR.Block.Length(k) = count - c + tmppos;
8407  end;
8408  end;
8409  HDR.SPR = HDR.Block.Length/HDR.NS;
8410  HDR.Dur = max(HDR.SPR./HDR.SampleRate);
8411  HDR.NRec = k;
8412 
8413  if HDR.FLAG.TimeStamp,
8414  tmp=char(HDR.Frame(1).TimeStamp);
8415  HDR.T0(4) = str2double(tmp(1:2));
8416  HDR.T0(5) = str2double(tmp(3:4));
8417  HDR.T0(6) = str2double([tmp(5:6),'.',tmp(7:9)]);
8418  end;
8419  end;
8420 
8421 elseif strcmp(HDR.TYPE,'AINF'),
8422  if any(HDR.FILE.PERMISSION=='r'),
8423  %%%% read header %%%%
8424  fid = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.ainf']),'rt');
8425  s = char(fread(fid,[1,inf],'uint8'));
8426  fclose(fid);
8427  [tline,s] = strtok(s,[10,13]);
8428  while strncmp(tline,'#',1)
8429  [tline,s]=strtok(s,[10,13]);
8430  [t,r]=strtok(tline,[9,10,13,' #:=']);
8431  if strcmp(t,'sfreq'),
8432  [t,r]=strtok(r,[9,10,13,' #:=']);
8433  HDR.SampleRate = str2double(t);
8434  end;
8435  end;
8436  [n,v,sa] = str2double([tline,s]);
8437  HDR.NS = max(n(:,1));
8438  for k = 1:HDR.NS,
8439  HDR.Label{k} = [sa{k,2},' ',sa{k,3}];
8440  end;
8441  HDR.Cal = [n(:,4).*n(:,5)];
8442 
8443  %%%% read data %%%%
8444  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.raw']),HDR.FILE.PERMISSION,'ieee-be');
8445  fseek(HDR.FILE.FID,0,'eof');
8446  HDR.FILE.size = ftell(HDR.FILE.FID);
8447  fseek(HDR.FILE.FID,0,'bof');
8448 
8449  HDR.GDFTYP = 3;
8450  HDR.AS.bpb = HDR.NS*2+4;
8451  HDR.SPR = floor(HDR.FILE.size/HDR.AS.bpb);
8452  HDR.NRec = 1;
8453  HDR.FILE.POS = 0;
8454  HDR.HeadLen = 0;
8455  HDR.PhysDimCode = zeros(HDR.NS,1);
8456  end;
8457 
8458 
8459 elseif strcmp(HDR.TYPE,'CTF'),
8460  if any(HDR.FILE.PERMISSION=='r'),
8461  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.res4']),HDR.FILE.PERMISSION,'ieee-be');
8462  if HDR.FILE.FID<0,
8463  return
8464  end;
8465  HDR.FILE.OPEN = 1;
8466  HDR.FILE.POS = 0;
8467  fseek(HDR.FILE.FID,778,'bof');
8468  tmp = char(fread(HDR.FILE.FID,255,'uint8')');
8469  tmp(tmp==':')=' ';
8470  tmp = str2double(tmp);
8471  if length(tmp)==3,
8472  HDR.T0(4:6)=tmp;
8473  end;
8474  tmp = char(fread(HDR.FILE.FID,255,'uint8')');
8475  tmp(tmp=='/')=' ';
8476  tmp = str2double(tmp);
8477  if length(tmp)==3,
8478  HDR.T0(1:3) = tmp;
8479  end;
8480 
8481  HDR.SPR = fread(HDR.FILE.FID,1,'int32');
8482  HDR.NS = fread(HDR.FILE.FID,1,'int16');
8483  HDR.CTF.NS2 = fread(HDR.FILE.FID,1,'int16');
8484  HDR.SampleRate = fread(HDR.FILE.FID,1,'double');
8485  HDR.Dur = fread(HDR.FILE.FID,1,'double');
8486  HDR.NRec = fread(HDR.FILE.FID,1,'int16');
8487  HDR.CTF.NRec2 = fread(HDR.FILE.FID,1,'int16');
8488  HDR.TriggerOffset = fread(HDR.FILE.FID,1,'int32');
8489 
8490  fseek(HDR.FILE.FID,1712,'bof');
8491  HDR.PID = char(fread(HDR.FILE.FID,32,'uint8')');
8492  HDR.Operator = char(fread(HDR.FILE.FID,32,'uint8')');
8493  HDR.FILE.SensorFileName = char(fread(HDR.FILE.FID,60,'uint8')');
8494 
8495  %fseek(HDR.FILE.FID,1836,'bof');
8496  HDR.CTF.RunSize = fread(HDR.FILE.FID,1,'int32');
8497  HDR.CTF.RunSize2 = fread(HDR.FILE.FID,1,'int32');
8498  HDR.CTF.RunDescription = char(fread(HDR.FILE.FID,HDR.CTF.RunSize,'uint8')');
8499  HDR.CTF.NumberOfFilters = fread(HDR.FILE.FID,1,'int16');
8500 
8501  for k = 1:HDR.CTF.NumberOfFilters,
8502  F.Freq = fread(HDR.FILE.FID,1,'double');
8503  F.Class = fread(HDR.FILE.FID,1,'int32');
8504  F.Type = fread(HDR.FILE.FID,1,'int32');
8505  F.NA = fread(HDR.FILE.FID,1,'int16');
8506  F.A = fread(HDR.FILE.FID,[1,F.NA],'double');
8507  HDR.CTF.Filter(k) = F;
8508  end;
8509 
8510  tmp = fread(HDR.FILE.FID,[32,HDR.NS],'uint8');
8511  tmp(tmp<0) = 0;
8512  tmp(tmp>127) = 0;
8513  tmp(cumsum(tmp==0)>0)=0;
8514  HDR.Label = cellstr(char(tmp'));
8515 
8516  for k = 1:HDR.NS,
8517  info.index(k,:) = fread(HDR.FILE.FID,1,'int16');
8518  info.extra(k,:) = fread(HDR.FILE.FID,1,'int16');
8519  info.ix(k,:) = fread(HDR.FILE.FID,1,'int32');
8520  info.gain(k,:) = fread(HDR.FILE.FID,[1,4],'double');
8521 
8522  info.index2(k,:) = fread(HDR.FILE.FID,1,'int16');
8523  info.extra2(k,:) = fread(HDR.FILE.FID,1,'int16');
8524  info.ix2(k,:) = fread(HDR.FILE.FID,1,'int32');
8525 
8526  fseek(HDR.FILE.FID,1280,'cof');
8527  end;
8528  fclose(HDR.FILE.FID);
8529 
8530  %%%%% read Markerfile %%%%%
8531  fid = fopen(fullfile(HDR.FILE.Path,'MarkerFile.mrk'),'rb','ieee-be');
8532  if fid > 0,
8533  while ~feof(fid),
8534  s = fgetl(fid);
8535  if ~isempty(strmatch('PATH OF DATASET:',s))
8536  file = fgetl(fid);
8537 
8538  elseif 0,
8539 
8540  elseif ~isempty(strmatch('TRIAL NUMBER',s))
8541  N = 0;
8542  x = fgetl(fid);
8543  while ~isempty(x),
8544  tmp = str2double(x);
8545  N = N+1;
8546  HDR.EVENT.POS(N,1) = tmp(1)*HDR.SPR+tmp(2)*HDR.SampleRate;
8547  HDR.EVENT.TYP(N,1) = 1;
8548  x = fgetl(fid);
8549  end
8550  else
8551 
8552  end
8553  end
8554  fclose(fid);
8555  end;
8556 
8557  HDR.CTF.info = info;
8558  ix = (info.index==0) | (info.index==1) | (info.index==9);
8559  ix0 = find(ix);
8560  HDR.Cal(ix0) = 1./(info.gain(ix0,1) .* info.gain(ix0,2));
8561  ix0 = find(~ix);
8562  HDR.Cal(ix0) = 1./info.gain(ix0,2);
8563  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
8564  HDR.FLAG.TRIGGERED = HDR.NRec > 1;
8565  HDR.AS.spb = HDR.NRec * HDR.NS;
8566  HDR.AS.bpb = HDR.AS.spb * 4;
8567 
8568  HDR.CHANTYP = char(repmat(32,HDR.NS,1));
8569  HDR.CHANTYP(info.index==9) = 'E';
8570  HDR.CHANTYP(info.index==5) = 'M';
8571  HDR.CHANTYP(info.index==1) = 'R';
8572  HDR.CHANTYP(info.index==0) = 'R';
8573 
8574  if 0,
8575 
8576  elseif strcmpi(CHAN,'MEG'),
8577  CHAN = find(info.index==5);
8578  elseif strcmpi(CHAN,'EEG'),
8579  CHAN = find(info.index==9);
8580  elseif strcmpi(CHAN,'REF'),
8581  CHAN = find((info.index==0) | (info.index==1));
8582  elseif strcmpi(CHAN,'other'),
8583  CHAN = find((info.index~=0) & (info.index~=1) & (info.index~=5) & (info.index~=9));
8584  end;
8585 
8586  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.meg4']),'rb','ieee-be');
8587  HDR.VERSION = char(fread(HDR.FILE.FID,[1,8],'uint8'));
8588  HDR.HeadLen = ftell(HDR.FILE.FID);
8589  fseek(HDR.FILE.FID,0,'eof');
8590  HDR.AS.endpos = ftell(HDR.FILE.FID);
8591  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
8592  end;
8593 
8594 
8595 elseif strcmp(HDR.TYPE,'BrainVision_MarkerFile'),
8596  %read event file
8597  fid = fopen(HDR.FileName,'rt');
8598  if fid>0,
8599  NoSegs = 0;
8600  while ~feof(fid),
8601  u = fgetl(fid);
8602  if strncmp(u,'Mk',2),
8603  [N,s] = strtok(u(3:end),'=');
8604  ix = find(s==',');
8605  ix(length(ix)+1) = length(s)+1;
8606  N = str2double(N);
8607  HDR.EVENT.POS(N,1) = str2double(s(ix(2)+1:ix(3)-1));
8608  HDR.EVENT.TYP(N,1) = 0;
8609  HDR.EVENT.DUR(N,1) = str2double(s(ix(3)+1:ix(4)-1));
8610  HDR.EVENT.CHN(N,1) = str2double(s(ix(4)+1:ix(5)-1));
8611  HDR.EVENT.TeegType{N,1} = s(2:ix(1)-1);
8612  Desc{N,1} = s(ix(1)+1:ix(2)-1);
8613  if strncmp('New Segment',s(2:ix(1)-1),4);
8614  t = s(ix(5)+1:end);
8615  NoSegs = NoSegs+1;
8616  HDR.EVENT.Segments{NoSegs}.T0 = str2double(char([t(1:4),32,t(5:6),32,t(7:8),32,t(9:10),32,t(11:12),32,t(13:14)]));
8617  HDR.EVENT.Segments{NoSegs}.Start = HDR.EVENT.POS(N);
8618  HDR.EVENT.TYP(N,1) = hex2dec('7ffe');
8619  end;
8620  if NoSegs>0,
8621  HDR.T0 = HDR.EVENT.Segments{1}.T0;
8622  end;
8623  end;
8624  end;
8625  fclose(fid);
8626  HDR.TYPE = 'EVENT';
8627  HDR.EVENT.Desc = Desc;
8628  [HDR.EVENT.CodeDesc, CodeIndex, j] = unique(Desc);
8629  ix = (HDR.EVENT.TYP==0);
8630  HDR.EVENT.TYP(ix) = j(ix);
8631  end;
8632 
8633 
8634 elseif strncmp(HDR.TYPE,'BrainVision',11),
8635  % get the header information from the VHDR ascii file
8636  fid = fopen(HDR.FileName,'rt');
8637  if fid<0,
8638  fprintf('Error SOPEN: could not open file %s\n',HDR.FileName);
8639  return;
8640  end;
8641  tline = fgetl(fid);
8642  HDR.BV.SkipLines = 0;
8643  HDR.BV.SkipColumns = 0;
8644  UCAL = 0;
8645  flag = 1;
8646  while ~feof(fid),
8647  tline = fgetl(fid);
8648  if isempty(tline),
8649  elseif tline(1)==';',
8650  elseif tline(1)==10,
8651  elseif tline(1)==13, % needed for Octave
8652  elseif strncmp(tline,'[Common Infos]',14)
8653  flag = 2;
8654  elseif strncmp(tline,'[Binary Infos]',14)
8655  flag = 3;
8656  elseif strncmp(tline,'[ASCII Infos]',13)
8657  flag = 3;
8658  elseif strncmp(tline,'[Channel Infos]',14)
8659  flag = 4;
8660  elseif strncmp(tline,'[Coordinates]',12)
8661  flag = 5;
8662  elseif strncmp(tline,'[Marker Infos]',12)
8663  flag = 6;
8664  elseif strncmp(tline,'[Comment]',9)
8665  flag = 7;
8666  elseif strncmp(tline,'[',1) % any other segment
8667  flag = 8;
8668 
8669  elseif any(flag==[2,3]),
8670  [t1,r] = strtok(tline,'=');
8671  [t2,r] = strtok(r,['=',char([10,13])]);
8672  [n2,v2,s2] = str2double(t2);
8673  if isempty(n2),
8674  elseif isnan(n2)
8675  HDR.BV = setfield(HDR.BV,t1,t2);
8676  else
8677  HDR.BV = setfield(HDR.BV,t1,n2);
8678  end;
8679  if strcmp(t1,'NumberOfChannels')
8680  HDR.NS = n2;
8681  elseif strcmpi(t1,'SamplingInterval')
8682  HDR.BV.SamplingInterval = n2;
8683  end;
8684  elseif flag==4,
8685  [t1,r] = strtok(tline,'=');
8686  [t2,r] = strtok(r, ['=',char([10,13])]);
8687  [chan, stat1] = str2double(t1(3:end));
8688  ix = [find(t2==','),length(t2)+1];
8689  tmp = [t2(1:ix(1)-1),' '];
8690  ix2 = strfind(tmp,'\1');
8691  for k=length(ix2):-1:1, % replace '\1' with comma
8692  tmp = [tmp(1:ix2(k)-1),',',tmp(ix2(k)+2:end)];
8693  end;
8694  HDR.Label{chan,1} = tmp;
8695  HDR.BV.reference{chan,1} = t2(ix(1)+1:ix(2)-1);
8696  [v, stat] = str2double(t2(ix(2)+1:ix(3)-1)); % in microvolt
8697  if (prod(size(v))==1) && ~any(stat)
8698  HDR.Cal(chan) = v;
8699  else
8700  UCAL = 1;
8701  HDR.Cal(chan) = 1;
8702  end;
8703  tmp = t2(ix(3)+1:end);
8704  if isequal(tmp,char([194,'µV'])),
8705  tmp = tmp(2:3);
8706  elseif isempty(tmp),
8707  tmp = 'µV';
8708  end;
8709  HDR.PhysDim{chan,1} = tmp;
8710 
8711  elseif flag==5,
8712  % Coordinates: <R>,<theta>,<phi>
8713  tline(tline=='=')=',';
8714  v = str2double(tline(3:end));
8715  chan = v(1); R=v(2); Theta = v(3)*pi/180; Phi = v(4)*pi/180;
8716  HDR.ELEC.XYZ(chan,:) = R*[sin(Theta).*cos(Phi),sin(Theta).*sin(Phi),cos(Theta)];
8717 
8718  elseif (flag>=7) && (flag<8),
8719  if flag==7,
8720  if tline(1)=='#',
8721  flag = 7.1;
8722  end;
8723  elseif flag==7.1,
8724  if (tline(1)<'0') || (tline(1)>'9'),
8725  if ~isempty(strfind(tline,'Impedance'));
8726  ix1 = find(tline=='[');
8727  ix2 = find(tline==']');
8728  Zunit = tline(ix1+1:ix2-1);
8729  [Zcode,Zscale] = physicalunits(Zunit);
8730  flag = 7.2; % stop
8731  end;
8732  else
8733  %[n,v,s] = str2double(tline(19:end));
8734  [n,v,s] = str2double(tline);
8735  ch = n(1);
8736  if ch>0,
8737  HDR.Label{ch} = tline(7:18);
8738  HDR.Cal(ch) = n(4);
8739  if v(3),
8740  HDR.PhysDim{ch} = s{5}(strncmp(s{5},char(194),1)+1:end);
8741  end;
8742  HDR.Filter.HighPass(ch)= 1/(2*pi*n(5+(v(3)~=0))); % Low Cut Off [s]: f = 1/(2.pi.tau)
8743  HDR.Filter.LowPass(ch) = n(6+(v(3)~=0)); % High Cut Off [Hz]
8744  HDR.Filter.Notch(ch) = strcmpi(s{7+(v(3)~=0)},'on');
8745  end;
8746  if ch==HDR.NS,
8747  flag=7.3;
8748  end;
8749  end;
8750  elseif flag==7.2,
8751  [n,v,s]=str2double(tline,[': ',9]);
8752  ch = strmatch(s{1},HDR.Label);
8753  if ~isempty(strfind(tline,'Out of Range!'))
8754  n(2) = Inf;
8755  end;
8756  if any(ch),
8757  HDR.Impedance(ch,1) = n(2)*Zscale;
8758  end;
8759  end;
8760  end;
8761  end;
8762  fclose(fid);
8763 
8764  % convert the header information to BIOSIG standards
8765  HDR.SampleRate = 1e6/HDR.BV.SamplingInterval; % sampling rate in Hz
8766  HDR.NRec = 1; % it is a continuous datafile, therefore one record
8767  HDR.Calib = [zeros(1,HDR.NS) ; diag(HDR.Cal)]; % is this correct?
8768  HDR.FLAG.TRIGGERED = 0;
8769 
8770  if ~isfield(HDR.BV,'BinaryFormat')
8771  % default
8772  HDR.GDFTYP = 3; % 'int16';
8773  HDR.AS.bpb = HDR.NS * 2;
8774  if ~isfield(HDR,'THRESHOLD'),
8775  HDR.THRESHOLD = repmat([-2^15,2^15-1],HDR.NS,1);
8776  end;
8777  elseif strncmpi(HDR.BV.BinaryFormat, 'int_16',6)
8778  HDR.GDFTYP = 3; % 'int16';
8779  HDR.DigMin = -32768*ones(HDR.NS,1);
8780  HDR.DigMax = 32767*ones(HDR.NS,1);
8781  HDR.PhysMax = HDR.DigMax(:).*HDR.Cal(:);
8782  HDR.PhysMin = HDR.DigMin(:).*HDR.Cal(:);
8783  HDR.AS.bpb = HDR.NS * 2;
8784  if ~isfield(HDR,'THRESHOLD'),
8785  HDR.THRESHOLD = repmat([-2^15,2^15-1],HDR.NS,1);
8786  end;
8787  elseif strncmpi(HDR.BV.BinaryFormat, 'uint_16',7)
8788  HDR.GDFTYP = 4; % 'uint16';
8789  HDR.AS.bpb = HDR.NS * 2;
8790  HDR.DigMin = 0*ones(HDR.NS,1);
8791  HDR.DigMax = 65535*ones(HDR.NS,1);
8792  HDR.PhysMax = HDR.DigMax(:).*HDR.Cal(:);
8793  HDR.PhysMin = HDR.DigMin(:).*HDR.Cal(:);
8794  if ~isfield(HDR,'THRESHOLD'),
8795  HDR.THRESHOLD = repmat([0,2^16-1],HDR.NS,1);
8796  end;
8797  elseif strncmpi(HDR.BV.BinaryFormat, 'ieee_float_32',13)
8798  HDR.GDFTYP = 16; % 'float32';
8799  HDR.AS.bpb = HDR.NS * 4;
8800  elseif strncmpi(HDR.BV.BinaryFormat, 'ieee_float_64',13)
8801  HDR.GDFTYP = 17; % 'float64';
8802  HDR.AS.bpb = HDR.NS * 8;
8803  end
8804  if (strcmp(HDR.TYPE,'BrainVisionVAmp'))
8805  HDR.AS.bpb = HDR.AS.bpb+4;
8806  end;
8807 
8808  % read event file
8809  tmp = fullfile(HDR.FILE.Path, HDR.BV.MarkerFile);
8810  if ~exist(tmp,'file')
8811  tmp = fullfile(HDR.FILE.Path, [HDR.FILE.Name,'.vmrk']);
8812  end;
8813  if exist(tmp,'file')
8814  H = sopen(tmp,'rt');
8815  if strcmp(H.TYPE,'EVENT');
8816  HDR.EVENT = H.EVENT;
8817  HDR.T0 = H.T0;
8818 
8819  tmp = which('sopen'); %%% used for BBCI
8820  if exist(fullfile(fileparts(tmp),'bv2biosig_events.m'),'file');
8821  try
8822  HDR = bv2biosig_events(HDR);
8823  catch
8824  warning('bv2biosig_events not executed');
8825  end;
8826  end;
8827  end;
8828  end;
8829 
8830  %open data file
8831  if strncmpi(HDR.BV.DataFormat, 'binary',5)
8832  PERMISSION='rb';
8833  elseif strncmpi(HDR.BV.DataFormat, 'ascii',5)
8834  PERMISSION='rt';
8835  end;
8836 
8837  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,HDR.BV.DataFile),PERMISSION,'ieee-le');
8838  try % Octave: catch if native2unicode and unicode2native are not supported
8839  if HDR.FILE.FID < 0,
8840  DataFile = native2unicode(HDR.BV.DataFile);
8841  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,DataFile),PERMISSION,'ieee-le');
8842  end;
8843  if HDR.FILE.FID < 0,
8844  DataFile = unicode2native(HDR.BV.DataFile);
8845  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,DataFile),PERMISSION,'ieee-le');
8846  end;
8847  catch
8848  warning('native2unicode/unicode2native failed');
8849  end;
8850  if HDR.FILE.FID < 0,
8851  fprintf(HDR.FILE.stderr,'ERROR SOPEN BV: could not open file %s\n',fullfile(HDR.FILE.Path,HDR.BV.DataFile));
8852  HDR.BV.DataFile = [HDR.FILE.Name,'.dat'];
8853  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,HDR.BV.DataFile),PERMISSION,'ieee-le');
8854  end;
8855  if HDR.FILE.FID < 0,
8856  fprintf(HDR.FILE.stderr,'ERROR SOPEN BV: could not open file %s\n',fullfile(HDR.FILE.Path,HDR.BV.DataFile));
8857  HDR.BV.DataFile = [HDR.FILE.Name,'.eeg'];
8858  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,HDR.BV.DataFile),PERMISSION,'ieee-le');
8859  end;
8860  if HDR.FILE.FID < 0,
8861  fprintf(HDR.FILE.stderr,'ERROR SOPEN BV: could not open file %s\n',fullfile(HDR.FILE.Path,HDR.BV.DataFile));
8862  return;
8863  end;
8864 
8865  HDR.FILE.OPEN= 1;
8866  HDR.FILE.POS = 0;
8867  HDR.HeadLen = 0;
8868  if strncmpi(HDR.BV.DataFormat, 'binary',5)
8869  fseek(HDR.FILE.FID,0,'eof');
8870  HDR.AS.endpos = ftell(HDR.FILE.FID);
8871  fseek(HDR.FILE.FID,0,'bof');
8872  HDR.AS.endpos = HDR.AS.endpos/HDR.AS.bpb;
8873 
8874  elseif strncmpi(HDR.BV.DataFormat, 'ASCII',5)
8875  while (HDR.BV.SkipLines>0),
8876  fgetl(HDR.FILE.FID);
8877  HDR.BV.SkipLines = HDR.BV.SkipLines-1;
8878  end;
8879  s = char(fread(HDR.FILE.FID,inf,'uint8')');
8880  fclose(HDR.FILE.FID);
8881  if isfield(HDR.BV,'DecimalSymbol')
8882  s(s==HDR.BV.DecimalSymbol)='.';
8883  end;
8884  [tmp,status] = str2double(s);
8885  if (HDR.BV.SkipColumns>0),
8886  tmp = tmp(:,HDR.BV.SkipColumns+1:end);
8887  end;
8888  if strncmpi(HDR.BV.DataOrientation, 'multiplexed',6),
8889  HDR.data = tmp;
8890  elseif strncmpi(HDR.BV.DataOrientation, 'vectorized',6),
8891  HDR.data = tmp';
8892  end
8893  HDR.TYPE = 'native';
8894  HDR.AS.endpos = size(HDR.data,1);
8895  if ~any(HDR.NS ~= size(tmp));
8896  fprintf(HDR.FILE.stderr,'ERROR SOPEN BV-ascii: number of channels inconsistency\n');
8897  end;
8898  end
8899  HDR.SPR = HDR.AS.endpos;
8900 
8901 
8902 %elseif strncmp(HDR.TYPE,'EEProbe',7),
8903 % HDR = openeep(HDR);
8904 elseif strncmp(HDR.TYPE,'EEProbe',7),
8905  if strcmp(HDR.TYPE,'EEProbe-CNT'),
8906  %if
8907  try
8908  % Read the first sample of the file with a mex function
8909  % this also gives back header information, which is needed here
8910  tmp = read_eep_cnt(HDR.FileName, 1, 1);
8911 
8912  % convert the header information to BIOSIG standards
8913  HDR.FILE.FID = 1; % ?
8914  HDR.FILE.POS = 0;
8915  HDR.NS = tmp.nchan; % number of channels
8916  HDR.SampleRate = tmp.rate; % sampling rate
8917  HDR.NRec = 1; % it is always continuous data, therefore one record
8918  HDR.FLAG.TRIGGERED = 0;
8919  HDR.SPR = tmp.nsample; % total number of samples in the file
8920  HDR.Dur = tmp.nsample/tmp.rate; % total duration in seconds
8921  HDR.Calib = [zeros(1,HDR.NS) ; eye(HDR.NS, HDR.NS)]; % is this correct?
8922  HDR.Cal = ones(1,HDR.NS);
8923  HDR.Label = char(tmp.label);
8924  HDR.PhysDimCode = ones(1,HDR.NS)*4275; % uV
8925  HDR.AS.endpos = HDR.SPR;
8926  HDR.Label = tmp.label;
8927  H = [];
8928  %else %
8929  catch
8930  HDR.FILE.FID = fopen(HDR.FileName,'rb');
8931  H = openiff(HDR.FILE.FID);
8932  end;
8933 
8934  if isfield(H,'RIFF');
8935  HDR.FILE.OPEN = 1;
8936  HDR.RIFF = H.RIFF;
8937  HDR.Label = {};
8938  HDR.PhysDim = {};
8939  HDR.SPR = inf;
8940  HDR.NRec = 1;
8941  HDR.FILE.POS = 0;
8942  if ~isfield(HDR.RIFF,'CNT');
8943  HDR.TYPE = 'unknown';
8944  elseif ~isfield(HDR.RIFF.CNT,'eeph');
8945  HDR.TYPE = 'unknown';
8946  else
8947  s = char(HDR.RIFF.CNT.eeph);
8948  field = '';
8949  while ~isempty(s)
8950  [line,s] = strtok(s,[10,13]);
8951  if strncmp(line,'[Sampling Rate]',15);
8952  field = 'SampleRate';
8953  elseif strncmp(line,'[Samples]',9);
8954  field = 'SPR';
8955  elseif strncmp(line,'[Channels]',10);
8956  field = 'NS';
8957  elseif strncmp(line,'[Basic Channel Data]',20);
8958  k = 0;
8959  while (k<HDR.NS),
8960  [line,s] = strtok(s,[10,13]);
8961  if ~strncmp(line,';',1);
8962  k = k+1;
8963  [num,status,sa]=str2double(line);
8964  HDR.Label{k} = sa{1};
8965  HDR.PhysDim{k} = sa{4};
8966  HDR.Cal(k) = num(2)*num(3);
8967  end;
8968  end;
8969  elseif strncmp(line,';',1);
8970  elseif strncmp(line,'[',1);
8971  field = '';
8972  elseif ~isempty(field);
8973  [num,status,sa] = str2double(line);
8974  if ~status,
8975  HDR = setfield(HDR,field,num);
8976  end;
8977  end;
8978  end;
8979 
8980  %HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
8981  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1); % because SREAD uses READ_EEP_CNT.MEX
8982  HDR.Cal = ones(1,HDR.NS);
8983  HDR.GDFTYP = repmat(16,1,HDR.NS); %float32
8984  end
8985  end
8986  end;
8987 
8988  % read event file, if applicable
8989  fid = 0;
8990  if strcmp(HDR.TYPE,'EEProbe-TRG'),
8991  fid = fopen(HDR.FileName,'rt');
8992  elseif strcmp(HDR.TYPE,'EEProbe-CNT')
8993  fid = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.trg']),'rt');
8994  end;
8995  if fid>0,
8996  tmp = str2double(fgetl(fid));
8997  if ~isnan(tmp(1))
8998  HDR.EVENT.SampleRate = 1/tmp(1);
8999  N = 0;
9000  while ~feof(fid),
9001  tmp = fscanf(fid, '%f %d %s', 3);
9002  if ~isempty(tmp)
9003  N = N + 1;
9004  HDR.EVENT.POS(N,1) = round(tmp(1)*HDR.EVENT.SampleRate);
9005  HDR.EVENT.TYP(N,1) = 0;
9006  %HDR.EVENT.DUR(N,1) = 0;
9007  %HDR.EVENT.CHN(N,1) = 0;
9008 
9009  HDR.EVENT.TeegType{N,1} = char(tmp(3:end));
9010  HDR.EVENT.TYP(N,1) = str2double(HDR.EVENT.TeegType{N,1}); % numeric
9011  end
9012  end;
9013  HDR.EVENT.TYP(isnan(HDR.EVENT.TYP))=0;
9014  HDR.TRIG = HDR.EVENT.POS(HDR.EVENT.TYP>0);
9015  % HDR.EVENT.POS = HDR.EVENT.POS(HDR.EVENT.TYP>0);
9016  % HDR.EVENT.TYP = HDR.EVENT.TYP(HDR.EVENT.TYP>0);
9017  % HDR.EVENT = rmfield(HDR.EVENT,'TeegType');
9018  end;
9019  fclose(fid);
9020  end;
9021 
9022  if strcmp(HDR.TYPE,'EEProbe-AVR'),
9023  % it appears to be a EEProbe file with an averaged ERP
9024  try
9025  tmp = read_eep_avr(HDR.FileName);
9026  catch
9027  fprintf(HDR.FILE.stderr,'ERROR SOPEN (EEProbe): Cannot open EEProbe-file, because read_eep_avr.mex not installed. \n');
9028  fprintf(HDR.FILE.stderr,'ERROR SOPEN (EEProbe): see http://www.smi.auc.dk/~roberto/eeprobe/\n');
9029  return;
9030  end
9031 
9032  % convert the header information to BIOSIG standards
9033  HDR.FILE.FID = 1; % ?
9034  HDR.FILE.POS = 0;
9035  HDR.NS = tmp.nchan; % number of channels
9036  HDR.SampleRate = tmp.rate; % sampling rate
9037  HDR.NRec = 1; % it is an averaged ERP, therefore one record
9038  HDR.SPR = tmp.npnt; % total number of samples in the file
9039  HDR.Dur = tmp.npnt/tmp.rate; % total duration in seconds
9040  HDR.Calib = [zeros(1,HDR.NS) ; eye(HDR.NS, HDR.NS)]; % is this correct?
9041  HDR.Label = char(tmp.label);
9042  HDR.PhysDim = 'uV';
9043  HDR.FLAG.UCAL = 1;
9044  HDR.FILE.POS = 0;
9045  HDR.AS.endpos = HDR.SPR;
9046  HDR.Label = tmp.label;
9047  HDR.TriggerOffset = 0;
9048 
9049  HDR.EEP.data = tmp.data';
9050  end;
9051 
9052 
9053 elseif strcmp(HDR.TYPE,'FAMOS'),
9054  HDR = famosopen(HDR);
9055  return;
9056 
9057 elseif strncmp(HDR.TYPE,'FIF',3),
9058  if any(exist('rawdata')==[3,6]),
9059  if isempty(FLAG_NUMBER_OF_OPEN_FIF_FILES)
9060  FLAG_NUMBER_OF_OPEN_FIF_FILES = 0;
9061  end;
9062  if ~any(FLAG_NUMBER_OF_OPEN_FIF_FILES==[0,1])
9063  fprintf(HDR.FILE.stderr,'ERROR SOPEN (FIF): number of open FIF files should be zero or one\n\t Perhaps, you forgot to SCLOSE(HDR) the previous FIF-file.\n');
9064  %return;
9065  end;
9066 
9067  try
9068  rawdata('any',HDR.FileName); % opens file
9069  FLAG_NUMBER_OF_OPEN_FIF_FILES = 1;
9070  catch
9071  tmp = which('rawdata');
9072  [p,f,e]=fileparts(tmp);
9073  fprintf(HDR.FILE.stderr,'ERROR SOPEN (FIF): Maybe you forgot to do \"export LD_LIBRARY_PATH=%s/i386 \" before you started Matlab. \n',p);
9074  return
9075  end
9076  HDR.FILE.FID = 1;
9077  HDR.SampleRate = rawdata('sf');
9078  HDR.AS.endpos = rawdata('samples');
9079  [HDR.MinMax,HDR.Cal] = rawdata('range');
9080  [HDR.Label, cIDX, number] = channames(HDR.FileName);
9081  if (sum(cIDX==1)==122)
9082  tmp = 'NM122coildef.mat';
9083  if exist(tmp,'file'),
9084  load(tmp);
9085  HDR.ELEC.XYZ = VM(ceil([1:122]/2),:);
9086  end;
9087  elseif (sum(cIDX==1)==306)
9088  tmp = 'NM306coildef.mat';
9089  if exist(tmp,'file'),
9090  load(tmp);
9091  HDR.ELEC.XYZ = VM(ceil([1:306]/3),:);
9092  end;
9093  end;
9094 
9095  rawdata('goto',-inf);
9096  [buf, status] = rawdata('next');
9097  HDR.Dur = rawdata('t');
9098  [HDR.NS,HDR.SPR] = size(buf);
9099  HDR.NRec = 1;
9100  HDR.AS.bpb = HDR.NS * 2;
9101  HDR.Calib = [zeros(1,HDR.NS);diag(HDR.Cal)];
9102 
9103  rawdata('goto', -inf);
9104  HDR.FILE.POS = 0;
9105  HDR.FILE.OPEN = 1;
9106  HDR.PhysDimCode = zeros(HDR.NS,1);
9107 
9108  else
9109  fprintf(HDR.FILE.stderr,'ERROR SOPEN (FIF): NeuroMag FIFF access functions not available. \n');
9110  fprintf(HDR.FILE.stderr,'\tOnline available at: http://www.kolumbus.fi/kuutela/programs/meg-pd/ \n');
9111  return;
9112  end;
9113 
9114 
9115 elseif strcmp(HDR.TYPE,'AndrewsHerzberg1985')
9116  s = HDR.s;
9117  ix1 = find((s==10) | (s==13)); % line breaks
9118  ix2 = find(s>'@'); % letters
9119  ix3 = [];
9120  for k=2:length(ix1)
9121  if any(s(ix1(k-1)+1:ix1(k))>64) && (s(ix1(k-1)+1)==' ')
9122  ix3 = [ix3,k-1];
9123  HDR.Label{length(ix3)} = s(ix1(k-1)+1:ix1(k)-1);
9124  t = str2double(s(ix1(k-2)+1:ix1(k-1)-1));
9125  if length(t)>1, t=t(2); end;
9126  HDR.AS.SPR(length(ix3)) = t;
9127  end;
9128  end;
9129  ix3 = [ix3,length(ix1)];
9130  for k=1:length(ix3)-1
9131  t = str2double(s(ix1(ix3(k)+2)+1:ix1(ix3(k+1)-1)))';
9132  HDR.data{k} = t(1:HDR.AS.SPR(k));
9133  end;
9134 
9135 elseif strcmp(HDR.TYPE,'CinC2007Challenge')
9136  ix = find(HDR.s==10);
9137  d = str2double(HDR.data(ix(4)+1:end));
9138  HDR.data = d(:,7:end);
9139  HDR.TYPE = 'native';
9140  [HDR.SPR,HDR.NS] = size(HDR.data);
9141  HDR.NRec = 1;
9142  HDR.Calib= sparse(2:HDR.NS+1,1:HDR.NS,1);
9143  %%% FIXME
9144  % HDR.ELEC.XYZ
9145  % HDR.PhysDimCode
9146 
9147 elseif strcmp(HDR.TYPE,'ET-MEG'),
9148  HDR = fltopen(HDR);
9149 
9150 
9151 elseif strcmp(HDR.TYPE,'ET-MEG:SQD'),
9152  if any(HDR.FILE.PERMISSION=='r'),
9153  fprintf(HDR.FILE.stderr,'Warning SOPEN: support of SQD format is experimental.\n');
9154  HDR.HeadLen = 55576;
9155  HDR.FILE.FID = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.',HDR.FILE.Ext]),'rb',HDR.Endianity);
9156  HDR.H8 = fread(HDR.FILE.FID,HDR.HeadLen,'uint8');
9157  fseek(HDR.FILE.FID,0,-1);
9158  HDR.H32 = fread(HDR.FILE.FID,HDR.HeadLen/4,'uint32');
9159  HDR.FILE.POS = 0;
9160  HDR.FILE.OPEN= 1;
9161  HDR.GDFTYP = 3; % int16
9162  tmp = HDR.H32([19,20,23,24,196,7485,7486,7489,7490,7662,7763,7931,13495,13524,13582,13640,13669,13727,13785,13814]);
9163  if ~all(tmp==tmp(1))
9164  fprintf(HDR.FILE.stderr,'Warning SOPEN(SQD): possible problem in HDR.NS');
9165  end;
9166  HDR.NS = tmp(1);
9167  tmp = HDR.H32([4247,4248,7733,7766,8644,8645]);
9168  HDR.SPR = tmp(1);
9169  if all(tmp==tmp(1))
9170  fprintf(HDR.FILE.stderr,'Warning SOPEN(SQD): possible problem in HDR.SPR');
9171  end;
9172  HDR.NRec = 1;
9173 
9174  HDR.AS.endpos= HDR.SPR*HDR.NRec;
9175  HDR.AS.bpb = 2*HDR.NS; % Bytes per Block
9176  end
9177 
9178 
9179 elseif strncmp(HDR.TYPE,'WINEEG',3),
9180  if any(HDR.FILE.PERMISSION=='r'),
9181  fprintf(HDR.FILE.stderr,'Warning SOPEN (WINEEG): this is still under developement.\n');
9182  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
9183  % HDR.FILE.OPEN = 1;
9184  HDR.FILE.POS = 0;
9185  HDR.EEG.H1 = fread(HDR.FILE.FID,[1,1152],'uint8');
9186  fseek(HDR.FILE.FID,0,'bof');
9187  HDR.EEG.H1u16 = fread(HDR.FILE.FID,[1,1152/2],'uint16');
9188  tmp = HDR.EEG.H1(197:218); tmp(tmp==47) = ' '; tmp(tmp==0) = ' '; tmp(tmp==':') = ' ';
9189  [n,v,s] = str2double(char(tmp));
9190  HDR.T0 = n([3,2,1,4,5,6]);
9191  HDR.NS = HDR.EEG.H1(3:4)*[1;256];
9192  HDR.SampleRate = HDR.EEG.H1(5:6)*[1;256];
9193  HDR.EEG.H2 = fread(HDR.FILE.FID,[64,HDR.NS],'uint8')';
9194  fseek(HDR.FILE.FID,1152,'bof');
9195  HDR.EEG.H2f32 = fread(HDR.FILE.FID,[64/4,HDR.NS],'float')';
9196  HDR.Label = char(HDR.EEG.H2(:,1:4));
9197  %HDR.FLAG.UCAL = 1;
9198  HDR.Cal = HDR.EEG.H2f32(:,7);
9199  HDR.PhysDim = repmat({'uV'},HDR.NS,1);
9200 
9201  HDR.HeadLen = ftell(HDR.FILE.FID);
9202  HDR.SPR = floor((HDR.FILE.size-HDR.HeadLen)/(HDR.NS*2));
9203  HDR.NRec = 1;
9204 
9205  HDR.data = fread(HDR.FILE.FID,[HDR.NS,inf],'int16')';
9206  HDR.TYPE = 'native';
9207  fclose(HDR.FILE.FID);
9208  end;
9209 
9210 
9211 elseif strncmp(HDR.TYPE,'FS3',3),
9212  if any(HDR.FILE.PERMISSION=='r'),
9213  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
9214  HDR.FILE.OPEN = 1;
9215  HDR.FILE.POS = 0;
9216  HDR.Date = fgets(HDR.FILE.FID);
9217  HDR.Info = fgets(HDR.FILE.FID);
9218  HDR.SURF.N = fread(HDR.FILE.FID,1,'int32');
9219  HDR.FACE.N = fread(HDR.FILE.FID,1,'int32');
9220  HDR.VERTEX.COORD = fread(HDR.FILE.FID,3*HDR.SURF.N,'float32');
9221 
9222  HDR.FACES = fread(HDR.FILE.FID,[3,HDR.FACE.N],'int32')';
9223  fclose(HDR.FILE.FID);
9224  end
9225 
9226 
9227 elseif strncmp(HDR.TYPE,'FS4',3),
9228  if any(HDR.FILE.PERMISSION=='r'),
9229  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-be');
9230  HDR.FILE.OPEN = 1;
9231  HDR.FILE.POS = 0;
9232 
9233  tmp = fread(HDR.FILE.FID,[1,3],'uint8');
9234  HDR.SURF.N = tmp*(2.^[16;8;1]);
9235  tmp = fread(HDR.FILE.FID,[1,3],'uint8');
9236  HDR.FACE.N = tmp*(2.^[16;8;1]);
9237  HDR.VERTEX.COORD = fread(HDR.FILE.FID,3*HDR.SURF.N,'int16')./100;
9238  tmp = fread(HDR.FILE.FID,[4*HDR.FACE.N,3],'uint8')*(2.^[16;8;1]);
9239  HDR.FACES = reshape(tmp,4,HDR.FACE.N)';
9240  fclose(HDR.FILE.FID);
9241  end;
9242 
9243 
9244 elseif strncmp(HDR.TYPE,'GEO:STL:BIN',11),
9245  % http://en.wikipedia.org/wiki/STL_%28file_format%29
9246  % http://www.fastscan3d.com/download/samples/engineering.html
9247  if any(HDR.FILE.PERMISSION=='r'),
9248  HDR.FILE.FID = fopen(HDR.FileName,HDR.FILE.PERMISSION,HDR.Endianity);
9249  HDR.H1 = char(fread(HDR.FILE.FID,[1,80],'uint8'));
9250  tmp = HDR.H1(53:72); tmp(tmp==':')=' ';
9251  HDR.T0(2) = strmatch(tmp(1:3),['Jan';'Feb';'Mar';'Apr';'May';'Jun';'Jul';'Aug';'Sep';'Oct';'Nov';'Dec']);
9252  HDR.T0([3:6,1]) = str2double(tmp(5:end));
9253  N = fread(HDR.FILE.FID,1,'int32');
9254  HDR.HeadLen = ftell(HDR.FILE.FID);
9255  if HDR.FILE.size~=HDR.HeadLen+N*50;
9256  fprintf(HDR.FILE.stderr,'WARNING SOPEN(STL): size of file %s does not fit to header information\n',HDR.FILE.Name);
9257  end;
9258  HDR.STL.DAT = fread(HDR.FILE.FID,[12,inf],'12*float32',2)';
9259  fseek(HDR.FILE.FID,80+4+12*4,-1);
9260  HDR.STL.ATT = fread(HDR.FILE.FID,[1,inf],'uint16',12*4)';
9261  fclose(HDR.FILE.FID);
9262  if N~=size(HDR.STL.DAT,1)
9263  fprintf(HDR.FILE.stderr,'WARNING SOPEN(STL): number of elements do not fit. Maybe file %s is corrupted!',HDR.FILE.Name);
9264  end;
9265  end;
9266 
9267 
9268 elseif strncmp(HDR.TYPE,'TRI',3),
9269  if any(HDR.FILE.PERMISSION=='r'),
9270  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
9271  HDR.FILE.POS = 0;
9272 
9273  HDR.ID = fread(HDR.FILE.FID,1,'int32');
9274  HDR.type = fread(HDR.FILE.FID,1,'int16');
9275  HDR.VERSION = fread(HDR.FILE.FID,1,'int16');
9276  HDR.ELEC.Thickness = fread(HDR.FILE.FID,1,'float');
9277  HDR.ELEC.Diameter = fread(HDR.FILE.FID,1,'float');
9278  HDR.reserved = fread(HDR.FILE.FID,4080,'uint8');
9279 
9280  HDR.FACE.N = fread(HDR.FILE.FID,1,'int16');
9281  HDR.SURF.N = fread(HDR.FILE.FID,1,'int16');
9282 
9283  HDR.centroid = fread(HDR.FILE.FID,[4,HDR.FACE.N],'float')';
9284  HDR.VERTICES = fread(HDR.FILE.FID,[4,HDR.SURF.N],'float')';
9285  HDR.FACES = fread(HDR.FILE.FID,[3,HDR.FACE.N],'int16')';
9286 
9287  HDR.ELEC.N = fread(HDR.FILE.FID,1,'uint16');
9288  for k = 1:HDR.ELEC.N,
9289  tmp = fread(HDR.FILE.FID,[1,10],'uint8');
9290  Label{k,1} = [strtok(tmp,0), ' '];
9291  HDR.ELEC.Key(k,1) = fread(HDR.FILE.FID,1,'int16');
9292  tmp = fread(HDR.FILE.FID,[1,3],'float');
9293  % HDR.elec(k).POS = tmp(:);
9294  HDR.ELEC.XYZ(k,:) = tmp;
9295  HDR.ELEC.CHAN(k,1) = fread(HDR.FILE.FID,1,'uint16');
9296  end;
9297  fclose(HDR.FILE.FID);
9298  HDR.Label = Label;
9299  HDR.TYPE = 'ELPOS';
9300  end
9301 
9302 
9303 elseif strcmp(HDR.TYPE,'DICOM'),
9304  HDR = opendicom(HDR,HDR.FILE.PERMISSION);
9305 
9306 
9307 elseif 0, strcmp(HDR.TYPE,'DXF'),
9308  if any(HDR.FILE.PERMISSION=='r'),
9309  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
9310 
9311  while ~feof(HDR.FILE.FID),
9312  line1 = fgetl(HDR.FILE.FID);
9313  line2 = fgetl(HDR.FILE.FID);
9314 
9315  [val,status] = str2double(line1);
9316 
9317  if any(status),
9318  error('SOPEN (DXF)');
9319  elseif val==999,
9320 
9321  elseif val==0,
9322 
9323  elseif val==1,
9324 
9325  elseif val==2,
9326 
9327  else
9328 
9329  end;
9330  end;
9331 
9332  fclose(HDR.FILE.FID);
9333  end
9334 
9335 
9336 elseif strcmp(HDR.TYPE,'STX'),
9337  if any(HDR.FILE.PERMISSION=='r'),
9338  fid = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'t'],'ieee-le');
9339  FileInfo = fread(fid,20,'uint8');
9340  HDR.Label = {char(fread(fid,[1,50],'uint8'))};
9341  tmp = fread(fid,6,'int');
9342  HDR.NRec = tmp(1);
9343  HDR.SPR = 1;
9344 
9345  tmp = fread(fid,5,'long');
9346  HDR.HeadLen = 116;
9347 
9348  fclose(HDR.FILE.FID);
9349  end
9350 
9351 
9352 elseif strcmp(HDR.TYPE,'ABF2'),
9353  fprintf(HDR.FILE.stderr,'Warning: SOPEN (ABF2) is very experimental.\n');
9354  if any(HDR.FILE.PERMISSION=='r'),
9355  HDR.FILE.FID = fopen(HDR.FileName,HDR.FILE.PERMISSION,'ieee-le');
9356  HDR.ABF.ID = char(fread(HDR.FILE.FID,[1,4],'uint8'));
9357  HDR.Version = fread(HDR.FILE.FID,1,'uint32');
9358  HDR.HeadLen = fread(HDR.FILE.FID,1,'uint32');
9359  HDR.ABF.StartDate = fread(HDR.FILE.FID,1,'uint32');
9360  HDR.ABF.StartTimeMS = fread(HDR.FILE.FID,1,'uint32');
9361  HDR.ABF.StopWatchTime = fread(HDR.FILE.FID,1,'uint32');
9362  HDR.ABF.FLAGS = fread(HDR.FILE.FID,4,'uint16');
9363  HDR.ABF.FileCRC = fread(HDR.FILE.FID,1,'uint32');
9364  HDR.ABF.FileGUID= fread(HDR.FILE.FID,16,'uint8');
9365  HDR.ABF.VersionIndex = fread(HDR.FILE.FID,5,'uint32');
9366  NSections1 = 8;
9367  NSections2= 0;
9368  if strcmp(HDR.TYPE,'ABF2'),
9369  NSections2 = 10;
9370  end;
9371  for k=1:NSections1+NSections2;,
9372  HDR.Section{k}.BlockIndex = fread(HDR.FILE.FID,1,'int32');
9373  HDR.Section{k}.Bytes = fread(HDR.FILE.FID,1,'int32');
9374  HDR.Section{k}.NumEntries = fread(HDR.FILE.FID,1,'int32');
9375  end;
9376 
9377  %% read various sections
9378  for k=1:NSections1+NSections2,
9379  if (HDR.Section{k}.BlockIndex)
9380  fseek(HDR.FILE.FID,HDR.Section{k}.BlockIndex * 512,'bof');
9381 
9382  if (NSections2>0) && (k==1), % StringsSection
9383 
9384  elseif (NSections2>0) && (k==10), % StringsSection
9385  HDR.ABF.StringSection = char(fread(HDR.FILE.FID,[1,HDR.Section{k}.NumEntries*HDR.Section{k}.Bytes],'uint8'));
9386  end;
9387  end;
9388  end;
9389  fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
9390  end
9391 
9392 
9393 elseif strncmp(HDR.TYPE,'ABF',3),
9394  fprintf(HDR.FILE.stderr,'Warning: SOPEN (ABF) is still experimental.\n');
9395  if any(HDR.FILE.PERMISSION=='r'),
9396  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'t'],'ieee-le');
9397  HDR.ABF.ID = char(fread(HDR.FILE.FID,[1,4],'uint8'));
9398  %HDR.ABF.ID = fread(HDR.FILE.FID,1,'uint32');
9399  %HDR.Version = fread(HDR.FILE.FID,1,'float32');
9400  HDR.Version = fread(HDR.FILE.FID,1,'uint32');
9401  HDR.ABF.Mode = fread(HDR.FILE.FID,1,'uint16');
9402  HDR.AS.endpos = fread(HDR.FILE.FID,1,'uint32');
9403  HDR.ABF.NumPoinstsIgnored = fread(HDR.FILE.FID,1,'uint16');
9404  HDR.NRec = fread(HDR.FILE.FID,1,'uint32');
9405  t = fread(HDR.FILE.FID,3,'uint32');
9406  HDR.T0(1:3) = [floor(t(1)/1e4), floor(mod(t(1),1e4)/100), mod(t(1),100)];
9407  HDR.T0(4:6) = [floor(t(2)/3600),floor(mod(t(2),3600)/60),mod(t(2),60)];
9408  if HDR.T0(1)<80, HDR.T0(1)=HDR.T0(1)+2000;
9409  elseif HDR.T0(1)<100, HDR.T0(1)=HDR.T0(1)+1900;
9410  end;
9411 
9412  HDR.ABF.HeaderVersion = fread(HDR.FILE.FID,1,'float');
9413  if HDR.ABF.HeaderVersion>=1.6,
9414  HDR.HeadLen = 1394+6144+654;
9415  else
9416  HDR.HeadLen = 370+2048+654;
9417  end;
9418  HDR.ABF.FileType = fread(HDR.FILE.FID,1,'uint16');
9419  HDR.ABF.MSBinFormat = fread(HDR.FILE.FID,1,'uint16');
9420 
9421  HDR.ABF.SectionStart = fread(HDR.FILE.FID,15,'uint32');
9422  DataFormat = fread(HDR.FILE.FID,1,'uint16');
9423  HDR.ABF.simultanousScan = fread(HDR.FILE.FID,1,'uint16');
9424  t = fread(HDR.FILE.FID,4,'uint32');
9425 
9426  HDR.NS = fread(HDR.FILE.FID,1,'uint16');
9427  tmp = fread(HDR.FILE.FID,4,'float32');
9428 
9429  HDR.SampleRate = 1000/tmp(1);
9430  if ~DataFormat
9431  HDR.GDFTYP = 3; % int16
9432  HDR.AS.bpb = 2*HDR.NS;
9433  else
9434  HDR.GDFTYP = 16; % float32
9435  HDR.AS.bpb = 4*HDR.NS;
9436  end;
9437  HDR.SPR = HDR.AS.endpos/HDR.NRec;
9438  HDR.Dur = HDR.SPR/HDR.SampleRate;
9439  if HDR.FILE.size ~= HDR.HeadLen + HDR.AS.bpb*HDR.NRec*HDR.SPR;
9440  [HDR.FILE.size,HDR.HeadLen,HDR.AS.bpb*HDR.NRec*HDR.SPR]
9441  fprintf(HDR.FILE.stderr,'Warning SOPEN (ABF): filesize does not fit.\n');
9442  end;
9443 
9444  t = fread(HDR.FILE.FID,5,'uint32');
9445 
9446  t = fread(HDR.FILE.FID,3,'uint16');
9447  HDR.FLAG.AVERAGE = t(1);
9448 
9449  HDR.TRIGGER.THRESHOLD = fread(HDR.FILE.FID,1,'float');
9450  t = fread(HDR.FILE.FID,3,'uint16');
9451 
9452 % this part is from IMPORT_ABF.M from
9453 % © 2002 - Michele Giugliano, PhD (http://www.giugliano.info) (Bern, Friday March 8th, 2002 - 20:09)
9454 
9455 HDR.ABF.ScopeOutputInterval = fread(HDR.FILE.FID,1,'float'); % 174
9456 HDR.ABF.EpisodeStartToStart = fread(HDR.FILE.FID,1,'float'); % 178
9457 HDR.ABF.RunStartToStart = fread(HDR.FILE.FID,1,'float'); % 182
9458 HDR.ABF.TrialStartToStart = fread(HDR.FILE.FID,1,'float'); % 186
9459 HDR.ABF.AverageCount = fread(HDR.FILE.FID,1,'int'); % 190
9460 HDR.ABF.ClockChange = fread(HDR.FILE.FID,1,'int'); % 194
9461 HDR.ABF.AutoTriggerStrategy = fread(HDR.FILE.FID,1,'int16'); % 198
9462 %-----------------------------------------------------------------------------
9463 % Display Parameters
9464 HDR.ABF.DrawingStrategy = fread(HDR.FILE.FID,1,'int16'); % 200
9465 HDR.ABF.TiledDisplay = fread(HDR.FILE.FID,1,'int16'); % 202
9466 HDR.ABF.EraseStrategy = fread(HDR.FILE.FID,1,'int16'); % 204
9467 HDR.ABF.DataDisplayMode = fread(HDR.FILE.FID,1,'int16'); % 206
9468 HDR.ABF.DisplayAverageUpdate = fread(HDR.FILE.FID,1,'int'); % 208
9469 HDR.ABF.ChannelStatsStrategy = fread(HDR.FILE.FID,1,'int16'); % 212
9470 HDR.ABF.CalculationPeriod = fread(HDR.FILE.FID,1,'int'); % 214
9471 HDR.ABF.SamplesPerTrace = fread(HDR.FILE.FID,1,'int'); % 218
9472 HDR.ABF.StartDisplayNum = fread(HDR.FILE.FID,1,'int'); % 222
9473 HDR.ABF.FinishDisplayNum = fread(HDR.FILE.FID,1,'int'); % 226
9474 HDR.ABF.MultiColor = fread(HDR.FILE.FID,1,'int16'); % 230
9475 HDR.ABF.ShowPNRawData = fread(HDR.FILE.FID,1,'int16'); % 232
9476 HDR.ABF.StatisticsPeriod = fread(HDR.FILE.FID,1,'float'); % 234
9477 HDR.ABF.StatisticsMeasurements=fread(HDR.FILE.FID,1,'int'); % 238
9478 %-----------------------------------------------------------------------------
9479 % Hardware Information
9480 HDR.ABF.StatisticsSaveStrategy=fread(HDR.FILE.FID,1,'int16'); % 242
9481 HDR.ABF.ADCRange = fread(HDR.FILE.FID,1,'float'); % 244
9482 HDR.ABF.DACRange = fread(HDR.FILE.FID,1,'float'); % 248
9483 HDR.ABF.ADCResolution = fread(HDR.FILE.FID,1,'int'); % 252
9484 HDR.ABF.DACResolution = fread(HDR.FILE.FID,1,'int'); % 256
9485 %-----------------------------------------------------------------------------
9486 % Environmental Information
9487 HDR.ABF.ExperimentType = fread(HDR.FILE.FID,1,'int16'); % 260
9488 HDR.ABF.x_AutosampleEnable = fread(HDR.FILE.FID,1,'int16'); % 262
9489 HDR.ABF.x_AutosampleADCNum = fread(HDR.FILE.FID,1,'int16'); % 264
9490 HDR.ABF.x_AutosampleInstrument=fread(HDR.FILE.FID,1,'int16'); % 266
9491 HDR.ABF.x_AutosampleAdditGain= fread(HDR.FILE.FID,1,'float'); % 268
9492 HDR.ABF.x_AutosampleFilter = fread(HDR.FILE.FID,1,'float'); % 272
9493 HDR.ABF.x_AutosampleMembraneCapacitance=fread(HDR.FILE.FID,1,'float'); % 276
9494 HDR.ABF.ManualInfoStrategy = fread(HDR.FILE.FID,1,'int16'); % 280
9495 HDR.ABF.CellID1 = fread(HDR.FILE.FID,1,'float'); % 282
9496 HDR.ABF.CellID2 = fread(HDR.FILE.FID,1,'float'); % 286
9497 HDR.ABF.CellID3 = fread(HDR.FILE.FID,1,'float'); % 290
9498 HDR.ABF.CreatorInfo = fread(HDR.FILE.FID,16,'uint8'); % 16char % 294
9499 HDR.ABF.x_FileComment = fread(HDR.FILE.FID,56,'uint8'); % 56char % 310
9500 HDR.ABF.Unused366 = fread(HDR.FILE.FID,12,'uint8'); % 12char % 366
9501 %-----------------------------------------------------------------------------
9502 % Multi-channel Information
9503 HDR.ABF.ADCPtoLChannelMap = fread(HDR.FILE.FID,16,'int16'); % 378
9504 HDR.ABF.ADCSamplingSeq = fread(HDR.FILE.FID,16,'int16'); % 410
9505 HDR.ABF.ADCChannelName = fread(HDR.FILE.FID,16*10,'uint8'); % 442
9506 HDR.ABF.ADCUnits = fread(HDR.FILE.FID,16*8,'uint8'); % 8char % 602
9507 HDR.ABF.ADCProgrammableGain = fread(HDR.FILE.FID,16,'float'); % 730
9508 HDR.ABF.ADCDisplayAmplification=fread(HDR.FILE.FID,16,'float'); % 794
9509 HDR.ABF.ADCDisplayOffset = fread(HDR.FILE.FID,16,'float'); % 858
9510 HDR.ABF.InstrumentScaleFactor= fread(HDR.FILE.FID,16,'float'); % 922
9511 HDR.ABF.InstrumentOffset = fread(HDR.FILE.FID,16,'float'); % 986
9512 HDR.ABF.SignalGain = fread(HDR.FILE.FID,16,'float'); % 1050
9513 HDR.Off = fread(HDR.FILE.FID,16,'float'); % 1114
9514 HDR.ABF.SignalLowpassFilter = fread(HDR.FILE.FID,16,'float'); % 1178
9515 HDR.ABF.SignalHighpassFilter = fread(HDR.FILE.FID,16,'float'); % 1242
9516 HDR.ABF.DACChannelName = fread(HDR.FILE.FID,4*10,'uint8'); % 1306
9517 HDR.ABF.DACChannelUnits = fread(HDR.FILE.FID,4*8,'uint8'); % 8char % 1346
9518 HDR.ABF.DACScaleFactor = fread(HDR.FILE.FID,4,'float'); % 1378
9519 HDR.ABF.DACHoldingLevel = fread(HDR.FILE.FID,4,'float'); % 1394
9520 HDR.ABF.SignalType = fread(HDR.FILE.FID,1,'int16'); % 12char % 1410
9521 HDR.ABF.Unused1412 = fread(HDR.FILE.FID,10,'uint8'); % 10char % 1412
9522 %-----------------------------------------------------------------------------
9523 % Synchronous Timer Outputs
9524 HDR.ABF.OUTEnable = fread(HDR.FILE.FID,1,'int16'); % 1422
9525 HDR.ABF.SampleNumberOUT1 = fread(HDR.FILE.FID,1,'int16'); % 1424
9526 HDR.ABF.SampleNumberOUT2 = fread(HDR.FILE.FID,1,'int16'); % 1426
9527 HDR.ABF.FirstEpisodeOUT = fread(HDR.FILE.FID,1,'int16'); % 1428
9528 HDR.ABF.LastEpisodeOUT = fread(HDR.FILE.FID,1,'int16'); % 1430
9529 HDR.ABF.PulseSamplesOUT1 = fread(HDR.FILE.FID,1,'int16'); % 1432
9530 HDR.ABF.PulseSamplesOUT2 = fread(HDR.FILE.FID,1,'int16'); % 1434
9531 %-----------------------------------------------------------------------------
9532 % Epoch Waveform and Pulses
9533 HDR.ABF.DigitalEnable = fread(HDR.FILE.FID,1,'int16'); % 1436
9534 HDR.ABF.x_WaveformSource = fread(HDR.FILE.FID,1,'int16'); % 1438
9535 HDR.ABF.ActiveDACChannel = fread(HDR.FILE.FID,1,'int16'); % 1440
9536 HDR.ABF.x_InterEpisodeLevel = fread(HDR.FILE.FID,1,'int16'); % 1442
9537 HDR.ABF.x_EpochType = fread(HDR.FILE.FID,10,'int16'); % 1444
9538 HDR.ABF.x_EpochInitLevel = fread(HDR.FILE.FID,10,'float'); % 1464
9539 HDR.ABF.x_EpochLevelInc = fread(HDR.FILE.FID,10,'float'); % 1504
9540 HDR.ABF.x_EpochInitDuration = fread(HDR.FILE.FID,10,'int16'); % 1544
9541 HDR.ABF.x_EpochDurationInc = fread(HDR.FILE.FID,10,'int16'); % 1564
9542 HDR.ABF.DigitalHolding = fread(HDR.FILE.FID,1,'int16'); % 1584
9543 HDR.ABF.DigitalInterEpisode = fread(HDR.FILE.FID,1,'int16'); % 1586
9544 HDR.ABF.DigitalValue = fread(HDR.FILE.FID,10,'int16'); % 1588
9545 HDR.ABF.Unavailable1608 = fread(HDR.FILE.FID,4,'uint8'); % 1608
9546 HDR.ABF.Unused1612 = fread(HDR.FILE.FID,8,'uint8'); % 8char % 1612
9547 %-----------------------------------------------------------------------------
9548 % DAC Output File
9549 HDR.ABF.x_DACFileScale = fread(HDR.FILE.FID,1,'float'); % 1620
9550 HDR.ABF.x_DACFileOffset = fread(HDR.FILE.FID,1,'float'); % 1624
9551 HDR.ABF.Unused1628 = fread(HDR.FILE.FID,2,'uint8'); % 2char % 1628
9552 HDR.ABF.x_DACFileEpisodeNum = fread(HDR.FILE.FID,1,'int16'); % 1630
9553 HDR.ABF.x_DACFileADCNum = fread(HDR.FILE.FID,1,'int16'); % 1632
9554 HDR.ABF.x_DACFileName = fread(HDR.FILE.FID,12,'uint8'); % 12char % 1634
9555 HDR.ABF.DACFilePath=fread(HDR.FILE.FID,60,'uint8'); % 60char % 1646
9556 HDR.ABF.Unused1706=fread(HDR.FILE.FID,12,'uint8'); % 12char % 1706
9557 %-----------------------------------------------------------------------------
9558 % Conditioning Pulse Train
9559 HDR.ABF.x_ConditEnable = fread(HDR.FILE.FID,1,'int16'); % 1718
9560 HDR.ABF.x_ConditChannel = fread(HDR.FILE.FID,1,'int16'); % 1720
9561 HDR.ABF.x_ConditNumPulses = fread(HDR.FILE.FID,1,'int'); % 1722
9562 HDR.ABF.x_BaselineDuration = fread(HDR.FILE.FID,1,'float'); % 1726
9563 HDR.ABF.x_BaselineLevel = fread(HDR.FILE.FID,1,'float'); % 1730
9564 HDR.ABF.x_StepDuration = fread(HDR.FILE.FID,1,'float'); % 1734
9565 HDR.ABF.x_StepLevel = fread(HDR.FILE.FID,1,'float'); % 1738
9566 HDR.ABF.x_PostTrainPeriod = fread(HDR.FILE.FID,1,'float'); % 1742
9567 HDR.ABF.x_PostTrainLevel = fread(HDR.FILE.FID,1,'float'); % 1746
9568 HDR.ABF.Unused1750 = fread(HDR.FILE.FID,12,'uint8'); % 12char % 1750
9569 %-----------------------------------------------------------------------------
9570 % Variable Parameter User List
9571 HDR.ABF.x_ParamToVary = fread(HDR.FILE.FID,1,'int16'); % 1762
9572 HDR.ABF.x_ParamValueList = fread(HDR.FILE.FID,80,'uint8'); % 80char % 1764
9573 %-----------------------------------------------------------------------------
9574 % Statistics Measurement
9575 HDR.ABF.AutopeakEnable = fread(HDR.FILE.FID,1,'int16'); % 1844
9576 HDR.ABF.AutopeakPolarity = fread(HDR.FILE.FID,1,'int16'); % 1846
9577 HDR.ABF.AutopeakADCNum = fread(HDR.FILE.FID,1,'int16'); % 1848
9578 HDR.ABF.AutopeakSearchMode = fread(HDR.FILE.FID,1,'int16'); % 1850
9579 HDR.ABF.AutopeakStart = fread(HDR.FILE.FID,1,'int'); % 1852
9580 HDR.ABF.AutopeakEnd = fread(HDR.FILE.FID,1,'int'); % 1856
9581 HDR.ABF.AutopeakSmoothing = fread(HDR.FILE.FID,1,'int16'); % 1860
9582 HDR.ABF.AutopeakBaseline = fread(HDR.FILE.FID,1,'int16'); % 1862
9583 HDR.ABF.AutopeakAverage = fread(HDR.FILE.FID,1,'int16'); % 1864
9584 HDR.ABF.Unavailable1866 = fread(HDR.FILE.FID,2,'uint8'); % 1866
9585 HDR.ABF.AutopeakBaselineStart= fread(HDR.FILE.FID,1,'int'); % 1868
9586 HDR.ABF.AutopeakBaselineEnd = fread(HDR.FILE.FID,1,'int'); % 1872
9587 HDR.ABF.AutopeakMeasurements = fread(HDR.FILE.FID,1,'int'); % 1876
9588 %-----------------------------------------------------------------------------
9589 % Channel Arithmetic
9590 HDR.ABF.ArithmeticEnable = fread(HDR.FILE.FID,1,'int16'); % 1880
9591 HDR.ABF.ArithmeticUpperLimit = fread(HDR.FILE.FID,1,'float'); % 1882
9592 HDR.ABF.ArithmeticLowerLimit = fread(HDR.FILE.FID,1,'float'); % 1886
9593 HDR.ABF.ArithmeticADCNumA = fread(HDR.FILE.FID,1,'int16'); % 1890
9594 HDR.ABF.ArithmeticADCNumB = fread(HDR.FILE.FID,1,'int16'); % 1892
9595 HDR.ABF.ArithmeticK1 = fread(HDR.FILE.FID,1,'float'); % 1894
9596 HDR.ABF.ArithmeticK2 = fread(HDR.FILE.FID,1,'float'); % 1898
9597 HDR.ABF.ArithmeticK3 = fread(HDR.FILE.FID,1,'float'); % 1902
9598 HDR.ABF.ArithmeticK4 = fread(HDR.FILE.FID,1,'float'); % 1906
9599 HDR.ABF.ArithmeticOperator = fread(HDR.FILE.FID,2,'uint8'); % 2char % 1910
9600 HDR.ABF.ArithmeticUnits = fread(HDR.FILE.FID,8,'uint8'); % 8char % 1912
9601 HDR.ABF.ArithmeticK5 = fread(HDR.FILE.FID,1,'float'); % 1920
9602 HDR.ABF.ArithmeticK6 = fread(HDR.FILE.FID,1,'float'); % 1924
9603 HDR.ABF.ArithmeticExpression = fread(HDR.FILE.FID,1,'int16'); % 1928
9604 HDR.ABF.Unused1930 = fread(HDR.FILE.FID,2,'uint8'); % 2char % 1930
9605 %-----------------------------------------------------------------------------
9606 % On-line Subtraction
9607 HDR.ABF.x_PNEnable = fread(HDR.FILE.FID,1,'int16'); % 1932
9608 HDR.ABF.PNPosition = fread(HDR.FILE.FID,1,'int16'); % 1934
9609 HDR.ABF.x_PNPolarity = fread(HDR.FILE.FID,1,'int16'); % 1936
9610 HDR.ABF.PNNumPulses = fread(HDR.FILE.FID,1,'int16'); % 1938
9611 HDR.ABF.x_PNADCNum = fread(HDR.FILE.FID,1,'int16'); % 1940
9612 HDR.ABF.x_PNHoldingLevel = fread(HDR.FILE.FID,1,'float'); % 1942
9613 HDR.ABF.PNSettlingTime = fread(HDR.FILE.FID,1,'float'); % 1946
9614 HDR.ABF.PNInterpulse = fread(HDR.FILE.FID,1,'float'); % 1950
9615 HDR.ABF.Unused1954 = fread(HDR.FILE.FID,12,'uint8'); % 12char % 1954
9616 %-----------------------------------------------------------------------------
9617 % Unused Space at End of Header Block
9618 HDR.ABF.x_ListEnable = fread(HDR.FILE.FID,1,'int16'); % 1966
9619 HDR.ABF.BellEnable = fread(HDR.FILE.FID,2,'int16'); % 1968
9620 HDR.ABF.BellLocation = fread(HDR.FILE.FID,2,'int16'); % 1972
9621 HDR.ABF.BellRepetitions = fread(HDR.FILE.FID,2,'int16'); % 1976
9622 HDR.ABF.LevelHysteresis = fread(HDR.FILE.FID,1,'int'); % 1980
9623 HDR.ABF.TimeHysteresis = fread(HDR.FILE.FID,1,'int'); % 1982
9624 HDR.ABF.AllowExternalTags = fread(HDR.FILE.FID,1,'int16'); % 1986
9625 HDR.ABF.LowpassFilterType = fread(HDR.FILE.FID,16,'uint8'); % 1988
9626 HDR.ABF.HighpassFilterType = fread(HDR.FILE.FID,16,'uint8');% 2004
9627 HDR.ABF.AverageAlgorithm = fread(HDR.FILE.FID,1,'int16'); % 2020
9628 HDR.ABF.AverageWeighting = fread(HDR.FILE.FID,1,'float'); % 2022
9629 HDR.ABF.UndoPromptStrategy = fread(HDR.FILE.FID,1,'int16'); % 2026
9630 HDR.ABF.TrialTriggerSource = fread(HDR.FILE.FID,1,'int16'); % 2028
9631 HDR.ABF.StatisticsDisplayStrategy= fread(HDR.FILE.FID,1,'int16'); % 2030
9632 HDR.ABF.Unused2032 = fread(HDR.FILE.FID,16,'uint8'); % 2032
9633 
9634 %-----------------------------------------------------------------------------
9635 % File Structure 2
9636 HDR.ABF.DACFilePtr = fread(HDR.FILE.FID,2,'int'); % 2048
9637 HDR.ABF.DACFileNumEpisodes = fread(HDR.FILE.FID,2,'int'); % 2056
9638 HDR.ABF.Unused2 = fread(HDR.FILE.FID,10,'uint8');%2064
9639 %-----------------------------------------------------------------------------
9640 % Multi-channel Information 2
9641 HDR.ABF.DACCalibrationFactor = fread(HDR.FILE.FID,4,'float'); % 2074
9642 HDR.ABF.DACCalibrationOffset = fread(HDR.FILE.FID,4,'float'); % 2090
9643 HDR.ABF.Unused7 = fread(HDR.FILE.FID,190,'uint8');% 2106
9644 %-----------------------------------------------------------------------------
9645 % Epoch Waveform and Pulses 2
9646 HDR.ABF.WaveformEnable = fread(HDR.FILE.FID,2,'int16'); % 2296
9647 HDR.ABF.WaveformSource = fread(HDR.FILE.FID,2,'int16'); % 2300
9648 HDR.ABF.InterEpisodeLevel = fread(HDR.FILE.FID,2,'int16'); % 2304
9649 HDR.ABF.EpochType = fread(HDR.FILE.FID,10*2,'int16');% 2308
9650 HDR.ABF.EpochInitLevel = fread(HDR.FILE.FID,10*2,'float');% 2348
9651 HDR.ABF.EpochLevelInc = fread(HDR.FILE.FID,10*2,'float');% 2428
9652 HDR.ABF.EpochInitDuration = fread(HDR.FILE.FID,10*2,'int'); % 2508
9653 HDR.ABF.EpochDurationInc = fread(HDR.FILE.FID,10*2,'int'); % 2588
9654 HDR.ABF.Unused9 = fread(HDR.FILE.FID,40,'uint8'); % 2668
9655 %-----------------------------------------------------------------------------
9656 % DAC Output File 2
9657 HDR.ABF.DACFileScale = fread(HDR.FILE.FID,2,'float'); % 2708
9658 HDR.ABF.DACFileOffset = fread(HDR.FILE.FID,2,'float'); % 2716
9659 HDR.ABF.DACFileEpisodeNum = fread(HDR.FILE.FID,2,'int'); % 2724
9660 HDR.ABF.DACFileADCNum = fread(HDR.FILE.FID,2,'int16'); % 2732
9661 HDR.ABF.DACFilePath = fread(HDR.FILE.FID,2*256,'uint8'); % 2736
9662 HDR.ABF.Unused10 = fread(HDR.FILE.FID,12,'uint8'); % 3248
9663 %-----------------------------------------------------------------------------
9664 % Conditioning Pulse Train 2
9665 HDR.ABF.ConditEnable = fread(HDR.FILE.FID,2,'int16'); % 3260
9666 HDR.ABF.ConditNumPulses = fread(HDR.FILE.FID,2,'int'); % 3264
9667 HDR.ABF.BaselineDuration = fread(HDR.FILE.FID,2,'float'); % 3272
9668 HDR.ABF.BaselineLevel = fread(HDR.FILE.FID,2,'float'); % 3280
9669 HDR.ABF.StepDuration = fread(HDR.FILE.FID,2,'float'); % 3288
9670 HDR.ABF.StepLevel = fread(HDR.FILE.FID,2,'float'); % 3296
9671 HDR.ABF.PostTrainPeriod = fread(HDR.FILE.FID,2,'float'); % 3304
9672 HDR.ABF.PostTrainLevel = fread(HDR.FILE.FID,2,'float'); % 3312
9673 HDR.ABF.Unused11 = fread(HDR.FILE.FID,2,'int16'); % 3320
9674 HDR.ABF.Unused11 = fread(HDR.FILE.FID,36,'uint8'); % 3324
9675 %-----------------------------------------------------------------------------
9676 % Variable Parameter User List 2
9677 HDR.ABF.ULEnable = fread(HDR.FILE.FID,4,'int16'); % 3360
9678 HDR.ABF.ULParamToVary = fread(HDR.FILE.FID,4,'int16'); % 3368
9679 HDR.ABF.ULParamValueList = fread(HDR.FILE.FID,4*256,'uint8'); % 3376
9680 HDR.ABF.Unused11 = fread(HDR.FILE.FID,56,'uint8'); % 4400
9681 %-----------------------------------------------------------------------------
9682 % On-line Subtraction 2
9683 HDR.ABF.PNEnable = fread(HDR.FILE.FID,2,'int16'); % 4456
9684 HDR.ABF.PNPolarity = fread(HDR.FILE.FID,2,'int16'); % 4460
9685 HDR.ABF.PNADCNum = fread(HDR.FILE.FID,2,'int16'); % 4464
9686 HDR.ABF.PNHoldingLevel = fread(HDR.FILE.FID,2,'float'); % 4468
9687 HDR.ABF.Unused15 = fread(HDR.FILE.FID,36,'uint8'); % 4476
9688 %-----------------------------------------------------------------------------
9689 % Environmental Information 2
9690 HDR.ABF.TelegraphEnable = fread(HDR.FILE.FID,16,'int16'); % 4512
9691 HDR.ABF.TelegraphInstrument = fread(HDR.FILE.FID,16,'int16'); % 4544
9692 HDR.ABF.TelegraphAdditGain = fread(HDR.FILE.FID,16,'float'); % 4576
9693 HDR.ABF.TelegraphFilter = fread(HDR.FILE.FID,16,'float'); % 4640
9694 HDR.ABF.TelegraphMembraneCap = fread(HDR.FILE.FID,16,'float'); % 4704
9695 HDR.ABF.TelegraphMode = fread(HDR.FILE.FID,16,'int16'); % 4768
9696 HDR.ABF.ManualTelegraphStrategy= fread(HDR.FILE.FID,16,'int16'); % 4800
9697 HDR.ABF.AutoAnalyseEnable = fread(HDR.FILE.FID,1,'int16'); % 4832
9698 HDR.ABF.AutoAnalysisMacroName= fread(HDR.FILE.FID,64,'uint8'); % 4834
9699 HDR.ABF.ProtocolPath = fread(HDR.FILE.FID,256,'uint8'); % 4898
9700 HDR.ABF.FileComment = fread(HDR.FILE.FID,128,'uint8'); % 5154
9701 HDR.ABF.Unused6 = fread(HDR.FILE.FID,128,'uint8'); % 5282
9702 HDR.ABF.Unused2048 = fread(HDR.FILE.FID,734,'uint8'); % 5410
9703 %
9704 %-----------------------------------------------------------------------------
9705 %
9706 
9707  HDR.Cal = (HDR.ABF.ADCRange / (HDR.ABF.ADCResolution * HDR.ABF.x_AutosampleAdditGain))./ (HDR.ABF.InstrumentScaleFactor .* HDR.ABF.ADCProgrammableGain .* HDR.ABF.SignalGain);
9708 
9709  HDR.Calib = sparse([HDR.Off(1:HDR.NS)'; diag(HDR.Cal(1:HDR.NS))]);
9710 
9711  status = fseek(HDR.FILE.FID,HDR.HeadLen,'bof');
9712  HDR.FILE.POS = 0;
9713  %HDR.FILE.OPEN = 1;
9714 
9715  HDR.data = fread(HDR.FILE.FID,[HDR.NS,HDR.NRec*HDR.SPR],gdfdatatype(HDR.GDFTYP))';
9716  HDR.TYPE = 'native';
9717  fclose(HDR.FILE.FID);
9718  end
9719 
9720 
9721 elseif strcmp(HDR.TYPE,'ATF'), % axon text file
9722  if any(HDR.FILE.PERMISSION=='r'),
9723  HDR.FILE.FID = fopen(HDR.FileName,[HDR.FILE.PERMISSION,'t'],'ieee-le');
9724  t = fgetl(HDR.FILE.FID);
9725  t = str2double(fgetl(HDR.FILE.FID));
9726  HDR.ATF.NoptHdr = t(1);
9727  HDR.ATF.NS = t(2);
9728  HDR.ATF.NormalizationFactor = [];
9729  t = fgetl(HDR.FILE.FID);
9730  while any(t=='=')
9731  [f,t]=strtok(t,[34,61]); % "=
9732  [c,t]=strtok(t,[34,61]); % "=
9733  if strfind(f,'NormalizationFactor:')
9734  [t1, t2] = strtok(f,':');
9735  [f] = strtok(t2,':');
9736  HDR.ATF.NormalizationFactor = setfield(HDR.ATF.NormalizationFactor,f,str2double(c));
9737  else
9738  HDR.ATF = setfield(HDR.ATF,f,c);
9739  end
9740  t = fgetl(HDR.FILE.FID);
9741  end;
9742  k = 0;
9743  HDR.Label = {};
9744  while ~isempty(t),
9745  k = k + 1;
9746  [HDR.Label{k,1},t] = strtok(t,[9,34]); % ", TAB
9747  end
9748  HDR.HeadLen = ftell(HDR.FILE.FID);
9749  if isfield(HDR.ATF,'DateTime');
9750  tmp = HDR.ATF.DateTime;
9751  tmp(tmp=='/' | tmp==':')=' ';
9752  HDR.T0 = str2double(tmp);
9753  end;
9754  HDR.FILE.OPEN = 1;
9755  end
9756 
9757 
9758 elseif strncmp(HDR.TYPE,'CSE',3), % axon text file
9759  if any(HDR.FILE.PERMISSION=='r'),
9760  HDR.FILE.FID = fopen(HDR.FileName,HDR.FILE.PERMISSION,'ieee-le');
9761  HDR.HeadLen = 3000;
9762  HDR.H1 = fread(HDR.FILE.FID,HDR.HeadLen,'uint8');
9763  HDR.data = fread(HDR.FILE.FID,[3,inf],'int16')';
9764  [HDR.SPR, HDR.NS] = size(HDR.data);
9765  HDR.NRec = 1;
9766 
9767 % % reconstruction of transitions not fixed.
9768 % d = diff([zeros(1,HDR.NS);HDR.data],[],1);
9769 % e = -sign(d)*2^16;
9770 % e(abs(d) <= 2^15) = 0;
9771 % %HDR.data = HDR.data + cumsum(e);
9772 
9773  fclose(HDR.FILE.FID);
9774  HDR.TYPE = 'native';
9775  HDR.LeadIdCode = repmat(0,HDR.NS,1);
9776  HDR.FILE.POS = 0;
9777  end;
9778 
9779 
9780 elseif strcmp(HDR.TYPE,'EMBLA')
9781  fn = dir(fullfile(HDR.FILE.Path,'*.ebm'));
9782  HDR.NS = 0;
9783  k = 0;
9784  HDR.SPR = 1;
9785  HDR.NRec = 1;
9786  for k1 = 1:length(fn),
9787  [p,f,e]= fileparts(fn(k1).name);
9788  fid = fopen(fullfile(HDR.FILE.Path,fn(k1).name),'rb','ieee-le');
9789  [ss,c] = fread(fid,[1,48],'uint8=>char');
9790  if strncmp(ss,'Embla data file',15) && (c==48),
9791  tag = fread(fid,[1],'uint32');
9792  Embla=[];
9793  k = k+1;
9794  while ~feof(fid),
9795  siz = fread(fid,[1],'uint32');
9796  switch tag,
9797  case 32
9798  Embla.Data = fread(fid,[siz/2,1],'int16');
9799  HDR.AS.SPR(1,k)=length(Embla.Data);
9800  HDR.SPR = lcm(HDR.SPR,HDR.AS.SPR(1,k));
9801  case 48
9802  Embla.DateGuid = fread(fid,[1,siz],'uint8');
9803  case 64
9804  Embla.DateRecGuid = fread(fid,[1,siz],'uint8');
9805  case 128
9806  EmblaVersion = fread(fid,[1,siz/2],'uint16');
9807  case 129
9808  Embla.Header = fread(fid,[1,siz],'uint8');
9809  case 132
9810  t0 = fread(fid,[1,siz],'uint8');
9811  Embla.Time = t0;
9812  T0 = t0(2:7);
9813  T0(1) = t0(1)+t0(2)*256;
9814  T0(6) = t0(7)+t0(8)/100;
9815  T0 = datenum(T0);
9816  Embla.T0 = T0; %datevec(T0);
9817  if (k==1)
9818  HDR.T0 = T0;
9819  elseif abs(HDR.T0-T0) > 2/(24*3600),
9820  fprintf(HDR.FILE.stderr,'Warning SOPEN(EMBLA): start time differ between channels\n');
9821  end;
9822  case 133
9823  Embla.Channel = fread(fid,[1,siz],'uint8');
9824  case 134
9825  %Embla.SamplingRate = fread(fid,[1,siz/4],'uint32');
9826  HDR.AS.SampleRate(1,k) = fread(fid,[1,siz/4],'uint32')/1000;
9827  case 135
9828  u = fread(fid,[1,siz/4],'uint32');
9829  if (u~=1) u=u*1e-9; end;
9830  HDR.Cal(k) = u;
9831  case 136
9832  Embla.SessionCount = fread(fid,[1,siz],'uint8');
9833  case 137
9834  %Embla.DoubleSampleingRate = fread(fid,[1,siz/8],'double');
9835  HDR.AS.SampleRate(1,k) = fread(fid,[1,siz/8],'double');
9836  case 138
9837  Embla.RateCorrection = fread(fid,[1,siz/8],'double');
9838  case 139
9839  Embla.RawRange = fread(fid,[1,siz/2],'int16');
9840  case 140
9841  Embla.TransformRange = fread(fid,[1,siz/2],'int16');
9842  case 141
9843  Embla.Channel32 = fread(fid,[1,siz],'uint8');
9844  case 144
9845  %Embla.ChannelName = fread(fid,[1,siz],'uint8=>char');
9846  HDR.Label{k} = deblank(fread(fid,[1,siz],'uint8=>char'));
9847  case 149
9848  Embla.DataMask16bit = fread(fid,[1,siz/2],'int16');
9849  case 150
9850  Embla.SignedData = fread(fid,[1,siz],'uint8');
9851  case 152
9852  Embla.CalibrationFunction = fread(fid,[1,siz],'uint8=>char');
9853  case 153
9854  %Embla.CalibrationUnit = fread(fid,[1,siz],'uint8=>char');
9855  HDR.PhysDim{k} = deblank(fread(fid,[1,siz],'uint8=>char'));
9856  %HDR.PhysDimCode(k) = physicalunits(fread(fid,[1,siz],'uint8=>char'));
9857  case 154
9858  Embla.CalibrationPoint = fread(fid,[1,siz],'uint8');
9859  case 160
9860  Embla.CalibrationEvent = fread(fid,[1,siz],'uint8');
9861  case 192
9862  Embla.DeviceSerialNumber = fread(fid,[1,siz],'uint8=>char');
9863  case 193
9864  Embla.DeviceType = fread(fid,[1,siz],'uint8=>char');
9865  case 208
9866  Embla.SubjectName = fread(fid,[1,siz],'uint8=>char');
9867  case 209
9868  Embla.SubjectID = fread(fid,[1,siz],'uint8=>char');
9869  case 210
9870  Embla.SubjectGroup = fread(fid,[1,siz],'uint8=>char');
9871  case 211
9872  Embla.SubjectAttendant = fread(fid,[1,siz],'uint8=>char');
9873  case 224
9874  Embla.FilterSettings = fread(fid,[1,siz],'uint8');
9875  case hex2dec('020000A0')
9876  Embla.SensorSignalType = fread(fid,[1,siz],'uint8=>char');
9877  case hex2dec('03000070')
9878  Embla.InputReference = fread(fid,[1,siz],'uint8=>char');
9879  case hex2dec('03000072')
9880  Embla.InputMainType = fread(fid,[1,siz],'uint8=>char');
9881  case hex2dec('03000074')
9882  Embla.InputSubType = fread(fid,[1,siz],'uint8=>char');
9883  case hex2dec('03000080')
9884  Embla.InputComment = fread(fid,[1,siz],'uint8=>char');
9885  case hex2dec('04000020')
9886  Embla.WhatComment = fread(fid,[1,siz],'uint8=>char');
9887  otherwise
9888  fread(fid,[1,siz],'uint8=>char');
9889  end;
9890  tag = fread(fid,[1],'uint32');
9891  end;
9892  fclose(fid);
9893  HDR.Embla{k}=Embla;
9894  end;
9895  end;
9896  HDR.NS=k;
9897  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal,HDR.NS+1,HDR.NS);
9898  HDR.Filter.Notch = repmat(NaN,1,HDR.NS);
9899  HDR.Filter.HighPass = repmat(NaN,1,HDR.NS);
9900  HDR.Filter.LowPass = repmat(NaN,1,HDR.NS);
9901  HDR.GDFTYP = repmat(3,1,HDR.NS);
9902  HDR.DigMax = repmat(2^15-1,1,HDR.NS);
9903  HDR.DigMin = repmat(-2^15,1,HDR.NS);
9904  HDR.PhysMax = HDR.DigMax.*HDR.Cal(:)';
9905  HDR.PhysMin = HDR.DigMin.*HDR.Cal(:)';
9906  HDR.THRESHOLD = [HDR.DigMin(:),HDR.DigMax(:)];
9907  Duration = mean(HDR.AS.SPR./HDR.AS.SampleRate);
9908  HDR.SampleRate = HDR.SPR/Duration;
9909 
9910  % compute time intervals for each channel, and LeastCommonMultiple SampleRate
9911  t = repmat(NaN,HDR.NS,2);
9912  Fs = 1;
9913  for k = 1:HDR.NS,
9914  t(k,1:2) = (datenum(HDR.Embla{k}.T0)-HDR.T0)*24*3600+[1,length(HDR.Embla{k}.Data)]/HDR.AS.SampleRate(k);
9915  Fs = lcm(Fs,HDR.AS.SampleRate(k));
9916  end;
9917  T = [min(t(:,1)),max(t(:,2))];
9918  HDR.data = repmat(NaN,floor(diff(T)/Fs+1),HDR.NS);
9919  HDR.T0 = HDR.T0+T(1);
9920  HDR.SampleRate = Fs;
9921  t = t-T(1);
9922  for k = 1:HDR.NS,
9923  d = rs(HDR.Embla{k}.Data,HDR.AS.SampleRate(k),Fs);
9924  HDR.data(floor(t(k,1)*Fs)+[1:length(d)],k)=d;
9925  end;
9926  HDR.Embla = [];
9927  HDR.TYPE = 'native';
9928  HDR.FILE.POS = 0;
9929 
9930 
9931 elseif strcmp(HDR.TYPE,'ETG4000') % NIRS - Hitachi ETG 4000
9932  HDR.FILE.FID = fopen(HDR.FileName,'rt');
9933  HDR.s = fread(HDR.FILE.FID,[1,inf],'uint8=>char');
9934  fclose(HDR.FILE.FID);
9935 
9936  [t,s] = strtok(HDR.s,[10,13]);
9937  HDR.VERSION = -1;
9938  ix = strfind(HDR.s,'File Version');
9939  dlm = HDR.s(ix(1) + 12);
9940  HDR.s(HDR.s==dlm)=9;
9941  dlm = char(9);
9942  [t,s] = strtok(HDR.s,[10,13]);
9943  while ((t(1)<'0') || (t(1)>'9'))
9944  [NUM, STATUS,STRARRAY] = str2double(t,dlm);
9945  if 0,
9946  elseif strncmp(t,'File Version',12)
9947  HDR.VERSION = NUM(2);
9948  elseif strncmp(t,'Name',4)
9949  HDR.Patient.Id = STRARRAY{2};
9950  elseif strncmp(t,'Sex',3)
9951  HDR.Patient.Sex = strncmpi(STRARRAY{2},'M',1)+strncmpi(STRARRAY{2},'F',1)*2;
9952  elseif strncmp(t,'Age',3)
9953  if STATUS(2)
9954  tmp = STRARRAY{2};
9955  if (lower(tmp(end))=='y')
9956  tmp = tmp(1:end-1);
9957  end;
9958  HDR.Patient.Age = str2double(tmp);
9959  else
9960  HDR.Patient.Age = NUM(2);
9961  end
9962  elseif strncmp(t,'Date',4),
9963  tmp = STRARRAY{2};
9964  tmp((tmp==47) | (tmp==':')) = ' ';
9965  HDR.T0 = zeros(1,6);
9966  tmp = str2double(tmp);
9967  HDR.T0(1:length(tmp)) = tmp;
9968  elseif strncmp(t,'HPF[Hz]',7)
9969  HDR.Filter.HighPass = NUM(2);
9970  elseif strncmp(t,'LPF[Hz]',7)
9971  HDR.Filter.LowPass = NUM(2);
9972  elseif strncmp(t,'Analog Gain',11)
9973  HDR.ETG4000.aGain = NUM(2:end);
9974  elseif strncmp(t,'Digital Gain',12)
9975  HDR.ETG4000.dGain = NUM(2:end);
9976  elseif strncmp(t,'Sampling Period[s]',12)
9977  HDR.SampleRate = 1./NUM(2);
9978  elseif strncmp(t,'Probe',5)
9979  Label = STRARRAY;
9980  HDR.AS.TIMECHAN = strmatch('Time',Label);
9981  elseif strncmp(t,'StimType',8)
9982  FLAG = STRARRAY{2};
9983  end;
9984  [t,s] = strtok(s,[10,13]);
9985  end
9986  if ~any(HDR.VERSION==[1.06,1.09])
9987  fprintf(HDR.FILE.stdout,'SOPEN (ETG4000): Version %f has not been tested.\n',HDR.VERSION);
9988  end;
9989  fprintf(1,'Please wait - conversion takes some time');
9990 
9991  nc = length(Label);
9992  chansel = [2:nc-5,nc-3]; % with time channel
9993  chansel = [2:nc-5]; % without time channel
9994  HDR.Label = Label(chansel);
9995  F = ['%d',dlm];
9996  for k=1:length(Label)-6,
9997  F = [F,'%f',dlm];
9998  end;
9999  F = [F,'%d',dlm];
10000  F = [F,'%d:%d:%d.%d',dlm];
10001  F = [F,'%d',dlm];
10002  F = [F,'%d',dlm];
10003  F = [F,'%d'];
10004 
10005  [num,count] = sscanf([t,s],F,[length(Label)+3,inf]);
10006  NUM = num';
10007  T = NUM(:,end+[-6:-3])*[3600;60;1;.01];
10008  NUM(:,end-6) = T;
10009  NUM(:,end-5:end-3) = [];
10010 
10011  fprintf(1,' - FINISHED\n');
10012  ix = ~isnan(NUM(:,1));
10013 % HDR.data = [NUM(ix,2:end-8),T];
10014  HDR.data = [NUM(ix,chansel)];
10015 
10016  HDR.TYPE = 'native';
10017  [HDR.SPR, HDR.NS] = size(HDR.data);
10018  HDR.NRec = 1;
10019  HDR.FILE.POS = 0;
10020 
10021  %HDR.Cal = aGain.*dGain;
10022  HDR.PhysMax = max(HDR.data,[],1);
10023  HDR.PhysMin = min(HDR.data,[],1);
10024  HDR.DigMax = HDR.PhysMax;
10025  HDR.DigMin = HDR.PhysMin;
10026  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1);
10027  HDR.Cal = ones(1,HDR.NS);
10028  HDR.Off = zeros(1,HDR.NS);
10029 
10030  HDR.GDFTYP = 16*ones(1,HDR.NS);
10031  HDR.LeadIdCode = repmat(NaN,1,HDR.NS);
10032  HDR.FLAG.OVERFLOWDETECTION = 0;
10033 
10034  %HDR.PhysDimCode = zeros(HDR.NS,1);
10035  PhysDimCode = [512,repmat(65362,1,HDR.NS),512,2176,repmat(512,1,3)];
10036  HDR.PhysDimCode = PhysDimCode(chansel);
10037  %HDR.PhysDim = physicalunits(HDR.PhysDimCode);
10038 
10039  % EVENTS
10040  evchan = strmatch('Mark',Label);
10041  HDR.EVENT.POS = find(NUM(:,evchan));
10042  HDR.EVENT.TYP = NUM(HDR.EVENT.POS,evchan);
10043  if strcmp(FLAG,'STIM')
10044  if (rem(length(HDR.EVENT.TYP),2)),
10045  HDR.EVENT.TYP(end+1) = HDR.EVENT.TYP(end);
10046  HDR.EVENT.POS(end+1) = size(HDR.data,1);
10047  end;
10048  HDR.EVENT.TYP(2:2:end) = HDR.EVENT.TYP(2:2:end)+hex2dec('8000');
10049  end;
10050 
10051 elseif strcmp(HDR.TYPE,'FEPI3'), % Freiburg epileptic seizure prediction Contest
10052  % https://epilepsy.uni-freiburg.de/seizure-prediction-workshop-2007/prediction-contest/data-download
10053  if any(HDR.FILE.PERMISSION=='r'),
10054  if isfield(HDR,'H1'),
10055  t = HDR.H1;
10056  HDR.Cal = .165;
10057  while ~isempty(t)
10058  [line,t]=strtok(t,[10,13]);
10059  [t1,r] = strtok(line,'=');
10060  [t2,r] = strtok(r,'=');
10061  num = str2double(t2);
10062  if strcmp(t1,'SamplingRate')
10063  HDR.SampleRate = num;
10064  elseif strcmp(t1,'NbOfChannels')
10065  HDR.NS = num;
10066  elseif strcmp(t1,'unit')
10067  HDR.PhysDim = repmat({t2},HDR.NS,1);
10068  elseif strcmp(t1,'FirstSampleTime')
10069  t2(t2==':')=' ';
10070  HDR.T0(4:6) = str2double(t2);
10071  elseif strcmp(t1,'Gainx1000')
10072  HDR.Cal = str2double(t2,',')/1000;
10073  elseif strcmp(t1,'PatientNo')
10074  switch num,
10075  case 1,
10076  HDR.Patient.Age = 30;
10077  HDR.Patient.Sex = 2; % female
10078  case 2,
10079  HDR.Patient.Age = 17;
10080  HDR.Patient.Sex = 1; % male
10081  case 3,
10082  HDR.Patient.Age = 10;
10083  HDR.Patient.Sex = 1; % male
10084  end;
10085  elseif strcmp(t1,'Channels')
10086  for k=1:HDR.NS,
10087  [HDR.Label{k},t2] = strtok(t2,',');
10088  end;
10089  end;
10090  end;
10091  end;
10092 % fclose(fid);
10093 
10094  n = length(HDR.FEPI.ListOfDataFiles);
10095  HDR.FEPI.SEG = repmat(NaN,n,2);
10096  K = 0; % event counter
10097  for k = 1:n;
10098  tmp = HDR.FEPI.ListOfDataFiles{k};
10099  f1 = fullfile(HDR.FILE.Path,[tmp,'.bin']);
10100  f2 = fullfile(HDR.FILE.Path,[tmp,'.info']);
10101  fid = fopen(f2,'r');
10102  if fid>0,
10103  STATUS = 0;
10104  while ~feof(fid)
10105  line = fgetl(fid);
10106  if strcmp(line,'[INFORMATIONS]')
10107  STATUS = 1;
10108  elseif strcmp(line,'[EVENT]')
10109  STATUS = 2;
10110  end
10111 
10112  line = fgetl(fid);
10113  if ischar(line) && ~isempty(line),
10114  switch STATUS,
10115  case 1,
10116  [t1,r] = strtok(line,[10,13,'=']);
10117  [t2,r] = strtok(r,[10,13,'=']);
10118  num = str2double(t2);
10119  if strcmp(t1,'FirstSample')
10120  HDR.FEPI.SEG(k,1) = num;
10121  elseif strcmp(t1,'LastSample')
10122  HDR.FEPI.SEG(k,2) = num;
10123  end;
10124  case 2,
10125  [t1,r] = strtok(line,',');
10126  [t2,r] = strtok(r,',');
10127  [t3,r] = strtok(t2,': ');
10128  [t4,r] = strtok(r,': ()');
10129  num = str2double(t1);
10130  K = K+1;
10131  HDR.EVENT.POS(K,1) = num;
10132  tmp = 0;
10133  if ~isempty(t4),
10134  tmp = strmatch(t4,HDR.Label);
10135  end;
10136  if isempty(tmp), tmp=0; end;
10137  HDR.EVENT.CHN(K,1) = tmp;
10138  %HDR.EVENT.Desc{K,1} = t2;
10139  Desc{K,1} = t4;
10140 
10141  % according to https://epilepsy.uni-freiburg.de/seizure-prediction-workshop-2007/prediction-contest/data-download/the-datareader
10142  % ESO (Electrographic seizure onset): Type 1
10143  % EST (Electrographic seizure termination): Type 3
10144  % CSO (Clinical Seizure Onset): Type 5
10145  % CSO NA (Clinical Seizure Onset not available): Type 7
10146  % CST (Clinical Seizure Termination): Type 8
10147  % CST NA (Clinical Seizure Termination not available): Type 10
10148  % SSO (Subclinical Seizure Onset): Type 11
10149  % SST (Subclinical Seizure Termination): Type 14
10150  % STS (Start of Stimulation Interval): Type 17
10151  % STE (End of Stimulation Interval): Type 18
10152  % ART (Artefact): Type 19
10153  % MRX (Measurement Range Exceeded): Type 21
10154  % EBD (Electrode Box Disconnected): Type 24
10155  % EBR (Electrode Box Reconnected): Type 25
10156  % No Data (Gap in the Recording): Type 26
10157 
10158  if 0,
10159  elseif strncmp(t2,'ESO',3), typ = 1;
10160  elseif strncmp(t2,'EST',3), typ = 3;
10161  elseif strncmp(t2,'CSO NA',6), typ = 7;
10162  elseif strncmp(t2,'CSO',3), typ = 5;
10163  elseif strncmp(t2,'CST NA',6), typ = 10;
10164  elseif strncmp(t2,'CST',3), typ = 8;
10165  elseif strncmp(t2,'SSO',3), typ = 11;
10166  elseif strncmp(t2,'SST',3), typ = 14;
10167  elseif strncmp(t2,'STS',3), typ = 17;
10168  elseif strncmp(t2,'STE',3), typ = 18;
10169 
10170  elseif strncmp(t2,'ART',3), typ = 19;
10171  elseif strncmp(t2,'MRX',3), typ = 21;
10172  elseif strncmp(t2,'EBD',3), typ = 24;
10173  elseif strncmp(t2,'EBR',3), typ = 25;
10174  elseif strncmp(t2,'No Data',3), typ = 26;
10175  else typ = 0;
10176  end;
10177  HDR.EVENT.TYP(K,1) = typ;
10178  HDR.EVENT.CodeDesc{typ} = t2;
10179  end;
10180  end;
10181  end;
10182  fclose(fid);
10183  end;
10184  end;
10185  HDR.EVENT.DUR = zeros(size(HDR.EVENT.POS));
10186 
10187  x = [NaN;HDR.FEPI.SEG(1:end-1,2)-HDR.FEPI.SEG(2:end,1)+1];
10188  if any(x),
10189  for k=1:n,
10190  fprintf(1,'%s\t%10i %10i %10i\n', HDR.FEPI.ListOfDataFiles{k},HDR.FEPI.SEG(k,:),x(k));
10191  end;
10192  end;
10193 
10194  HDR.Cal = HDR.Cal(1); % hack for pat2
10195  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
10196  HDR.FILE.OPEN = 1;
10197  HDR.FILE.POS = 0;
10198  HDR.NRec = 1;
10199  HDR.SPR = HDR.FEPI.SEG(end,2);
10200  HDR.AS.endpos = HDR.FEPI.SEG(end,2);
10201  end;
10202 
10203 
10204 elseif strcmp(HDR.TYPE,'nakamura'),
10205  % Nakamura data set
10206  fid = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.chn']),'r');
10207  s = char(fread(fid,[1,inf],'uint8'));
10208  fclose(fid);
10209  [tmp1,tmp2,HDR.Label]=str2double(s);
10210  HDR.NS = length(HDR.Label);
10211  for k=1:HDR.NS
10212  HDR.Label{k} = sprintf('#%02i: %s',k,HDR.Label{k});
10213  end;
10214 
10215  fid = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.log']),'r');
10216  s = char(fread(fid,[1,inf],'uint8'));
10217  fclose(fid);
10218  [n,v,sa] = str2double(s);
10219  HDR.NRec = size(n,1);
10220  HDR.LOG.num = n(:,3:2:end);
10221  HDR.LOG.str = sa(:,2:2:end);
10222  styIDX = strmatch('sty',sa(1,:),'exact')+1; % stimulus type
10223  stmIDX = strmatch('sttm',sa(1,:),'exact')+1; % stimulus time
10224  rtyIDX = strmatch('rty',sa(1,:),'exact')+1; % response type
10225  rtmIDX = strmatch('rstm',sa(1,:),'exact')+1; % response time
10226 
10227  fid = fopen(fullfile(HDR.FILE.Path,[HDR.FILE.Name,'.dm6']),'r','ieee-le');
10228  [s,count] = fread(fid,[1,inf],'float');
10229  fclose(fid);
10230  HDR.SPR = count/(HDR.NS*HDR.NRec);
10231  HDR.SampleRate = 200;
10232  HDR.data = reshape(permute(reshape(s(1:HDR.SPR*HDR.NS*HDR.NRec),[HDR.SPR,HDR.NS,HDR.NRec]),[1,3,2]),[HDR.SPR*HDR.NRec,HDR.NS]);
10233  HDR.FLAG.TRIGGERED = 1;
10234  HDR.TYPE = 'native';
10235  HDR.FILE.POS = 0;
10236  HDR.EVENT.POS = [0:HDR.NRec-1]'*HDR.SPR+n(:,rtyIDX);
10237  HDR.EVENT.TYP = n(:,11);
10238  %%% ###FIXME###
10239  HDR.PhysDimCode = 512+zeros(1,HDR.NS); % normalized, dimensionless
10240  % HDR.PhysDim
10241  % HDR.Calib
10242 
10243 
10244 elseif strcmp(HDR.TYPE,'BIFF'),
10245  try,
10246  NEW_INTERFACE=1;
10247  try
10248  [TFM.S,txt,TFM.E] = xlsread(HDR.FileName,'Beat-To-Beat');
10249  catch
10250  [TFM.S,TFM.E] = xlsread(HDR.FileName,'Beat-to-Beat');
10251  NEW_INTERFACE=0;
10252  end;
10253  if size(TFM.S,1)+1==size(TFM.E,1)
10254  %if ~isnan(TFM.S(1,1)) && ~isempty(TFM.E{1,1})
10255  fprintf('Warning: XLSREAD-BUG has occured in file %s.\n',HDR.FileName);
10256  TFM.S = [repmat(NaN,1,size(TFM.S,2));TFM.S];
10257  end;
10258  HDR.TFM = TFM;
10259 
10260  HDR.TYPE = 'TFM_EXCEL_Beat_to_Beat';
10261  %HDR.Patient.Name = [TFM.E{2,3},' ', TFM.E{2,4}];
10262  ix = 1; while ~strncmp(TFM.E{1,ix},'Build',5); ix=ix+1; end;
10263  TFM.VERSION = TFM.E{2,ix};
10264 
10265  gender = TFM.E{2,6};
10266  if isnumeric(gender)
10267  HDR.Patient.Sex = gender;
10268  elseif strncmpi(gender,'M',1)
10269  HDR.Patient.Sex = 1;
10270  elseif strncmpi(gender,'F',1)
10271  HDR.Patient.Sex = 2;
10272  else
10273  HDR.Patient.Sex = 0;
10274  end;
10275  if NEW_INTERFACE;
10276  HDR.Patient.Birthday = datevec(TFM.E{2,5},'dd.mm.yyyy');
10277  HDR.T0 = datevec(datenum(datevec(TFM.E{2,1},'dd.mm.yyyy')+TFM.E{2,2}));
10278  HDR.Patient.Height = TFM.E{2,7};
10279  HDR.Patient.Weight = TFM.E{2,8};
10280  HDR.Patient.Surface = TFM.E{2,9};
10281  else
10282  HDR.Patient.Height = TFM.S(2,7);
10283  HDR.Patient.Weight = TFM.S(2,8);
10284  HDR.Patient.Surface = TFM.S(2,9);
10285  HDR.Patient.Birthday = datevec(datenum('30-Dec-1899')+TFM.S(2,5));
10286  HDR.T0 = datevec(datenum('30-Dec-1899')+TFM.S(2,1)+TFM.S(2,2));
10287  end;
10288  HDR.Patient.BMI = HDR.Patient.Weight * HDR.Patient.Height^-2 * 1e4;
10289  HDR.Patient.Birthday(4) = 12;
10290  HDR.Patient.Age = (datenum(HDR.T0)-datenum(HDR.Patient.Birthday))/365.25;
10291  catch
10292  end;
10293 
10294  if strcmp(HDR.TYPE, 'TFM_EXCEL_Beat_to_Beat');
10295  if ~isempty(strfind(TFM.E{3,1},'---'))
10296  TFM.S(3,:) = [];
10297  TFM.E(3,:) = [];
10298  end;
10299 
10300  HDR.Label = TFM.E(4,:)';
10301  HDR.PhysDim = TFM.E(5,:)';
10302  if strcmp(HDR.Label{3},'RRI') && strcmp(HDR.PhysDim{3},'[%]')
10303  %%%% correct bug in file (due to bug in TFM
10304  %%%% software
10305  HDR.PhysDim{3} = '[ms]';
10306  end;
10307  for k=1:length(HDR.PhysDim),
10308  HDR.PhysDim{k} = HDR.PhysDim{k}(2:end-1); % remove brackets []
10309  end;
10310 
10311  TFM.S = TFM.S(6:end,:);
10312  TFM.E = TFM.E(6:end,:);
10313 
10314  ix = find(isnan(TFM.S(:,2)) & ~isnan(TFM.S(:,1)));
10315  Desc = TFM.E(ix,2);
10316  HDR.EVENT.POS = ix(:);
10317  HDR.EVENT.TYP = zeros(size(HDR.EVENT.POS));
10318  [HDR.EVENT.CodeDesc, CodeIndex, HDR.EVENT.TYP] = unique(Desc);
10319 
10320  [HDR.SPR,HDR.NS] = size(TFM.S);
10321  HDR.Label = HDR.Label(1:HDR.NS);
10322  HDR.PhysDim = HDR.PhysDim(1:HDR.NS);
10323  HDR.NRec = 1;
10324  HDR.THRESHOLD = repmat([0,NaN],HDR.NS,1); % Underflow Detection
10325  HDR.data = TFM.S;
10326  HDR.TYPE = 'native';
10327  HDR.FILE.POS = 0;
10328  end;
10329 
10330 
10331 elseif strcmp(HDR.TYPE,'ASCII:IBI')
10332  fid = fopen(HDR.FileName,'r');
10333  line = fgetl(fid);
10334  N = 0;
10335  HDR.SampleRate = 1000;
10336  HDR.EVENT.SampleRate = 1000;
10337  HDR.EVENT.POS = [];
10338  HDR.EVENT.TYP = [];
10339  DescList = {};
10340 %% while (~isempty(line))
10341  while (length(line)>5)
10342  if ((line(1)<'0') || (line(1)>'9'))
10343  f=deblank(strtok(line,':'));
10344  v=deblank(strtok(line,':'));
10345  if strcmp(f,'File version')
10346  HDR.VERSION = str2double(v);
10347  elseif strcmp(f,'Identification')
10348  HDR.Patient.Name = v;
10349  end;
10350  else
10351  N = N+1;
10352  if (N>length(HDR.EVENT.POS))
10353  HDR.EVENT.POS = [HDR.EVENT.POS;zeros(2^12,1)];
10354  HDR.EVENT.TYP = [HDR.EVENT.TYP;zeros(2^12,1)];
10355  end;
10356  if exist('OCTAVE_VERSION','builtin')
10357  [y,mo,dd,hh,mi,se,ms,desc,rri,count]=sscanf(line,'%02u-%02u-%02u %02u:%02u:%02u %03u %s %f','C');
10358  y = [y,mo,dd,hh,mi,se,ms];
10359  else
10360  [y,COUNT,ERRMSG,NEXTINDEX1] = sscanf(line,'%02u-%02u-%02u %02u:%02u:%02u %03u',7);
10361  [desc,COUNT,ERRMSG,NEXTINDEX2] = sscanf(line(NEXTINDEX1:end),'%s',1);
10362  [rri,COUNT,ERRMSG,NEXTINDEX] = sscanf(line(NEXTINDEX1+NEXTINDEX2-1:end),'%4i',1);
10363  end;
10364 
10365  %% t = datenum(y,mo,dd,hh,mi,se+ms/1000);
10366  if (N==1)
10367  if y(3)<70, y(3)=y(3)+2000;
10368  else y(3)=y(3)+1900;
10369  end;
10370  HDR.T0 = [y(3),y(2),y(1),y(4),y(5),y(6)+(y(7)-rri)/1000];
10371  HDR.EVENT.POS = [0;rri];
10372  HDR.EVENT.TYP = [1;1]*hex2dec('0501');
10373  N = 2;
10374  else
10375  HDR.EVENT.POS(N) = HDR.EVENT.POS(N-1)+rri;
10376  HDR.EVENT.TYP(N) = hex2dec('0501');
10377  end;
10378  %% ix = strmatch(desc,DescList,'exact');
10379  %% if isempty(ix)
10380  %% DescList{end+1}=desc;
10381  %% ix = length(DescList);
10382  %% end;
10383  %% HDR.EVENT.TYP(N) = ix;
10384  end;
10385  line = fgetl(fid);
10386  end
10387  fclose(fid);
10388  HDR.EVENT.POS = HDR.EVENT.POS(1:N);
10389  HDR.EVENT.TYP = HDR.EVENT.TYP(1:N);
10390  HDR.EVENT.CodeDesc = DescList;
10391  % HDR.EVENT.CodeIndex = [1:length(DescList)]';
10392  HDR.TYPE = 'EVENT';
10393 
10394  return;
10395 
10396 elseif strncmp(HDR.TYPE,'HL7aECG',3) || strncmp(HDR.TYPE,'XML',3),
10397  if exist('mexSLOAD','file')
10398  try
10399  [s,H] = mexSLOAD(HDR.FileName,0,'UCAL:ON');
10400  catch
10401  fprintf(stdout,'SOPEN: failed to read XML file %s.',HDR.FileName);
10402  return;
10403  end;
10404  H.data = s;
10405  H.FLAG = HDR.FLAG;
10406  H.TYPE = 'native';
10407  H.FILE = HDR.FILE;
10408  H.FILE.POS = 0;
10409  HDR = H;
10410  else
10411  fprintf(stdout,'SOPEN: failed to read HL7aECG/FDA-XML files.\nUse mexSLOAD from BioSig4C++ instead!\n');
10412  %HDR = openxml(HDR); % experimental version for reading various xml files
10413  return;
10414  end;
10415 
10416 
10417 elseif strcmp(HDR.TYPE,'ZIP'),
10418  % extract content into temporary directory;
10419  HDR.ZIP.TEMPDIR = tempname;
10420  mkdir(HDR.ZIP.TEMPDIR);
10421  system(sprintf('unzip %s -d %s >NULL',HDR.FileName,HDR.ZIP.TEMPDIR));
10422 
10423  H1 = [];
10424  fn = fullfile(HDR.ZIP.TEMPDIR,'content.xml');
10425  if exist(fn,'file')
10426  H1.FileName = fn;
10427  H1.FILE.PERMISSION = 'r';
10428  HDR.Content = openxml(H1);
10429  end;
10430  fn = fullfile(HDR.ZIP.TEMPDIR,'META-INF/manifest.xml');
10431  if exist(fn,'file')
10432  H1.FileName = fn;
10433  H1.FILE.PERMISSION = 'r';
10434  HDR.manifest = openxml(H1);
10435  end;
10436  fn = fullfile(HDR.ZIP.TEMPDIR,'meta.xml');
10437  if exist(fn,'file')
10438  H1.FileName = fn;
10439  H1.FILE.PERMISSION = 'r';
10440  HDR.Meta = openxml(H1);
10441  end;
10442  fn = fullfile(HDR.ZIP.TEMPDIR,'styles.xml');
10443  if exist(fn,'file')
10444  H1.FileName = fn;
10445  H1.FILE.PERMISSION = 'r';
10446  HDR.Styles = openxml(H1);
10447  end;
10448  fn = fullfile(HDR.ZIP.TEMPDIR,'settings.xml');
10449  if exist(fn,'file')
10450  H1.FileName = fn;
10451  H1.FILE.PERMISSION = 'r';
10452  HDR.Settings = openxml(H1);
10453  end;
10454 
10455  if 0,
10456  elseif strncmp(HDR.ZIP.tmp(31:end),'mimetypeapplication/vnd.sun.xml.writer',38)
10457  elseif strncmp(HDR.ZIP.tmp(31:end),'mimetypeapplication/vnd.sun.xml.calc',36) % OpenOffice 1.x
10458  HDR.table = HDR.XML.office_body.table_table;
10459  elseif strncmp(HDR.ZIP.tmp(31:end),'mimetypeapplication/vnd.oasis.opendocument.spreadsheet',54) % OpenOffice 2.0
10460  HDR.table = HDR.XML.office_body.office_spreadsheet.table_table;
10461  end;
10462 
10463  if isfield(HDR,'table'),
10464  try
10465  for k0 = 1, %:length(HDR.table),
10466  strarray= {};
10467  c_table = HDR.table{k0};
10468  if ~isempty(c_table.table_table_row)
10469  nr = length(c_table.table_table_row);
10470  for k1 = 1:nr-1,
10471  c_row = c_table.table_table_row{k1}.table_table_cell;
10472  nc = length(c_row);
10473  for k2 = 1:nc-1,
10474  strarray{k1,k2} = c_row{k2}.text_p;
10475  end;
10476  end;
10477  end;
10478  HDR.sa{k0} = strarray;
10479  HDR.data = repmat(NaN,size(strarray));
10480  for k1=1:size(HDR.data,1)
10481  for k2=1:size(HDR.data,2)
10482  tmp = strarray{k1,k2};
10483  tmp(tmp==',')=='.';
10484  if ~isempty(tmp)
10485  tmp = str2double(tmp)
10486  end;
10487  if prod(size(tmp))==1,
10488  HDR.data(k1,k2) = tmp;
10489  else
10490  strarray{k1,k2},
10491  end;
10492  end;
10493  end;
10494  end;
10495  catch;
10496  end
10497  end;
10498 
10499  if isempty(H1),
10500  fn = dir(HDR.ZIP.TEMPDIR);
10501  fn = fn(~[fn.isdir]);
10502  if (length(fn)==1)
10503  HDR = sopen(fullfile(HDR.ZIP.TEMPDIR,fn(1).name));
10504  return;
10505  end;
10506  end;
10507 
10508  % remove temporary directory - could be moved to SCLOSE
10509  [SUCCESS,MESSAGE,MESSAGEID] = rmdir(HDR.ZIP.TEMPDIR,'s');
10510 
10511 
10512 elseif strncmp(HDR.TYPE,'IMAGE:',6),
10513  % forward call to IOPEN
10514  HDR = iopen(HDR);
10515  return;
10516 
10517 
10518 elseif strcmp(HDR.TYPE,'unknown'),
10519  if ~isfield(HDR.FLAG,'ASCII'); HDR.FLAG.ASCII = 0; end;
10520  if HDR.FLAG.ASCII,
10521  s = HDR.s;
10522  if strcmpi(HDR.FILE.Ext,'DAT')
10523  [NUM, STATUS,STRARRAY] = str2double(char(s));
10524  if (size(NUM,2)<4) && ~any(any(STATUS))
10525  HDR.Label = STRARRAY(:,1);
10526  r2 = sum(NUM(:,2:3).^2,2);
10527  HDR.ELEC.XYZ = [NUM(:,2:3),sqrt(max(r2)-r2)];
10528  HDR.CHAN = NUM(:,1);
10529  HDR.TYPE = 'ELPOS';
10530  elseif (size(NUM,2)==4) && ~any(any(STATUS))
10531  HDR.Label = STRARRAY(:,1);
10532  HDR.ELEC.XYZ = NUM(:,2:4);
10533  HDR.ELEC.CHAN = NUM(:,1);
10534  HDR.TYPE = 'ELPOS';
10535  elseif (size(NUM,2)==4) && ~any(any(STATUS(:,[1,3:4])))
10536  HDR.Label = STRARRAY(:,2);
10537  r2 = sum(NUM(:,3:4).^2,2);
10538  HDR.ELEC.XYZ = [NUM(:,3:4),sqrt(max(r2)-r2)];
10539  HDR.CHAN = NUM(:,1);
10540  HDR.TYPE = 'ELPOS';
10541  elseif (size(NUM,2)==5) && ~any(any(STATUS(:,3:5)))
10542  HDR.Label = STRARRAY(:,1);
10543  HDR.ELEC.XYZ = NUM(:,3:5);
10544  HDR.TYPE = 'ELPOS';
10545  end;
10546  return;
10547 
10548 
10549  elseif strncmp(s,'NumberPositions',15) && strcmpi(HDR.FILE.Ext,'elc'); % Polhemus
10550  K = 0;
10551  [tline, s] = strtok(s, [10,13]);
10552  while ~isempty(s),
10553  [num, stat, strarray] = str2double(tline);
10554  if strcmp(strarray{1},'NumberPositions')
10555  NK = num(2);
10556  elseif strcmp(strarray{1},'UnitPosition')
10557  HDR.ELEC.PositionUnit = strarray{2};
10558  elseif strcmp(strarray{1},'Positions')
10559  ix = strfind(s,'Labels');
10560  ix = min([ix-1,length(s)]);
10561  [num, stat, strarray] = str2double(s(1:ix));
10562  s(1:ix) = [];
10563  if ~any(any(stat))
10564  HDR.ELEC.XYZ = num*[0,-1,0;1,0,0;0,0,1];
10565  HDR.TYPE = 'ELPOS';
10566  end;
10567  elseif strcmp(strarray{1},'Labels')
10568  [tline, s] = strtok(s, [10,13]);
10569  [num, stat, strarray] = str2double(tline);
10570  HDR.Label = strarray';
10571  end
10572  [tline, s] = strtok(s, [10,13]);
10573  end;
10574  return;
10575 
10576  elseif strncmp(s,'Site',4) && strcmpi(HDR.FILE.Ext,'txt');
10577  [line1, s] = strtok(s, [10,13]);
10578  s(s==',') = '.';
10579  [NUM, STATUS, STRARRAY] = str2double(s,[9,32]);
10580  if (size(NUM,2)==3) && ~any(any(STATUS(:,2:3)))
10581  HDR.Label = STRARRAY(:,1);
10582  Theta = abs(NUM(:,2))*pi/180;
10583  Phi = NUM(:,3)*pi/180 + pi*(NUM(:,2)<0);
10584  HDR.ELEC.XYZ = [sin(Theta).*cos(Phi),sin(Theta).*sin(Phi),cos(Theta)];
10585  HDR.ELEC.R = 1;
10586  HDR.TYPE = 'ELPOS';
10587  elseif (size(NUM,2)==4) && ~any(any(STATUS(:,2:4)))
10588  HDR.Label = STRARRAY(:,1);
10589  HDR.ELEC.XYZ = NUM(:,2:4);
10590  HDR.TYPE = 'ELPOS';
10591  end;
10592  return;
10593 
10594  elseif strcmpi(HDR.FILE.Ext,'elp')
10595  [line1,s]=strtok(s,[10,13]);
10596  [NUM, STATUS,STRARRAY] = str2double(char(s));
10597  if size(NUM,2)==3,
10598  if ~any(any(STATUS(:,2:3)))
10599  HDR.Label = STRARRAY(:,1);
10600  Theta = NUM(:,2)*pi/180;
10601  Phi = NUM(:,3)*pi/180;
10602  HDR.ELEC.XYZ = [sin(Theta).*cos(Phi),sin(Theta).*sin(Phi),cos(Theta)];
10603  HDR.ELEC.R = 1;
10604  HDR.TYPE = 'ELPOS';
10605  end;
10606  elseif size(NUM,2)==4,
10607  if ~any(any(STATUS(:,3:4)))
10608  HDR.Label = STRARRAY(:,2);
10609  Theta = NUM(:,2)*pi/180;
10610  Phi = NUM(:,3)*pi/180;
10611  HDR.ELEC.XYZ = [sin(Theta).*cos(Phi),sin(Theta).*sin(Phi),cos(Theta)];
10612  HDR.ELEC.R = 1;
10613  HDR.ELEC.CHAN = NUM(:,1);
10614  HDR.TYPE = 'ELPOS';
10615  end;
10616  end;
10617  return;
10618 
10619  elseif strcmpi(HDR.FILE.Ext,'ced')
10620  [line1,s]=strtok(char(s),[10,13]);
10621  [NUM, STATUS,STRARRAY] = str2double(char(s));
10622  if ~any(any(STATUS(:,[1,5:7])))
10623  HDR.Label = STRARRAY(:,2);
10624  HDR.ELEC.XYZ = NUM(:,5:7)*[0,1,0;-1,0,0;0,0,1];
10625  HDR.ELEC.CHAN = NUM(:,1);
10626  HDR.TYPE = 'ELPOS';
10627  end;
10628  return;
10629 
10630 
10631  elseif (strcmpi(HDR.FILE.Ext,'loc') || strcmpi(HDR.FILE.Ext,'locs'))
10632 % [line1,s]=strtok(char(s),[10,13]);
10633  [NUM, STATUS,STRARRAY] = str2double(char(s));
10634  if ~any(any(STATUS(:,1:3)))
10635  HDR.Label = STRARRAY(:,4);
10636  HDR.CHAN = NUM(:,1);
10637  Phi = NUM(:,2)/180*pi;
10638  %Theta = asin(NUM(:,3));
10639  Theta = NUM(:,3);
10640  HDR.ELEC.XYZ = [sin(Theta).*sin(Phi),sin(Theta).*cos(Phi),cos(Theta)];
10641  HDR.TYPE = 'ELPOS';
10642  end;
10643  return;
10644 
10645  elseif strcmpi(HDR.FILE.Ext,'sfp')
10646  [NUM, STATUS,STRARRAY] = str2double(char(s));
10647  if ~any(any(STATUS(:,2:4)))
10648  HDR.Label = STRARRAY(:,1);
10649  HDR.ELEC.XYZ = NUM(:,2:4);
10650  HDR.TYPE = 'ELPOS';
10651  end;
10652  return;
10653 
10654  elseif strcmpi(HDR.FILE.Ext,'xyz')
10655  [NUM, STATUS,STRARRAY] = str2double(char(s));
10656  if ~any(any(STATUS(:,2:4)))
10657  HDR.Label = STRARRAY(:,5);
10658  HDR.ELEC.CHAN= NUM(:,1);
10659  HDR.ELEC.XYZ = NUM(:,2:4);
10660  HDR.TYPE = 'ELPOS';
10661  end;
10662  return;
10663  end;
10664  else
10665  %HDR.ErrMsg = sprintf('ERROR SOPEN: File %s could not be opened - unknown type.\n',HDR.FileName);
10666  %fprintf(HDR.FILE.stderr,'ERROR SOPEN: File %s could not be opened - unknown type.\n',HDR.FileName);
10667  end;
10668 
10669 else
10670  %fprintf(HDR.FILE.stderr,'SOPEN does not support your data format yet. Contact <Biosig-general@lists.sourceforge.net> if you are interested in this feature.\n');
10671  HDR.FILE.FID = -1; % this indicates that file could not be opened.
10672  return;
10673 end;
10674 
10675 
10676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10677 % General Postprecessing for all formats of Header information
10678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10679 
10680 if isfield(HDR,'Patient') && isfield(HDR.Patient,'Weight') && isfield(HDR.Patient,'Height')
10681  %% Body Mass Index
10682  HDR.Patient.BMI = HDR.Patient.Weight * HDR.Patient.Height^-2 * 1e4;
10683 
10684  %% Body Surface Area
10685  % DuBois D, DuBois EF. A formula to estimate the approximate surface area if height and weight be known. Arch Intern Medicine. 1916; 17:863-71.
10686  % Wang Y, Moss J, Thisted R. Predictors of body surface area. J Clin Anesth. 1992; 4(1):4-10.
10687  HDR.Patient.BSA = 0.007184 * HDR.Patient.Weight^0.425 * HDR.Patient.Height^0.725;
10688 end;
10689 
10690 % check consistency
10691 if (HDR.NS>0) && HDR.FLAG.OVERFLOWDETECTION && ~isfield(HDR,'THRESHOLD') && ~strcmp(HDR.TYPE,'EVENT'),
10692  fprintf(HDR.FILE.stderr,'Warning SOPEN: Automated OVERFLOWDETECTION not supported - check yourself for saturation artifacts.\n');
10693 end;
10694 
10695 % identify type of signal, complete header information
10696 if HDR.NS>0,
10697  HDR = physicalunits(HDR); % complete information on PhysDim, and PhysDimCode
10698  HDR = leadidcodexyz(HDR); % complete information on LeadIdCode and Electrode positions of EEG channels.
10699  if ~isfield(HDR,'Label')
10700  HDR.Label = cellstr([repmat('#',HDR.NS,1),int2str([1:HDR.NS]')]);
10701  elseif isempty(HDR.Label)
10702  HDR.Label = cellstr([repmat('#',HDR.NS,1),int2str([1:HDR.NS]')]);
10703  elseif ischar(HDR.Label)
10704  HDR.Label = cellstr(HDR.Label);
10705  end;
10706  if ischar(HDR.PhysDim)
10707  HDR.PhysDim = cellstr(HDR.PhysDim);
10708  end;
10709  HDR.CHANTYP = repmat(' ',1,HDR.NS);
10710  tmp = HDR.NS-length(HDR.Label);
10711  %HDR.Label = [HDR.Label(1:HDR.NS,:);repmat(' ',max(0,tmp),size(HDR.Label,2))];
10712  Label = char(HDR.Label);
10713  tmp = reshape(lower([[Label(1:min(HDR.NS,size(Label,1)),:);repmat(' ',max(0,tmp),size(Label,2))],repmat(' ',HDR.NS,1)])',1,HDR.NS*(size(Label,2)+1));
10714 
10715  HDR.CHANTYP(ceil([strfind(tmp,'eeg'),strfind(tmp,'meg')]/(size(Label,2)+1))) = 'E';
10716  HDR.CHANTYP(ceil([strfind(tmp,'emg')]/(size(Label,2)+1))) = 'M';
10717  HDR.CHANTYP(ceil([strfind(tmp,'eog')]/(size(Label,2)+1))) = 'O';
10718  HDR.CHANTYP(ceil([strfind(tmp,'ecg'),strfind(tmp,'ekg')]/(size(Label,2)+1))) = 'C';
10719  HDR.CHANTYP(ceil([strfind(tmp,'air'),strfind(tmp,'resp')]/(size(Label,2)+1))) = 'R';
10720  HDR.CHANTYP(ceil([strfind(tmp,'trig')]/(size(Label,2)+1))) = 'T';
10721 end;
10722 
10723 % add trigger information for triggered data
10724 if HDR.FLAG.TRIGGERED && isempty(HDR.EVENT.POS)
10725  HDR.EVENT.POS = [0:HDR.NRec-1]'*HDR.SPR+1;
10726  HDR.EVENT.TYP = repmat(hex2dec('0300'),HDR.NRec,1);
10727  HDR.EVENT.CHN = repmat(0,HDR.NRec,1);
10728  HDR.EVENT.DUR = repmat(0,HDR.NRec,1);
10729 end;
10730 
10731 % apply channel selections to EVENT table
10732 if any(CHAN) && ~isempty(HDR.EVENT.POS) && isfield(HDR.EVENT,'CHN'), % only if channels are selected.
10733  sel = (HDR.EVENT.CHN(:)==0); % memory allocation, select all general events
10734  for k = find(~sel'), % select channel specific elements
10735  sel(k) = any(HDR.EVENT.CHN(k)==CHAN);
10736  end;
10737  HDR.EVENT.POS = HDR.EVENT.POS(sel);
10738  HDR.EVENT.TYP = HDR.EVENT.TYP(sel);
10739  HDR.EVENT.DUR = HDR.EVENT.DUR(sel); % if EVENT.CHN available, also EVENT.DUR is defined.
10740  HDR.EVENT.CHN = HDR.EVENT.CHN(sel);
10741  % assigning new channel number
10742  a = zeros(1,HDR.NS);
10743  for k = 1:length(CHAN), % select channel specific elements
10744  a(CHAN(k)) = k; % assigning to new channel number.
10745  end;
10746  ix = HDR.EVENT.CHN>0;
10747  HDR.EVENT.CHN(ix) = a(HDR.EVENT.CHN(ix)); % assigning new channel number
10748 end;
10749 
10750 % complete event information - needed by SVIEWER
10751 if ~isfield(HDR.EVENT,'CHN') && ~isfield(HDR.EVENT,'DUR'),
10752  HDR.EVENT.CHN = zeros(size(HDR.EVENT.POS));
10753  HDR.EVENT.DUR = zeros(size(HDR.EVENT.POS));
10754 
10755  % convert EVENT.Version 1 to 3, currently used by GDF, BDF and alpha
10756  flag_remove = zeros(size(HDR.EVENT.TYP));
10757  types = unique(HDR.EVENT.TYP);
10758  for k1 = find(bitand(types(:)',hex2dec('8000')));
10759  TYP0 = bitand(types(k1),hex2dec('7fff'));
10760  TYP1 = types(k1);
10761  ix0 = (HDR.EVENT.TYP==TYP0);
10762  ix1 = (HDR.EVENT.TYP==TYP1);
10763 
10764  if sum(ix0)==sum(ix1),
10765  HDR.EVENT.DUR(ix0) = HDR.EVENT.POS(ix1) - HDR.EVENT.POS(ix0);
10766  flag_remove = flag_remove | (HDR.EVENT.TYP==TYP1);
10767  else
10768  fprintf(2,'Warning SOPEN: number of event onset (TYP=%s) and event offset (TYP=%s) differ (%i,%i)\n',dec2hex(double(TYP0)),dec2hex(double(TYP1)),sum(ix0),sum(ix1));
10769  %% double(.) operator needed because Matlab6.5 can not fix fix(uint16(..))
10770  end;
10771  end
10772  if any(HDR.EVENT.DUR<0)
10773  fprintf(2,'Warning SOPEN: EVENT ONSET later than EVENT OFFSET\n',dec2hex(TYP0),dec2hex(TYP1));
10774  %HDR.EVENT.DUR(:) = 0
10775  end;
10776  HDR.EVENT.TYP = HDR.EVENT.TYP(~flag_remove);
10777  HDR.EVENT.POS = HDR.EVENT.POS(~flag_remove);
10778  HDR.EVENT.CHN = HDR.EVENT.CHN(~flag_remove);
10779  HDR.EVENT.DUR = HDR.EVENT.DUR(~flag_remove);
10780 end;
10781 [tmp,ix] = sort(HDR.EVENT.POS);
10782 HDR.EVENT.TYP=HDR.EVENT.TYP(ix);
10783 HDR.EVENT.POS=HDR.EVENT.POS(ix);
10784 HDR.EVENT.DUR=HDR.EVENT.DUR(ix);
10785 HDR.EVENT.CHN=HDR.EVENT.CHN(ix);
10786 
10787 % Calibration matrix
10788 if any(HDR.FILE.PERMISSION=='r') && (HDR.NS>0);
10789  if isempty(ReRefMx) % CHAN==0,
10790  ReRefMx = speye(max(1,HDR.NS));
10791  end;
10792  sz = size(ReRefMx);
10793  if (HDR.NS > 0) && (sz(1) > HDR.NS),
10794  fprintf(HDR.FILE.stderr,'ERROR SOPEN: to many channels (%i) required, only %i channels available.\n',size(ReRefMx,1),HDR.NS);
10795  HDR = sclose(HDR);
10796  return;
10797  end;
10798  if ~isfield(HDR,'Calib')
10799  HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,1);
10800  end;
10801  if ~HDR.FLAG.FORCEALLCHANNEL,
10802  HDR.Calib = HDR.Calib*sparse([ReRefMx; zeros(HDR.NS-sz(1),sz(2))]);
10803  else
10804  HDR.ReRefMx = ReRefMx;
10805  end;
10806 
10807  HDR.InChanSelect = find(any(HDR.Calib(2:HDR.NS+1,:),2));
10808  HDR.Calib = sparse(HDR.Calib([1;1+HDR.InChanSelect(:)],:));
10809  if strcmp(HDR.TYPE,'native')
10810  HDR.data = HDR.data(:,HDR.InChanSelect);
10811  end;
10812 end;
10813 
sclose
function sclose(in HDR)
bni2hdr
function bni2hdr(in arg1, in arg3, in arg4, in arg5, in arg6)
openxml
function openxml(in arg1, in CHAN, in arg4, in arg5, in arg6)
bkropen
function bkropen(in arg1, in arg3, in arg4, in arg5, in arg6)
bv2biosig_events
function bv2biosig_events(in EVENT)
gdfdatatype
function gdfdatatype(in GDFTYP)
physicalunits
function physicalunits(in arg1)
fefopen
function fefopen(in arg1)
cntopen
function cntopen(in arg1, in arg2, in arg3, in arg4, in arg5, in arg6)
sopen
function sopen(in arg1, in PERMISSION, in CHAN, in MODE, in arg5, in arg6)
str2double
function str2double(in s, in cdelim, in rdelim, in ddelim)
bdf2biosig_events
function bdf2biosig_events(in HDR, in Mode)
getfiletype
function getfiletype(in arg1)
matread
function matread(in HDR, in arg2, in idxlist)
sread
function sread(in HDR, in NoS, in StartPos)
iopen
function iopen(in HDR, in PERMISSION, in CHAN, in MODE, in arg5, in arg6)