TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
bkropen.m
Go to the documentation of this file.
1 function [BKR,s]=bkropen(arg1,arg3,arg4,arg5,arg6)
2 % BKROPEN opens BKR file
3 % However, it is recommended to use SOPEN instead .
4 % For loading whole data files, use SLOAD.
5 %
6 % see also: SOPEN, SREAD, SSEEK, STELL, SCLOSE, SWRITE, SEOF
7 
8 % $Id: bkropen.m 2205 2009-10-27 12:18:15Z schloegl $
9 % Copyright (c) 1997-2008 by Alois Schloegl <a.schloegl@ieee.org>
10 % This is part of the BIOSIG-toolbox http://biosig.sf.net/
11 
12 % This program is free software; you can redistribute it and/or
13 % modify it under the terms of the GNU General Public License
14 % as published by the Free Software Foundation; either version 3
15 % of the License, or (at your option) any later version.
16 
17 if isstruct(arg1),
18  BKR=arg1;
19  FILENAME=BKR.FileName;
20  if BKR.FILE.OPEN,
21  fseek(BKR.FILE.FID,0,'bof');
22  else
23  BKR.FILE.FID = fopen(FILENAME,BKR.FILE.PERMISSION,'ieee-le');
24  end;
25 else
26  FILENAME=arg1;
27  BKR.FILE.FID = fopen(FILENAME,BKR.FILE.PERMISSION,'ieee-le');
28  BKR.FileName = FILENAME;
29  [pfad,file,FileExt] = fileparts(BKR.FileName);
30  BKR.FILE.Name = file;
31  BKR.FILE.Path = pfad;
32  BKR.FILE.Ext = FileExt(2:length(FileExt));
33 end;
34 if BKR.FILE.FID<0,
35  fprintf(2,'Error BKROPEN: file %s not found.\n',FILENAME);
36  return;
37 end;
38 if ftell(BKR.FILE.FID)~=0, %
39  fprintf(2,'Error: Fileposition is not 0\n');
40 end;
41 
42 BOOL ='int16';
43 ULONG='uint32';
44 FLOAT='float32';
45 
46 if any(BKR.FILE.PERMISSION=='r'),
47  BKR.FILE.OPEN = 1;
48  fid = BKR.FILE.FID;
49  %%%%% READ HEADER
50 
51  %VARIABLE TYPE #bytes OFFSET COMMENT
52  BKR.VERSION = fread(fid,1,'uint16'); % 2 Byte 0 Versionsnummer
53  if ((BKR.VERSION<=200) | (BKR.VERSION>207)) fprintf(2,'LOADBKR: WARNING Version BKR Format %i',BKR.VERSION); end;
54  BKR.NS = fread(fid,1,'uint16'); % 2 Byte 2 Anzahl der Kanäle
55  BKR.SampleRate = fread(fid,1,'uint16'); % 2 Byte 4 Abtastfrequenz
56  BKR.NRec = fread(fid,1,'uint32'); % 4 Byte 6 Anzahl der Trials
57  BKR.SPR = fread(fid,1,'uint32'); % 4 Byte 10 Anzahl Samples per Trial
58  BKR.PhysMax(1:BKR.NS) = fread(fid,1,'uint16'); % 2 Byte 14 Kalibrierspannung
59  BKR.DigMax(1:BKR.NS) = fread(fid,1,'uint16'); % 2 Byte 16 Kalibrierwert
60  Label = fread(fid,[1,4],'uint8'); % 4 Byte 18 Elektrodencode
61  BKR.Label = repmat({char(Label)},BKR.NS,1);
62  BKR.Filter.LowPass = fread(fid,1, FLOAT); % 4 Byte 22 untere Eckfrequenz
63  BKR.Filter.HighPass = fread(fid,1, FLOAT); % 4 Byte 26 obere Eckfrequenz
64  BKR.BKR.sref=fread(fid,1, ULONG); % 4 Byte 30 Startzeitpunkt Referenz in Samples
65  BKR.BKR.eref=fread(fid,1, ULONG); % 4 Byte 34 Länge Referenz in Samples
66  BKR.BKR.sact=fread(fid,1, ULONG); % 4 Byte 38 Startzeitpunkt Aktion in Samples
67  BKR.BKR.eact=fread(fid,1, ULONG); % 4 Byte 42 Länge Aktion in Samples
68  BKR.FLAG.TRIGGERED = fread(fid,1,BOOL); % 2 Byte 46 flag für Trigger
69  BKR.BKR.pre=fread(fid,1, ULONG); % 4 Byte 48 Anzahl der Sampels vor dem Trigger
70  BKR.BKR.pst=fread(fid,1, ULONG); % 4 Byte 52 Anzahl der Sampels nach dem Trigger
71  BKR.BKR.hav=fread(fid,1,BOOL); % 2 Byte 56 flag für "horizontale" Mittelung
72  BKR.BKR.nah=fread(fid,1, ULONG); % 4 Byte 58 Anzahl der gemittelten Trials
73  BKR.BKR.vav=fread(fid,1,BOOL); % 2 Byte 62 flag für "vertikale" Mittelung
74  BKR.BKR.nav=fread(fid,1,'uint16'); % 2 Byte 64 Anzahl der gemittelten Kanäle
75  BKR.BKR.cav=fread(fid,1,BOOL); % 2 Byte 66 flag für Datenkomprimierung
76  BKR.BKR.nac=fread(fid,1, ULONG); % 4 Byte 68 Anzahl der gemittelten Samples
77  BKR.FLAG.ref=fread(fid,4,BOOL); % 2 Byte 72 flag: Common Average Reference
78  % loc=fread(fid,1,BOOL); % 2 Byte 74 flag: Local Average Reference
79  % lap=fread(fid,1,BOOL); % 2 Byte 76 flag: Laplace Berechnung
80  % wgt=fread(fid,1,BOOL); % 2 Byte 78 flag: Weighted Average Reference
81  BKR.BKR.pwr=fread(fid,1,BOOL); % 2 Byte 80 flag: Leistung
82  BKR.BKR.avr=fread(fid,1,BOOL); % 2 Byte 82 flag: Mittelwert
83  BKR.BKR.std=fread(fid,1,BOOL); % 2 Byte 84 flag: Streuung
84  BKR.BKR.bps=fread(fid,1,BOOL); % 2 Byte 86 flag: Bandpaß BKR.BKR.erd=fread(fid,1,BOOL); % 2 Byte 88 flag: ERD BKR.BKR.sig=fread(fid,1,BOOL); % 2 Byte 90 flag: Signifikanz BKR.BKR.coh=fread(fid,1,BOOL); % 2 Byte 92 flag: Kohärenz BKR.BKR.spc=fread(fid,1,BOOL); % 2 Byte 94 flag: Spectrum BKR.BKR.conf=fread(fid,1, FLOAT); % 4 Byte 96 Konfidenz BKR.BKR.csp=fread(fid,1,BOOL); % 2 Byte 100 flag: Kohärenz Leistungsspektrum BKR.BKR.erc=fread(fid,1,BOOL); % 2 Byte 102 flag: ERC BKR.BKR.ham=fread(fid,1,BOOL); % 2 Byte 104 flag: Hanning smoothed BKR.BKR.ann=fread(fid,1,BOOL); % 2 Byte 106 flag: art. Neuronal. NW. Filter (ANN) niu=fread(fid,1,'uint16'); % 2 Byte 108 ANN: Anzahl input units nhu=fread(fid,1,'uint16'); % 2 Byte 110 ANN: Anzahl hidden units nlc=fread(fid,1, ULONG); % 4 Byte 112 ANN: Anzahl Lernzyklen reg=fread(fid,1, FLOAT); % 4 Byte 116 ANN: regression lco=fread(fid,1, FLOAT); % 4 Byte 120 ANN: Lernkoeffizient epo=fread(fid,1,'uint16'); % 2 Byte 124 ANN: Epoche BKR.BKR.rel=fread(fid,1,BOOL); % 2 Byte 126 flag: ERC in Relativwerten wnd=fread(fid,1,'uint16'); % 2 Byte 128 Fenstertyp BKR.BKR.kal=fread(fid,1,BOOL); % 2 Byte 130 flag: Kalman gefilterte Daten BKR.BKR.cwt=fread(fid,1,BOOL); % 2 Byte 132 flag: kont. Wavelet transformtiert cwt_fmin=fread(fid,1, FLOAT); % 4 Byte 134 unterste Frequenz, kont. Wavelettransform. cwt_fmax=fread(fid,1, FLOAT); % 4 Byte 138 oberste Frequenz, kont. Wavelettransform. scales=fread(fid,1,'uint16'); % 2 Byte 142 Anzahl Frequenzbänder für kont. WT cwt_fe=fread(fid,1, FLOAT); % 4 Byte 144 frequ. für Dt = Df = 1/2Öp cwt_start=fread(fid,1, ULONG); % 4 Byte 148 Startsample für kont. WT Berechnung %-- NULL -- ------------- -------- 152 -- Offset bis 512 Byte -- if 1, fread(fid,1024-152,'uint8'); else fread(fid,512-152,'uint8'); for i=1:BKR.NS, eletyp(i)=fread(fid,1,'uchar'); % 1 Byte 512 Elektrode 1: Signalart (z.B: EEG) elenum(i)=fread(fid,1,'uchar'); % 1 Byte 513 Elektrode 1: Kanalnr. für gleiche Signalart ref(i)=fread(fid,1, FLOAT); % 4 Byte 514 Referenzwert für Kanal 1 end; if BKR.NS>85, fprintf(2,'Warning BKRLOAD: Number of channels larger than 85; Header does not support more\n'); end; fseek(fid,512-(BKR.NS*6),'cof'); end; BKR.HeadLen = ftell(fid); if BKR.HeadLen~=1024, fprintf(2,'Warning BKRLOAD: Length of Header does not confirm BKR-specification\n'); end; %BKR.HeadLen = 1024; %%%%% Generate BKR-Struct according to biosig/doc/header.txt BKR.Dur=1/BKR.SampleRate; BKR.DigMin = -BKR.DigMax; BKR.PhysMin= -BKR.PhysMax; BKR.Cal=BKR.PhysMax./BKR.DigMax; BKR.Off=zeros(BKR.NS,1); BKR.Calib = sparse(2:BKR.NS+1,1:BKR.NS,BKR.Cal,BKR.NS+1,BKR.NS); %BKR.PhysDim = repmat({'µV'},BKR.NS,1); BKR.PhysDimCode = repmat(4275,BKR.NS,1); % uV tmp=sprintf('LowPass %4.1f Hz; HighPass %4.1f Hz; Notch ?',BKR.Filter.LowPass,BKR.Filter.HighPass); BKR.PreFilt=tmp; %ones(BKR.NS,1)*[tmp 32+zeros(1,80-length(tmp))]; BKR.Filter.Notch = nan; %h.notchfilter; BKR.AS.startrec = 0; BKR.AS.numrec = 0; BKR.AS.bpb = BKR.NS*2; % Bytes per Block BKR.AS.spb = BKR.NS; % Samples per Block BKR.FILE.POS = 0; if ~BKR.FLAG.TRIGGERED & (BKR.NRec>1); fprintf(BKR.FILE.stderr,'Warning: TriggerFlag in file %s was not set.\n',BKR.FileName); BKR.FLAG.TRIGGERED = 1; end; BKR.FLAG.REFERENCE = 'unknown'; if BKR.FLAG.ref(1), BKR.FLAG.REFERENCE = 'COM'; end; if BKR.FLAG.ref(2), BKR.FLAG.REFERENCE = 'LOC'; end; if BKR.FLAG.ref(3), BKR.FLAG.REFERENCE = 'LAP'; end; if BKR.FLAG.ref(4), BKR.FLAG.REFERENCE = 'WGT'; end; % THRESHOLD for Overflow detection BKR.AS.endpos = (BKR.FILE.size-BKR.HeadLen)/BKR.AS.bpb; BKR.data = fread(fid,[BKR.NS,inf],'int16')'; fclose(fid); BKR.TYPE = 'native'; % check whether Headerinfo fits to file length. if (BKR.FILE.size-BKR.HeadLen)~=BKR.SPR*BKR.NRec*BKR.NS*2, %[BKR.FILE.size,BKR.HeadLen,BKR.SPR,BKR.NRec,BKR.NS], %[BKR.FILE.size-BKR.HeadLen-BKR.SPR*BKR.NRec*BKR.NS*2], fprintf(2,'Warning BKROPEN: Header information in %s corrupted;',BKR.FileName); if BKR.NRec==1, fprintf(2,'Data could be reconstructed.\n',BKR.FileName); BKR.SPR=(BKR.FILE.size-BKR.HeadLen)/(BKR.NRec*BKR.NS*2); elseif BKR.NRec==0, fprintf(2,'Data could be reconstructed.\n',BKR.FileName); BKR.NRec=(BKR.FILE.size-BKR.HeadLen)/(BKR.SPR*BKR.NS*2); end; if (BKR.FILE.size-BKR.HeadLen)~=BKR.SPR*BKR.NRec*BKR.NS*2, fprintf(2,'Unable to reconstruct data.\n',BKR.FileName); end; end; % look for Classlabel information if ~isfield(BKR,'Classlabel'), BKR.Classlabel = []; end; if ~isfield(BKR,'TRIG'), BKR.TRIG = []; end; tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.mat']); if ~exist(tmp,'file'), tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.MAT']); end x = []; if exist(tmp,'file'), x = load('-mat',tmp); end; if isfield(x,'header'), BKR.MAT = x.header; if isfield(x.header,'Setup'), if isfield(x.header.Setup,'Bits'), BKR.Bits = x.header.Setup.Bits; [datatyp, limits, datatypes] = gdfdatatype(BKR.Bits+255); % THRESHOLD for Overflow detection if ~isfield(BKR,'THRESHOLD') BKR.THRESHOLD = repmat(limits, BKR.NS, 1); end; end; end; if isfield(x.header,'Result') & isfield(x.header.Result,'Classlabel'), BKR.Classlabel = x.header.Result.Classlabel; end; if isfield(x.header,'Paradigm') if isempty(BKR.Classlabel) & isfield(x.header.Paradigm,'Classlabel') BKR.Classlabel = x.header.Paradigm.Classlabel; end; BKR.BCI.Paradigm = x.header.Paradigm; if isfield(BKR.BCI.Paradigm,'TriggerOnset'); BKR.TriggerOffset = BKR.BCI.Paradigm.TriggerOnset; elseif isfield(BKR.BCI.Paradigm,'TriggerTiming'); % BKR.BCI.Paradigm.TriggerTiming, BKR.TriggerOffset = BKR.BCI.Paradigm.TriggerTiming; fprintf(2,'Warning BKROPEN: Paradigm.TriggerOnset is unknown. Paradigm.TriggerTiming= %f ms is used instead\n',BKR.TriggerOffset); end; end; if isfield(x.header,'PhysioRec'), % R. Leeb's data BKR.Label = x.header.PhysioRec; end; if isfield(x.header,'BKRHeader'), % R. Scherer Data if isfield(x.header.BKRHeader,'TO'), BKR.T0 = x.header.BKRHeader.TO; end; if isfield(x.header.BKRHeader,'Label'), BKR.Label = x.header.BKRHeader.Label; ns = BKR.NS-size(BKR.Label,1); if ns == 1; BKR.Label = strvcat(BKR.Label,'TRIGGER'); elseif ns > 1; BKR.Label = strvcat(BKR.Label,char(repmat('n.a.',ns,1))); end; end; end; if isfield(x.header,'Model'), % More if isfield(x.header.Model,'AnalogInput'), for k = 1:length(x.header.Model.AnalogInput), BKR.Filter.HighPass(k) = x.header.Model.AnalogInput{k}{5}; BKR.Filter.LowPass(k) = x.header.Model.AnalogInput{k}{6}; BKR.Filter.Notch(k) = strcmpi(x.header.Model.AnalogInput{k}{7},'on'); BKR.MAT.Cal(k) = x.header.Model.AnalogInput{k}{3}; end end; end; if ~isempty(strmatch('TRIGGER',BKR.Label)) BKR.AS.TRIGCHAN = BKR.NS; %strmatch('TRIGGER',H.Label); end; end; if 1; %~isfield(BKR,'Classlabel'), tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.par']); if ~exist(tmp,'file'), tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.PAR']); end if exist(tmp,'file'), BKR.Classlabel = load(tmp); end; end; %%% Artifact Selection files tmp1=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.sel']); if ~exist(tmp1,'file'), tmp1=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.SEL']); end tmp2 = fullfile(BKR.FILE.Path,[BKR.FILE.Name,'_artifact.mat']); SW = (exist(tmp1,'file')>0) + 2*(exist(tmp2,'file')>0); if SW == 0, elseif SW == 1, if exist('OCTAVE_VERSION')>5 BKR.ArtifactSelection = load('-ascii',tmp1); else BKR.ArtifactSelection = load(tmp1); end; elseif SW == 2, if exist('OCTAVE_VERSION')>5 tmp = load('-mat',tmp2); else tmp = load(tmp2); end; BKR.ArtifactSelection = tmp.artifact(:); elseif SW == 3, fprintf(BKR.FILE.stderr,'Warning BKROPEN: more than one ArtifactSelection files. File %s is used.\n',tmp1); if exist('OCTAVE_VERSION')>5 BKR.ArtifactSelection = load('-ascii',tmp1); else BKR.ArtifactSelection = load(tmp1); end; end; if isfield(BKR,'ArtifactSelection'), if any(BKR.ArtifactSelection>1) | (length(BKR.ArtifactSelection)<length(BKR.Classlabel)) sel = zeros(size(BKR.Classlabel)); sel(BKR.ArtifactSelection) = 1; BKR.ArtifactSelection = sel(:); end; BKR.ArtifactSelection = BKR.ArtifactSelection(:); end; if isfield(BKR.AS,'TRIGCHAN') % & isempty(BKR.EVENT.POS) if BKR.AS.TRIGCHAN <= BKR.NS, %size(BKR.data,2), BKR.THRESHOLD(BKR.AS.TRIGCHAN,1:2) = [-1-2^15,2^15]; % do not apply overflow detection for Trigger channel TRIGon = gettrigger(double(BKR.data(:,BKR.AS.TRIGCHAN))); %TRIGoff = gettrigger(-double(BKR.data(:,BKR.AS.TRIGCHAN))); if isfield(BKR,'TriggerOffset') TRIGon = TRIGon - round(BKR.TriggerOffset/1000*BKR.SampleRate); % TRIGoff = TRIGoff - round(BKR.TriggerOffset/1000*BKR.SampleRate); end; end; BKR.TRIG = TRIGon(:); BKR.EVENT.POS = TRIGon(:); %[TRIGon(:); TRIGoff(:)]; BKR.EVENT.TYP = repmat(hex2dec('0300'),numel(TRIGon),1); %repmat(hex2dec('8300'),numel(TRIGoff),1)]; end; if length(BKR.TRIG)~=length(BKR.Classlabel), % hack to deal with BCI22 data fprintf(2,'Warning BKROPEN: Number of triggers (%i) and number of Classlabels (%i) do not fit\n',length(BKR.TRIG),length(BKR.Classlabel)); BKR.TRIG = []; BKR.Classlabel = []; BKR.ArtifactSelection = []; end; elseif any(BKR.FILE.PERMISSION=='w'), BKR.FILE.OPEN = 2; BKR.VERSION = 207; BKR.TYPE = 'BKR'; if ~strcmpi(BKR.FILE.Ext,'BKR'), fprintf(2,'Warning BKROPEN-WRITE: file extionsion is not BKR.\n'); end; if ~isfield(BKR,'SampleRate'), fprintf(2,'Error BKROPEN-WRITE: BKR.SampleRate not defined.\n'); return; end; if ~isfield(BKR,'NS'), BKR.NS = 0; % unknown channel number ... end; if ~isfield(BKR,'SPR'), BKR.SPR = 0; % Unknown - Value will be fixed when file is closed. end; if isfield(BKR,'NRec'), BKR.FLAG.TRIGGERED = BKR.NRec>1; else BKR.NRec = -1; % Unknown - Value will be fixed when file is closed. end; if ~isfield(BKR,'PhysMax'), BKR.PhysMax = NaN; end; if isempty(BKR.PhysMax), BKR.PhysMax = NaN; end; if ~isfield(BKR,'DigMax'), BKR.DigMax = NaN; end; if isnan(BKR.DigMax) | isempty(BKR.DigMax), BKR.DigMax = 2^15-1; end; if any([BKR.NS==0,BKR.SPR==0,BKR.NRec<0,isnan([BKR.NRec,BKR.NS,BKR.SPR,BKR.DigMax,BKR.PhysMax,BKR.SampleRate])]), % if any unknown, ... BKR.FILE.OPEN = 3; % ... fix header when file is closed. end; if ~isfield(BKR,'FLAG'), BKR.FLAG.UCAL = 0; elseif ~isfield(BKR.FLAG,'UCAL'), BKR.FLAG.UCAL = 0; end; tmp = round(BKR.PhysMax); fprintf(1,'Scaling error in file %s due to rounding of PhysMax is in the range of %f%%.\n',BKR.FileName, abs((BKR.PhysMax-tmp)/tmp)*100); BKR.PhysMax = tmp; count=fwrite(BKR.FILE.FID,BKR.VERSION,'short'); % version number of header count=fwrite(BKR.FILE.FID,BKR.NS,'short'); % number of channels count=fwrite(BKR.FILE.FID,BKR.SampleRate,'short'); % sampling rate count=fwrite(BKR.FILE.FID,BKR.NRec,'int32'); % number of trials: 1 for untriggered data count=fwrite(BKR.FILE.FID,BKR.SPR,'uint32'); % samples/trial/channel count=fwrite(BKR.FILE.FID,BKR.PhysMax,'short'); % Kalibrierspannung count=fwrite(BKR.FILE.FID,BKR.DigMax, 'short'); % Kalibrierwert count=fwrite(BKR.FILE.FID,zeros(4,1),'uint8'); if isfield(BKR,'Filter'), if ~isfield(BKR.Filter,'LowPass'), BKR.Filter.LowPass = NaN; end; if ~isfield(BKR.Filter,'HighPass'), BKR.Filter.HighPass= NaN; end; else BKR.Filter.LowPass =NaN; BKR.Filter.HighPass=NaN; end; if all(BKR.Filter.LowPass(1)==BKR.Filter.LowPass) BKR.Filter.LowPass = BKR.Filter.LowPass(1); else BKR.Filter.LowPass = NaN; end; if all(BKR.Filter.HighPass(1)==BKR.Filter.HighPass) BKR.Filter.HighPass = BKR.Filter.HighPass(1); else BKR.Filter.HighPass = NaN; end; count=fwrite(BKR.FILE.FID,[BKR.Filter.LowPass,BKR.Filter.HighPass],'float'); count=fwrite(BKR.FILE.FID,zeros(16,1),'uint8'); % offset 30 count=fwrite(BKR.FILE.FID,BKR.FLAG.TRIGGERED,'int16'); % offset 32 count=fwrite(BKR.FILE.FID,zeros(24,1),'uint8'); % offset 46 if ~isfield(BKR,'FLAG') BKR.FLAG.REFERENCE=''; end; if ~isfield(BKR.FLAG,'REFERENCE') BKR.FLAG.REFERENCE=''; end; tmp = [strcmp(BKR.FLAG.REFERENCE,'COM')|strcmp(BKR.FLAG.REFERENCE,'CAR'), strcmp(BKR.FLAG.REFERENCE,'LOC')|strcmp(BKR.FLAG.REFERENCE,'LAR'), strcmp(BKR.FLAG.REFERENCE,'LAP'), strcmp(BKR.FLAG.REFERENCE,'WGT')]; fwrite(BKR.FILE.FID,tmp,BOOL); % offset 72 + 4*BOOL %speichert den rest des BKR-headers count = fwrite(BKR.FILE.FID,zeros(1024-80,1),'uint8'); BKR.HeadLen = ftell(BKR.FILE.FID); if BKR.HeadLen~=1024, fprintf(2,'Error BKROPEN WRITE: HeaderLength is not 1024 but %i\n',BKR.HeadLen); end; BKR.FILE.POS = 0; BKR.AS.endpos = 0; BKR.AS.bpb = BKR.NS*2; % Bytes per Block BKR.AS.spb = BKR.NS; % Samples per Block if isfield(BKR,'Classlabel'); fid = fopen(fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.par']),'w+b'); % force binary mode fprintf(fid,'%i\r\n',BKR.Classlabel); % explicit 0x0d and 0x0a fclose(fid); end; if isfield(BKR,'ArtifactSelection'); fid = fopen(fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.sel']),'w+b'); % force binary mode fprintf(fid,'%i\r\n',BKR.ArtifactSelection); % explicit 0x0d and 0x0a fclose(fid); end; end;
85  BKR.BKR.erd=fread(fid,1,BOOL); % 2 Byte 88 flag: ERD
86  BKR.BKR.sig=fread(fid,1,BOOL); % 2 Byte 90 flag: Signifikanz
87  BKR.BKR.coh=fread(fid,1,BOOL); % 2 Byte 92 flag: Kohärenz
88  BKR.BKR.spc=fread(fid,1,BOOL); % 2 Byte 94 flag: Spectrum
89  BKR.BKR.conf=fread(fid,1, FLOAT); % 4 Byte 96 Konfidenz
90  BKR.BKR.csp=fread(fid,1,BOOL); % 2 Byte 100 flag: Kohärenz Leistungsspektrum
91  BKR.BKR.erc=fread(fid,1,BOOL); % 2 Byte 102 flag: ERC
92  BKR.BKR.ham=fread(fid,1,BOOL); % 2 Byte 104 flag: Hanning smoothed
93  BKR.BKR.ann=fread(fid,1,BOOL); % 2 Byte 106 flag: art. Neuronal. NW. Filter (ANN)
94  niu=fread(fid,1,'uint16'); % 2 Byte 108 ANN: Anzahl input units
95  nhu=fread(fid,1,'uint16'); % 2 Byte 110 ANN: Anzahl hidden units
96  nlc=fread(fid,1, ULONG); % 4 Byte 112 ANN: Anzahl Lernzyklen
97  reg=fread(fid,1, FLOAT); % 4 Byte 116 ANN: regression
98  lco=fread(fid,1, FLOAT); % 4 Byte 120 ANN: Lernkoeffizient
99  epo=fread(fid,1,'uint16'); % 2 Byte 124 ANN: Epoche
100  BKR.BKR.rel=fread(fid,1,BOOL); % 2 Byte 126 flag: ERC in Relativwerten
101  wnd=fread(fid,1,'uint16'); % 2 Byte 128 Fenstertyp
102  BKR.BKR.kal=fread(fid,1,BOOL); % 2 Byte 130 flag: Kalman gefilterte Daten
103  BKR.BKR.cwt=fread(fid,1,BOOL); % 2 Byte 132 flag: kont. Wavelet transformtiert
104  cwt_fmin=fread(fid,1, FLOAT); % 4 Byte 134 unterste Frequenz, kont. Wavelettransform.
105  cwt_fmax=fread(fid,1, FLOAT); % 4 Byte 138 oberste Frequenz, kont. Wavelettransform.
106  scales=fread(fid,1,'uint16'); % 2 Byte 142 Anzahl Frequenzbänder für kont. WT
107  cwt_fe=fread(fid,1, FLOAT); % 4 Byte 144 frequ. für Dt = Df = 1/2Öp
108  cwt_start=fread(fid,1, ULONG); % 4 Byte 148 Startsample für kont. WT Berechnung
109  %-- NULL -- ------------- -------- 152 -- Offset bis 512 Byte --
110  if 1,
111  fread(fid,1024-152,'uint8');
112  else
113  fread(fid,512-152,'uint8');
114  for i=1:BKR.NS,
115  eletyp(i)=fread(fid,1,'uchar'); % 1 Byte 512 Elektrode 1: Signalart (z.B: EEG)
116  elenum(i)=fread(fid,1,'uchar'); % 1 Byte 513 Elektrode 1: Kanalnr. für gleiche Signalart
117  ref(i)=fread(fid,1, FLOAT); % 4 Byte 514 Referenzwert für Kanal 1
118  end;
119  if BKR.NS>85,
120  fprintf(2,'Warning BKRLOAD: Number of channels larger than 85; Header does not support more\n');
121  end;
122  fseek(fid,512-(BKR.NS*6),'cof');
123  end;
124  BKR.HeadLen = ftell(fid);
125  if BKR.HeadLen~=1024,
126  fprintf(2,'Warning BKRLOAD: Length of Header does not confirm BKR-specification\n');
127  end;
128  %BKR.HeadLen = 1024;
129 
130  %%%%% Generate BKR-Struct according to biosig/doc/header.txt
131  BKR.Dur=1/BKR.SampleRate;
132  BKR.DigMin = -BKR.DigMax;
133  BKR.PhysMin= -BKR.PhysMax;
134  BKR.Cal=BKR.PhysMax./BKR.DigMax;
135  BKR.Off=zeros(BKR.NS,1);
136  BKR.Calib = sparse(2:BKR.NS+1,1:BKR.NS,BKR.Cal,BKR.NS+1,BKR.NS);
137  %BKR.PhysDim = repmat({'µV'},BKR.NS,1);
138  BKR.PhysDimCode = repmat(4275,BKR.NS,1); % uV
139  tmp=sprintf('LowPass %4.1f Hz; HighPass %4.1f Hz; Notch ?',BKR.Filter.LowPass,BKR.Filter.HighPass);
140  BKR.PreFilt=tmp; %ones(BKR.NS,1)*[tmp 32+zeros(1,80-length(tmp))];
141  BKR.Filter.Notch = nan; %h.notchfilter;
142 
143  BKR.AS.startrec = 0;
144  BKR.AS.numrec = 0;
145  BKR.AS.bpb = BKR.NS*2; % Bytes per Block
146  BKR.AS.spb = BKR.NS; % Samples per Block
147  BKR.FILE.POS = 0;
148 
149  if ~BKR.FLAG.TRIGGERED & (BKR.NRec>1);
150  fprintf(BKR.FILE.stderr,'Warning: TriggerFlag in file %s was not set.\n',BKR.FileName);
151  BKR.FLAG.TRIGGERED = 1;
152  end;
153  BKR.FLAG.REFERENCE = 'unknown';
154  if BKR.FLAG.ref(1), BKR.FLAG.REFERENCE = 'COM'; end;
155  if BKR.FLAG.ref(2), BKR.FLAG.REFERENCE = 'LOC'; end;
156  if BKR.FLAG.ref(3), BKR.FLAG.REFERENCE = 'LAP'; end;
157  if BKR.FLAG.ref(4), BKR.FLAG.REFERENCE = 'WGT'; end;
158 
159  % THRESHOLD for Overflow detection
160  BKR.AS.endpos = (BKR.FILE.size-BKR.HeadLen)/BKR.AS.bpb;
161 
162  BKR.data = fread(fid,[BKR.NS,inf],'int16')';
163  fclose(fid);
164  BKR.TYPE = 'native';
165 
166  % check whether Headerinfo fits to file length.
167  if (BKR.FILE.size-BKR.HeadLen)~=BKR.SPR*BKR.NRec*BKR.NS*2,
168  %[BKR.FILE.size,BKR.HeadLen,BKR.SPR,BKR.NRec,BKR.NS],
169  %[BKR.FILE.size-BKR.HeadLen-BKR.SPR*BKR.NRec*BKR.NS*2],
170  fprintf(2,'Warning BKROPEN: Header information in %s corrupted;',BKR.FileName);
171  if BKR.NRec==1,
172  fprintf(2,'Data could be reconstructed.\n',BKR.FileName);
173  BKR.SPR=(BKR.FILE.size-BKR.HeadLen)/(BKR.NRec*BKR.NS*2);
174  elseif BKR.NRec==0,
175  fprintf(2,'Data could be reconstructed.\n',BKR.FileName);
176  BKR.NRec=(BKR.FILE.size-BKR.HeadLen)/(BKR.SPR*BKR.NS*2);
177  end;
178  if (BKR.FILE.size-BKR.HeadLen)~=BKR.SPR*BKR.NRec*BKR.NS*2,
179  fprintf(2,'Unable to reconstruct data.\n',BKR.FileName);
180  end;
181  end;
182 
183  % look for Classlabel information
184  if ~isfield(BKR,'Classlabel'),
185  BKR.Classlabel = [];
186  end;
187  if ~isfield(BKR,'TRIG'),
188  BKR.TRIG = [];
189  end;
190  tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.mat']);
191  if ~exist(tmp,'file'),
192  tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.MAT']);
193  end
194  x = [];
195  if exist(tmp,'file'),
196  x = load('-mat',tmp);
197  end;
198  if isfield(x,'header'),
199  BKR.MAT = x.header;
200  if isfield(x.header,'Setup'),
201  if isfield(x.header.Setup,'Bits'),
202  BKR.Bits = x.header.Setup.Bits;
203  [datatyp, limits, datatypes] = gdfdatatype(BKR.Bits+255);
204  % THRESHOLD for Overflow detection
205  if ~isfield(BKR,'THRESHOLD')
206  BKR.THRESHOLD = repmat(limits, BKR.NS, 1);
207  end;
208  end;
209  end;
210  if isfield(x.header,'Result') & isfield(x.header.Result,'Classlabel'),
211  BKR.Classlabel = x.header.Result.Classlabel;
212  end;
213  if isfield(x.header,'Paradigm')
214  if isempty(BKR.Classlabel) & isfield(x.header.Paradigm,'Classlabel')
215  BKR.Classlabel = x.header.Paradigm.Classlabel;
216  end;
217  BKR.BCI.Paradigm = x.header.Paradigm;
218  if isfield(BKR.BCI.Paradigm,'TriggerOnset');
219  BKR.TriggerOffset = BKR.BCI.Paradigm.TriggerOnset;
220  elseif isfield(BKR.BCI.Paradigm,'TriggerTiming');
221  % BKR.BCI.Paradigm.TriggerTiming,
222  BKR.TriggerOffset = BKR.BCI.Paradigm.TriggerTiming;
223  fprintf(2,'Warning BKROPEN: Paradigm.TriggerOnset is unknown. Paradigm.TriggerTiming= %f ms is used instead\n',BKR.TriggerOffset);
224  end;
225  end;
226 
227  if isfield(x.header,'PhysioRec'), % R. Leeb's data
228  BKR.Label = x.header.PhysioRec;
229  end;
230  if isfield(x.header,'BKRHeader'), % R. Scherer Data
231  if isfield(x.header.BKRHeader,'TO'),
232  BKR.T0 = x.header.BKRHeader.TO;
233  end;
234  if isfield(x.header.BKRHeader,'Label'),
235  BKR.Label = x.header.BKRHeader.Label;
236  ns = BKR.NS-size(BKR.Label,1);
237  if ns == 1;
238  BKR.Label = strvcat(BKR.Label,'TRIGGER');
239  elseif ns > 1;
240  BKR.Label = strvcat(BKR.Label,char(repmat('n.a.',ns,1)));
241  end;
242  end;
243  end;
244  if isfield(x.header,'Model'), % More
245  if isfield(x.header.Model,'AnalogInput'),
246  for k = 1:length(x.header.Model.AnalogInput),
247  BKR.Filter.HighPass(k) = x.header.Model.AnalogInput{k}{5};
248  BKR.Filter.LowPass(k) = x.header.Model.AnalogInput{k}{6};
249  BKR.Filter.Notch(k) = strcmpi(x.header.Model.AnalogInput{k}{7},'on');
250 
251  BKR.MAT.Cal(k) = x.header.Model.AnalogInput{k}{3};
252  end
253  end;
254  end;
255  if ~isempty(strmatch('TRIGGER',BKR.Label))
256  BKR.AS.TRIGCHAN = BKR.NS; %strmatch('TRIGGER',H.Label);
257  end;
258  end;
259  if 1; %~isfield(BKR,'Classlabel'),
260  tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.par']);
261  if ~exist(tmp,'file'),
262  tmp=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.PAR']);
263  end
264  if exist(tmp,'file'),
265  BKR.Classlabel = load(tmp);
266  end;
267  end;
268 
269  %%% Artifact Selection files
270  tmp1=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.sel']);
271  if ~exist(tmp1,'file'),
272  tmp1=fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.SEL']);
273  end
274  tmp2 = fullfile(BKR.FILE.Path,[BKR.FILE.Name,'_artifact.mat']);
275  SW = (exist(tmp1,'file')>0) + 2*(exist(tmp2,'file')>0);
276  if SW == 0,
277  elseif SW == 1,
278  if exist('OCTAVE_VERSION')>5
279  BKR.ArtifactSelection = load('-ascii',tmp1);
280  else
281  BKR.ArtifactSelection = load(tmp1);
282  end;
283  elseif SW == 2,
284  if exist('OCTAVE_VERSION')>5
285  tmp = load('-mat',tmp2);
286  else
287  tmp = load(tmp2);
288  end;
289  BKR.ArtifactSelection = tmp.artifact(:);
290  elseif SW == 3,
291  fprintf(BKR.FILE.stderr,'Warning BKROPEN: more than one ArtifactSelection files. File %s is used.\n',tmp1);
292  if exist('OCTAVE_VERSION')>5
293  BKR.ArtifactSelection = load('-ascii',tmp1);
294  else
295  BKR.ArtifactSelection = load(tmp1);
296  end;
297  end;
298  if isfield(BKR,'ArtifactSelection'),
299  if any(BKR.ArtifactSelection>1) | (length(BKR.ArtifactSelection)<length(BKR.Classlabel))
300  sel = zeros(size(BKR.Classlabel));
301  sel(BKR.ArtifactSelection) = 1;
302  BKR.ArtifactSelection = sel(:);
303  end;
304  BKR.ArtifactSelection = BKR.ArtifactSelection(:);
305  end;
306 
307  if isfield(BKR.AS,'TRIGCHAN') % & isempty(BKR.EVENT.POS)
308  if BKR.AS.TRIGCHAN <= BKR.NS, %size(BKR.data,2),
309  BKR.THRESHOLD(BKR.AS.TRIGCHAN,1:2) = [-1-2^15,2^15]; % do not apply overflow detection for Trigger channel
310  TRIGon = gettrigger(double(BKR.data(:,BKR.AS.TRIGCHAN)));
311  %TRIGoff = gettrigger(-double(BKR.data(:,BKR.AS.TRIGCHAN)));
312  if isfield(BKR,'TriggerOffset')
313  TRIGon = TRIGon - round(BKR.TriggerOffset/1000*BKR.SampleRate);
314  % TRIGoff = TRIGoff - round(BKR.TriggerOffset/1000*BKR.SampleRate);
315  end;
316  end;
317  BKR.TRIG = TRIGon(:);
318  BKR.EVENT.POS = TRIGon(:); %[TRIGon(:); TRIGoff(:)];
319  BKR.EVENT.TYP = repmat(hex2dec('0300'),numel(TRIGon),1); %repmat(hex2dec('8300'),numel(TRIGoff),1)];
320  end;
321  if length(BKR.TRIG)~=length(BKR.Classlabel),
322  % hack to deal with BCI22 data
323  fprintf(2,'Warning BKROPEN: Number of triggers (%i) and number of Classlabels (%i) do not fit\n',length(BKR.TRIG),length(BKR.Classlabel));
324  BKR.TRIG = [];
325  BKR.Classlabel = [];
326  BKR.ArtifactSelection = [];
327  end;
328 
329 
330 elseif any(BKR.FILE.PERMISSION=='w'),
331 
332  BKR.FILE.OPEN = 2;
333  BKR.VERSION = 207;
334  BKR.TYPE = 'BKR';
335  if ~strcmpi(BKR.FILE.Ext,'BKR'),
336  fprintf(2,'Warning BKROPEN-WRITE: file extionsion is not BKR.\n');
337  end;
338  if ~isfield(BKR,'SampleRate'),
339  fprintf(2,'Error BKROPEN-WRITE: BKR.SampleRate not defined.\n');
340  return;
341  end;
342  if ~isfield(BKR,'NS'),
343  BKR.NS = 0; % unknown channel number ...
344  end;
345  if ~isfield(BKR,'SPR'),
346  BKR.SPR = 0; % Unknown - Value will be fixed when file is closed.
347  end;
348  if isfield(BKR,'NRec'),
349  BKR.FLAG.TRIGGERED = BKR.NRec>1;
350  else
351  BKR.NRec = -1; % Unknown - Value will be fixed when file is closed.
352  end;
353  if ~isfield(BKR,'PhysMax'), BKR.PhysMax = NaN; end;
354  if isempty(BKR.PhysMax), BKR.PhysMax = NaN; end;
355  if ~isfield(BKR,'DigMax'), BKR.DigMax = NaN; end;
356  if isnan(BKR.DigMax) | isempty(BKR.DigMax),
357  BKR.DigMax = 2^15-1;
358  end;
359 
360  if any([BKR.NS==0,BKR.SPR==0,BKR.NRec<0,isnan([BKR.NRec,BKR.NS,BKR.SPR,BKR.DigMax,BKR.PhysMax,BKR.SampleRate])]), % if any unknown, ...
361  BKR.FILE.OPEN = 3; % ... fix header when file is closed.
362  end;
363  if ~isfield(BKR,'FLAG'),
364  BKR.FLAG.UCAL = 0;
365  elseif ~isfield(BKR.FLAG,'UCAL'),
366  BKR.FLAG.UCAL = 0;
367  end;
368 
369  tmp = round(BKR.PhysMax);
370  fprintf(1,'Scaling error in file %s due to rounding of PhysMax is in the range of %f%%.\n',BKR.FileName, abs((BKR.PhysMax-tmp)/tmp)*100);
371  BKR.PhysMax = tmp;
372 
373  count=fwrite(BKR.FILE.FID,BKR.VERSION,'short'); % version number of header
374  count=fwrite(BKR.FILE.FID,BKR.NS,'short'); % number of channels
375  count=fwrite(BKR.FILE.FID,BKR.SampleRate,'short'); % sampling rate
376  count=fwrite(BKR.FILE.FID,BKR.NRec,'int32'); % number of trials: 1 for untriggered data
377  count=fwrite(BKR.FILE.FID,BKR.SPR,'uint32'); % samples/trial/channel
378  count=fwrite(BKR.FILE.FID,BKR.PhysMax,'short'); % Kalibrierspannung
379  count=fwrite(BKR.FILE.FID,BKR.DigMax, 'short'); % Kalibrierwert
380 
381  count=fwrite(BKR.FILE.FID,zeros(4,1),'uint8');
382  if isfield(BKR,'Filter'),
383  if ~isfield(BKR.Filter,'LowPass'),
384  BKR.Filter.LowPass = NaN;
385  end;
386  if ~isfield(BKR.Filter,'HighPass'),
387  BKR.Filter.HighPass= NaN;
388  end;
389  else
390  BKR.Filter.LowPass =NaN;
391  BKR.Filter.HighPass=NaN;
392  end;
393  if all(BKR.Filter.LowPass(1)==BKR.Filter.LowPass)
394  BKR.Filter.LowPass = BKR.Filter.LowPass(1);
395  else
396  BKR.Filter.LowPass = NaN;
397  end;
398  if all(BKR.Filter.HighPass(1)==BKR.Filter.HighPass)
399  BKR.Filter.HighPass = BKR.Filter.HighPass(1);
400  else
401  BKR.Filter.HighPass = NaN;
402  end;
403  count=fwrite(BKR.FILE.FID,[BKR.Filter.LowPass,BKR.Filter.HighPass],'float');
404 
405  count=fwrite(BKR.FILE.FID,zeros(16,1),'uint8'); % offset 30
406  count=fwrite(BKR.FILE.FID,BKR.FLAG.TRIGGERED,'int16'); % offset 32
407  count=fwrite(BKR.FILE.FID,zeros(24,1),'uint8'); % offset 46
408 
409  if ~isfield(BKR,'FLAG')
410  BKR.FLAG.REFERENCE='';
411  end;
412  if ~isfield(BKR.FLAG,'REFERENCE')
413  BKR.FLAG.REFERENCE='';
414  end;
415 
416  tmp = [strcmp(BKR.FLAG.REFERENCE,'COM')|strcmp(BKR.FLAG.REFERENCE,'CAR'), strcmp(BKR.FLAG.REFERENCE,'LOC')|strcmp(BKR.FLAG.REFERENCE,'LAR'), strcmp(BKR.FLAG.REFERENCE,'LAP'), strcmp(BKR.FLAG.REFERENCE,'WGT')];
417 
418  fwrite(BKR.FILE.FID,tmp,BOOL); % offset 72 + 4*BOOL
419 
420  %speichert den rest des BKR-headers
421  count = fwrite(BKR.FILE.FID,zeros(1024-80,1),'uint8');
422  BKR.HeadLen = ftell(BKR.FILE.FID);
423  if BKR.HeadLen~=1024,
424  fprintf(2,'Error BKROPEN WRITE: HeaderLength is not 1024 but %i\n',BKR.HeadLen);
425  end;
426  BKR.FILE.POS = 0;
427  BKR.AS.endpos = 0;
428  BKR.AS.bpb = BKR.NS*2; % Bytes per Block
429  BKR.AS.spb = BKR.NS; % Samples per Block
430 
431  if isfield(BKR,'Classlabel');
432  fid = fopen(fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.par']),'w+b'); % force binary mode
433  fprintf(fid,'%i\r\n',BKR.Classlabel); % explicit 0x0d and 0x0a
434  fclose(fid);
435  end;
436  if isfield(BKR,'ArtifactSelection');
437  fid = fopen(fullfile(BKR.FILE.Path,[BKR.FILE.Name,'.sel']),'w+b'); % force binary mode
438  fprintf(fid,'%i\r\n',BKR.ArtifactSelection); % explicit 0x0d and 0x0a
439  fclose(fid);
440  end;
441 end;
442 
443 
gettrigger
function gettrigger(in s, in TH, in rfp)
bkropen
function bkropen(in arg1, in arg3, in arg4, in arg5, in arg6)