Reads .dat files from the Aquadopp Outputs a structured array containing the data. TODO: Add compass correction (have as input) Add pressure correction (also as input) Allow header items as input (currently hard-coded below) Allow side-lobe depth correction as an input (also hard-coded below) Optimise / speed up! Deal with testing for equidistances V2 DP 4/7/2012 - Removed all reference to the 'arbitary' percentage of the water column cut-off (which is totally bollocks). The correct number is always cos(deg2rad(angle_of_the_beam)) - which for Nortek equipment happens to be approx 90% - Added 'header_items' as input (assumes 19 as the default if not supplied).
0001 function [AQDdat_mat_out] = mrg_AQD_dat_to_mat(filename, n_header_items) 0002 % Reads .dat files from the Aquadopp 0003 % Outputs a structured array containing the data. 0004 % TODO: 0005 % Add compass correction (have as input) 0006 % Add pressure correction (also as input) 0007 % Allow header items as input (currently hard-coded below) 0008 % Allow side-lobe depth correction as an input (also hard-coded 0009 % below) 0010 % Optimise / speed up! 0011 % Deal with testing for equidistances 0012 % V2 DP 4/7/2012 0013 % - Removed all reference to the 'arbitary' percentage of the water 0014 % column cut-off (which is totally bollocks). The correct number is 0015 % always cos(deg2rad(angle_of_the_beam)) - which for Nortek equipment 0016 % happens to be approx 90% 0017 % - Added 'header_items' as input (assumes 19 as the default if not supplied). 0018 0019 %% Check input variables 0020 0021 % Check that the supplied file exists 0022 if ~exist(filename, 'file') 0023 error(['The filename you passed to ' mfilename ' does not exists, or is not accessible by MATLAB']); 0024 end 0025 0026 % The number of header items (find this in the AquaDopp .hdr file). 0027 if ~exist('n_header_items', 'var') 0028 n_header_items = 19; 0029 warning('mrg:DefaultValue', ['The function ' mfilename ' is assuming you have 19 header items']); 0030 end 0031 0032 %% Try to open a file connection 0033 fid = fopen(filename, 'r'); 0034 % Check that the file was opened 0035 if fid == -1 0036 error(['MATLAB was unable to open the file supplied to ' mfilename]); 0037 end 0038 0039 %% Check compass correction input 0040 0041 0042 %% Check pressure correction input 0043 0044 0045 %% Get started 0046 0047 AQDdat_mat = []; 0048 AQDdat_raw_meta = {}; 0049 0050 % Setup some counters and internal variables 0051 text_line_no = 1; 0052 meta_dim = 1; 0053 0054 % Read a line of text. The first line should be a header 0055 text_line = fgetl(fid); 0056 0057 while text_line ~= -1 % i.e. Until the end of the file 0058 header = textscan(text_line, '%d %d %d %d %d %d %s %s %f %f %f %f %f %f %f %f %f %f %f'); 0059 % Is a floating point number the best way to read this? 0060 if length(header) ~= n_header_items 0061 error(['The header on line ', num2str(text_line_no), ' did not have ', num2str(n_header_items), ' items. This is probably an error.']); 0062 else 0063 % Write the header to the meta object 0064 AQDdat_raw_meta(meta_dim,:) = header; 0065 % Now we need to read the actual profile data... 0066 % First, lets figure out how many lines to read... 0067 nread = header{n_header_items}; 0068 % n_read should be the last object in the header 0069 % i.e. it should be the number of bins and therefore the number of 0070 % lines to read 0071 data_line_no = 1; % Set (or re-set) a new line counter... 0072 while data_line_no <= nread 0073 text_line = fgetl(fid); 0074 text_line_no = text_line_no+1; % Increment the whole-file line counter 0075 data_line = textscan(text_line, '%f'); 0076 AQDdat_mat(meta_dim,data_line_no,:) = data_line{1}; 0077 data_line_no = data_line_no + 1; % Increment the local data_line counter 0078 end 0079 0080 text_line = fgetl(fid); % Get a new line to feed back into the while loop test 0081 text_line_no = text_line_no+1; % Increment the whole-file line counter 0082 meta_dim = meta_dim+1; % and increment the meta_dim counter 0083 end 0084 end 0085 0086 fclose(fid); 0087 0088 %% Converting to MATLAB datetime and finding duplicates 0089 datevector = cell2mat(AQDdat_raw_meta(:,[3,1,2,4,5,6])); 0090 datetime = datenum(double(datevector)); 0091 % Looking for double ups in datetimes... 0092 % This is probably caused by the wavebursts (profiles can't be taken while 0093 % the wavebursts are underway) 0094 % The ASCII output function of AquaPro seems to just duplicate the next 'good' profile to fill the gap. 0095 % e.g. if 1715 is missing, there will be two (identical) readings for 1730. 0096 [~, m, ~] = unique(datetime, 'last'); 0097 0098 % Dropping double ups before processing... 0099 datetime = datetime(m); 0100 datevector = datevector(m,:); 0101 0102 AQDdat_mat = AQDdat_mat(m,:,:); 0103 AQDdat_raw_meta = AQDdat_raw_meta(m,:,:); 0104 0105 %% Generating output 0106 % Ideally this would be dymanic i.e. read from the .hdr file. Oh well. 0107 AQDdat_mat_out = struct(... 0108 'datetime', datetime, ... 0109 'datevector', datevector, ... 0110 'error_code', {AQDdat_raw_meta(:,7)}, ... 0111 'status_code', {AQDdat_raw_meta(:,8)}, ... 0112 'batt_volt_v', cell2mat(AQDdat_raw_meta(:,9)), ... 0113 'heading_deg', cell2mat(AQDdat_raw_meta(:,11)), ... 0114 'pitch_deg', cell2mat(AQDdat_raw_meta(:,12)), ... 0115 'roll_deg', cell2mat(AQDdat_raw_meta(:,13)), ... 0116 'pressure_dbar', cell2mat(AQDdat_raw_meta(:,14)), ... 0117 'temp_degC', cell2mat(AQDdat_raw_meta(:,15))... 0118 ); 0119 % Appending the profile data from above... 0120 AQDdat_mat_out.profile = AQDdat_mat; 0121 0122 end