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>
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