TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
sclose.m
Go to the documentation of this file.
1 function [HDR] = sclose(HDR)
2 % SCLOSE closes the file with the handle HDR
3 % [HDR] = sclose(HDR)
4 % HDR.FILE.status = -1 if file could not be closed.
5 % HDR.FILE.status = 0 indicates the file has been closed.
6 %
7 % see also: SOPEN, SREAD, SSEEK, STELL, SCLOSE, SWRITE
8 
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.
13 
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://biosig.sf.net/
17 
18 
19 if (HDR.FILE.FID<0) || ~HDR.FILE.OPEN,
20  HDR.FILE.status = -1;
21  %fprintf(HDR.FILE.stderr,'Warning SCLOSE (%s): invalid handle\n',HDR.FileName);
22 end;
23 
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');
29 
30  if strcmp(HDR.TYPE,'BKR');
31  if HDR.NS<1,
32  fprintf(HDR.FILE.stderr,'Error SCLOSE BKR: number of channels (HDR.NS) must be larger than zero.\n');
33  return;
34  end;
35  if HDR.NRec<1,
36  fprintf(HDR.FILE.stderr,'Error SCLOSE BKR: number of blocks (HDR.NRec) must be larger than zero.\n');
37  return;
38  end;
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;
42  if HDR.FILE.OPEN==3;
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');
47  end;
48 
49  fclose(HDR.FILE.FID);
50  HDR.FILE.FID = fopen(HDR.FileName,'r+');
51 
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');
61 
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
65  end;
66 
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
69  if isnan(tmp)
70  tmp = 0;
71  end;
72 
73  if (HDR.NRec~=tmp)
74  if ~any(HDR.FILE.PERMISSION=='z')
75  HDR.NRec=tmp;
76  fseek(HDR.FILE.FID,236,'bof');
77  if strcmp(HDR.TYPE,'GDF')
78  c=fwrite(HDR.FILE.FID,[HDR.NRec,0],'int32');
79  else
80  fprintf(HDR.FILE.FID,'%-8i',HDR.NRec);
81  end;
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);
84  end;
85  end;
86 
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;
90  else
91  HDR.AS.EVENTTABLEPOS = HDR.HeadLen+HDR.AS.bpb*HDR.NRec;
92  end;
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));
97  end;
98  if (HDR.VERSION<1.90)
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');
106  end;
107  end;
108  if isfield(HDR.EVENT,'VAL')
109  ix = find(~isnan(HDR.EVENT.VAL));
110  tmp = unique(HDR.EVENT.CHN(ix));
111 
112  flag.invalid = 0;
113  if (~all(HDR.EVENT.CHN(ix) > 0))
114  flag.invalid = 1;
115  fprintf(2,'Warning SCLOSE: Sparse sampling values without valid channel. Samples are not stored.\n');
116  tmp = tmp(tmp > 0);
117  end;
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');
120  end;
121 
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));
130  end;
131  end;
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);
138  end;
139 
140  % prepare for storing
141  HDR.EVENT.TYP(ix) = hex2dec('7fff');
142  HDR.EVENT.DUR(ix) = HDR.EVENT.VAL(ix);
143  end;
144 
145  len = [length(HDR.EVENT.POS),length(HDR.EVENT.TYP)];
146  EVENT.Version = 1;
147  if isfield(HDR.EVENT,'CHN') && isfield(HDR.EVENT,'DUR'),
148  if any(HDR.EVENT.CHN) || any(HDR.EVENT.DUR),
149  EVENT.Version = 3;
150  len = [len,length(HDR.EVENT.CHN),length(HDR.EVENT.DUR)];
151  end;
152  end;
153 
154  if any(len~=len(1))
155  fprintf(HDR.FILE.stderr,'Error SCLOSE-GDF: cannot write Event table, file %s not closed.\n',HDR.FileName);
156  return;
157  else
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');
162  end
163  if ~isfield(HDR.EVENT,'SampleRate'),
164  HDR.EVENT.SampleRate = HDR.SampleRate;
165  end;
166 
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');
173  else
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');
178  end;
179 
180  % write table
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;
184  if EVENT.Version==3;
185  c3 = fwrite(HDR.FILE.FID,HDR.EVENT.CHN,'uint16');
186  c4 = fwrite(HDR.FILE.FID,HDR.EVENT.DUR,'uint32');
187  end;
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);
190  return;
191  end
192  end;
193  end;
194 
195  elseif strcmp(HDR.TYPE,'CFWB');
196  tmp = (EndPos-HDR.HeadLen)/HDR.AS.bpb;
197  if isnan(tmp), tmp=0; end;
198  if (tmp~=HDR.NRec);
199  if ~any(HDR.FILE.PERMISSION=='z')
200  HDR.NRec = tmp;
201  fseek(HDR.FILE.FID,14*4,-1);
202  count = fwrite(HDR.FILE.FID,HDR.NRec,'int32'); % channels
203  else
204  fprintf(HDR.FILE.stderr,'ERROR SCLOSE (CFWB): number-of-samples-field (HDR.SPR) could not be updated in file %s.\n',HDR.FileName);
205  end;
206  end;
207 
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')
213  HDR.SPR = tmp;
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
218  else
219  fprintf(HDR.FILE.stderr,'ERROR SCLOSE (SND): fields HDR.SPR and HDR.NS could not be updated in file %s.\n',HDR.FileName);
220  end;
221  end;
222 
223  elseif strcmp(HDR.TYPE,'AIF');
224  if HDR.FILE.OPEN==3;
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
229  end;
230 
231  elseif strcmp(HDR.TYPE,'FLT') ;
232  % warning FLT/header might have changed in needs to be rewritten
233  elseif strcmp(HDR.TYPE,'WAV') ;
234  if HDR.FILE.OPEN==3;
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
239  end;
240  end;
241 end;
242 
243 if 0,
244 elseif strcmp(HDR.TYPE,'ZIP')
245  [SUCCESS,MESSAGE,MESSAGEID] = rmdir(HDR.ZIP.TEMPDIR,'s');
246 
247 elseif strcmp(HDR.TYPE,'FIF') && HDR.FILE.OPEN;
248  global FLAG_NUMBER_OF_OPEN_FIF_FILES
249  rawdata('close');
250  HDR.FILE.OPEN = 0;
251  HDR.FILE.status = 0;
252  FLAG_NUMBER_OF_OPEN_FIF_FILES = FLAG_NUMBER_OF_OPEN_FIF_FILES-1;
253 
254 elseif strmatch(HDR.TYPE,{'ADI','GTEC','LABVIEW','MAT','MAT4','MAT5','native','XML','XML-FDA','SierraECG'}),
255  HDR.FILE.OPEN = 0;
256 
257 elseif HDR.FILE.OPEN,
258  HDR.FILE.OPEN = 0;
259  HDR.FILE.status = fclose(HDR.FILE.FID);
260 end;
261 
sclose
function sclose(in HDR)