1 function [HDR]=
openxml(arg1,CHAN,arg4,arg5,arg6)
2 % OPENXML reads XML files and tries to extract biosignal data
4 % This is an auxilary
function to SOPEN.
5 % Use SOPEN instead of OPENXML.
11 % HDR contains the Headerinformation and
internal data
13 % see also: SOPEN, SREAD, SSEEK, STELL, SCLOSE, SWRITE, SEOF
16 % This program is free software; you can redistribute it and/or
17 % modify it under the terms of the GNU General Public License
18 % as published by the Free Software Foundation; either version 3
19 % of the License, or (at your option) any later version.
21 % $Id:
openxml.m 2205 2009-10-27 12:18:15Z schloegl $
22 % Copyright 2006,2007,2008 by Alois Schloegl <a.schloegl@ieee.org>
23 % This is part of the BIOSIG-toolbox http:
27 HDR.FILE.PERMISSION =
'r';
32 %
if strncmp(HDR.TYPE,
'XML',3),
33 %
if any(HDR.FILE.PERMISSION==
'r'),
34 fid = fopen(HDR.FileName,HDR.FILE.PERMISSION,
'ieee-le');
35 s = char(fread(fid,[1,1024],
'char'));
36 if all(s(1:2)==[255,254]) & all(s(4:2:end)==0)
38 elseif ~isempty(findstr(
char(s),'?xml version'))
42 if strcmp(HDR.TYPE,'XML-UTF16'),
43 magic =
char(fread(fid,1,'uint16'));
44 HDR.XML =
char(fread(fid,[1,inf],'uint16'));
45 elseif strcmp(HDR.TYPE,'XML-UTF8'),
46 HDR.XML =
char(fread(fid,[1,inf],'uint8'));
52 if 0, ~exist('xmlstruct')
53 warning('XML toolbox missing')
56 HDR.XMLstruct = xmlstruct(HDR.XML,'sub');
57 HDR.XMLlist = xmlstruct(HDR.XML);
61 XML = xmltree(HDR.XML);
66 fprintf(HDR.FILE.stderr,'ERROR SOPEN (XML): XML-toolbox missing or invalid XML file.\n');
70 tmp = fieldnames(HDR.XML);
71 if any(strmatch('PatientDemographics',tmp)) & any(strmatch('TestDemographics',tmp)) & any(strmatch('RestingECGMeasurements',tmp)) & any(strmatch('Diagnosis',tmp)) & any(strmatch('Waveform',tmp)),
72 % GE-Marquette FDA-XML MAC5000
74 HDR.Patient.ID = HDR.XML.PatientDemographics.PatientID;
75 tmp = HDR.XML.PatientDemographics.Gender;
76 HDR.Patient.Sex = 2*(upper(tmp(1))=='F') + (upper(tmp(1))=='M');
77 HDR.Patient.Name = [HDR.XML.PatientDemographics.PatientLastName,', ',HDR.XML.PatientDemographics.PatientFirstName];
79 tmp = HDR.XML.TestDemographics.AcquisitionDate;
82 tmp = HDR.XML.TestDemographics.AcquisitionTime;
86 HDR.NS =
str2double(HDR.XML.Waveform.NumberofLeads);
87 HDR.SampleRate =
str2double(HDR.XML.Waveform.SampleBase);
88 HDR.Filter.LowPass =
str2double(HDR.XML.Waveform.LowPassFilter)*ones(1,HDR.NS);
89 HDR.Filter.HighPass =
str2double(HDR.XML.Waveform.HighPassFilter)*ones(1,HDR.NS);
90 HDR.Filter.Notch =
str2double(HDR.XML.Waveform.ACFilter)*ones(1,HDR.NS);
95 CH = HDR.XML.Waveform.LeadData{k};
96 HDR.AS.SPR(k) =
str2double(CH.LeadSampleCountTotal);
97 HDR.SPR = lcm(HDR.SPR,HDR.AS.SPR(k));
98 HDR.Cal(k) =
str2double(CH.LeadAmplitudeUnitsPerBit);
99 HDR.PhysDim{k} = CH.LeadAmplitudeUnits;
100 HDR.Label{k} = CH.LeadID;
103 t = 256*t(2:2:end) + t(1:2:end);
104 t = t - (t>=(2^15))*(2^16);
105 HDR.data(:,k) = t(:);
110 elseif any(strmatch(
'component',tmp))
112 tmp = HDR.XML.component.series.derivation;
113 if isfield(tmp,
'Series');
114 tmp = tmp.Series.component.sequenceSet.component;
115 else % Dovermed.CO.IL version of format
116 tmp = tmp.derivedSeries.component.sequenceSet.component;
118 HDR.NS = length(tmp)-1;
123 HDR.TYPE =
'XML-FDA'; % that
's an FDA XML file
126 elseif any(strmatch('dataacquisition
',tmp)) & any(strmatch('reportinfo
',tmp)) & any(strmatch('patient
',tmp)) & any(strmatch('documentinfo
',tmp)),
127 % SierraECG 1.03 *.open.xml from PHILIPS
128 HDR.SampleRate = str2double(HDR.XML.dataacquisition.signalcharacteristics.samplingrate);
129 HDR.NS = str2double(HDR.XML.dataacquisition.signalcharacteristics.numberchannelsvalid);
130 HDR.Cal = str2double(HDR.XML.reportinfo.reportgain.amplitudegain.overallgain);
131 HDR.PhysDim = {'uV
'};
132 HDR.Filter.HighPass = str2double(HDR.XML.reportinfo.reportbandwidth.highpassfiltersetting);
133 HDR.Filter.LowPass = str2double(HDR.XML.reportinfo.reportbandwidth.lowpassfiltersetting);
134 HDR.Filter.Notch = str2double(HDR.XML.reportinfo.reportbandwidth.notchfiltersetting);
136 t = HDR.XML.reportinfo.reportformat.waveformformat.mainwaveformformat;
140 [s,t] = strtok(t,' ');
142 HDR.Label{k, 1} = [s,' '];
144 HDR.Patient.Id = str2double(HDR.XML.patient.generalpatientdata.patientid);
145 tmp = HDR.XML.patient.generalpatientdata.age;
146 if isfield(tmp,'years
'),
147 HDR.Patient.Age = str2double(tmp.years);
149 if isfield(tmp,'dateofbirth
')
150 tmp = tmp.dateofbirth;
152 HDR.Patient.Birthday([6,5,4]) = str2double(tmp);
155 tmp = HDR.XML.patient.generalpatientdata.sex;
156 HDR.Patient.Sex = strncmpi(tmp,'Male
',1) + strncmpi(tmp,'Female
',1)*2;
157 HDR.Patient.Weight = str2double(HDR.XML.patient.generalpatientdata.weight.kg);
158 HDR.Patient.Height = str2double(HDR.XML.patient.generalpatientdata.height.cm);
160 HDR.VERSION = HDR.XML.documentinfo.documentversion;
161 HDR.TYPE = HDR.XML.documentinfo.documenttype;
164 elseif any(strmatch('component
',tmp)) & any(strmatch('reportinfo
',tmp)) & any(strmatch('patient
',tmp)) & any(strmatch('documentinfo
',tmp)),
166 tmp = HDR.XML.component.series.derivation;
167 if isfield(tmp,'Series
');
168 tmp = tmp.Series.component.sequenceSet.component;
169 else % Dovermed.CO.IL version of format
170 tmp = tmp.derivedSeries.component.sequenceSet.component;
172 HDR.NS = length(tmp)-1;
177 HDR.TYPE = 'XML-FDA
'; % that's an FDA XML file
180 elseif any(strmatch(
'StripData',tmp)) & any(strmatch(
'ClinicalInfo',tmp)) & any(strmatch(
'PatientInfo',tmp)) & any(strmatch(
'ArrhythmiaData',tmp)),
181 % GE Case8000 stress ECG
183 HDR.SampleRate =
str2double(HDR.XML.StripData.SampleRate);
184 tmp = HDR.XML.ClinicalInfo.ObservationDateTime;
187 HDR.Patient.Id = HDR.XML.PatientInfo.PID;
188 HDR.Patient.Name =
'X'; % [HDR.XML.PatientInfo.Name,
', ', HDR.XML.PatientInfo.GivenName];
189 HDR.Patient.Age =
str2double(HDR.XML.PatientInfo.Age);
190 tmp = HDR.XML.PatientInfo.Gender;
191 HDR.Patient.Sex = any(tmp(1)==
'Mm') + any(tmp(1)==
'Ff')*2;
192 HDR.Patient.Height =
str2double(HDR.XML.PatientInfo.Height);
193 HDR.Patient.Weight =
str2double(HDR.XML.PatientInfo.Weight);
194 tmp = HDR.XML.PatientInfo.BirthDateTime;
197 tmp = HDR.XML.StripData.Strip;
198 HDR.NS = length(tmp{1}.WaveformData);
200 data = repmat(NaN,tmax*HDR.SampleRate,HDR.NS);
201 for k = 1:length(tmp);
205 data(t+1:t+length(x),k2)=x(:);
208 tmp = HDR.XML.ArrhythmiaData.Strip;
209 for k = 1:length(tmp);
213 data(t+1:t+length(x),k2)=x(:);
216 HDR.data = data - 2^12*(data>2^11);
219 HDR.SPR = size(HDR.data,1);
220 HDR.Calib = sparse(2:HDR.NS,1:HDR.NS,1);
224 fprintf(HDR.FILE.stderr,
'Warning SOPEN (XML): File %s is not supported.\n',HDR.FileName);
230 tmp=HDR.XML.componentOf.timepointEvent.componentOf.subjectAssignment.subject.trialSubject.subjectDemographicPerson.name;
231 HDR.Patient.Name = sprintf(
'%s, %s',tmp.family, tmp.given);
236 HDR.Calib = sparse(2:HDR.NS+1,1:HDR.NS,HDR.Cal);
243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 % Auxillary functions
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 % RADIX64D - decoding of radix64 encoded sequence
254 % This program is free software; you can redistribute it and/or
255 % modify it under the terms of the GNU General Public License
256 % as published by the Free Software Foundation; either version 2
257 % of the License, or (at your option) any later version.
259 % This program is distributed in the hope that it will be useful,
260 % but WITHOUT ANY WARRANTY; without even the implied warranty of
261 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
262 % GNU General Public License
for more details.
264 % You should have received a copy of the GNU General Public License
265 % along with
this program;
if not, write to the Free Software
266 % Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
268 % $Id:
openxml.m 2205 2009-10-27 12:18:15Z schloegl $
269 % (C) 2006 by Alois Schloegl <a.schloegl@ieee.org>
270 % This is part of the BIOSIG-toolbox http:
275 if ~isfield(BIOSIG_GLOBAL,
'R64E');
276 BIOSIG_GLOBAL.R64E = [
'A':
'Z',
'a':
'z',
'0':
'9',
'+',
'/'];
277 BIOSIG_GLOBAL.R64D = zeros(256,1)-1;
278 for k = 1:length(BIOSIG_GLOBAL.R64E),
279 BIOSIG_GLOBAL.R64D(BIOSIG_GLOBAL.R64E(k)) = k-1;
285 t = BIOSIG_GLOBAL.R64D(x);
286 t = [t(t>=0); zeros(3,1)];
287 N = floor(length(t)/4);
288 t = reshape(bitand(t(1:N*4),2^6-1),4,N);
290 y(1,:) = bitshift(t(1,:),2) + bitshift(t(2,:),-4);
291 y(2,:) = bitshift(mod(t(2,:),16),4) + bitshift(t(3,:),-2);
292 y(3,:) = bitshift(mod(t(3,:),4),6) + t(4,:);
295 y = y(1:end-sum(x=='=
')); % remove possible pad characters