dba2mat

PURPOSE ^

DBA2MAT Load data and metadata from a dba file.

SYNOPSIS ^

function [meta, data] = dba2mat(filename, varargin)

DESCRIPTION ^

DBA2MAT  Load data and metadata from a dba file.

  Syntax:
    [META, DATA] = DBA2MAT(FILENAME)
    [META, DATA] = DBA2MAT(FILENAME, OPTIONS)
    [META, DATA] = DBA2MAT(FILENAME, OPT1, VAL1, ...)

  Description:
    [META, DATA] = DBA2MAT(FILENAME) reads the dba file named by string
    FILENAME, loading its metadata in struct META and its data in array DATA.

    [META, DATA] = DBA2MAT(FILENAME, OPTIONS) and 
    [META, DATA] = DBA2MAT(FILENAME, OPT1, VAL1, ...) accept the following 
    options given in key-value pairs OPT1, VAL1... or in a struct OPTIONS with 
    field names as option keys and field values as option values:
      FORMAT: data output format.
        String setting the format of the output DATA. Valid values are:
          'array': DATA is a matrix with sensor readings in the column order
            specified by the SENSORS metadata field.
          'struct': DATA is a struct with sensor names as field names
            and column vectors of sensor readings as field values.
        Default value: 'array'
      SENSORS: sensor filtering list.
        String cell array with the names of the sensors of interest.
        If given, only the sensors present in both the input data file and this
        list will be present in output. The string 'all' may also be given,
        in which case sensor filtering is not performed and all sensors
        in the input data file will be present in output.
        Default value: 'all' (do not perform sensor filtering).

    META has the following fields based on the tags of the ascii header:
      HEADERS: a struct with the ascii tags present in dba header with fields:
        DBD_LABEL: ascii tag in dba header.
        ENCODING_VER: ascii tag in dba header.
        NUM_ASCII_TAGS: ascii tag in dba header.
        ALL_SENSORS: ascii tag in dba header.
        FILENAME: ascii tag in dba header.
        THE8X3_FILENAME: ascii tag in dba header.
        FILENAME_EXTENSION: ascii tag in dba header.
        FILENAME_LABEL: ascii tag in dba header.
        MISSION_NAME: ascii tag in dba header.
        FILEOPEN_TIME: ascii tag in dba header.
        SENSORS_PER_CYCLE: ascii tag in dba header.
        NUM_LABEL_LINES: ascii tag in dba header.
        NUM_SEGMENTS: ascii tag in dba header.
        SEGMENT_FILENAMES: string cell array with the contents of
           the ascii tags SEGMENT_FILENAME_0, ... , SEGMENT_FILENAME_N-1.
      SENSORS: string cell array with the names of the sensors present
        in the returned data array (in the same column order as the data).
      UNITS: string cell array with the units of the sensors present
        in the returned data array.
      BYTES: array with the number of bytes of each sensor present
        in the returned data array.
      SOURCES: string cell array containing FILENAME.

  Notes:
    A description of the dba format may be found here:
      <http://marine.rutgers.edu/~kerfoot/slocum/data/readme/wrc_doco/dbd_file_format.txt>

  Examples:
    % Retrieve data from all sensors as array:
    [meta, data] = dba2mat('test.dba')
    % Retrieve data from all sensors as struct:
    [meta, data] = dba2mat('test.dba', 'format', 'struct')
    % Retrieve data from time sensors as struct:
    [meta, data] = dba2mat('test.dba', 'format', 'struct', ...
                           'sensors', {'m_present_time' 'sci_m_present_time'})

  See also:
    XBD2DBA
    DBACAT
    DBAMERGE

  Authors:
    Joan Pau Beltran  <joanpau.beltran@socib.cat>

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

DOWNLOAD ^

dba2mat.m

SOURCE CODE ^

0001 function [meta, data] = dba2mat(filename, varargin)
0002 %DBA2MAT  Load data and metadata from a dba file.
0003 %
0004 %  Syntax:
0005 %    [META, DATA] = DBA2MAT(FILENAME)
0006 %    [META, DATA] = DBA2MAT(FILENAME, OPTIONS)
0007 %    [META, DATA] = DBA2MAT(FILENAME, OPT1, VAL1, ...)
0008 %
0009 %  Description:
0010 %    [META, DATA] = DBA2MAT(FILENAME) reads the dba file named by string
0011 %    FILENAME, loading its metadata in struct META and its data in array DATA.
0012 %
0013 %    [META, DATA] = DBA2MAT(FILENAME, OPTIONS) and
0014 %    [META, DATA] = DBA2MAT(FILENAME, OPT1, VAL1, ...) accept the following
0015 %    options given in key-value pairs OPT1, VAL1... or in a struct OPTIONS with
0016 %    field names as option keys and field values as option values:
0017 %      FORMAT: data output format.
0018 %        String setting the format of the output DATA. Valid values are:
0019 %          'array': DATA is a matrix with sensor readings in the column order
0020 %            specified by the SENSORS metadata field.
0021 %          'struct': DATA is a struct with sensor names as field names
0022 %            and column vectors of sensor readings as field values.
0023 %        Default value: 'array'
0024 %      SENSORS: sensor filtering list.
0025 %        String cell array with the names of the sensors of interest.
0026 %        If given, only the sensors present in both the input data file and this
0027 %        list will be present in output. The string 'all' may also be given,
0028 %        in which case sensor filtering is not performed and all sensors
0029 %        in the input data file will be present in output.
0030 %        Default value: 'all' (do not perform sensor filtering).
0031 %
0032 %    META has the following fields based on the tags of the ascii header:
0033 %      HEADERS: a struct with the ascii tags present in dba header with fields:
0034 %        DBD_LABEL: ascii tag in dba header.
0035 %        ENCODING_VER: ascii tag in dba header.
0036 %        NUM_ASCII_TAGS: ascii tag in dba header.
0037 %        ALL_SENSORS: ascii tag in dba header.
0038 %        FILENAME: ascii tag in dba header.
0039 %        THE8X3_FILENAME: ascii tag in dba header.
0040 %        FILENAME_EXTENSION: ascii tag in dba header.
0041 %        FILENAME_LABEL: ascii tag in dba header.
0042 %        MISSION_NAME: ascii tag in dba header.
0043 %        FILEOPEN_TIME: ascii tag in dba header.
0044 %        SENSORS_PER_CYCLE: ascii tag in dba header.
0045 %        NUM_LABEL_LINES: ascii tag in dba header.
0046 %        NUM_SEGMENTS: ascii tag in dba header.
0047 %        SEGMENT_FILENAMES: string cell array with the contents of
0048 %           the ascii tags SEGMENT_FILENAME_0, ... , SEGMENT_FILENAME_N-1.
0049 %      SENSORS: string cell array with the names of the sensors present
0050 %        in the returned data array (in the same column order as the data).
0051 %      UNITS: string cell array with the units of the sensors present
0052 %        in the returned data array.
0053 %      BYTES: array with the number of bytes of each sensor present
0054 %        in the returned data array.
0055 %      SOURCES: string cell array containing FILENAME.
0056 %
0057 %  Notes:
0058 %    A description of the dba format may be found here:
0059 %      <http://marine.rutgers.edu/~kerfoot/slocum/data/readme/wrc_doco/dbd_file_format.txt>
0060 %
0061 %  Examples:
0062 %    % Retrieve data from all sensors as array:
0063 %    [meta, data] = dba2mat('test.dba')
0064 %    % Retrieve data from all sensors as struct:
0065 %    [meta, data] = dba2mat('test.dba', 'format', 'struct')
0066 %    % Retrieve data from time sensors as struct:
0067 %    [meta, data] = dba2mat('test.dba', 'format', 'struct', ...
0068 %                           'sensors', {'m_present_time' 'sci_m_present_time'})
0069 %
0070 %  See also:
0071 %    XBD2DBA
0072 %    DBACAT
0073 %    DBAMERGE
0074 %
0075 %  Authors:
0076 %    Joan Pau Beltran  <joanpau.beltran@socib.cat>
0077 
0078 %  Copyright (C) 2013-2016
0079 %  ICTS SOCIB - Servei d'observacio i prediccio costaner de les Illes Balears
0080 %  <http://www.socib.es>
0081 %
0082 %  This program is free software: you can redistribute it and/or modify
0083 %  it under the terms of the GNU General Public License as published by
0084 %  the Free Software Foundation, either version 3 of the License, or
0085 %  (at your option) any later version.
0086 %
0087 %  This program is distributed in the hope that it will be useful,
0088 %  but WITHOUT ANY WARRANTY; without even the implied warranty of
0089 %  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0090 %  GNU General Public License for more details.
0091 %
0092 %  You should have received a copy of the GNU General Public License
0093 %  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0094 
0095   error(nargchk(1, 5, nargin, 'struct'));
0096   
0097   
0098   %% Set options and default values.
0099   options.format = 'array';
0100   options.sensors = 'all';
0101   
0102   
0103   %% Parse optional arguments.
0104   % Get option key-value pairs in any accepted call signature.
0105   argopts = varargin;
0106   if isscalar(argopts) && isstruct(argopts{1})
0107     % Options passed as a single option struct argument:
0108     % field names are option keys and field values are option values.
0109     opt_key_list = fieldnames(argopts{1});
0110     opt_val_list = struct2cell(argopts{1});
0111   elseif mod(numel(argopts), 2) == 0
0112     % Options passed as key-value argument pairs.
0113     opt_key_list = argopts(1:2:end);
0114     opt_val_list = argopts(2:2:end);
0115   else
0116     error('glider_toolbox:dba2mat:InvalidOptions', ...
0117           'Invalid optional arguments (neither key-value pairs nor struct).');
0118   end
0119   % Overwrite default options with values given in extra arguments.
0120   for opt_idx = 1:numel(opt_key_list)
0121     opt = lower(opt_key_list{opt_idx});
0122     val = opt_val_list{opt_idx};
0123     if isfield(options, opt)
0124       options.(opt) = val;
0125     else
0126       error('glider_toolbox:dba2mat:InvalidOption', ...
0127             'Invalid option: %s.', opt);
0128     end
0129   end
0130   
0131   
0132   %% Set option flags and values.
0133   output_format = lower(options.format);
0134   sensor_filtering = true;
0135   if ischar(options.sensors) && strcmp(options.sensors, 'all')
0136     sensor_filtering = false;
0137   end
0138   sensor_list = cellstr(options.sensors);
0139   
0140   
0141   %% Open the file.
0142   [fid, fid_msg] = fopen(filename, 'r');
0143   if fid < 0
0144     error('glider_toolbox:dba2mat:FileError', fid_msg);
0145   end
0146   
0147   
0148   %% Process the file.
0149   try
0150     % Read mandatory header tags.
0151     num_mandatory_ascii_tags = 12;
0152     header_map = { ...
0153       'dbd_label'          'dbd_label: %s\n'
0154       'encoding_ver'       'encoding_ver: %s\n'
0155       'num_ascii_tags'     'num_ascii_tags: %d\n'
0156       'all_sensors'        'all_sensors: %d\n'
0157       'filename'           'filename: %s\n'
0158       'the8x3_filename'    'the8x3_filename: %s\n'
0159       'filename_extension' 'filename_extension: %s\n'
0160       'filename_label'     'filename_label: %s\n'
0161       'mission_name'       'mission_name: %s\n'
0162       'fileopen_time'      'fileopen_time: %s\n'
0163       'sensors_per_cycle'  'sensors_per_cycle: %d\n'
0164       'num_label_lines'    'num_label_lines: %d\n' };
0165     header_fields = header_map(:,1);
0166     header_fmtstr = [header_map{:,2}];
0167     header_values = textscan(fid, header_fmtstr, 1, 'ReturnOnError', false);
0168     header_struct = {header_fields{:}; header_values{:}};
0169     header_struct = struct(header_struct{:});
0170     
0171     % Read optional tags (number of segment files and segment file names).
0172     num_ascii_tags = header_values{3};
0173     if num_ascii_tags == num_mandatory_ascii_tags
0174       header_struct.num_segments = [];
0175       header_struct.segment_filenames = {};
0176     else
0177       num_segments_values = ...
0178         textscan(fid, 'num_segments: %d\n', 1, 'ReturnOnError', false);
0179       segment_format = repmat(sprintf('segment_filename_%%*u: %%s\n'), ...
0180                               1, num_segments_values{1});
0181       segment_values = textscan(fid, segment_format, 1, 'ReturnOnError', false);
0182       header_struct.num_segments = num_segments_values{1};
0183       header_struct.segment_filenames = vertcat(segment_values{:});
0184     end
0185     
0186     % Read label lines (sensor names, sensor units and bytes per sensor).
0187     num_sensors = header_struct.sensors_per_cycle;
0188     sensor_values = textscan(fid, '%s', num_sensors, 'ReturnOnError', false);
0189     unit_values   = textscan(fid, '%s', num_sensors, 'ReturnOnError', false);
0190     byte_values   = textscan(fid, '%d', num_sensors, 'ReturnOnError', false);
0191     
0192     % Build metadata structure.
0193     [~, name, ext] = fileparts(filename);
0194     meta.sources = {[name ext]};
0195     meta.headers = header_struct;
0196     meta.sensors = sensor_values{1};
0197     meta.units = unit_values{1};
0198     meta.bytes = byte_values{1};
0199     
0200     % Read sensor data filtering selected sensors if needed.
0201     sensor_format = repmat({'%f'}, meta.headers.sensors_per_cycle, 1);
0202     if sensor_filtering
0203       selected_sensors = ismember(meta.sensors, sensor_list);
0204       meta.sensors = meta.sensors(selected_sensors);
0205       meta.units = meta.units(selected_sensors);
0206       meta.bytes = meta.bytes(selected_sensors);
0207       sensor_format(~selected_sensors) = {'%*f'};
0208     end
0209     fmt_str = [sprintf('%s ', sensor_format{1:end-1}) sensor_format{end} '\n'];
0210     data_values = textscan(fid, fmt_str, 'ReturnOnError', false);
0211     
0212     % Convert data to desired output format.
0213     switch output_format
0214       case 'array'
0215         data = [data_values{:}];
0216       case 'struct'
0217         data = cell2struct(data_values, meta.sensors, 2);
0218       otherwise
0219         error('glider_toolbox:dba2mat:InvalidFormat', ...
0220               'Invalid output format: %s.', format)
0221     end
0222   catch exception
0223     % Close the file after a reading error.
0224     fclose(fid);
0225     rethrow(exception);
0226   end
0227   
0228   
0229   %% Close the file after successful reading.
0230   fclose(fid); 
0231 
0232 end

Generated on Fri 06-Oct-2017 10:47:42 by m2html © 2005