sgeng2mat Load data and metadata from a Seaglider eng file. Syntax: [META, DATA] = sgeng2mat(FILENAME) [META, DATA] = sgeng2mat(FILENAME, OPTIONS) [META, DATA] = sgeng2mat(FILENAME, OPT1, VAL1, ...) Description: [META, DATA] = sgeng2mat(FILENAME, VARARGIN) reads the Seaglider eng file named by string FILENAME, loading its metadata in struct META and its data in struct DATA. [META, DATA] = sgeng2mat(FILENAME, OPTIONS) and [META, DATA] = sgeng2mat(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 data readings as columns ordered as in the COLUMNS metadata field. 'struct': DATA is a struct with column names as field names and column vectors of data columns as field values. Default value: 'array' COLUMNS: data column filtering list. String cell array with the names of the data columns of interest as reported in the COLUMNS metadata field (see note on column renaming). If given, only parameters present in both the input file and this list will be present in output. The string 'all' may also be given, in which case column filtering is not performed and all columns in the input list will be present in output. Default value: 'all' (do not perform column filtering). META has the following fields based on the tags of the header and the content of some metaparameters: HEADERS: a struct with the initial tags in the eng file: VERSION: string with the version tag in eng header. GLIDER : string with the glider id tag in eng header. MISSION: mission number tag in eng header. DIVE : dive number tag in eng header. BASESTATION_VERSION: string with the basestation tag in eng header. START : start date and time tag in eng header (month, day of month, year after 1900, hour, minute and second). START_SECS: dive start time from header tag in POSIX time (seconds since 1970 Janyuay 01 00:00:00 UTC). COLUMNS: string cell array with the names of the columns in the returned data array (in the same column order as the data). See note on column renaming. SOURCES: string cell array containing FILENAME. Notes: This parsing is based on the information about the eng files provided by the Seaglider User's Guide and the Seaglider File Formats Manual and the Parameter Reference Manual. The information there is not complete, so the final result might be suboptimal. Some column names reported in the COLUMNS field of the eng file header are not valid identifiers because they contain a dot character ('sbect.tempFreq'). They are renamed in the COLUMNS metadata field by replacing the dot character '.' by an underscore '_' ('sbect.tempFreq'). The columns header line is still available untouched in the COLUMNS field of the HEADERS metadata field. Examples: [meta, data] = sgeng2mat(filename) [meta, data] = sgeng2mat(filename, 'format', 'struct') options = struct( ... 'columns', {{'elaps_t' 'depth' 'head' 'pitchAng' 'rollAng'}}, ... 'format', {'merged'}); [meta, data] = sgeng2mat(filename, options) See also: SGLOG2MAT SGLOGCAT SGENGCAT SGENGLOGMERGE Authors: Joan Pau Beltran <joanpau.beltran@socib.cat>
0001 function [meta, data] = sgeng2mat(filename, varargin) 0002 %sgeng2mat Load data and metadata from a Seaglider eng file. 0003 % 0004 % Syntax: 0005 % [META, DATA] = sgeng2mat(FILENAME) 0006 % [META, DATA] = sgeng2mat(FILENAME, OPTIONS) 0007 % [META, DATA] = sgeng2mat(FILENAME, OPT1, VAL1, ...) 0008 % 0009 % Description: 0010 % [META, DATA] = sgeng2mat(FILENAME, VARARGIN) reads the Seaglider eng file 0011 % named by string FILENAME, loading its metadata in struct META and its data 0012 % in struct DATA. 0013 % 0014 % [META, DATA] = sgeng2mat(FILENAME, OPTIONS) and 0015 % [META, DATA] = sgeng2mat(FILENAME, OPT1, VAL1, ...) accept the following 0016 % options given in key-value pairs OPT1, VAL1... or in a struct OPTIONS 0017 % with field names as option keys and field values as option values: 0018 % FORMAT: data output format. 0019 % String setting the format of the output DATA. Valid values are: 0020 % 'array': DATA is a matrix with data readings as columns ordered 0021 % as in the COLUMNS metadata field. 0022 % 'struct': DATA is a struct with column names as field names 0023 % and column vectors of data columns as field values. 0024 % Default value: 'array' 0025 % COLUMNS: data column filtering list. 0026 % String cell array with the names of the data columns of interest 0027 % as reported in the COLUMNS metadata field (see note on column 0028 % renaming). If given, only parameters present in both the input 0029 % file and this list will be present in output. The string 'all' 0030 % may also be given, in which case column filtering is not performed 0031 % and all columns in the input list will be present in output. 0032 % Default value: 'all' (do not perform column filtering). 0033 % 0034 % META has the following fields based on the tags of the header and the 0035 % content of some metaparameters: 0036 % HEADERS: a struct with the initial tags in the eng file: 0037 % VERSION: string with the version tag in eng header. 0038 % GLIDER : string with the glider id tag in eng header. 0039 % MISSION: mission number tag in eng header. 0040 % DIVE : dive number tag in eng header. 0041 % BASESTATION_VERSION: string with the basestation tag in eng header. 0042 % START : start date and time tag in eng header (month, day of month, 0043 % year after 1900, hour, minute and second). 0044 % START_SECS: dive start time from header tag in POSIX time 0045 % (seconds since 1970 Janyuay 01 00:00:00 UTC). 0046 % COLUMNS: string cell array with the names of the columns in the returned 0047 % data array (in the same column order as the data). See note on column 0048 % renaming. 0049 % SOURCES: string cell array containing FILENAME. 0050 % 0051 % Notes: 0052 % This parsing is based on the information about the eng files provided by 0053 % the Seaglider User's Guide and the Seaglider File Formats Manual and the 0054 % Parameter Reference Manual. The information there is not complete, so the 0055 % final result might be suboptimal. 0056 % 0057 % Some column names reported in the COLUMNS field of the eng file header 0058 % are not valid identifiers because they contain a dot character 0059 % ('sbect.tempFreq'). They are renamed in the COLUMNS metadata field by 0060 % replacing the dot character '.' by an underscore '_' ('sbect.tempFreq'). 0061 % The columns header line is still available untouched in the COLUMNS field 0062 % of the HEADERS metadata field. 0063 % 0064 % Examples: 0065 % [meta, data] = sgeng2mat(filename) 0066 % [meta, data] = sgeng2mat(filename, 'format', 'struct') 0067 % options = struct( ... 0068 % 'columns', {{'elaps_t' 'depth' 'head' 'pitchAng' 'rollAng'}}, ... 0069 % 'format', {'merged'}); 0070 % [meta, data] = sgeng2mat(filename, options) 0071 % 0072 % See also: 0073 % SGLOG2MAT 0074 % SGLOGCAT 0075 % SGENGCAT 0076 % SGENGLOGMERGE 0077 % 0078 % Authors: 0079 % Joan Pau Beltran <joanpau.beltran@socib.cat> 0080 0081 % Copyright (C) 2013-2016 0082 % ICTS SOCIB - Servei d'observacio i prediccio costaner de les Illes Balears 0083 % <http://www.socib.es> 0084 % 0085 % This program is free software: you can redistribute it and/or modify 0086 % it under the terms of the GNU General Public License as published by 0087 % the Free Software Foundation, either version 3 of the License, or 0088 % (at your option) any later version. 0089 % 0090 % This program is distributed in the hope that it will be useful, 0091 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0092 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0093 % GNU General Public License for more details. 0094 % 0095 % You should have received a copy of the GNU General Public License 0096 % along with this program. If not, see <http://www.gnu.org/licenses/>. 0097 0098 error(nargchk(1, 5, nargin, 'struct')); 0099 0100 0101 %% Set options and default values. 0102 options.format = 'array'; 0103 options.columns = 'all'; 0104 0105 0106 %% Parse optional arguments. 0107 % Get option key-value pairs in any accepted call signature. 0108 argopts = varargin; 0109 if isscalar(argopts) && isstruct(argopts{1}) 0110 % Options passed as a single option struct argument: 0111 % field names are option keys and field values are option values. 0112 opt_key_list = fieldnames(argopts{1}); 0113 opt_val_list = struct2cell(argopts{1}); 0114 elseif mod(numel(argopts), 2) == 0 0115 % Options passed as key-value argument pairs. 0116 opt_key_list = argopts(1:2:end); 0117 opt_val_list = argopts(2:2:end); 0118 else 0119 error('glider_toolbox:sgeng2mat:InvalidOptions', ... 0120 'Invalid optional arguments (neither key-value pairs nor struct).'); 0121 end 0122 % Overwrite default options with values given in extra arguments. 0123 for opt_idx = 1:numel(opt_key_list) 0124 opt = lower(opt_key_list{opt_idx}); 0125 val = opt_val_list{opt_idx}; 0126 if isfield(options, opt) 0127 options.(opt) = val; 0128 else 0129 error('glider_toolbox:sgeng2mat:InvalidOption', ... 0130 'Invalid option: %s.', opt); 0131 end 0132 end 0133 0134 0135 %% Set option flags and values. 0136 output_format = lower(options.format); 0137 column_filter = true; 0138 if ischar(options.columns) && strcmp(options.columns, 'all') 0139 column_filter = false; 0140 end 0141 column_list = cellstr(options.columns); 0142 0143 0144 %% Open the file. 0145 [fid, fid_msg] = fopen(filename, 'r'); 0146 if fid < 0 0147 error('glider_toolbox:sgeng2mat:FileError', fid_msg); 0148 end 0149 0150 0151 %% Parse the file. 0152 try 0153 % Read header tags: 0154 header_map = { ... 0155 'version' '%%version: %s\n' 1 0156 'glider' '%%glider: %s\n' 1 0157 'mission' '%%mission: %d\n' 1 0158 'dive' '%%dive: %d\n' 1 0159 'basestation_version' '%%basestation_version: %s\n' 1 0160 'start' '%%start: %d %d %d %d %d %d\n' 6 0161 'columns' '%%columns: %s\n' 1}; 0162 header_fields = header_map(:,1); 0163 header_fmtstr = header_map(:,2); 0164 header_length = vertcat(header_map{:,3}); 0165 % TEXTSCAN whould be useful here, but it fails on escaped '%' sign. 0166 % header_values = ... 0167 % textscan([header_fmt_str{:}], 1, 'ReturnOnError', false, 'Delimiter', ''); 0168 header_values = cell(size(header_fields)); 0169 for header_field_idx = 1:numel(header_fields) 0170 [header_values{header_field_idx}, header_field_count] = ... 0171 fscanf(fid, header_fmtstr{header_field_idx}, ... 0172 [1, header_length(header_field_idx)]); 0173 if header_field_count < 1 0174 error('glider_toolbox:sgeng2mat:BadFileFormat', ... 0175 'Mismatch between file and header format (field %d).', ... 0176 header_field_index); 0177 end 0178 end 0179 header_struct = {header_fields{:}; header_values{:}}; 0180 header_struct = struct(header_struct{:}); 0181 0182 % Build metadata structure: 0183 % - The filename (without base directory). 0184 % - The log file header lines. 0185 % - The dive start time as POSIX time. 0186 % - The list of names of data columns. 0187 [~, name, ext] = fileparts(filename); 0188 meta.sources = {[name ext]}; 0189 meta.headers = header_struct; 0190 meta.start_secs = ... 0191 utc2posixtime(datenum([header_struct.start(:, 3) + 1900 ... 0192 header_struct.start(:, [1 2 4 5 6])])); 0193 meta.columns = ... 0194 strrep(regexp(header_struct.columns, ',', 'split'), '.', '_')'; 0195 0196 % Read eng data columns filtering selected columns if needed: 0197 fscanf(fid, '%%data:\n'); 0198 dataline_format = repmat({'%f'}, numel(meta.columns), 1); 0199 if column_filter 0200 column_filtering = ismember(meta.columns, column_list); 0201 meta.columns = meta.columns(column_filtering); 0202 dataline_format(~column_filtering) = {'%*f'}; 0203 end 0204 format_str = ... 0205 [sprintf('%s ', dataline_format{1:end-1}) dataline_format{end} '\n']; 0206 data_values = textscan(fid, format_str, 'ReturnOnError', false); 0207 switch lower(output_format) 0208 case 'array' 0209 data = [data_values{:}]; 0210 case 'struct' 0211 data = cell2struct(data_values, meta.columns, 2); 0212 otherwise 0213 error('glider_toolbox:sgeng2mat:InvalidFormat', ... 0214 'Invalid output format: %s.', output_format) 0215 end 0216 catch exception 0217 % Close the file after a reading error. 0218 fclose(fid); 0219 rethrow(exception); 0220 end 0221 0222 0223 %% Close the file after successful reading. 0224 fclose(fid); 0225 0226 end