TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
sload.m
Go to the documentation of this file.
1 function [signal,H] = sload(FILENAME,varargin)
2 % SLOAD loads signal data of various data formats
3 % [signal,header] = sload(FILENAME)
4 % [signal,header] = sload(FILENAME,CHAN)
5 % read selected channels in list CHAN
6 % CHAN=0 [default], reads all channels
7 %
8 % [signal,header] = sload(dir('f*.emg') ... )
9 % [signal,header] = sload('f*.emg' ...)
10 % loads all files 'f*.emg'
11 %
12 % [signal,header] = sload(..., PropertyName1,PropertyValue1,...)
13 % PropertyName(s) PropertyValue
14 % 'UCAL' - data uncalibrated (not scaled)
15 % 'On' data uncalibrated (not scaled)
16 % 'Off' data calibrated (scaled) [default]
17 % 'OVERFLOWDETECTION' 'On' [default]
18 % 'Off' no overflow detection
19 % 'OUTPUT' 'single' single precision data [default: 'double']
20 % 'NUMBER_OF_NAN_IN_BREAK' N inserts N NaN's between two concatanated segments
21 % default: N=100
22 % 'SampleRate' Fs target sampling rate (supports resampling)
23 % 'EOG_CORRECTION' 'On' uses two-channel regression analysis - if possible
24 % 'Off' no correction of EOG artifacts [default]
25 % 'CNT32', '32bit' force CNT 32bit format
26 % 'BDF' N decodes BDF status channel into eventtable
27 % using Mode = N. For details see HELP BDF2BIOSIG_EVENTS
28 %
29 % The list of supported formats is available here:
30 % http://pub.ist.ac.at/~schloegl/biosig/TESTED
31 %
32 % SLOAD loads all the data (of the selected channels)
33 % at once. In case of large data files, This can be
34 % a problem. Instead, You can use
35 % HDR = sopen(FILENAME,'r');
36 % [s,HDR]=sread(HDR,duration_segment1);
37 % [s,HDR]=sread(HDR,duration_segment2);
38 % ....
39 % [s,HDR]=sread(HDR,duration_segmentM);
40 % HDR = sclose(HDR);
41 %
42 % see also: SVIEW, SOPEN, SREAD, SCLOSE, SAVE2BKR, BDF2BIOSIG_EVENTS, TLOAD
43 %
44 % In order to increase the speed, install mexSLOAD.mex from biosig4c++
45 %
46 % Reference(s):
47 
48 
49 % $Id: sload.m 3169 2012-12-04 15:39:03Z schloegl $
50 % Copyright (C) 1997-2007,2008,2009,2010,2011,2012 by Alois Schloegl
51 % This is part of the BIOSIG-toolbox http://biosig.sf.net/
52 
53 %
54 % BioSig is free software: you can redistribute it and/or modify
55 % it under the terms of the GNU General Public License as published by
56 % the Free Software Foundation, either version 3 of the License, or
57 % (at your option) any later version.
58 %
59 % BioSig is distributed in the hope that it will be useful,
60 % but WITHOUT ANY WARRANTY; without even the implied warranty of
61 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62 % GNU General Public License for more details.
63 %
64 % You should have received a copy of the GNU General Public License
65 % along with BioSig. If not, see <http://www.gnu.org/licenses/>.
66 
67 if length(varargin)<2;
68  MODE = '';
69 else
70  MODE = varargin{2};
71 end;
72 
73 CHAN = 0;
74 STATE.CNT32 = 0;
75 STATE.UCAL = 0;
76 STATE.OVERFLOWDETECTION = 1;
77 STATE.NUMBER_OF_NAN_IN_BREAK = 100; %% default value, always include when several files are concatanated
78 STATE.FLAG_NUM_NAN = 0; %% flags whether explicit argument NUMBER_OF_NAN_IN_BREAK is used, only then NaNs are introduced between sweeps(segments) within single files
79 STATE.EOG_CORRECTION = 0 ;
80 STATE.BDF = [] ;
81 STATE.OUTPUT = 'double';
82 
83 Fs = NaN;
84 k = 1;
85 while (k<=length(varargin))
86  if isnumeric(varargin{k})
87  if (k==1), CHAN=varargin{k}; end;
88  elseif ~isempty(strfind(varargin{k},'UCAL'))
89  MODE = varargin{k};
90  if strcmpi(varargin{k+1},'on');
91  STATE.UCAL = 1;
92  k=k+1;
93  elseif strcmpi(varargin{k+1},'off');
94  STATE.UCAL = 0;
95  k=k+1;
96  else
97  STATE.UCAL = 1;
98  end;
99  elseif ~isempty(strfind(varargin{k},'OVERFLOWDETECTION:OFF'))
100  MODE = varargin{k};
101  STATE.OVERFLOWDETECTION = 0;
102  elseif strcmpi(varargin{k},'OVERFLOWDETECTION')
103  if strcmpi(varargin{k+1},'on');
104  STATE.OVERFLOWDETECTION = 1;
105  elseif strcmpi(varargin{k+1},'off');
106  STATE.OVERFLOWDETECTION = 0;
107  elseif isnumeric(varargin{k+1})
108  STATE.OVERFLOWDETECTION = varargin{k+1};
109  end;
110  k=k+1;
111  elseif ~isempty(strfind(varargin{k},'OUTPUT:SINGLE'))
112  MODE = varargin{k};
113  STATE.OUTPUT = 'single';
114  elseif strcmpi(varargin{k},'OUTPUT')
115  STATE.OUTPUT = varargin{k+1};
116  elseif strcmpi(varargin{k},'EOG_CORRECTION')
117  if strcmpi(varargin{k+1},'on');
118  STATE.EOG_CORRECTION = 1;
119  elseif strcmpi(varargin{k+1},'off');
120  STATE.EOG_CORRECTION = 0;
121  elseif isnumeric(varargin{k+1})
122  STATE.EOG_CORRECTION = varargin{k+1};
123  end;
124  k=k+1;
125  elseif strcmpi(varargin{k},'Number_of_nan_in_break')
126  STATE.NUMBER_OF_NAN_IN_BREAK = varargin{k+1};
127  STATE.FLAG_NUM_NAN = 1;
128  k=k+1;
129  elseif strcmpi(varargin{k},'SampleRate')
130  Fs = varargin{k+1};
131  k=k+1;
132  elseif strcmpi(varargin{k},'BDF')
133  STATE.BDF = varargin{k+1};
134  k=k+1;
135  elseif strcmpi(varargin{k},'CNT32') || strcmpi(varargin{k},'32bit')
136  STATE.CNT32 = 1;
137  elseif exist(varargin{k},'file') && (k==1)
138  CHAN = varargin{k};
139  end;
140  k=k+1;
141 end;
142 
143 
144 %%% resolve wildcards %%%
145 if ischar(FILENAME)
146 if any(FILENAME=='*')
147  p = fileparts(FILENAME);
148  f = dir(FILENAME);
149  EOGix = zeros(1,length(f));
150  for k = 1:length(f);
151  f(k).name = fullfile(p,f(k).name);
152  [p,g,e] = fileparts(f(k).name);
153  lg = length(g);
154  if (lg>2) && strcmp(upper(g(lg+(-2:0))),'EOG')
155  EOGix(k) = 1;
156  end
157  end;
158  FILENAME={f([find(EOGix),find(~EOGix)]).name};
159 end;
160 end;
161 
162 if nargout>0,
163  signal = [];
164 end;
165 
166 if (iscell(FILENAME) && (length(FILENAME)==1)),
167  FILENAME = FILENAME{k};
168 end;
169 
170 if ((iscell(FILENAME) || isstruct(FILENAME))),
171  signal = [];
172  for k = 1:length(FILENAME),
173  if iscell(FILENAME(k))
174  f = FILENAME{k};
175  else
176  f = FILENAME(k);
177  end
178 
179  [s,h] = sload(f,varargin{:});
180  if k==1,
181  H = h;
182  signal = s;
183  H.SegLen = [0,size(s,1)];
184  %H.EVENT.POS = [H.EVENT.POS; 0];
185  %H.EVENT.TYP = [H.EVENT.TYP; hex2dec('7ffe')];
186  %if isfield(H.EVENT,'CHN');
187  % H.EVENT.CHN = [H.EVENT.CHN; 0];
188  %end;
189  %if isfield(H.EVENT,'DUR');
190  % H.EVENT.DUR = [H.EVENT.DUR; size(s,1)];
191  %end;
192  %if isfield(H.EVENT,'Desc'); % TFM-Excel-Beat-to-Beat
193  % H.EVENT.Desc = [H.EVENT.Desc; {'New Segment'}; h.EVENT.Desc];
194  %end;
195  else
196  H.FILE(k) = h.FILE;
197  H.T0(k,1:6) = h.T0;
198  if ~isnan(h.SampleRate) && (H.SampleRate ~= h.SampleRate),
199  fprintf(2,'Warning SLOAD: sampling rates of multiple files differ %i!=%i.\n',H.SampleRate, h.SampleRate);
200  end;
201  if size(s,2)==size(signal,2), %(H.NS == h.NS)
202  signal = [signal; repmat(NaN,STATE.NUMBER_OF_NAN_IN_BREAK,size(s,2)); s];
203  H.SegLen = [H.SegLen,size(signal,1)];
204  else
205  error('ERROR SLOAD: incompatible channel numbers %i!=%i of multiple files\n',H.NS,h.NS);
206  end;
207 
208  if ~isempty(h.EVENT.POS),
209  H.EVENT.POS = [H.EVENT.POS; size(signal,1); h.EVENT.POS+size(signal,1)-size(s,1)];
210  H.EVENT.TYP = [H.EVENT.TYP; hex2dec('7ffe'); h.EVENT.TYP];
211  if isfield(H.EVENT,'CHN');
212  H.EVENT.CHN = [H.EVENT.CHN; 0; h.EVENT.CHN];
213  end;
214  if isfield(H.EVENT,'DUR');
215  H.EVENT.DUR = [H.EVENT.DUR; size(s,1); h.EVENT.DUR];
216  end;
217  if isfield(H.EVENT,'Desc'); % TFM-Excel-Beat-to-Beat
218  H.EVENT.Desc = [H.EVENT.Desc; {'New Segment'}; h.EVENT.Desc];
219  end;
220  end;
221 
222  if ~isequal(H.Label,h.Label) || ~isequal(H.PhysDimCode,h.PhysDimCode)
223  warning('Labels and PhysDim of multiple files differ!\n');
224  for k2 = 1:length(H.InChanSelect),
225  k1 = H.InChanSelect(k2);
226  if ~strcmp(H.Label{k1},h.Label{k1}) || (H.PhysDimCode(k1)~=h.PhysDimCode(k1)),
227  warning('#%02i: %s | %s | (%i)%s | (%i)%s\n',k1, H.Label{k1},h.Label{k1}, H.PhysDimCode(k1),H.PhysDim{k1},h.PhysDimCode(k1),h.PhysDim{k1});
228  end;
229  end;
230  end;
231  if ~isequal(H.Calib,h.Calib) && H.FLAG.UCAL,
232  error('SLOAD: concatanating uncalibrated data with different scaling factors does not make sense!');
233  end;
234 
235  if isfield(H,'TriggerOffset'),
236  if H.TriggerOffset ~= h.TriggerOffset,
237  fprintf(2,'Warning SLOAD: Triggeroffset %f does not fit.%f \n',H.TriggerOffset,h.TriggerOffset);
238  end;
239  end;
240 
241  if isfield(h,'TRIG'),
242  if ~isfield(H,'TRIG'),
243  H.TRIG = [];
244  end;
245  H.TRIG = [H.TRIG(:); h.TRIG(:)+size(signal,1)-size(s,1)];
246  else h.TRIG=[];
247  end;
248 
249  if isfield(h,'Classlabel'),
250  if isfield(h,'ArtifactSelection'),
251  if (any(h.ArtifactSelection>1) || (length(h.ArtifactSelection) < length(h.Classlabel)))
252  sel = zeros(size(h.Classlabel));
253  sel(h.ArtifactSelection) = 1;
254  else
255  sel = h.ArtifactSelection(:);
256  end;
257  else
258  h.ArtifactSelection = repmat(logical(0),length(h.Classlabel),1);
259  end;
260 
261  if isfield(H,'ArtifactSelection')
262  H.ArtifactSelection = [H.ArtifactSelection; h.ArtifactSelection(:)];
263  else
264  H.ArtifactSelection = [repmat(logical(0),length(H.Classlabel),1); h.ArtifactSelection(:)];
265  end;
266  H.Classlabel = [H.Classlabel(:); h.Classlabel(:)];
267 
268  elseif isfield(H,'Classlabel') && (length(h.TRIG)>0),
269  warning(sprintf('field classlabel missing in %s. This might corrupt the resulting classlabels!',h.FileName));
270 
271  end;
272  clear s;
273  end;
274  end;
275 
276  % fprintf(1,'SLOAD: data segments are concatenated with NaNs in between.\n');
277  return;
278 end;
279 %%% end of multi-file section
280 
281 
282 %%%% start of single file section
283 %%%%%%%%%% --------- EOG CORRECTION -------------- %%%%%%
284 if STATE.EOG_CORRECTION,
285 try
286  h = get_regress_eog(FILENAME,'REG fft16');
287 catch,
288  fprintf(H.FILE.stderr,'Error: SLOAD (EOG_CORRECTION): %s\n',lasterr);
289  H.FLAG.EOG_CORRECTION = 0;
290 end;
291 end;
292 
293 
294 FlagLoaded = 0;
295 if exist('mexSLOAD','file')==3,
296  try
297  valid_rerefmx = 1;
298  if ischar(CHAN)
299  HDR = sopen(CHAN,'r'); HDR=sclose(HDR);
300  if isfield(HDR.Calib),
301  ReRefMx = HDR.Calib;
302  else
303  valid_rerefmx = 0;
304  end;
305  elseif all(size(CHAN)>1) || any(floor(CHAN)~=CHAN) || any(CHAN<0) || (any(CHAN==0) && (numel(CHAN)>1));
306  ReRefMx = CHAN;
307  CHAN = find(any(CHAN,2));
308  elseif all(CHAN>0) && all(floor(CHAN)==CHAN),
309  [tmp,ix]= sort(CHAN);
310  ReRefMx = sparse(CHAN,1:length(CHAN),1);
311  else
312  ReRefMx = [];
313  valid_rerefmx=0;
314  end
315 
316  if STATE.EOG_CORRECTION,
317  ReRefMx = h.r0*ReRefMx;
318  valid_rerefmx=1;
319  end
320  if STATE.OVERFLOWDETECTION,
321  arg1 = 'OVERFLOWDETECTION:ON';
322  else
323  arg1 = 'OVERFLOWDETECTION:OFF';
324  end
325  if STATE.UCAL,
326  arg2 = {'UCAL:ON'};
327  else
328  arg2 = {'UCAL:OFF'};
329  end
330  if STATE.CNT32
331  arg2 = {arg2,'CNT32'};
332  end
333  if ~valid_rerefmx,
334  [signal,HDR] = mexSLOAD(FILENAME,0,arg1,arg2{:});
335  if isfield(HDR,'ErrNum') && (HDR.ErrNum>0),
336  fprintf(1,'%s\n',HDR.ErrMsg);
337  H = HDR;
338  x = HDR.nonsense; % hack: triggers CATCH branch in TRY-CATCH-END;
339  end
340 
341  if isfield(HDR.FLAG,'ROW_BASED_CHANNELS') && HDR.FLAG.ROW_BASED_CHANNELS, signal = signal.'; end;
342  FlagLoaded = isfield(HDR,'NS');
343  HDR.InChanSelect = 1:HDR.NS;
344  else
345  InChanSelect = find(any(ReRefMx,2));
346  [signal,HDR] = mexSLOAD(FILENAME,InChanSelect,arg1,arg2{:});
347  if isfield(HDR,'ErrNum') && HDR.ErrNum==3,
348  %% file not found - fopen failed
349  H = HDR;
350  return;
351  end
352  if isfield(HDR.FLAG,'ROW_BASED_CHANNELS') && HDR.FLAG.ROW_BASED_CHANNELS, signal = signal.'; end;
353  FlagLoaded = isfield(HDR,'NS');
354  HDR.InChanSelect = InChanSelect(InChanSelect <= HDR.NS);
355  signal = signal*ReRefMx(InChanSelect,:); %% can be sparse if just a single channel is loaded
356  signal = full(signal); %% make sure signal is not sparse
357  end;
358  HDR = bdf2biosig_events(HDR, STATE.BDF);
359 
360  HDR.T0 = datevec(HDR.T0);
361  HDR.Patient.Birthday = datevec(HDR.Patient.Birthday);
362  HDR.Calib = [HDR.Off(:)';diag(HDR.Cal)];
363  [HDR.FILE.Path,HDR.FILE.Name,HDR.FILE.Ext] = fileparts(FILENAME);
364  HDR.FileName = FILENAME;
365  HDR = leadidcodexyz(HDR);
366 
367  H=HDR;
368  H.FLAG.EOG_CORRECTION = STATE.EOG_CORRECTION;
369  if isfield(HDR,'Patient') && isfield(HDR.Patient,'Weight') && isfield(HDR.Patient,'Height')
370  %% Body Mass Index
371  HDR.Patient.BMI = HDR.Patient.Weight * HDR.Patient.Height^-2 * 1e4;
372 
373  %% Body Surface Area
374  % 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.
375  % Wang Y, Moss J, Thisted R. Predictors of body surface area. J Clin Anesth. 1992; 4(1):4-10.
376  HDR.Patient.BSA = 0.007184 * HDR.Patient.Weight^0.425 * HDR.Patient.Height^0.725;
377  end;
378 
379  if strcmp(H.TYPE,'GDF');
380  % Classlabels according to
381  % http://biosig.cvs.sourceforge.net/*checkout*/biosig/biosig/doc/eventcodes.txt
382 
383  % sort event table before extracting HDR.Classlabel and HDR.TRIG
384  [H.EVENT.POS,ix] = sort(H.EVENT.POS);
385  H.EVENT.TYP = H.EVENT.TYP(ix);
386  if isfield(H.EVENT,'CHN')
387  H.EVENT.CHN = H.EVENT.CHN(ix);
388  end;
389  if isfield(H.EVENT,'DUR')
390  H.EVENT.DUR = H.EVENT.DUR(ix);
391  end;
392  if isfield(H.EVENT,'TimeStamp')
393  H.EVENT.TimeStamp = H.EVENT.TimeStamp(ix);
394  end;
395 
396  if (length(H.EVENT.TYP)>0)
397  ix = (H.EVENT.TYP>hex2dec('0300')) & (H.EVENT.TYP<hex2dec('030d'));
398  ix = ix | ((H.EVENT.TYP>=hex2dec('0320')) & (H.EVENT.TYP<=hex2dec('037f')));
399  ix = ix | (H.EVENT.TYP==hex2dec('030f')); % unknown/undefined cue
400  H.Classlabel = mod(H.EVENT.TYP(ix),256);
401  H.Classlabel(H.Classlabel==15) = NaN; % unknown/undefined cue
402  end;
403 
404  % Trigger information and Artifact Selection
405  ix = find(H.EVENT.TYP==hex2dec('0300'));
406  H.TRIG = H.EVENT.POS(ix);
407  ArtifactSelection = repmat(logical(0),length(ix),1);
408  for k = 1:length(ix),
409  ix2 = find(H.EVENT.POS(ix(k))==H.EVENT.POS);
410  if any(H.EVENT.TYP(ix2)==hex2dec('03ff'))
411  ArtifactSelection(k) = logical(1);
412  end;
413  end;
414  if any(ArtifactSelection), % define only if necessary
415  H.ArtifactSelection = ArtifactSelection;
416  end;
417 
418  % apply channel selections to EVENT table
419  if valid_rerefmx && ~isempty(H.EVENT.POS) && (isfield(H.EVENT,'CHN')), % only if channels are selected.
420  sel = (H.EVENT.CHN(:)==0); % memory allocation, select all general events
421  for k = find(~sel'), % select channel specific elements
422  sel(k) = any(H.EVENT.CHN(k)==InChanSelect);
423  end;
424  H.EVENT.POS = H.EVENT.POS(sel);
425  H.EVENT.TYP = H.EVENT.TYP(sel);
426  H.EVENT.DUR = H.EVENT.DUR(sel); % if EVENT.CHN available, also EVENT.DUR is defined.
427  H.EVENT.CHN = H.EVENT.CHN(sel);
428  if isfield(H.EVENT,'TimeStamp')
429  H.EVENT.TimeStamp = H.EVENT.TimeStamp(sel);
430  end;
431  % assigning new channel number
432  a = zeros(1,HDR.NS);
433  for k = 1:length(InChanSelect), % select channel specific elements
434  a(InChanSelect(k)) = k; % assigning to new channel number.
435  end;
436  ix = H.EVENT.CHN>0;
437  H.EVENT.CHN(ix) = a(H.EVENT.CHN(ix)); % assigning new channel number
438  end;
439 
440  elseif strcmp(H.TYPE,'BDF');
441  H.BDF.ANNONS = zeros(HDR.NRec*HDR.SPR,1);
442  ix = HDR.EVENT.TYP==hex2dec('7ffe');
443  ix1 = find(~ix);
444  POS = HDR.EVENT.POS(ix1);
445  TYP = HDR.EVENT.TYP(ix1);
446  [s,ix2] = sort([POS; HDR.NRec*HDR.SPR+1]);
447  for k = 1:length(s)-1,
448  H.BDF.ANNONS(s(k):s(k+1)-1) = TYP(ix2(k));
449  end;
450  H.BDF.ANNONS(HDR.EVENT.POS(ix)) = H.BDF.ANNONS(HDR.EVENT.POS(ix)) | hex2dec('10000');
451 
452  elseif strcmp(H.TYPE,'BKR');
453  H.Classlabel = [];
454  H.TRIG = [];
455  tmp=fullfile(H.FILE.Path,[H.FILE.Name,'.mat']);
456  if ~exist(tmp,'file'),
457  tmp=fullfile(H.FILE.Path,[H.FILE.Name,'.MAT']);
458  end
459  x = [];
460  if exist(tmp,'file'),
461  x = load('-mat',tmp);
462  end;
463 
464  if isfield(x,'header'),
465  H.MAT = x.header;
466  if isfield(x.header,'Setup'),
467  if isfield(x.header.Setup,'Bits'),
468  H.Bits = x.header.Setup.Bits;
469  [datatyp, limits, datatypes] = gdfdatatype(H.Bits+255);
470  % THRESHOLD for Overflow detection
471  if ~isfield(H,'THRESHOLD')
472  H.THRESHOLD = repmat(limits, H.NS, 1);
473  end;
474  end;
475  end;
476  if isfield(x.header,'Result') && isfield(x.header.Result,'Classlabel'),
477  H.Classlabel = x.header.Result.Classlabel;
478  end;
479  if isfield(x.header,'Paradigm')
480  if isempty(H.Classlabel) && isfield(x.header.Paradigm,'Classlabel')
481  H.Classlabel = x.header.Paradigm.Classlabel;
482  end;
483  H.BCI.Paradigm = x.header.Paradigm;
484  if isfield(H.BCI.Paradigm,'TriggerOnset');
485  H.TriggerOffset = H.BCI.Paradigm.TriggerOnset;
486  elseif isfield(H.BCI.Paradigm,'TriggerTiming');
487  % H.BCI.Paradigm.TriggerTiming,
488  H.TriggerOffset = H.BCI.Paradigm.TriggerTiming;
489  fprintf(2,'Warning BKROPEN: Paradigm.TriggerOnset is unknown. Paradigm.TriggerTiming= %f ms is used instead\n',H.TriggerOffset);
490  end;
491  end;
492 
493  if isfield(x.header,'PhysioRec'), % R. Leeb's data
494  H.Label = cellstr(x.header.PhysioRec);
495  end;
496  if isfield(x.header,'BKRHeader'), % R. Scherer Data
497  if isfield(x.header.BKRHeader,'TO'),
498  H.T0 = x.header.BKRHeader.TO;
499  end;
500  if isfield(x.header.BKRHeader,'Label'),
501  H.Label = cellstr(x.header.BKRHeader.Label);
502  ns = H.NS-length(H.Label);
503  if ns == 1;
504  H.Label = strvcat(H.Label,'TRIGGER');
505  elseif ns > 1;
506  H.Label = strvcat(H.Label,char(repmat('n.a.',ns,1)));
507  end;
508  end;
509  end;
510  if isfield(x.header,'Model'), % More
511  if isfield(x.header.Model,'AnalogInput'),
512  for k = 1:length(x.header.Model.AnalogInput),
513  H.Filter.HighPass(k) = x.header.Model.AnalogInput{k}{5};
514  H.Filter.LowPass(k) = x.header.Model.AnalogInput{k}{6};
515  H.Filter.Notch(k) = strcmpi(x.header.Model.AnalogInput{k}{7},'on');
516 
517  H.MAT.Cal(k) = x.header.Model.AnalogInput{k}{3};
518  end
519  end;
520  end;
521  if ~isempty(strmatch('TRIGGER',H.Label))
522  H.AS.TRIGCHAN = H.NS; %strmatch('TRIGGER',H.Label);
523  end;
524  end;
525  if 1; ~isfield(H,'Classlabel');
526  tmp=fullfile(H.FILE.Path,[H.FILE.Name,'.par']);
527  if ~exist(tmp,'file'),
528  tmp=fullfile(H.FILE.Path,[H.FILE.Name,'.PAR']);
529  end
530  if exist(tmp,'file'),
531  H.Classlabel = load(tmp);
532  end;
533  end;
534 
535  %%% Artifact Selection files
536  tmp1=fullfile(H.FILE.Path,[H.FILE.Name,'.sel']);
537  if ~exist(tmp1,'file'),
538  tmp1=fullfile(H.FILE.Path,[H.FILE.Name,'.SEL']);
539  end
540  tmp2 = fullfile(H.FILE.Path,[H.FILE.Name,'_artifact.mat']);
541  SW = (exist(tmp1,'file')>0) + 2*(exist(tmp2,'file')>0);
542  if SW == 0,
543  elseif SW == 1,
544  if exist('OCTAVE_VERSION','builtin')
545  H.ArtifactSelection = load('-ascii',tmp1);
546  else
547  H.ArtifactSelection = load(tmp1);
548  end;
549  elseif SW == 2,
550  if exist('OCTAVE_VERSION','builtin')
551  tmp = load('-mat',tmp2);
552  else
553  tmp = load(tmp2);
554  end;
555  H.ArtifactSelection = tmp.artifact(:);
556  elseif SW == 3,
557  fprintf(H.FILE.stderr,'Warning BKROPEN: more than one ArtifactSelection files. File %s is used.\n',tmp1);
558  if exist('OCTAVE_VERSION')>5
559  H.ArtifactSelection = load('-ascii',tmp1);
560  else
561  H.ArtifactSelection = load(tmp1);
562  end;
563  end;
564  if isfield(H,'ArtifactSelection'),
565  if any(H.ArtifactSelection>1) || (length(H.ArtifactSelection)<length(H.Classlabel))
566  sel = zeros(size(H.Classlabel));
567  sel(H.ArtifactSelection) = 1;
568  H.ArtifactSelection = sel(:);
569  end;
570  H.ArtifactSelection = H.ArtifactSelection(:);
571  end;
572 
573  if isfield(H.AS,'TRIGCHAN') % & isempty(H.EVENT.POS)
574  if H.AS.TRIGCHAN <= H.NS, %size(H.data,2),
575  H.THRESHOLD(H.AS.TRIGCHAN,1:2) = [-1-2^15,2^15]; % do not apply overflow detection for Trigger channel
576  data = mexSLOAD(H.FileName,H.AS.TRIGCHAN,'UCAL:ON','OVERFLOWDETECTION:OFF');
577  TRIGon = gettrigger(data);
578  %TRIGoff = gettrigger(-double(H.data(:,H.AS.TRIGCHAN)));
579  if isfield(H,'TriggerOffset')
580  TRIGon = TRIGon - round(H.TriggerOffset/1000*H.SampleRate);
581  % TRIGoff = TRIGoff - round(H.TriggerOffset/1000*H.SampleRate);
582  end;
583  end;
584  H.TRIG = TRIGon(:);
585  H.EVENT.POS = TRIGon(:); %[TRIGon(:); TRIGoff(:)];
586  H.EVENT.TYP = repmat(hex2dec('0300'),numel(TRIGon),1); %repmat(hex2dec('8300'),numel(TRIGoff),1)];
587  end;
588  if length(H.TRIG)~=length(H.Classlabel),
589  % hack to deal with BCI22 data
590  fprintf(2,'Warning BKROPEN: Number of triggers (%i) and number of Classlabels (%i) do not fit\n',length(H.TRIG),length(H.Classlabel));
591  H.TRIG = [];
592  H.Classlabel = [];
593  H.ArtifactSelection = [];
594  end;
595  %% end of BKR
596 
597  elseif strcmp(H.TYPE,'BrainVision');
598  try
599  H = bv2biosig_events(H);
600  catch
601  %warning('bv2biosig_events not executed');
602  end;
603 
604  elseif strcmp(H.TYPE,'EDF') && isfield(H.EVENT,'Desc');
605  if length(H.EVENT.TYP)==length(H.EVENT.Desc)
606  [H.EVENT.CodeDesc, CodeIndex, H.EVENT.TYP] = unique(H.EVENT.Desc);
607  end;
608 
609  %% end of BKR
610 
611  elseif strcmp(H.TYPE,'BrainVision');
612  HDR = sopen(fullfile(H.FILE.Path,[H.FILE.Name,'.vmrk']));
613  HDR = sclose(HDR);
614  H.EVENT = HDR.EVENT;
615 
616  elseif strcmp(H.TYPE,'PDP');
617  signal = repmat(NaN,max(HDR.EVENT.POS),HDR.NS);
618  end;
619 
620  if isempty(signal);
621  signal = repmat(NaN,round(max(HDR.EVENT.POS)*HDR.SampleRate/HDR.EVENT.SampleRate),HDR.NS);
622  for k = 1:HDR.NS,
623  ix = find(HDR.EVENT.CHN==k);
624  signal(round(HDR.EVENT.POS(ix)*HDR.SampleRate/HDR.EVENT.SampleRate),k)=HDR.EVENT.DUR(ix);
625  end;
626  end;
627 
628  H.CHANTYP = repmat(' ',1,H.NS);
629  for k=1:H.NS,
630  if ~isempty(strfind(lower(H.Label{k}),'eeg')) H.CHANTYP(k) = 'E';
631  elseif ~isempty(strfind(lower(H.Label{k}),'meg')) H.CHANTYP(k) = 'E';
632  elseif ~isempty(strfind(lower(H.Label{k}),'emg')) H.CHANTYP(k) = 'M';
633  elseif ~isempty(strfind(lower(H.Label{k}),'eog')) H.CHANTYP(k) = 'O';
634  elseif ~isempty(strfind(lower(H.Label{k}),'ecg')) H.CHANTYP(k) = 'C';
635  elseif ~isempty(strfind(lower(H.Label{k}),'air')) H.CHANTYP(k) = 'R';
636  elseif ~isempty(strfind(lower(H.Label{k}),'trig')) H.CHANTYP(k) = 'T';
637  end;
638  end;
639 
640  catch
641  %fprintf(1,lasterr);
642  fprintf(1, 'SLOAD: mexSLOAD(''%s'') failed - the slower M-function is used.\n', FILENAME);
643  end;
644 else
645  global FLAG_HINT_mexSLOAD;
646  if isempty(FLAG_HINT_mexSLOAD)
647  fprintf(1, 'Hint: the performance of SLOAD can be improved with mexSLOAD.mex which is part of biosig4c++.\n');
648  FLAG_HINT_mexSLOAD = 1; % turn off hint
649  end;
650 end;
651 
652 if ~FlagLoaded,
653  H = getfiletype(FILENAME);
654 
655  if isempty(H)
656  fprintf(2,'Warning SLOAD: no file found\n');
657  return;
658  else
659  % FILENAME can be fn.name struct, or HDR struct.
660  FILENAME = H.FileName;
661  end;
662  H.FLAG.UCAL = STATE.UCAL;
663  H.FLAG.OVERFLOWDETECTION = STATE.OVERFLOWDETECTION;
664  H.FLAG.EOG_CORRECTION = STATE.EOG_CORRECTION;
665  H.FLAG.OUTPUT = STATE.OUTPUT;
666 
667 
668 if strncmp(H.TYPE,'IMAGE:',5)
669  [H] = iopen(H);
670  if H.FILE.OPEN,
671  signal = iread(H);
672  H.FILE.OPEN = 0;
673  fclose(H.FILE.FID);
674  end;
675  return;
676 end;
677 
678 %%%%%%%%%%%%%%% --------- Load single file ------------%%%%%%%%%%%
679 H = sopen(H,'r',CHAN,MODE);
680 if 0, ~isnan(H.NS),
681 %------ ignore 'NaC'-channels
682  NS = size(H.Calib,2);
683  SelMx = speye(NS);
684  ch = 1:NS; %ch(strmatch('NaC',H.Label))=[];
685  if length(ch)<NS,
686  fprintf(2,'Warning SLOAD: Some NaC channels have been removed %s\n',H.FileName);
687  end;
688  SelMx = SelMx(:,ch);
689  H.Calib = H.Calib*SelMx;
690 
691  % generate correction matrix
692  if H.FLAG.EOG_CORRECTION,
693  H.Calib = H.Calib*h.REGRESS.r0;
694  if ~isequal(H.Label(ch),h.Label)
695  fprintf(2, 'Warning SLOAD (EOG correction): Channel labels in %s do not fit with arti* recording!\n',H.FileName);
696  end;
697  elseif STATE.EOG_CORRECTION,
698  fprintf(2, 'Warning: EOG correction not supported for this file (%s)!\n',H.FileName);
699  end;
700 
701  %----- generate HDR.Calib -----
702  if all(size(CHAN)>1) || any(floor(CHAN)~=CHAN) || any(CHAN<0) || (any(CHAN==0) && (numel(CHAN)>1));
703  ReRefMx = CHAN;
704  CHAN = find(any(CHAN,2));
705  elseif all(CHAN>0) && all(floor(CHAN)==CHAN),
706  if any(diff(CHAN)<=0),
707  % fprintf(HDR.FILE.FID,'Warning SOPEN: CHAN-argument not sorted - header information like Labels might not correspond to data.\n');
708  end;
709  ReRefMx = sparse(CHAN,1:length(CHAN),1,H.NS,length(CHAN));
710  else %if (CHAN==0)
711  ReRefMx = [];
712  end
713  if ~isempty(ReRefMx),
714  %[size(H.Calib),size(SelMx),size(h.REGRESS.r0),size(ReRefMx)]
715  ReRefMx = [ReRefMx(1:min(size(ReRefMx,1),size(H.Calib,2)),:); zeros(max(0,size(H.Calib,2)-size(ReRefMx,1)),size(ReRefMx,2))];
716  H.Calib = H.Calib*ReRefMx;
717  end;
718 
719  H.InChanSelect = find(any(H.Calib(2:end,:),2));
720  H.Calib = H.Calib([1;1+H.InChanSelect(:)],:);
721 end
722 
723 if 0,
724 
725 elseif isfield(H,'data') && all(diag(H.Calib(2:end,1:end))==1) && ~H.FLAG.OVERFLOWDETECTION,
726  % only a single copy of the data
727  % important for large data sets, close to the available memory
728  signal = H.data;
729  H = rmfield(H,'data');
730  if (CHAN>0)
731  signal = signal(:,CHAN);
732  end;
733 
734 
735 elseif any(strmatch(H.TYPE,{'native','TFM_EXCEL_Beat_to_Beat','EEProbe-CNT','EEProbe-AVR'}));
736  [signal,H] = sread(H);
737  H = sclose(H);
738 
739 elseif (H.FILE.OPEN > 0)
740  [signal,H] = sread(H);
741  H = sclose(H);
742 
743 elseif (H.FILE.OPEN > 0)
744  signal = repmat(NaN,H.SPR*H.NRec,size(H.Calib,2));
745  k1 = 0;
746  while ~seof(H),
747  [s,H] = sread(H,100);
748  if 1,
749  k2 = size(s,1);
750  signal(k1+1:k1+k2,:)=s;
751  k1 = k1+k2;
752  else
753  %fprintf('%i/%i\n',stell(H),H.SPR*H.NRec);
754  signal=[signal;s];
755  end;
756  end;
757  H = sclose(H);
758 
759 
760 elseif strncmp(H.TYPE,'EVENT',5)
761  signal = H.EVENT;
762  return;
763 
764 
765 elseif strncmp(H.TYPE,'ELPOS',5)
766  signal = H.ELEC.XYZ;
767  return;
768 
769 elseif strcmp(H.TYPE,'DAQ')
770  fprintf(1,'Loading a matlab DAQ data file - this can take a while.\n');
771  tic;
772  [signal, tmp, H.DAQ.T0, H.DAQ.events, DAQ.info] = daqread(H.FileName);
773  fprintf(1,'Loading DAQ file finished after %.0f s.\n',toc);
774  [H.SPR,H.NS] = size(signal);
775 
776  H.SampleRate = DAQ.info.ObjInfo.SampleRate;
777  sz = size(signal);
778  if length(sz)==2, sz=[1,sz]; end;
779  H.NRec = sz(1);
780  H.Dur = sz(2)/H.SampleRate;
781  H.NS = sz(3);
782  H.FLAG.TRIGGERED = H.NRec>1;
783  H.FLAG.UCAL = 1;
784 
785  H.PhysDim = {DAQ.info.ObjInfo.Channel.Units};
786  H.DAQ = DAQ.info.ObjInfo.Channel;
787 
788  H.Cal = diff(cat(1,DAQ.info.ObjInfo.Channel.InputRange),[],2).*(2.^(-DAQ.info.HwInfo.Bits));
789  H.Off = cat(1,DAQ.info.ObjInfo.Channel.NativeOffset);
790  H.Calib = sparse([H.Off';eye(H.NS)]*diag(H.Cal));
791 
792  if CHAN<1,
793  CHAN = 1:H.NS;
794  end;
795  if ~H.FLAG.UCAL,
796  Calib = H.Calib; % Octave can not index sparse matrices within a struct
797  signal = [ones(size(signal,1),1),signal]*Calib(:,CHAN);
798  end;
799 
800 
801 elseif 0, strcmp(H.TYPE,'BIFF'),
802  try,
803  [H.TFM.S,H.TFM.E] = xlsread(H.FileName,'Beat-To-Beat');
804  if size(H.TFM.S,1)+1==size(H.TFM.E,1),
805  H.TFM.S = [repmat(NaN,1,size(H.TFM.S,2));H.TFM.S];
806  end;
807  H.TYPE = 'TFM_EXCEL_Beat_to_Beat';
808  catch
809  try
810  [H.TFM.S,H.TFM.E] = xlsread(H.FileName,'Beat-to-Beat');
811  H.TYPE = 'TFM_EXCEL_Beat_to_Beat';
812  catch
813  0;
814  end;
815  end;
816 
817  if strcmp(H.TYPE, 'TFM_EXCEL_Beat_to_Beat');
818  if ~isempty(strfind(H.TFM.E{3,1},'---'))
819  H.TFM.S(3,:) = [];
820  H.TFM.E(3,:) = [];
821  end;
822 
823  H.Label = strvcat(H.TFM.E{4,:});
824  H.PhysDim = strvcat(H.TFM.E{5,:});
825 
826  H.TFM.S = H.TFM.S(6:end,:);
827  H.TFM.E = H.TFM.E(6:end,:);
828 
829  ix = find(isnan(H.TFM.S(:,2)) & ~isnan(H.TFM.S(:,1)));
830  H.EVENT.Desc = H.TFM.E(ix,2);
831  H.EVENT.POS = ix;
832 
833  if any(CHAN),
834  H.TFM.S = H.TFM.S(:,CHAN);
835  H.TFM.E = H.TFM.E(:,CHAN);
836  end;
837  [H.SPR,H.NS] = size(H.TFM.S);
838  H.NRec = 1;
839  H.THRESHOLD = repmat([0,NaN],H.NS,1);
840 
841  signal = H.TFM.S;
842  signal(signal==0) = NaN;
843  end;
844 
845 
846 elseif strcmp(H.TYPE,'MatrixMarket'),
847  H.FILE.FID = fopen(H.FileName,'rt','ieee-le');
848 
849  line = fgetl(H.FILE.FID);
850 
851  H.FLAG.Coordinate = ~isempty(strfind(line,'coordinate'));
852  H.FLAG.Array = ~isempty(strfind(line,'array'));
853 
854  H.FLAG.Complex = ~isempty(strfind(line,'complex'));
855  H.FLAG.Real = ~isempty(strfind(line,'real'));
856  H.FLAG.Integer = ~isempty(strfind(line,'integer'));
857  H.FLAG.Pattern = ~isempty(strfind(line,'pattern'));
858 
859  H.FLAG.General = ~isempty(strfind(line,'general'));
860  H.FLAG.Symmetric = ~isempty(strfind(line,' symmetric'));
861  H.FLAG.SkewSymmetric = ~isempty(strfind(line,'skew-symmetric'));
862  H.FLAG.Hermitian = ~isempty(strfind(lower(line),'hermitian'));
863 
864  while strncmp(line,'%',1)
865  line = fgetl(H.FILE.FID);
866  end;
867 
868  [tmp,status] = str2double(line);
869  if any(status)
870  fprintf(H.FILE.stderr,'SLOAD (MM): invalid size %s\n',line);
871  else
872  H.MATRIX.Size = tmp;
873  end;
874 
875  if length(H.MATRIX.Size)==3,
876  H.Length = tmp(3);
877  signal = sparse([],[],[],tmp(1),tmp(2),tmp(3));
878  for k = 1:H.Length,
879  line = fgetl(H.FILE.FID);
880  [tmp,status] = str2double(line);
881  if any(status)
882  fprintf(H.FILE.stderr,'SLOAD (MM): invalid size %s\n',line);
883  elseif length(tmp)==4,
884  val = tmp(3) + i*tmp(4);
885  elseif length(tmp)==3,
886  val = tmp(3);
887  elseif length(tmp)==2,
888  val = 1;
889  else
890  fprintf(H.FILE.stderr,'SLOAD (MM): invalid size %s\n',line);
891  end;
892 
893  if H.FLAG.General,
894  signal(tmp(1),tmp(2)) = val;
895  elseif H.FLAG.Symmetric,
896  signal(tmp(1),tmp(2)) = val;
897  signal(tmp(2),tmp(1)) = val;
898  elseif H.FLAG.SkewSymmetric,
899  signal(tmp(1),tmp(2)) = val;
900  signal(tmp(2),tmp(1)) =-val;
901  elseif H.FLAG.Hermitian,
902  signal(tmp(1),tmp(2)) = val;
903  signal(tmp(2),tmp(1)) = conj(val);
904  else
905  fprintf(H.FILE.stderr,'SLOAD (MM): invalid size %s\n',line);
906  end;
907  end;
908 
909  elseif length(H.MATRIX.Size)==2
910  H.Length = prod(tmp);
911  signal = zeros(H.MATRIX.Size);
912  if H.FLAG.General==1,
913  [IX,IY]=find(ones(H.MATRIX.Size));
914  else
915  [IX,IY]=find(cumsum(eye(H.MATRIX.Size)));
916  end;
917 
918  for k = 1:H.Length,
919  line = fgetl(H.FILE.FID);
920  [tmp,status] = str2double(line);
921  if any(status)
922  error('SLOAD (MM)');
923  elseif length(tmp)==2,
924  val=tmp(1) + i*tmp(2);
925  elseif length(tmp)==1,
926  val=tmp(1);
927  else
928  fprintf(H.FILE.stderr,'SLOAD (MM): invalid size %s\n',line);
929  end;
930 
931  signal(IX(k),IY(k)) = val;
932  if H.FLAG.Symmetric,
933  signal(IY(k),IX(k)) = val;
934  elseif H.FLAG.SkewSymmetric,
935  signal(IY(k),IX(k)) =-val;
936  elseif H.FLAG.Hermitian,
937  signal(IY(k),IX(k)) = conj(val);
938  else
939  fprintf(H.FILE.stderr,'SLOAD (MM): invalid size %s\n',line);
940  end;
941  end;
942  end;
943  fclose(H.FILE.FID);
944 
945 
946 elseif strcmp(H.TYPE,'OFF'),
947  H.FILE.FID = fopen(H.FileName,'rt','ieee-le');
948 
949  line1 = fgetl(H.FILE.FID);
950  line2 = fgetl(H.FILE.FID);
951  while ~feof(H.FILE.FID) && (line2(1)=='#'),
952  line2 = fgetl(H.FILE.FID);
953  end;
954  [tmp,status] = str2double(line2);
955  if status || (size(tmp,2)~=3),
956  fclose(H.FILE.FID);
957  error('SOPEN (OFF)');
958  else
959  H.VertexCount = tmp(1);
960  H.FaceCount = tmp(2);
961  H.EdgeCount = tmp(3);
962  end
963 
964  H.Vertex = repmat(NaN,H.VertexCount,3);
965  for k = 1:H.VertexCount,
966  line = '';
967  while isempty(line) || strncmp(line,'#',1)
968  line = fgetl(H.FILE.FID);
969  end;
970  len = min(length(line),min(find(line=='#')));
971  tmp = str2double(line(1:len));
972  H.Vertex(k,:) = tmp(1:H.ND);
973  end;
974 
975 % H.Face = repmat(NaN,H.FaceCount,3);
976  for k = 1:H.FaceCount,
977  line = '';
978  while isempty(line) || strncmp(line,'#',1)
979  line = fgetl(H.FILE.FID);
980  end;
981  len = min(length(line),min(find(line=='#')));
982  tmp = str2double(line(1:len));
983  H.Ngon(k) = tmp(1);
984  H.Face{k} = tmp(2:tmp(1)+1) + 1;
985  end;
986  if all(H.Ngon(1)==H.Ngon),
987  H.Face = cat(1,H.Face{:});
988  end;
989  fclose(H.FILE.FID);
990 
991 
992 elseif strcmp(H.TYPE,'POLY'),
993  H.FILE.FID = fopen(H.FileName,'rt','ieee-le');
994 
995  K = 0;
996  while ~feof(H.FILE.FID)
997  line = fgetl(H.FILE.FID);
998  if isempty(line),
999  elseif line(1)=='#',
1000  else
1001  K = K + 1;
1002 
1003  end;
1004  end;
1005  fclose(H.FILE.FID);
1006 
1007 
1008 elseif strcmp(H.TYPE,'SMF'),
1009  H.FILE.FID = fopen(H.FileName,'rt','ieee-le');
1010 
1011  VertexCount = 0;
1012  FaceCount = 0;
1013  PalLen = 0;
1014  K = 1;
1015  while ~feof(H.FILE.FID)
1016  line = fgetl(H.FILE.FID);
1017  if isempty(line)
1018  elseif line(1)=='#';
1019 
1020  elseif line(1)=='v';
1021  [tmp,status] = str2double(line(3:end));
1022  if ~any(status)
1023  VertexCount = VertexCount + 1 ;
1024  H.Vertex(VertexCount,:) = tmp;
1025  else
1026  fprintf(H.FILE.stderr,'Warning SLOAD: could not read line %i in file %s\n',K,H.FileName);
1027  end;
1028 
1029  elseif line(1)=='f';
1030  [tmp,status] = str2double(line(3:end));
1031  if ~any(status)
1032  FaceCount = FaceCount + 1;
1033  H.Ngon(FaceCount) = length(tmp);
1034  H.Face{FaceCount} = tmp;
1035  else
1036  fprintf(H.FILE.stderr,'Warning SLOAD: could not read line %i in file %s\n',K,H.FileName);
1037  end;
1038 
1039  elseif line(1)=='n';
1040  [tmp,status] = str2double(line(3:end));
1041  if ~any(status)
1042  H.NormalVector = tmp;
1043  else
1044  fprintf(H.FILE.stderr,'Warning SLOAD: could not read line %i in file %s\n',K,H.FileName);
1045  end;
1046 
1047  elseif line(1)=='c';
1048  [tmp,status] = str2double(line(3:end));
1049  if ~any(status)
1050  PalLen = PalLen +1;
1051  H.Palette(PalLen,:)= tmp;
1052  else
1053  fprintf(H.FILE.stderr,'Warning SLOAD: could not read line %i in file %s\n',K,H.FileName);
1054  end;
1055  else
1056 
1057  end;
1058  K = K+1;
1059  end;
1060  fclose(H.FILE.FID);
1061  if all(H.Ngon(1)==H.Ngon),
1062  H.Face = cat(1,H.Face{:});
1063  end;
1064 
1065 
1066 elseif strcmp(H.TYPE,'TVF 1.1A'),
1067  H.FILE.FID = fopen(H.FileName,'rt');
1068 
1069  tmp = fgetl(H.FILE.FID);
1070  H.TVF.Name = fgetl(H.FILE.FID);
1071  H.TVF.Desc = fgetl(H.FILE.FID);
1072  [tmp,status] = str2double(fgetl(H.FILE.FID));
1073  H.TVF.NTR = tmp(1);
1074  H.TVF.NV = tmp(2);
1075  H.FLAG.CULL = ~~tmp(3);
1076  [tmp,status] = str2double(fgetl(H.FILE.FID));
1077  H.TVF.NTRC = tmp(1);
1078  H.TVF.NTRM = tmp(2);
1079  [tmp,status] = str2double(fgetl(H.FILE.FID));
1080  H.TVF.NVC = tmp(1);
1081  H.TVF.NVN = tmp(2);
1082  [tmp,status] = str2double(fgetl(H.FILE.FID));
1083  H.TVF.GlobalColor = tmp;
1084  [tmp,status] = str2double(fgetl(H.FILE.FID));
1085  H.TVF.GlobalMtrlProps = tmp;
1086 
1087  H.TVF.Triangles = repmat(NaN,[H.TVF.NTR,3]);
1088  for k = 1:H.TVF.NTR,
1089  [tmp, status] = str2double(fgetl(H.FILE.FID));
1090  H.TVF.Triangles(k,:) = tmp;
1091  end;
1092  H.TVF.TrColorSets = reshape(NaN,[H.TVF.NTRC,H.TVF.NTR]);
1093  for k = 1:H.TVF.NTRC,
1094  [tmp, status] = str2double(fgetl(H.FILE.FID));
1095  H.TVF.TrColorSets(k,:) = tmp;
1096  end;
1097  H.TVF.TrMtrlSets = repmat(NaN, [H.TVF.NTRM,H.TVF.NTR]);
1098  for k = 1:H.TVF.NTRM,
1099  [tmp, status] = str2double(fgetl(H.FILE.FID));
1100  H.TVF.TrMtrlSets(k,:) = tmp;
1101  end;
1102 
1103  H.TVF.Vertices = repmat(NaN, [H.TVF.NV,3]);
1104  for k = 1:H.TVF.NV,
1105  [tmp, status] = str2double(fgetl(H.FILE.FID));
1106  H.TVF.Vertices(k,:) = tmp;
1107  end;
1108  H.TVF.VColorSets = repmat(NaN, [H.TVF.NVC,H.TVF.NV]);
1109  for k = 1:H.TVF.NVC,
1110  [tmp, status] = str2double(fgetl(H.FILE.FID));
1111  H.TVF.VColorSets(k,:) = tmp;
1112  end;
1113  H.TVF.VNrmlSets = repmat(NaN, [H.TVF.NVN,3]);
1114  for k = 1:H.TVF.NVN,
1115  [tmp, status] = str2double(fgetl(H.FILE.FID));
1116  H.TVF.VNrmlSets(k,:) = tmp;
1117  end;
1118 
1119  fclose(H.FILE.FID);
1120 
1121 
1122 elseif strcmp(H.TYPE,'TVF 1.1B'),
1123  H.FILE.FID = fopen(H.FileName,'rb',H.Endianity);
1124 
1125  tmp = fread(H.FILE.FID,12,'uchar');
1126  H.TVF.Name = char(fread(H.FILE.FID,32,'uchar'));
1127  H.TVF.Desc = char(fread(H.FILE.FID,80,'uchar'));
1128  tmp = fread(H.FILE.FID,7,'uint32');
1129  H.TVF.NTR = tmp(1);
1130  H.TVF.NV = tmp(2);
1131  H.FLAG.CULL = ~~tmp(3);
1132  H.TVF.NTRC = tmp(4);
1133  H.TVF.NTRM = tmp(5);
1134  H.TVF.NVC = tmp(6);
1135  H.TVF.NVN = tmp(7);
1136  tmp = fread(H.FILE.FID,[4,2],'float32');
1137  H.TVF.GlobalColor = tmp(:,1)';
1138  H.TVF.GlobalMtrlProps = tmp(:,2)';
1139 
1140  H.TVF.Triangles = fread(H.FILE.FID, [3,H.TVF.NTR],'uint32')';
1141  H.TVF.TrColorSets = fread(H.FILE.FID, [H.TVF.NTR,H.TVF.NTRC],'uint32')';
1142  H.TVF.TrMtrlSets = fread(H.FILE.FID, [H.TVF.NTR,H.TVF.NTRM],'uint32')';
1143 
1144  H.TVF.Vertices = fread(H.FILE.FID, [3,H.TVF.NV],'float32')';
1145  H.TVF.VColorSets = fread(H.FILE.FID, [H.TVF.NV,H.TVF.NVC],'uint32')';
1146  H.TVF.VNrmlSets = fread(H.FILE.FID, [3,H.TVF.NVN],'float32')';
1147 
1148  fclose(H.FILE.FID);
1149 
1150 
1151 elseif strcmp(H.TYPE,'VTK'),
1152  H.FILE.FID = fopen(H.FileName,'rt','ieee-le');
1153 
1154  H.VTK.version = fgetl(H.FILE.FID);
1155  H.VTK.Title = fgetl(H.FILE.FID);
1156  H.VTK.type = fgetl(H.FILE.FID);
1157 
1158  while ~feof(H.FILE.FID),
1159  tline = fgetl(H.FILE.FID);
1160 
1161  if 0,
1162  elseif strncmp(tline,'CELLS',5);
1163  elseif strncmp(tline,'CELL_DATA',9);
1164  elseif strncmp(tline,'DATASET',7);
1165  H.VTK.DATASET = tline(8:end);
1166  elseif strncmp(tline,'LINES',6);
1167  elseif strncmp(tline,'POINTS',6);
1168  elseif strncmp(tline,'POINT_DATA',10);
1169  elseif strncmp(tline,'POLYGON',7);
1170  elseif strncmp(tline,'SCALARS',7);
1171  [t1,r]=strtok(tline);
1172  [dataName,r]=strtok(r);
1173  [dataType,r]=strtok(r);
1174  [numComp ,r]=strtok(r);
1175  if isempty(numComp), numComp=1;
1176  else numComp = str2double(numComp); end;
1177  tline = fgetl(fid);
1178  if strcmp(tline,'LOOKUP_TABLE');
1179  [t1,r]=strtok(tline);
1180  [tableName,r]=strtok(tline);
1181  else
1182  tline = fgetl(fid);
1183  end;
1184  end;
1185 
1186 
1187  end;
1188  fclose(H.FILE.FID);
1189 
1190  fprintf(H.FILE.stderr,'Warning SOPEN: VTK-format not supported, yet.\n');
1191 
1192 
1193 elseif strcmp(H.TYPE,'unknown')
1194  [p,f,e]=fileparts(H.FileName);
1195  TYPE = upper(e);
1196  if 0,
1197  elseif strcmp(TYPE,'.RAW')
1198  loadraw;
1199  elseif strcmp(TYPE,'.RDT')
1200  [signal] = loadrdt(FILENAME,CHAN);
1201  fs = 128;
1202  elseif strcmp(TYPE,'.XLS')
1203  loadxls;
1204  elseif strcmp(TYPE,'.DA_')
1205  fprintf('Warning SLOAD: Format DA# in testing state and is not supported\n');
1206  loadda_;
1207  elseif strcmp(TYPE,'.RG64')
1208  [signal,H.SampleRate,H.Label,H.PhysDim,H.NS]=loadrg64(FILENAME,CHAN);
1209  %loadrg64;
1210  else
1211  fprintf('Error SLOAD: Unknown Data Format\n');
1212  signal = [];
1213  return;
1214  end;
1215 end;
1216 
1217 end;
1218 
1219 %%%%%%%%%% Post-Processing %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 if strcmp(H.TYPE,'CNT');
1221  f = fullfile(H.FILE.Path, [H.FILE.Name,'.txt']);
1222  if exist(f,'file'),
1223  fid = fopen(f,'r');
1224  tmp = fread(fid,inf,'uint8');
1225  fclose(fid);
1226  [tmp,v] = str2double(char(tmp'));
1227  if ~any(v),
1228  H.Classlabel=tmp(:);
1229  end;
1230  end
1231  f = fullfile(H.FILE.Path, [H.FILE.Name,'.par']);
1232  if exist(f,'file'),
1233  fid = fopen(f,'r');
1234  tmp = fread(fid,inf,'uint8');
1235  fclose(fid);
1236  [tmp,v] = str2double(char(tmp'));
1237  if ~any(v),
1238  H.Classlabel=tmp(:);
1239  end;
1240  end
1241  f = fullfile(H.FILE.Path, [H.FILE.Name,'.mat']);
1242  if exist(f,'file'),
1243  try,
1244  tmp = load(f);
1245  catch
1246  tmp = [];
1247  end
1248  if isfield(tmp,'classlabel') && ~isfield(H,'Classlabel')
1249  H.Classlabel=tmp.classlabel(:);
1250  elseif isfield(tmp,'classlabel') && isfield(tmp,'header') && isfield(tmp.header,'iniFile') && strcmp(tmp.header.iniFile,'oom.ini'), %%% for OOM study only.
1251  H.Classlabel=tmp.classlabel(:);
1252  end;
1253  end;
1254  f = fullfile(H.FILE.Path, [H.FILE.Name,'c.mat']);
1255  if exist(f,'file'),
1256  try,
1257  tmp = load(f);
1258  catch
1259  tmp = [];
1260  end
1261  if isfield(tmp,'classlabel') && ~isfield(H,'Classlabel')
1262  H.Classlabel=tmp.classlabel(:);
1263  end;
1264  end;
1265  f = fullfile(H.FILE.Path, [H.FILE.Name,'_classlabel.mat']);
1266  if exist(f,'file'),
1267  try,
1268  tmp = load(f);
1269  catch
1270  tmp = [];
1271  end
1272  if isfield(tmp,'Classlabel') && (size(tmp.Classlabel,2)==4)
1273  [x,H.Classlabel] = max(tmp.Classlabel,[],2);
1274  end;
1275  if isfield(tmp,'classlabel') && (size(tmp.classlabel,2)==4)
1276  [x,H.Classlabel] = max(tmp.classlabel,[],2);
1277  end;
1278  end;
1279 
1280  f=fullfile(H.FILE.Path,[H.FILE.Name,'.sel']);
1281  if ~exist(f,'file'),
1282  f=fullfile(H.FILE.Path,[H.FILE.Name,'.SEL']);
1283  end
1284  if exist(f,'file'),
1285  fid = fopen(f,'r');
1286  tmp = fread(fid,inf,'uint8');
1287  fclose(fid);
1288  [tmp,v] = str2double(char(tmp'));
1289  if any(isnan(tmp)) || any(tmp~=ceil(tmp)) || any(tmp<0) || (any(tmp==0) && any(tmp>1))
1290  fprintf(2,'Warning SLOAD(CNT): corrupted SEL-file %s\n',f);
1291  else
1292  if ~isfield(H,'Classlabel'),
1293  H.Classlabel = H.EVENT.TYP;
1294  end;
1295  n = length(H.Classlabel);
1296 
1297  H.ArtifactSelection = zeros(n,1);
1298  if all((tmp==0) | (tmp==1)) && (length(tmp)>1) && (sum(diff(sort(tmp))~=0) ~= length(tmp)-1)
1299  H.ArtifactSelection = logical(tmp);
1300  else
1301  H.ArtifactSelection(tmp) = 1;
1302  end;
1303  end;
1304  end;
1305 end;
1306 
1307 if ~isempty(strfind(upper(MODE),'TSD'));
1308  f = fullfile(H.FILE.Path, [H.FILE.Name,'.tsd']);
1309  if ~exist(f,'file'),
1310  fprintf(2,'Warning SLOAD-TSD: file %s.tsd found\n',H.FILE(1).Name,H.FILE(1).Name);
1311  else
1312  fid = fopen(f,'rb');
1313  tsd = fread(fid,inf,'float');
1314  fclose(fid);
1315  nc = size(signal,1)\size(tsd,1);
1316  if (nc == round(nc)),
1317  signal = [signal, reshape(tsd,nc,size(tsd,1)/nc)'];
1318  else
1319  fprintf(2,'Warning SLOAD: size of %s.tsd does not fit to size of %s.bkr\n',H.FILE(1).Name,H.FILE(1).Name);
1320  end;
1321  end;
1322 end;
1323 
1324 
1325 if strcmp(H.TYPE,'GDF')
1326  if isfield(H.EVENT,'TYP')
1327  if isempty(H.EVENT.TYP)
1328  %%%%% if possible, load Reinhold's configuration files
1329  f = fullfile(H.FILE.Path, [H.FILE.Name,'.mat']);
1330  if exist(f,'file'),
1331  try
1332  x = load(f,'header');
1333  catch;
1334  x=[];
1335  end;
1336  if isfield(x,'header'),
1337  if isfield(x.header,'Paradigm')
1338  fprintf(2,'Warning SLOAD (GDF): Obsolete feature is used (header information loaded from MAT-file %s).\n',H.FileName);
1339  fprintf(2,'This feature will be removed in future. Contact <a.schloegl@ieee.org> if you need this.\n ');
1340  H.BCI.Paradigm = x.header.Paradigm;
1341  if isfield(H.BCI.Paradigm,'TriggerTiming');
1342  H.TriggerOffset = H.BCI.Paradigm.TriggerTiming;
1343  elseif isfield(H.BCI.Paradigm,'TriggerOnset');
1344  H.TriggerOffset = H.BCI.Paradigm.TriggerOnset;
1345  end;
1346 
1347  if isfield(H,'Classlabel') && isempty(H.Classlabel),
1348  H.Classlabel = x.header.Paradigm.Classlabel;
1349  end;
1350  end;
1351  end;
1352  end;
1353  end;
1354  end;
1355 
1356  fid=fopen(fullfile(H.FILE.Path,[H.FILE.Name,'.sel']),'r');
1357  if fid<0,
1358  fid=fopen(fullfile(H.FILE.Path,[H.FILE.Name,'.SEL']),'r');
1359  end
1360  if fid>0,
1361  [tmp,c] = fread(fid,[1,inf],'uint8');
1362  fclose(fid);
1363  [tmp,v,sa] = str2double(tmp);
1364  if isempty(sa) || isempty(sa{1})
1365  H.ArtifactSelection = repmat(0,length(H.TRIG),1);
1366  elseif any(isnan(tmp)) || any(tmp~=ceil(tmp)) || any(tmp<0) || (any(tmp==0) && any(tmp>1))
1367  fprintf(2,'Warning SLOAD(GDF): corrupted SEL-file %s\n',fullfile(H.FILE.Path,[H.FILE.Name,'.sel']));
1368  else
1369  H.ArtifactSelection = zeros(length(H.TRIG),1);
1370  if all((tmp==0) | (tmp==1)) && (length(tmp)>1) && (sum(diff(sort(tmp))~=0) ~= length(tmp)-1)
1371  H.ArtifactSelection = logical(tmp);
1372  else
1373  H.ArtifactSelection(tmp) = 1;
1374  end;
1375  end;
1376  end;
1377 end;
1378 
1379 
1380 %%%%% introduce NaNs between segments %%%%%%%
1381 if STATE.FLAG_NUM_NAN,
1382  %% NaN's between segments/sweeps are introduced, but only when argument NUMBER_OF_NAN_IN_BREAK is explicitely defined in the list of input arguments
1383  winlen = STATE.NUMBER_OF_NAN_IN_BREAK;
1384  ix = [1; H.EVENT.POS(H.EVENT.TYP==hex2dec('7ffe')); size(signal,1)+1];
1385  n = length(ix) - 1;
1386  signal = [signal; repmat(NaN, (n-1)*winlen, size(signal, 2))];
1387  for k = n:-1:1,
1388  H.EVENT.POS(H.EVENT.POS >= ix(k+1)) = H.EVENT.POS(H.EVENT.POS >= ix(k+1) ) + winlen;
1389  signal([ix(k) : ix(k+1) - 1] + (k-1) * winlen, :) = signal(ix(k) : ix(k+1) - 1,:);
1390  if k>1,
1391  signal(ix(k) + (k-1) * winlen + [-winlen:-1], :) = NaN;
1392  end;
1393  end;
1394  if H.SPR * H.NRec ~= size(signal,1),
1395  H.SPR = H.SPR + winlen * (n - 1);
1396  end;
1397 
1398  if ~STATE.FLAG_NUM_NAN && (H.SPR * H.NRec ~= size(signal,1))
1399  warning('Undefined state: HDR.SPR*HDR.NRec does not match size of data - if you see this message contact <alois.schloegl@gmail.com> and provide the details %s', HDR.FileName);
1400  end;
1401  % [HDR.SPR, HDR.NRec, size(signal)]
1402 end;
1403 
1404 
1405 %%%%% Resampling %%%%%
1406 if ~isnan(Fs) && (H.SampleRate~=Fs);
1407  tmp = ~mod(H.SampleRate,Fs) || ~mod(Fs,H.SampleRate);
1408  tmp2= ~mod(H.SampleRate,Fs*2.56);
1409  if tmp,
1410  signal = rs(signal,H.SampleRate,Fs);
1411  H.EVENT.POS = H.EVENT.POS/H.SampleRate*Fs;
1412  if isfield(H.EVENT,'DUR');
1413  H.EVENT.DUR = H.EVENT.DUR/H.SampleRate*Fs;
1414  end;
1415  if isfield(H,'TRIG');
1416  H.TRIG = H.TRIG/H.SampleRate*Fs;
1417  end;
1418  H.SampleRate = Fs;
1419  elseif tmp2,
1420  x = load('resample_matrix.mat');
1421  signal = rs(signal,x.T256100);
1422  if H.SampleRate*100~=Fs*256,
1423  signal = rs(signal,H.SampleRate/(Fs*2.56),1);
1424  end;
1425  H.EVENT.POS = H.EVENT.POS/H.SampleRate*Fs;
1426  if isfield(H.EVENT,'DUR');
1427  H.EVENT.DUR = H.EVENT.DUR/H.SampleRate*Fs;
1428  end;
1429  if isfield(H,'TRIG');
1430  H.TRIG = H.TRIG/H.SampleRate*Fs;
1431  end;
1432  H.SampleRate = Fs;
1433  else
1434  fprintf(2,'Warning SLOAD: resampling %f Hz to %f Hz not implemented.\n',H.SampleRate,Fs);
1435  end;
1436 end;
1437 
1438 return;
1439 ratiomissing = mean(isnan(signal));
1440 if any(ratiomissing>.1)
1441  fprintf(2,'Warning SLOAD: ratio of missing samples exceeds 10%% in file %s.\n',H.FileName);
1442  ix = find(ratiomissing);
1443  fprintf(1,'#%3i: %4.1f%%\n',[ix;ratiomissing(ix)*100])
1444 end;
1445 
gettrigger
function gettrigger(in s, in TH, in rfp)
sclose
function sclose(in HDR)
bv2biosig_events
function bv2biosig_events(in EVENT)
gdfdatatype
function gdfdatatype(in GDFTYP)
sload
function sload(in FILENAME, in varargin)
iread
function iread(in HDR, in CHAN, in StartPos)
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)
getfiletype
function getfiletype(in arg1)
seof
function seof(in HDR)
stell
function stell(in HDR)
leadidcodexyz
function leadidcodexyz(in arg1)
sread
function sread(in HDR, in NoS, in StartPos)
iopen
function iopen(in HDR, in PERMISSION, in CHAN, in MODE, in arg5, in arg6)