1 function [HDR] =
sclose(HDR)
2 % SCLOSE closes the file with the handle HDR
4 % HDR.FILE.status = -1
if file could not be closed.
5 % HDR.FILE.status = 0 indicates the file has been closed.
7 % see also: SOPEN, SREAD, SSEEK, STELL, SCLOSE, SWRITE
9 % This program is free software; you can redistribute it and/or
10 % modify it under the terms of the GNU General Public License
11 % as published by the Free Software Foundation; either version 3
12 % of the License, or (at your option) any later version.
14 % $Id:
sclose.m 2566 2010-11-24 13:04:34Z schloegl $
15 % (C) 1997-2005,2006,2008 by Alois Schloegl <a.schloegl@ieee.org>
16 % This is part of the BIOSIG-toolbox http:
19 if (HDR.FILE.FID<0) || ~HDR.FILE.OPEN,
21 %fprintf(HDR.FILE.stderr,
'Warning SCLOSE (%s): invalid handle\n',HDR.FileName);
24 if HDR.FILE.OPEN >= 2, % write-open of files
25 % check file length - simple test
for file integrity
26 EndPos = ftell(HDR.FILE.FID); % get file length
27 % force file pointer to the end, otherwise Matlab 6.5 R13 on PCWIN
28 status = fseek(HDR.FILE.FID,0,
'eof');
30 if strcmp(HDR.TYPE,
'BKR');
32 fprintf(HDR.FILE.stderr,
'Error SCLOSE BKR: number of channels (HDR.NS) must be larger than zero.\n');
36 fprintf(HDR.FILE.stderr,
'Error SCLOSE BKR: number of blocks (HDR.NRec) must be larger than zero.\n');
39 % check file length and write Headerinfo.
40 HDR.SPR = (EndPos-HDR.HeadLen)/(HDR.NRec*HDR.NS*2);
41 if isnan(HDR.SPR), HDR.SPR=0; end;
43 if any(isnan([HDR.NRec,HDR.NS,HDR.SPR,HDR.DigMax,HDR.PhysMax,HDR.SampleRate])), %
if any unknown, ...
44 fprintf(HDR.FILE.stderr,
'Error SCLOSE BKR: some important header information is still undefined (i.e. NaN).\n');
45 fprintf(HDR.FILE.stderr,
'\t HDR.NRec,HDR.NS,HDR.SPR,HDR.DigMax,HDR.PhysMax,HDR.SampleRate must be defined.\n');
46 fprintf(HDR.FILE.stderr,
'\t Try again.\n');
50 HDR.FILE.FID = fopen(HDR.FileName,
'r+');
52 count=fwrite(HDR.FILE.FID,HDR.VERSION,
'int16'); % version number of header
53 count=fwrite(HDR.FILE.FID,HDR.NS,
'int16'); % number of channels
54 count=fwrite(HDR.FILE.FID,HDR.SampleRate,
'int16'); % sampling rate
55 count=fwrite(HDR.FILE.FID,HDR.NRec,
'int32'); % number of trials: 1
for untriggered data
56 count=fwrite(HDR.FILE.FID,HDR.SPR,
'uint32'); % samples/trial/channel
57 count=fwrite(HDR.FILE.FID,HDR.PhysMax,
'int16'); % Kalibrierspannung
58 count=fwrite(HDR.FILE.FID,HDR.DigMax,
'int16'); % Kalibrierwert
59 count=fwrite(HDR.FILE.FID,zeros(4,1),
'uint8');
60 count=fwrite(HDR.FILE.FID,[HDR.Filter.LowPass,HDR.Filter.HighPass],
'float');
62 fseek(HDR.FILE.FID,32,
'bof');
63 HDR.FLAG.TRIGGERED = HDR.NRec>1; % Trigger Flag
64 count = fwrite(HDR.FILE.FID,HDR.FLAG.TRIGGERED,
'int16'); % FLAG TRIGGERED
67 elseif strcmp(HDR.TYPE,
'EDF') || strcmp(HDR.TYPE,
'BDF') || strcmp(HDR.TYPE,
'GDF'),
68 tmp = floor((EndPos - HDR.HeadLen) / HDR.AS.bpb); % calculate number of records
74 if ~any(HDR.FILE.PERMISSION==
'z')
76 fseek(HDR.FILE.FID,236,'bof');
77 if strcmp(HDR.TYPE,'GDF')
78 c=fwrite(HDR.FILE.FID,[HDR.NRec,0],'int32');
80 fprintf(HDR.FILE.FID,'%-8i',HDR.NRec);
82 else %% due to a limitation in zlib
83 fprintf(HDR.FILE.stderr,'ERROR SCLOSE: number-of-records-field (HDR.NRec) could not be updated in file %s.\n',HDR.FileName);
87 if strcmp(HDR.TYPE,'GDF') && isfield(HDR,'EVENT'),
88 if ~all([HDR.NS, HDR.NRec, HDR.AS.bpb]>0)
89 HDR.AS.EVENTTABLEPOS = HDR.HeadLen;
91 HDR.AS.EVENTTABLEPOS = HDR.HeadLen+HDR.AS.bpb*HDR.NRec;
93 if isfield(HDR.EVENT,'VAL')
94 % handling of sparse (non-equidistant) sampling values
95 if isempty(HDR.EVENT.DUR)
96 HDR.EVENT.DUR = zeros(size(HDR.EVENT.TYP));
99 fprintf(2,'Warning SCLOSE: GDF v2.0 or higher required for storing sparse samples but version is only %4.2f.\n',HDR.VERSION);
100 %ix0 = ~isnan(HDR.EVENT.VAL);
101 %HDR.EVENT.POS = HDR.EVENT.POS(~ix0);
102 %HDR.EVENT.TYP = HDR.EVENT.TYP(~ix0);
103 %HDR.EVENT.CHN = HDR.EVENT.CHN(~ix0);
104 %HDR.EVENT.DUR = HDR.EVENT.DUR(~ix0);
105 %HDR.EVENT = rmfield(HDR.EVENT,'VAL');
108 if isfield(HDR.EVENT,'VAL')
109 ix = find(~isnan(HDR.EVENT.VAL));
110 tmp = unique(HDR.EVENT.CHN(ix));
113 if (~all(HDR.EVENT.CHN(ix) > 0))
115 fprintf(2,'Warning SCLOSE: Sparse sampling values without valid channel. Samples are not stored.\n');
118 if any(HDR.GDFTYP(tmp) > 6)
119 fprintf(2,'Warning SCLOSE: Sparse sampling values must be of type integer using no more than 32 bits. Data is converted to uint32.\n');
122 if any(HDR.AS.SPR(tmp)) || flag.invalid,
123 fprintf(2,'Warning SCLOSE: Sparse sampling value for non-sparse channels not allowed. The following channel(s) is(are) affected: ');
124 fprintf(2,'%i', tmp(HDR.AS.SPR(tmp)>0) );
125 fprintf(2,'. Samples are not stored.\n')
126 ix0 = ~isnan(HDR.EVENT.VAL) & ~(HDR.EVENT.CHN>0); % initialize index with logical(0)
127 for k = 1:length(tmp),
128 if (HDR.AS.SPR(tmp(k))>0),
129 ix0 = ix0 | (HDR.EVENT.CHN==tmp(k));
132 HDR.EVENT.POS = HDR.EVENT.POS(~ix0);
133 HDR.EVENT.TYP = HDR.EVENT.TYP(~ix0);
134 HDR.EVENT.CHN = HDR.EVENT.CHN(~ix0);
135 HDR.EVENT.DUR = HDR.EVENT.DUR(~ix0);
136 HDR.EVENT.VAL = HDR.EVENT.VAL(~ix0);
137 ix = ~isnan(HDR.EVENT.VAL);
140 % prepare for storing
141 HDR.EVENT.TYP(ix) = hex2dec('7fff');
142 HDR.EVENT.DUR(ix) = HDR.EVENT.VAL(ix);
145 len = [length(HDR.EVENT.POS),length(HDR.EVENT.TYP)];
147 if isfield(HDR.EVENT,'CHN') && isfield(HDR.EVENT,'DUR'),
148 if any(HDR.EVENT.CHN) || any(HDR.EVENT.DUR),
150 len = [len,length(HDR.EVENT.CHN),length(HDR.EVENT.DUR)];
155 fprintf(HDR.FILE.stderr,'Error SCLOSE-GDF: cannot write Event table, file %s not closed.\n',HDR.FileName);
158 status = fseek(HDR.FILE.FID,HDR.HeadLen+HDR.AS.bpb*HDR.NRec,'bof');
159 %status = fseek(HDR.FILE.FID,0,'eof');
160 if ftell(HDR.FILE.FID)~=HDR.AS.EVENTTABLEPOS,
161 fprintf(HDR.FILE.stderr,'Warning SCLOSE-GDF: inconsistent GDF file\n');
163 if ~isfield(HDR.EVENT,'SampleRate'),
164 HDR.EVENT.SampleRate = HDR.SampleRate;
167 % write eventtable info: Version, SampleRate & length
168 if (HDR.VERSION<1.94)
169 tmp = HDR.EVENT.SampleRate;
170 tmp = [EVENT.Version,mod(tmp,256),floor(mod(tmp,65536)/256),floor(tmp/65536)];
171 fwrite(HDR.FILE.FID,tmp,'uint8');
172 fwrite(HDR.FILE.FID,length(HDR.EVENT.POS),'uint32');
174 tmp = length(HDR.EVENT.POS);
175 tmp = [EVENT.Version,mod(tmp,256),floor(mod(tmp,65536)/256),floor(tmp/65536)];
176 fwrite(HDR.FILE.FID,tmp,'uint8');
177 fwrite(HDR.FILE.FID,HDR.EVENT.SampleRate,'float32');
181 c1 = fwrite(HDR.FILE.FID,HDR.EVENT.POS,'uint32');
182 c2 = fwrite(HDR.FILE.FID,HDR.EVENT.TYP,'uint16');
183 c3 = length(HDR.EVENT.POS); c4 = c3;
185 c3 = fwrite(HDR.FILE.FID,HDR.EVENT.CHN,'uint16');
186 c4 = fwrite(HDR.FILE.FID,HDR.EVENT.DUR,'uint32');
188 if any([c1,c2,c3,c4]~=length(HDR.EVENT.POS))
189 fprintf(2,'\nError SCLOSE: writing of EVENTTABLE failed. File %s not closed.\n', HDR.FileName);
195 elseif strcmp(HDR.TYPE,'CFWB');
196 tmp = (EndPos-HDR.HeadLen)/HDR.AS.bpb;
197 if isnan(tmp), tmp=0; end;
199 if ~any(HDR.FILE.PERMISSION=='z')
201 fseek(HDR.FILE.FID,14*4,-1);
202 count = fwrite(HDR.FILE.FID,HDR.NRec,'int32'); % channels
204 fprintf(HDR.FILE.stderr,'ERROR SCLOSE (CFWB): number-of-samples-field (HDR.SPR) could not be updated in file %s.\n',HDR.FileName);
208 elseif strcmp(HDR.TYPE,'SND');
209 tmp = (EndPos-HDR.HeadLen)/HDR.AS.bpb;
210 if isnan(tmp), tmp=0; end;
211 if (HDR.FILE.OPEN==3) && (tmp~=HDR.SPR);
212 if ~any(HDR.FILE.PERMISSION=='z')
214 fseek(HDR.FILE.FID,8,'bof');
215 count = fwrite(HDR.FILE.FID,HDR.SPR*HDR.AS.bpb,'uint32'); % bytes
216 fseek(HDR.FILE.FID,20,-1);
217 count = fwrite(HDR.FILE.FID,HDR.NS,'uint32'); % channels
219 fprintf(HDR.FILE.stderr,'ERROR SCLOSE (SND): fields HDR.SPR and HDR.NS could not be updated in file %s.\n',HDR.FileName);
223 elseif strcmp(HDR.TYPE,'AIF');
225 fseek(HDR.FILE.FID,4,-1);
226 count = fwrite(HDR.FILE.FID,EndPos-8,'uint32'); % bytes
227 fseek(HDR.FILE.FID,HDR.WAV.posis(2),-1);
228 count = fwrite(HDR.FILE.FID,EndPos-4-HDR.WAV.posis(2),'uint32'); % channels
231 elseif strcmp(HDR.TYPE,'FLT') ;
232 % warning FLT/header might have changed in needs to be rewritten
233 elseif strcmp(HDR.TYPE,'WAV') ;
235 fseek(HDR.FILE.FID,4,-1);
236 count = fwrite(HDR.FILE.FID,EndPos-16,'uint32'); % bytes
237 fseek(HDR.FILE.FID,HDR.WAV.posis(2),-1);
238 count = fwrite(HDR.FILE.FID,EndPos-4-HDR.WAV.posis(2),'uint32'); % channels
244 elseif strcmp(HDR.TYPE,'ZIP')
245 [SUCCESS,MESSAGE,MESSAGEID] = rmdir(HDR.ZIP.TEMPDIR,'s');
247 elseif strcmp(HDR.TYPE,'FIF') && HDR.FILE.OPEN;
248 global FLAG_NUMBER_OF_OPEN_FIF_FILES
252 FLAG_NUMBER_OF_OPEN_FIF_FILES = FLAG_NUMBER_OF_OPEN_FIF_FILES-1;
254 elseif strmatch(HDR.TYPE,{
'ADI',
'GTEC',
'LABVIEW',
'MAT',
'MAT4',
'MAT5',
'native',
'XML',
'XML-FDA',
'SierraECG'}),
257 elseif HDR.FILE.OPEN,
259 HDR.FILE.status = fclose(HDR.FILE.FID);