function [adcp,cfg,ens,hdr]=rdradcp(name,varargin);
% RDRADCP Read (raw binary) RDI ADCP files,
% ADCP=RDRADCP(NAME) reads the raw binary RDI BB/Workhorse ADCP file NAME and
% puts all the relevant configuration and measured data into a data structure
% ADCP (which is self-explanatory). This program is designed for handling data
% recorded by moored instruments (primarily Workhorse-type but can also read
% Broadband) and then downloaded post-deployment. For vessel-mount data I
% usually make p-files (which integrate nav info and do coordinate transformations)
% and then use RDPADCP.
%
% This current version does have some handling of VMDAS, WINRIVER, and WINRIVER2 output
% files, but it is still 'beta'. There are (inadequately documented) timestamps
% of various kinds from VMDAS, for example, and caveat emptor on WINRIVER2 NMEA data.
%
% [ADCP,CFG]=RDRADCP(...) returns configuration data in a
% separate data structure.
%
% Various options can be specified on input:
% [..]=RDRADCP(NAME,NUMAV) averages NUMAV ensembles together in the result.
% [..]=RDRADCP(NAME,NUMAV,NENS) reads only NENS ensembles (-1 for all).
% [..]=RDRADCP(NAME,NUMAV,[NFIRST NEND]) reads only the specified range
% of ensembles. This is useful if you want to get rid of bad data before/after
% the deployment period.
%
% Notes- sometimes the ends of files are filled with garbage. In this case you may
% have to rerun things explicitly specifying how many records to read (or the
% last record to read). I don't handle bad data very well. Also - in Aug/2007
% I discovered that WINRIVER-2 files can have a varying number of bytes per
% ensemble. Thus the estimated number of ensembles in a file (based on the
% length of the first ensemble and file size) can be too high or too low.
%
% - I don't read in absolutely every parameter stored in the binaries;
% just the ones that are 'most' useful. Look through the code if
% you want to get other things.
%
% - chaining of files does not occur (i.e. read .000, .001, etc.). Sometimes
% a ping is split between the end of one file and the beginning of another.
% The only way to get this data is to concatentate the files, using
% cat file1.000 file1.001 > file1 (unix)
% copy file1.000/B+file2.001/B file3.000/B (DOS/Windows)
%
% (as of Dec 2005 we can probably read a .001 file)
%
% - velocity fields are always called east/north/vertical/error for all
% coordinate systems even though they should be treated as
% 1/2/3/4 in beam coordinates etc.
%
% String parameter/option pairs can be added after these initial parameters:
%
% 'baseyear' : Base century for BB/v8WH firmware (default to 2000).
%
% 'despike' : [ 'no' | 'yes' | 3-element vector ]
% Controls ensemble averaging. With 'no' a simple mean is used
% (default). With 'yes' a mean is applied to all values that fall
% within a window around the median (giving some outlier rejection).
% This is useful for noisy data. Window sizes are [.3 .3 .3] m/s
% for [ horiz_vel vert_vel error_vel ] values. If you want to
% change these values, set 'despike' to the 3-element vector.
%
% R. Pawlowicz (rich@eos.ubc.ca) - 17/09/99
% R. Pawlowicz - 17/Oct/99
% 5/july/00 - handled byte offsets (and mysterious 'extra" bytes) slightly better, Y2K
% 5/Oct/00 - bug fix - size of ens stayed 2 when NUMAV==1 due to initialization,
% hopefully this is now fixed.
% 10/Mar/02 - #bytes per record changes mysteriously,
% tried a more robust workaround. Guess that we have an extra
% 2 bytes if the record length is even?
% 28/Mar/02 - added more firmware-dependent changes to format; hopefully this
% works for everything now (put previous changes on firmer footing?)
% 30/Mar/02 - made cfg output more intuitive by decoding things.
% - An early version of WAVESMON and PARSE which split out this
% data from a wave recorder inserted an extra two bytes per record.
% I have removed the code to handle this but if you need it see line 509
% 29/Nov/02 - A change in the bottom-track block for version 4.05 (very old!).
% 29/Jan/03 - Status block in v4.25 150khzBB two bytes short?
% 14/Oct/03 - Added code to at least 'ignore' WinRiver GPS blocks.
% 11/Nov/03 - VMDAS navigation block, added hooks to output
% navigation data.
% 26/Mar/04 - better decoding of nav blocks
% - better handling of weird bytes at beginning and end of file
% (code fixes due to Matt Drennan).
% 25/Aug/04 - fixes to "junk bytes" handling.
% 27/Jan/05 - even more fixed to junk byte handling (move 1 byte at a time rather than
% two for odd lengths.
% 29/Sep/2005 - median windowing done slightly incorrectly in a way which biases
% results in a negative way in data is *very* noisy. Now fixed.
%
% 28/Dc/2005 - redid code for recovering from ensembles that mysteriously change length, added
% 'checkheader' to make a complete check of ensembles.
% Feb/2006 - handling of firmware version 9 (navigator)
% 23/Aug/2006 - more firmware updates (16.27)
% 23/Aug2006 - ouput some bt QC stiff
% 29/Oct/2006 - winriver bottom track block had errors in it - now fixed.
% 30/Oct/2006 - pitch_std, roll_std now uint8 and not int8 (thanks Felipe pimenta)
% 13/Aug/2007 - added Rio Grande (firmware v 10),
% better handling of those cursed winriver ASCII NMEA blocks whose
% lengths change unpredictably.
% skipping the inadequately documented 2022 WINRIVER-2 NMEA block
% 13/Mar/2010 - firmware version 50 for WH.
num_av=5; % Block filtering and decimation parameter (# ensembles to block together).
nens=-1; % Read all ensembles.
century=2000; % ADCP clock does not have century prior to firmware 16.05.
vels='no'; % Default to simple averaging
lv=length(varargin);
if lv>=1 & ~isstr(varargin{1}),
num_av=varargin{1}; % Block filtering and decimation parameter (# ensembles to block together).
varargin(1)=[];
lv=lv-1;
if lv>=1 & ~isstr(varargin{1}),
nens=varargin{1};
varargin(1)=[];
lv=lv-1;
end;
end;
% Read optional args
while length(varargin)>0,
switch varargin{1}(1:3),
case 'bas',
century = varargin{2};
case 'des',
if isstr(varargin{2}),
if strcmp(varargin{2},'no'), vels='no';
else vels=[.3 .3 .3]; end;
else
vels=varargin{2};
end;
otherwise,
error(['Unknown command line option ->' varargin{1}]);
end;
varargin([1 2])=[];
end;
% Check file information first
naminfo=dir(name);
if isempty(naminfo),
fprintf('ERROR******* Can''t find file %s\n',name);
return;
end;
fprintf('\nOpening file %s\n\n',name);
fd=fopen(name,'r','ieee-le');
% Read first ensemble to initialize parameters
[ens,hdr,cfg,pos]=rd_buffer(fd,-2); % Initialize and read first two records
if ~isstruct(ens) & ens==-1,
disp('No Valid data found');
adcp=[];
return;
end;
fseek(fd,pos,'bof'); % Rewind
if (cfg.prog_ver<16.05 & cfg.prog_ver>5.999) | cfg.prog_ver<5.55,
fprintf('***** Assuming that the century begins year %d (info not in this firmware version) \n\n',century);
else
century=0; % century included in clock.
end;
dats=datenum(century+ens.rtc(1,:),ens.rtc(2,:),ens.rtc(3,:),ens.rtc(4,:),ens.rtc(5,:),ens.rtc(6,:)+ens.rtc(7,:)/100);
t_int=diff(dats);
fprintf('Record begins at %s\n',datestr(dats(1),0));
fprintf('Ping interval appears to be %s\n',datestr(t_int,13));
% Estimate number of records (since I don't fee
评论2