Home > other > ilwdread.m

ilwdread

PURPOSE ^

ILWDREAD Load an ILWD (Internal LightWeight Data) formatted XML file.

SYNOPSIS ^

function data = ilwdread(filename, verbose)

DESCRIPTION ^

ILWDREAD Load an ILWD (Internal LightWeight Data) formatted XML file.
   ILWDREAD(FILENAME) returns a MATLAB struct representation of the ILWD file
   given by FILENAME.  Each element of the ILWD is a MATLAB struct with field
   "tag" storing the element type, and additional fields storing the values of
   the attributes of the element.  If the element is an array (such as real_8)
   a field named after the element ("real_8") stores the array data in MATLAB
   format.  If the element is a container (such as ilwd) the member elements
   are stored as fields m1, m2, ...

   ILWDREAD(FILENAME, VERBOSE) turns on verbose output if VERBOSE is true
   (nonzero).  This consists of a formatted representation of the structure
   but not the content of the ILWD (i.e. the tags and fields but not the
   data).

   The structure of ILWD files is often complex and this is reflected in the
   complicated structs produced by ILWDREAD.  The struct can be navigated by
   typing the element names on the command line to see the available fields.

   >>>> ilwd = ilwdread('results.ilwd')

   ilwd = 
   
           tag: 'ilwd'
       comment: 'ilwdread example'
          name: 'ligo:ldas:file'
            m1: [1x1   struct]
   
   >>>> ilwd.m1
   
   ans = 
   
          tag: 'int_4s'
         dims: 2
         name: 'one two'
       int_4s: [2x1 double]

   >>>> ilwd.m1.int_4s

   ans =

        1
        2
   
   It may be convenient to copy the data to a concisely named variable.

   >>>> a = ilwd.m1.int_4s;

   The member structs fields of a struct must be name-mangled (m1, m2, ...)
   rather than subscripted (m(1), m(2), ...) to allow them to represent
   different structures.  The EVAL command can be used to simulate
   subscripting, replacing "data.m(i)" with "eval(['data.m' i])".

   The array fields are MATLAB vectors containing numerical data.  The
   values are preserved but the format is not (for example, int types are
   converted to double).  Complex types are also unpacked to construct 
   complex vectors.

   ILWDREAD accepts only uncompressed ASCII ILWD files.  Any non-standard
   attributes should be correctly parsed to a string (but will issue a
   warning).  Any non-standard tags will cause an error.  Bugs and comments
   to Antony.Searle@anu.edu.au

   See also

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function data = ilwdread(filename, verbose)
0002 %ILWDREAD Load an ILWD (Internal LightWeight Data) formatted XML file.
0003 %   ILWDREAD(FILENAME) returns a MATLAB struct representation of the ILWD file
0004 %   given by FILENAME.  Each element of the ILWD is a MATLAB struct with field
0005 %   "tag" storing the element type, and additional fields storing the values of
0006 %   the attributes of the element.  If the element is an array (such as real_8)
0007 %   a field named after the element ("real_8") stores the array data in MATLAB
0008 %   format.  If the element is a container (such as ilwd) the member elements
0009 %   are stored as fields m1, m2, ...
0010 %
0011 %   ILWDREAD(FILENAME, VERBOSE) turns on verbose output if VERBOSE is true
0012 %   (nonzero).  This consists of a formatted representation of the structure
0013 %   but not the content of the ILWD (i.e. the tags and fields but not the
0014 %   data).
0015 %
0016 %   The structure of ILWD files is often complex and this is reflected in the
0017 %   complicated structs produced by ILWDREAD.  The struct can be navigated by
0018 %   typing the element names on the command line to see the available fields.
0019 %
0020 %   >>>> ilwd = ilwdread('results.ilwd')
0021 %
0022 %   ilwd =
0023 %
0024 %           tag: 'ilwd'
0025 %       comment: 'ilwdread example'
0026 %          name: 'ligo:ldas:file'
0027 %            m1: [1x1   struct]
0028 %
0029 %   >>>> ilwd.m1
0030 %
0031 %   ans =
0032 %
0033 %          tag: 'int_4s'
0034 %         dims: 2
0035 %         name: 'one two'
0036 %       int_4s: [2x1 double]
0037 %
0038 %   >>>> ilwd.m1.int_4s
0039 %
0040 %   ans =
0041 %
0042 %        1
0043 %        2
0044 %
0045 %   It may be convenient to copy the data to a concisely named variable.
0046 %
0047 %   >>>> a = ilwd.m1.int_4s;
0048 %
0049 %   The member structs fields of a struct must be name-mangled (m1, m2, ...)
0050 %   rather than subscripted (m(1), m(2), ...) to allow them to represent
0051 %   different structures.  The EVAL command can be used to simulate
0052 %   subscripting, replacing "data.m(i)" with "eval(['data.m' i])".
0053 %
0054 %   The array fields are MATLAB vectors containing numerical data.  The
0055 %   values are preserved but the format is not (for example, int types are
0056 %   converted to double).  Complex types are also unpacked to construct
0057 %   complex vectors.
0058 %
0059 %   ILWDREAD accepts only uncompressed ASCII ILWD files.  Any non-standard
0060 %   attributes should be correctly parsed to a string (but will issue a
0061 %   warning).  Any non-standard tags will cause an error.  Bugs and comments
0062 %   to Antony.Searle@anu.edu.au
0063 %
0064 %   See also
0065 
0066 %   Author : Antony C. Searle
0067 %   Version: 0.2
0068 
0069 fid = fopen(filename, 'rt');            % open the file
0070 if fid == -1                            % check for errors
0071    error('open failed');
0072 end
0073 header = fscanf(fid, '%c', 8);          % read in the file header
0074 if nargin < 2                           % check for a verbose argument
0075    verbose = 0;                         % no argument so set to default (quiet)
0076 end
0077 if header ~= '<?ilwd?>'                 % confirm we have an ilwd file
0078    error(['unhandled format ' header]);
0079 end
0080 if verbose
0081    disp(header);
0082 end
0083 data = parsetag(fid, '', verbose);      % recursively parse the ilwd element
0084 fclose(fid);                            % close the file
0085 
0086 % parsetag helper function
0087 
0088 function data = parsetag(fid, indent, verbose);
0089 %PARSETAG Recursively parse ILWD tags for ILWDREAD
0090 %   See also ILWDREAD
0091 
0092 %   Author : Antony C. Searle
0093 %   Version: 0.2
0094 
0095 c = fscanf(fid, '%c', 1);               % find the tag start
0096 while c ~= '<'
0097    c = fscanf(fid, '%c', 1);
0098 end
0099 
0100 [data.tag, terminator] = parseidentifier(fid);
0101                                         % read the tag
0102 
0103 local_ndim = 1;                         % set default attribute values
0104 local_size = 1;
0105 local_dims = 1;
0106 
0107 if verbose
0108    disp([indent '<' data.tag]);
0109 end
0110 
0111 flag = 1;                                   
0112 while flag                              % parse attributes
0113    if terminator ~= '>'                 % if not at the tag end, parse an
0114                                         %    attribute
0115       [string, terminator] = parseidentifier(fid);
0116    end
0117    switch terminator                    % switch on identifier terminating
0118                                         %    character
0119    case '='                             % assigned attribute
0120       fscanf(fid, '%c', 1);             % ignore opening quote
0121       switch string                     % switch on attribute name
0122       case 'size'
0123          data.size = fscanf(fid, '%d', 1);
0124                                         % read decimal integer
0125          local_size = data.size;
0126          fscanf(fid, '%c', 1);          % ignore the closing quote
0127          if verbose
0128             disp([indent '    size=' num2str(data.size)]);
0129          end
0130       case 'ndim'
0131          data.ndim = fscanf(fid, '%d', 1); 
0132                                         % read decimal integer
0133          local_ndim = data.ndim;
0134          fscanf(fid, '%c', 1);          % ignore the closing quote
0135          if verbose
0136             disp([indent '    ndim=' num2str(data.ndim)]);
0137          end
0138       case 'dims'
0139          data.dims = 1;                 % touch the field
0140          for i = 1:local_ndim           % loop over dimensions
0141             data.dims(i) = fscanf(fid, '%d', 1);
0142                                         % read in dimensions
0143             fscanf(fid, '%c', 1);       % ignore the closing quote
0144          end
0145          local_dims = data.dims;
0146          if verbose
0147             disp([indent '    dims=' num2str(data.dims)]);
0148          end
0149       case 'comment'
0150          [data.comment, terminator] = parseattribute(fid);
0151                                         % read string
0152          if verbose
0153             disp([indent '    comment=' data.comment]);
0154          end
0155       case 'name'
0156          [data.name, terminator] = parseattribute(fid);
0157                                         % read string
0158          if verbose
0159             disp([indent '    name=' data.name]);
0160          end
0161       case 'units'
0162          [data.units, terminator] = parseattribute(fid);
0163                                         % read string
0164          if verbose
0165             disp([indent '    units=' data.units]);
0166          end
0167       case 'mdorder'
0168          [data.mdorder, terminator] = parseattribute(fid);
0169                                         % read string
0170          if verbose
0171             disp([indent '    mdorder=' data.mdorder]);
0172          end
0173       case 'nullmask'
0174          [data.nullmask, terminator] = parseattribute(fid);
0175                                         %read string
0176          if verbose
0177             disp([indent '    nullmask=' data.nullmask]);
0178          end
0179       case 'format'
0180          [data.format, terminator] = parseattribute(fid);
0181                                         % read string
0182          if verbose
0183             disp([indent '    format=' data.format]);
0184          end
0185          if data.format ~= 'ascii'      % check format is ASCII
0186             error(['unhandled format: ' data.format]);
0187          end
0188       case 'compression'
0189          [data.compression, terminator] = parseattribute(fid);
0190                                         % read string
0191          if verbose
0192             disp([indent '    format=' data.format]);
0193          end
0194          if (data.compression ~= 'none') | (data.compression ~= 'gzip0');
0195                                         % check data is uncompressed
0196             error(['unhandled compression: ' data.compression']);
0197          end
0198       case 'byteorder'
0199          error(['unhandled binary attribute: byteorder']);
0200                                         % implies unsupported binary format
0201       case 'bytes'
0202          error(['unhandled binary attribute: bytes']);
0203                                         % implies unsupported binary format
0204       case 'parser'
0205          [data.parser, terminator] = parseattribute(fid);
0206                                         % read string
0207          if verbose
0208             disp([indent '    parser=' data.parser]);
0209          end
0210       case 'metadata'
0211           [data.metadata, terminator] = parseattribute(fid);
0212                                         % read string
0213           if verbose
0214               disp([indent '    metadata=' data.metadata]);
0215           end
0216       case 'dataValueUnit'
0217           [data.dataValueUnit, terminator] = parseattribute(fid);
0218                                         % read string
0219           if verbose
0220               disp([indent '    dataValueUnit=' data.dataValueUnit]);
0221           end
0222       case 'dx'
0223          data.dx = fscanf(fid, '%f', 1);
0224                                         % read floating-point number
0225          fscanf(fid, '%c', 1);          % ignore the closing quote
0226          if verbose
0227             disp([indent '    dx=' num2str(data.dx)]);
0228          end         
0229      case 'startx'
0230          data.startx = fscanf(fid, '%f', 1);
0231                                         % read floating-point number
0232          fscanf(fid, '%c', 1);          % ignore the closing quote
0233          if verbose
0234             disp([indent '    startx=' num2str(data.startx)]);
0235          end
0236       otherwise
0237          disp(['warning: nonstandard attribute ' string]);
0238          eval(['[data.' string ', terminator] = parseattribute(fid);']);
0239                                         % read string into nonstandard attribute
0240       end
0241    case '>'                             % end of the tag
0242       if verbose
0243          disp([indent '    >']);
0244       end
0245       flag = 0;                         % stop while loop
0246    otherwise
0247       error(['unhandled character ' terminator]);
0248                                         % unexpected character
0249    end
0250 end
0251 
0252 switch data.tag                         % switch on tag type
0253 case 'ilwd'                             % container type
0254    indent2 = ['    ' indent];           % set indentation level
0255    for i = 1:local_size                 % read in "size" elements
0256       eval(['data.m' num2str(i) ' = parsetag(fid, indent2, verbose);']);
0257                                         % construct the field name and parse
0258                                         %    into it
0259    end
0260 case 'char'
0261    data.char = fscanf(fid, '%c', data.dims);
0262                                         % read in "dims" characters
0263 case 'char_u'
0264    buffer = fscanf(fid, '%c%d');        % read in as many character-separated
0265                                         % decimal integers as possible
0266    data.char_u = buffer(2:2:length(buffer));
0267                                         % strip out the integers
0268 case 'char_s'
0269    buffer = fscanf(fid, '%c%d');        % read in as many character-separated
0270                                         % decimal integers as possible
0271    data.char_s = buffer(2:2:length(buffer));
0272                                         % strip out the integers
0273 case 'int_2u'
0274    data.int_2u = fscanf(fid, '%d');     % read in as many decimal integers as
0275                                         % possible
0276 case 'int_4u'
0277    data.int_4u = fscanf(fid, '%d');     % read in as many decimal integers as
0278                                         % possible
0279 case 'int_8u'
0280    data.int_8u = fscanf(fid, '%d');     % read in as many decimal integers as
0281                                         % possible
0282 case 'int_2s'
0283    data.int_2s = fscanf(fid, '%d');     % read in as many decimal integers as
0284                                         % possible
0285 case 'int_4s'
0286    data.int_4s = fscanf(fid, '%d');     % read in as many decimal integers as
0287                                         % possible
0288 case 'int_8s'
0289    data.int_8s = fscanf(fid, '%d');     % read in as many decimal integers as
0290                                         % possible
0291 case 'real_4'
0292    data.real_4 = fscanf(fid, '%f');     % read in as many decimal integers as
0293                                         % possible
0294 case 'real_8'
0295    data.real_8 = fscanf(fid, '%f');     % read in as many decimal integers as
0296                                         % possible
0297 case 'complex_8'
0298    buffer = fscanf(fid, '%f');          % read in as many floating point
0299                                         %    decimals as possible
0300    data.complex_8 = buffer(1:2:size(buffer)) + buffer(2:2:size(buffer)) * ...
0301       sqrt(-1);                         % unpack to a complex array
0302 case 'complex_16'
0303    buffer = fscanf(fid, '%f');          % read in as many floating point
0304                                         %    decimals as possible
0305    data.complex_16 = buffer(1:2:size(buffer)) + buffer(2:2:size(buffer)) * ...
0306       sqrt(-1);                         % unpack to a complex array
0307 case 'lstring'
0308    data.lstring = fscanf(fid, '%c', local_size);
0309                                         % read "size" characters into a string
0310 case 'external'
0311    data.external = fscanf(fid, '%c', local_size);
0312                                         % read "size" characters into a string
0313 otherwise
0314    error(['unrecognised tag ' data.tag]);
0315                                         % tag is not supported
0316 end
0317 
0318 [string, terminator] = parseidentifier(fid);      
0319                                         % ignore the end tag
0320 if verbose
0321    disp([indent string terminator]);
0322 end
0323 
0324 % parseattribute helper function
0325 
0326 function [string, terminator] = parseattribute(fid);
0327 %PARSEATTRIBUTE Parse attributes for ILWDREAD
0328 %   See also ILWDREAD
0329 
0330 %   Author : Antony C. Searle
0331 %   Version: 0.2
0332 
0333 string = '';                            % empty output
0334 flag = 1;
0335 while flag;                             % read in characters
0336    terminator = fscanf(fid, '%c', 1);   % get a character
0337    switch terminator                    % switch on the character
0338    case double(39)                      % single-quote terminates
0339       flag = 0;
0340    case double(34)                      % double-quote terminates
0341       flag = 0;
0342    otherwise                            % any other character
0343       string = [string terminator];     %    is part of output
0344    end
0345 end
0346 
0347 % parseidentifer
0348 
0349 function [string, terminator] = parseidentifier(fid);
0350 %PARSEIDENTIFIER Parse identifiers for ILWDREAD
0351 %   See also ILWDREAD
0352 
0353 %   Author : Antony C. Searle
0354 %   Version: 0.2
0355 
0356 string = '';                            % empty output
0357 flag = 1;
0358 white = 1;                              % leading whitespace?
0359 while flag;                             % read in characters
0360    terminator = fscanf(fid, '%c', 1);   % get a character
0361    switch terminator                    % switch on the character
0362    case '='                             % equals terminates
0363       flag = 0;
0364    case '>'                             % right-angle terminates
0365       flag = 0;
0366    case double(39)                      % single-quote terminates
0367       flag = 0;
0368    case double(34)                      % double-quote terminates
0369       flag = 0;
0370    case double(10)                      % newline terminates unless
0371                                         %    still leading whitespace
0372       flag = white;
0373    case ' '                             % space terminates unless
0374                                         %    still leading whitespace
0375       flag = white;
0376    otherwise                            % any other character
0377       white = 0;                        %    terminates whitespace
0378       string = [string terminator];     %    and is part of output
0379    end
0380 end
0381 
0382 
0383 
0384 
0385 
0386 
0387

Generated on Tue 05-Oct-2004 10:40:50 by m2html © 2003