function rdi2cdf(infile, outfile, minens, maxens);

% rdi2cdf.m converts RDI ADCP files to netCDF format
%
% function rdi2cdf(infile, outfile, minens, maxens);
%
% where:
%		infile	= the input file name in RDI broadband data format
%			  this includes the Workhorse family of ADCP's
%		outfile = the netCDF file name
%		minens = ensumble number at which to start converting
%		maxens = ensemble number at which to stop converting
%
% If no outfile is given, the header info for the file is displayed
% Version 2.2	7/22/99	


% Written by Marinna Martini
% for the U.S. Geological Survey
% Marine and Coastal Program
% Woods Hole Center, Woods Hole, MA
% http://woodshole.er.usgs.gov/
% Please report bugs to mmartini@usgs.gov
%
% dependents:
%	rdhead.m	reads RDI header data format
%	rdflead.m	reads RDI fixed leader format
%	rdvlead.m	reads RDI variable leader format
%	mcnote.m	annotate netCDF data
%	mexcdf.mex	netCDF file I/O
%
% netCDF attributes and variable names follow EPIC conventions
%
% information on netCDF may be obtained at
% http://www.unidata.ucar.edu
% it's free!!
%
%
prog_ver = '2.2b 7/22/99';
disp(['rdi2cdf.m version ',prog_ver]);
% 7/22/99	Version 2.2b  edited by JMC
%				- request for deployment dates in the netcdf file for future checks
% 7/14/99	Version 2.2  edited by JMC
%				- space added in for some attributes that will be placed in the final
%				processed data file	
% 4/16/99	Version 2.1
%				- I am, in fact, erverting back to mexcdf because
%				  that access code is more than 50% faster.
% 3/19/99	Version 2.0
%				- convert netCDF file access from mexcdf to netcdf
%				  the old code is still contained within
% 8/14/98	Version 1.2b
%				- add the instrument serial number to global attributes
% 11/15/97  Version 1.2a
%				- fix some minor details for USGS data processing needs
% 10/28/97  Version 1.2
%           - fix the incorrect estimation of number of ensembles in the file
% 10/12/97  Version 1.1
%           - fix bin2dec & dec2bin to use MATLAB versions
%           - Add a dialog box to get metadata from user
% 5/2/97    Version 1.0
%           - fix time translation so that year is 1996 instead of '96
%           - include provision for turn of the century, assuming RDI's
%             dates will continue to be two digit year numbers
%
% 10/29/96  Version 0.0

mexcdf('SETOPTS',0);
% no necdf equivalent
if nargin == 0,
	error('I need an input file name');
end
if nargin < 2,	% assume the user only wants header info output
	select=zeros(size(32,1));
	fid = fopen(infile,'r');
	disp(['Header information from RDI adcp file ',infile])
	[nbytes, nt, offsets] = rdhead(fid, 1);
	rdflead(fid,1,select);
	return;
end
tic

% offset indicators
% if RD changes the order of their data types
% be sure to update these types and the other
% info defined below
VELOCITY = 3;
CORRELATION = 4;
INTENSITY = 5;
GOOD = 6;
% the first two read types have no meaning, they are holders
% so that the offset indicator can be used as a universal
% index for code readability
read_types=['int16';'int16';'int16';'uchar';'uchar';'uchar'];
% likewise, the first two rec ids are for the fixed and
% variable leader records
rec_ids=[0 128 256 512 768 1024];
longnames = str2mat(' ',' ','velocity','correlation','intensity','percent good');
VARNAMES=['   ';'   ';'vel';'cor';'AGC';'PGd'];

%
% ------ Open the files & write global attributes -----
%
% create the file
cdf = mexcdf('CREATE',outfile,'NC_CLOBBER');
if cdf == -1,
	error(['Problem opening netCDF output file: ',outfile]);
end
%cdf = netcdf(outfile,'clobber');	%clobber = create or overwrite a new file
%if isempty(cdf), error(['Problem opening netCDF output file: ',outfile]); end

% get the deployment dates
prompt  = {'Enter the mooring number:',...
      'Enter the deployment date:', 'Enter the recovery date:'};
def     = {'0','01-jan-1999','01-jan-1999'};
title   = 'Input mooring data for ADCP';
lineNo  = 1;
dlgresult  = inputdlg(prompt,title,lineNo,def);
Mooring_number = dlgresult{1};
Deployment_date = dlgresult{2};
Recovery_date = dlgresult{3};

% enter the global attributes   
mexcdf('ATTPUT',cdf,'GLOBAL','CREATION_DATE','CHAR',11,date);
%cdf.CREATION_DATE = date;

mexcdf('ATTPUT',cdf,'GLOBAL','Mooring_number','CHAR',3,Mooring_number);
mexcdf('ATTPUT',cdf,'GLOBAL','Deployment_date','CHAR',11,Deployment_date);
mexcdf('ATTPUT',cdf,'GLOBAL','Recovery_date','CHAR',11,Recovery_date);

mexcdf('ATTPUT',cdf,'GLOBAL','INST_TYPE','CHAR',19,'RD Instruments ADCP');
%cdf.INST_TYPE = 'RD Instruments Broadband ADCP'
junk = ['Converted to netCDF via MATLAB by rdi2cdf.m ', prog_ver];
mexcdf('ATTPUT',cdf,'GLOBAL','History','CHAR',length(junk),junk);
%cdf.PROG_CMNT1 = junk;

fid = fopen(infile,'r');
%function [nb, nt, off] = rdhead(fid, verbose);
%	Read the header data from a raw ADCP
%	data file opened for binary reading.
%	fid = file handle returned by fopen
%	nb = number of bytes in the ensemble
%	nt = number of data types
%	off = offset to the data for each type
%	Set verbose = 1 in rdhead.m for a text output.
disp(['Header information from adcp file ',infile])
[nbytes, nt, offsets] = rdhead(fid, 1);
notenum = 1;	% for general notes to file

% this is essentially the code from rdflead.m
% adapted for writing attributes to the netcdf file
%
% ------ Process Fixed Leader Data --------
%
%	Read the fixed leader data from a raw ADCP
%	data file opened for binary reading 
%	Returns the contents of the fixed leader
%	as 31 elements of the vector 'data' or an
%	empty matrix if the fixed leader ID is not
%	identified (error condition)
%	Set verbose=1 for a text output.
%	The names and meanings of these attibutes are taken
%	directly from Appendix B in the RDI Broadband 
%	Phase III technical manual.

if exist('verbose') ~= 1,
	verbose = 1;	% verbose must be = 1 to get all header info
end
NFIELDS = 32;
data=zeros(1,NFIELDS);
fld=1;  

if exist('select') ~= 1,
	select = [];
end

% get the distance of the ADCP head from the bottom
% get the instrument serial number
prompt  = {'Enter the distance between the ADCP transducers and the sea bed in meters:',...
      'Enter the ADCP''s serial number:',...
      'Enter the amount of time the ADCP clock was slow by in seconds:'};
def     = {'0','0','0'};
title   = 'Input metadata from the mooring log';
lineNo  = 1;
dlgresult  = inputdlg(prompt,title,lineNo,def);
xducer_offset = str2num(dlgresult{1});
ADCP_serial_number = str2num(dlgresult{2});
slow_by = str2num(dlgresult{3});

%let's check to make sure these values make sense
if xducer_offset > 10 | ADCP_serial_number < 100; 
   prompt  = {'RE-Enter the distance between the ADCP and sea bed in METERS:',...
   			'RE-Enter the ADCP''s serial number:'};
	def     = {dlgresult{1},dlgresult{2}};
	title   = 'Check metadata, INVALID values';
	lineNo  = 1;
	dlgresult  = inputdlg(prompt,title,lineNo,def);
	xducer_offset = str2num(dlgresult{1});
	ADCP_serial_number = str2num(dlgresult{2});
end

% make sure we're looking at the beginning of
% the fixed leader record by testing for it's ID
data(fld)=fread(fid,1,'ushort');
if(data(fld)~=0),
	disp('Fixed Leader ID not found');
	data=[];
	return;
end
fld=fld+1;
% version number of CPU firmware
data(fld)=fread(fid,1,'uchar');
fld=fld+1;
% revision number of CPU firmware
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('CPU Version %d.%d',data(fld-1),data(fld))); end;
mexcdf('ATTPUT',cdf,'GLOBAL','firmware_version','FLOAT',1,data(fld-1)+data(fld)/100);
%cdf.firmware_version = ncfloat(data(fld-1)+data(fld)/100);
fld=fld+1;
% configuration, uninterpreted
data(fld)=fread(fid,1,'uchar');
if verbose, 
	disp(sprintf('Hardware Configuration for LSB %d',data(fld))); 
   b=zeros(1,8); %dec2bin(data(fld));
   b(9-length(dec2bin(data(fld))):8)=dec2bin(data(fld));
   b=char(b);
   freqs=[75 150 300 600 1200 2400];
	junk=bin2dec(b(6:8));
	disp(sprintf('	System Frequency = %d kHz',freqs(junk+1))); 
   mexcdf('ATTPUT',cdf,'GLOBAL','frequency','LONG',1,freqs(junk+1));
   %cdf.frequency = nclong(freqs(junk+1));
	if b(5) == '0', 
		disp('	Concave Beam'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','beam_pattern','CHAR',7,'concave');
      %cdf.beam_pattern = 'concave';
	end		
	if b(5) == '1', 
		disp('	Convex Beam'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','beam_pattern','CHAR',6,'convex');
      %cdf.beam_pattern = 'convex';
	end		
	junk=bin2dec(b(3:4));
	disp(sprintf('Sensor Configuration #%d',junk+1)); 
   mexcdf('ATTPUT',cdf,'GLOBAL','sensor_configuration','LONG',1,junk+1);
   %cdf.sensor_configuration = nclong(junk+1);
	if b(2) == '0', disp('	Transducer head not attached'); end		
	if b(2) == '1', disp('	Transducer head attached'); end		
   mexcdf('ATTPUT',cdf,'GLOBAL','transducer_attached','LONG',1,b(2));
   %cdf.transducer_attached = nclong(b(2));
	if b(1) == '0', 
		disp('	Downward facing beam orientation'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','orientation','CHAR',4,'DOWN');
      %cdf.orientation = 'DOWN';
	end		
	if b(1) == '1', 
		disp('	Upward facing beam orientation'); 
		mexcdf('ATTPUT',cdf,'GLOBAL','orientation','CHAR',2,'UP');
      %cdf.orientation = 'UP';
	end		
end;
fld=fld+1;
data(fld)=fread(fid,1,'uchar');
if verbose, 
	disp(sprintf('Hardware Configuration MSB %d',data(fld))); 
	%b=dec2bin(data(fld));
   b=zeros(1,8); %dec2bin(data(fld));
   b(9-length(dec2bin(data(fld))):8)=dec2bin(data(fld));
   b=char(b);
	angles = [15 20 30 0];
	junk=bin2dec(b(7:8));
	disp(sprintf('	Beam angle = %d degrees',angles(junk+1)));
	% note that is beam angle = 0, it is some other than the above
   mexcdf('ATTPUT',cdf,'GLOBAL','beam_angle','LONG',1,angles(junk+1));
   %cdf.beam_angle = nclong(angles(junk+1));
	junk=bin2dec(b(1:4));
	if junk == 4, 
		disp('	4-beam janus configuration'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','janus','CHAR',6,'4 Beam');
      %cdf.janus = '4 Beam';
	end
	if junk == 5, 
		disp('	5-beam janus configuration, 3 demodulators'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','janus','CHAR',15,'5 Beam, 3 demod');
      %cdf.janus = '5 Beam, 3 demod';
	end
	if junk == 15, 
		disp('	4-beam janus configuration, 2 demodulators'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','janus','CHAR',15,'4 Beam, 2 demod');
      %cdf.janus = '4 Beam, 2 demod';
	end
end;
fld=fld+1;
% real (0) or simulated (1) data flag
data(fld)=fread(fid,1,'uchar');
if data(fld),
	if verbose, disp('The data is simulated'); end
else
	if verbose, disp('The data is real'); end
end
mexcdf('ATTPUT',cdf,'GLOBAL','simulated_data','LONG',1,data(fld));
%cdf.simulated_data = nclong(data(fld));
fld=fld+1;
% undefined
data(fld)=fread(fid,1,'uchar');	fld=fld+1;
% number of beams
data(fld)=fread(fid,1,'uchar');	
if verbose, disp(sprintf('Number of beams used to calculate velocity data:  %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','beams_in_velocity_calculation','LONG',1,data(fld));
%cdf.beams_in_velocity_calculation = nclong(data(fld));
fld=fld+1;
nbeams = 4;	%data(fld)
% number of depth cells
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Number of depth cells %d',data(fld))); end;
nbins = data(fld);
fld=fld+1;
% pings per ensemble
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Pings per ensemble %d',data(fld))); end;
mexcdf('ATTPUT',cdf,'GLOBAL','pings_per_ensemble','LONG',1,data(fld));
%cdf.pings_per_ensemble = nclong(data(fld));
npings = data(fld);
fld=fld+1;
% depth cell length in cm
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Depth cell size %d cm',data(fld))); end
% this attribute is tagged to the depth variable
fld=fld+1;
% blanking distance (WF)
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Blank after xmit distance %d cm',data(fld))); end
% this attribute is tagged to the depth variable
fld=fld+1;
% Profiling mode (WM)
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Profiling mode %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','profiling_mode','LONG',1,data(fld));
%cdf.profiling_mode = nclong(data(fld));
fld=fld+1;

% Minimum correlation threshold (WC)
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Valid range for correlation %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','valid_correlation_range','LONG',2,[data(fld) 255]);
%cdf.valid_correlation_range = nclong([data(fld) 0]);
fld=fld+1;

% number of code repetitions
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Code repetitions %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','code_repetitions','LONG',1,data(fld));
%cdf.code_repetitions = nclong(data(fld));
fld=fld+1;

% Minimum percent good to output data (WG)
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Minimum and maximum percent good for output %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','minmax_percent_good','LONG',2,[data(fld) 100]);
%cdf.minmax_percent_good = nclong([data(fld) 0]);
fld=fld+1;

% Error velocity threshold (WE)
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Minimum and Maximum Error Velocity values permitted %d mm/s',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','error_velocity_threshold','LONG',1,data(fld));
%cdf.minmax_error_velocity = nclong([data(fld) 0]);
fld=fld+1;

% time between ping groups (TP)
data(fld)=fread(fid,1,'uchar');
fld=fld+1;
data(fld)=fread(fid,1,'uchar');
fld=fld+1;
data(fld)=fread(fid,1,'uchar');
tp=[data(fld-2),data(fld-1),data(fld)];  %added by JMC
TP=str2num(sprintf('%d.%d',(tp(1)*60 + tp(2)),tp(3)));
if verbose, disp(['Time between ping groups ' tp]); end
mexcdf('ATTPUT',cdf,'GLOBAL','time_between_ping_groups','FLOAT',1,...
	TP);
%cdf.time_between_ping_groups = ncfloat(TP);

fld=fld+1;
% coordinate transformation (EX)
data(fld)=fread(fid,1,'uchar');
if verbose, 
	disp(sprintf('Coordinate Transformation = %d',data(fld))); 
	%b=dec2bin(data(fld));
   %b=zeros(1,8); %dec2bin(data(fld));
   b=dec2bin(data(fld),8);
   %b(9-length(dec2bin(data(fld))):8)=dec2bin(data(fld));
   %b=char(b);
	transform=bin2dec(b(4:5));
	if transform == 0, 
		disp('	Data stored coordinates = Beam'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','transform','CHAR',4,'BEAM');
      %cdf.transform = 'BEAM';
	end
	if transform == 1, 
		disp('	Data stored coordinates = Instrument'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','transform','CHAR',4,'INST');
      %cdf.transform = 'INST';
	end
	if transform == 2, 
		disp('	Data stored coordinates = Ship'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','transform','CHAR',4,'SHIP');
      %cdf.transform = 'SHIP';
	end
	if transform == 3, 
		disp('	Data stored coordinates = Earth'); 
      mexcdf('ATTPUT',cdf,'GLOBAL','transform','CHAR',5,'EARTH');
      %cdf.transform = 'EARTH';
	end
%	if b(6) == '1', disp('	Tilts used in transformation'); end
%	if b(7) == '1', disp('	3-beam solution used, this ensemble'); end
end
fld=fld+1;
% Heading Alignment (EA)
data(fld)=fread(fid,1,'int16');
if verbose, disp(sprintf('Heading alignment %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','heading_alignment','LONG',1,data(fld));
%cdf.heading_alignment = nclong(data(fld));
fld=fld+1;
% Heading Bias (EB)
data(fld)=fread(fid,1,'int16');
if verbose, disp(sprintf('Heading Bias: %d deg',data(fld)./100)); end
mexcdf('ATTPUT',cdf,'GLOBAL','heading_bias','LONG',1,data(fld));
%cdf.heading_bias = nclong(data(fld));
% error here 
mcnote(cdf,'GLOBAL','units for heading bias and alignment are centidegrees',notenum);
notenum=notenum+1;
fld=fld+1;
% Sensor source (EZ)
data(fld)=fread(fid,1,'uchar');
if verbose,
	disp(sprintf('Sensor Source = %d',data(fld))); 
	%b=(data(fld));
   b=zeros(1,8); %dec2bin(data(fld));
   b(9-length(dec2bin(data(fld))):8)=dec2bin(data(fld));
   b=char(b);
	if b(2) == '1',
		buf='Sound speed computed from ED, ES & ET';
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end
	if b(3) == '1', 
		buf = 'ED taken from depth sensor';
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end	
	if b(4) == '1', 
		buf = 'EH taken from xducer heading sensor';
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end	
	if b(5) == '1', 
		buf = 'EP taken from xducer pitch sensor';	
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end	
	if b(6) == '1', 
		buf = 'ER taken from xducer roll sensor';	
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end	
	if b(7) == '1', 
		buf = 'ES derived from conductivity sensor';	
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end	
	if b(8) == '1', 
		buf = 'ET taken from temperature sensor';
		disp(['  ',buf]); 
		mcnote(cdf,'GLOBAL',buf,notenum);	
		notenum=notenum+1;
	end	
end
fld=fld+1;
% Sensors available
data(fld)=fread(fid,1,'uchar');
if verbose,
	disp(sprintf('Sensor Availability = %d',data(fld))); 
	%b=dec2bin(data(fld));
   b=zeros(1,8); %dec2bin(data(fld));
   b(9-length(dec2bin(data(fld))):8)=dec2bin(data(fld));
   b=char(b);
	if b(3) == '1', disp('	depth sensor'); 
		mcnote(cdf,'GLOBAL','depth sensor available',notenum);	
		notenum=notenum+1;
	end	
	if b(4) == '1', disp('	heading sensor');  
		mcnote(cdf,'GLOBAL','depth sensor available',notenum);	
		notenum=notenum+1;
	end	
	if b(5) == '1', disp('	pitch sensor');  
		mcnote(cdf,'GLOBAL','pitch sensor available',notenum);	
		notenum=notenum+1;
	end	
	if b(6) == '1', disp('	roll sensor');  
		mcnote(cdf,'GLOBAL','roll sensor available',notenum);	
		notenum=notenum+1;
	end	
	if b(7) == '1', disp('	conductivity sensor');  
		mcnote(cdf,'GLOBAL','conductivity sensor available',notenum);	
		notenum=notenum+1;
	end	
	if b(8) == '1', disp('	temperature sensor');  
		mcnote(cdf,'GLOBAL','temperature sensor available',notenum);	
		notenum=notenum+1;
	end	
end
fld=fld+1;
% Bin 1 distance
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Distance to center of bin 1: %d cm',data(fld))); end
% this is saved with the depth variable
fld=fld+1;
% xmit pulse length
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Transmit pulse length %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','transmit_pulse_length','LONG',1,data(fld));
%cdf.transmit_pulse_length = nclong(data(fld));
mcnote(cdf,'GLOBAL','transmit_pulse_length units are cm',notenum);	
notenum=notenum+1;
fld=fld+1;
% starting depth cell
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Starting water layer %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','starting_water_layer','LONG',1,data(fld));
%cdf.starting_water_layer = nclong(data(fld));
fld=fld+1;
% ending depth cell
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('Ending water layer %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','ending_water_layer','LONG',1,data(fld));
%cdf.ending_water_layer = nclong(data(fld));
fld=fld+1;
% false target reject threshold
data(fld)=fread(fid,1,'uchar');
if verbose, disp(sprintf('False target reject range values %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','false_target_reject_values','LONG',2,[data(fld) 255]);
%cdf.false_target_reject_values = nclong([data(fld) 0]);
fld=fld+1;
% spare
data(fld)=fread(fid,1,'uchar');
fld=fld+1;
% transmit lag distance
data(fld)=fread(fid,1,'ushort');
if verbose, disp(sprintf('Transmit lag distance %d',data(fld))); end
mexcdf('ATTPUT',cdf,'GLOBAL','transmit_lag_distance','LONG',1,data(fld));
%cdf.transmit_lag_distance = nclong(data(fld));
mexcdf('ATTPUT',cdf,'GLOBAL','ADCP_serial_number','LONG',1,ADCP_serial_number);
%cdf.ADCP_serial_number = nclong(ADCP_serial_number);

% save the rest of the data for later
fleader = data;
disp('-----------')
%
% ------ Set up the variables -----
%

% determine the number of ensembles from the file size
%	and number of bytes per ensemble
% there is an 8260 byte leader in every file
LEADERSIZE = 8260;
% the checksum at the end of every ensemble record is two bytes
CHECKSUMSIZE = 2;
fseek(fid,0,1);	% go to end of file
infilesize = ftell(fid);
nens = ceil((infilesize-LEADERSIZE)/(nbytes+CHECKSUMSIZE));
disp(sprintf('%d ensembles estimated from file size',nens))

% dimensions
ensid=mexcdf('DIMDEF',cdf,'ensemble','NC_UNLIMITED');
%cdf('ensemble') = 0; 	% the record dimension
binid=mexcdf('DIMDEF',cdf,'bin',nbins);
%cdf('bin') = nbins;

% variables
% 
mexcdf('VARDEF',cdf,'D','FLOAT',1,[binid]);
%cdf{'D'} = ncfloat('bin');
mexcdf('ATTPUT',cdf,'D','units','CHAR',1,'m');
%cdf{'D'}.units = 'm';
mexcdf('ATTPUT',cdf,'D','long_name','CHAR',9,'DEPTH (m)');
%cdf{'D'}.long_name = 'DEPTH (m)';
mexcdf('ATTPUT',cdf,'D','_FillValue','FLOAT',1,1e35);
% note, netcdf will not handle leading _
%cdf{'D'}.FillValue = ncfloat(1e35);
mexcdf('ATTPUT',cdf,'D','epic_code','LONG',1,3);
%cdf{'D'}.epic_code = nclong(3);


bin1=fleader(26)/100;
mexcdf('ATTPUT',cdf,'D','center_first_bin','FLOAT',1,bin1);
%cdf{'D'}.center_first_bin = ncfloat(fleader(26)/100);

blank=fleader(12)/100;
mexcdf('ATTPUT',cdf,'D','blanking_distance','FLOAT',1,blank);
%cdf{'D'}.blanking_distance = ncfloat(fleader(12)/100);

binsize=fleader(11)/100;
mexcdf('ATTPUT',cdf,'D','bin_size','FLOAT',1,binsize);
%cdf{'D'}.bin_size = ncfloat(fleader(11)/100);

bincnt=nbins;
mexcdf('ATTPUT',cdf,'D','bin_count','LONG',1,nbins);
%cdf{'D'}.bin_count = nclong(nbins);
water_depth = 0;
mexcdf('ATTPUT',cdf,'D','water_depth','FLOAT',1,water_depth);
%cdf{'D'}.water_depth = ncfloat(water_depth);
%xducer_offset = 0;
mexcdf('ATTPUT',cdf,'D','xducer_offset_from_bottom','FLOAT',1,xducer_offset);
%cdf{'D'}.xducer_offset_from_bottom = ncfloat(xducer_offset);
mcnote(cdf,'D','bin depths are relative to the transducer head',notenum);	
notenum=notenum+1;
% compute bin locations
depths = bin1:binsize:(((bincnt-1)*binsize)+bin1);
% adjust for ADCP position and save depths for later
depths = depths+xducer_offset;


mexcdf('VARDEF',cdf,'TIM','DOUBLE',1,0);
%cdf{'TIM'} = ncdouble('ensemble');
mexcdf('ATTPUT',cdf,'TIM','units','CHAR',12,'decimal days');
%cdf{'TIM'}.units = 'decimal days';
mexcdf('ATTPUT',cdf,'TIM','long_name','CHAR',11,'JULIAN DAYS');
%cdf{'TIM'}.long_name = 'JULIAN DAYS';
mexcdf('ATTPUT',cdf,'TIM','_FillValue','DOUBLE',1,1e35);
%cdf{'TIM'}.FillValue = 1e35;
mexcdf('ATTPUT',cdf,'TIM','epic_code','LONG',1,627);
%cdf{'TIM'}.epic_code = nclong(627);
mexcdf('ATTPUT',cdf,'TIM','valid_min','LONG',1,0);
%cdf{'TIM'}.valid_min = nclong(0);
mexcdf('ATTPUT',cdf,'TIM','slow_by','LONG',1,slow_by);
mcnote(cdf,'TIM','amoutn of time the ADCP clock was "slow_by" is in seconds',notenum);	
notenum=notenum+1;


mexcdf('VARDEF',cdf,'Rec','LONG',1,0);
%cdf{'Rec'} = nclong('ensemble');
mexcdf('ATTPUT',cdf,'Rec','units','CHAR',6,'counts');
%cdf{'Rec'}.units = 'counts';
mexcdf('ATTPUT',cdf,'Rec','long_name','CHAR',7,'Records');
%cdf{'Rec'}.long_name = 'Records';
mexcdf('ATTPUT',cdf,'Rec','_FillValue','LONG',1,1e35);
%cdf{'Rec'}.FillValue = nclong(1e35);
mexcdf('ATTPUT',cdf,'Rec','epic_code','LONG',1,1207);
%cdf{'Rec'}.epic_code = nclong(1207);
mexcdf('ATTPUT',cdf,'Rec','valid_min','LONG',1,0);
%cdf{'Rec'}.valid_min = nclong(0);
%
mexcdf('VARDEF',cdf,'sv','LONG',1,0);
%cdf{'sv'} = nclong('ensemble');
mexcdf('ATTPUT',cdf,'sv','units','CHAR',5,'m s-1');
%cdf{'sv'}.units = 'm s-1';
mexcdf('ATTPUT',cdf,'sv','long_name','CHAR',20,'sound velocity (m/s)');
%cdf{'sv'}.long_name = 'sound velocity (m/s)';
mexcdf('ATTPUT',cdf,'sv','_FillValue','LONG',1,1e35);
%cdf{'sv'}.FillValue = nclong(1e35);
mexcdf('ATTPUT',cdf,'sv','epic_code','LONG',1,80);
%cdf{'sv'}.epic_code = nclong(80);
mexcdf('ATTPUT',cdf,'sv','valid_range','LONG',2,[1400 1600]);
%cdf{'sv'}.valid_range = nclong([1400 1600]);
%
for i=1:nbeams,
	varname = [VARNAMES(VELOCITY,:),int2str(i)];
   mexcdf('VARDEF',cdf,varname,'FLOAT',2,[0 1]);
   %eval(['cdf{''',varname,'''} = ncfloat(''ensemble'',''bin'');'])
	mexcdf('ATTPUT',cdf,varname,'units','CHAR',6,'mm s-1');
   %eval(['cdf{''',varname,'''}.units = ''mm s-1'';'])
	if ~transform,	% this EPIC code is for BEAM coordinates only
		buf=sprintf('Beam %1i velocity, mm/s',i);
		mexcdf('ATTPUT',cdf,varname,'long_name','CHAR',length(buf),buf);
		%eval(['cdf{''',varname,'''}.long_name = buf;'])
      mexcdf('ATTPUT',cdf,varname,'epic_code','LONG',1,1279+i);
      %eval(['cdf{''',varname,'''}.epic_code = nclong(1279+i);'])
	end
	mexcdf('ATTPUT',cdf,varname,'_FillValue','FLOAT',1,1e35);
   %eval(['cdf{''',varname,'''}.FillValue = ncfloat(1e35);'])
   mexcdf('ATTPUT',cdf,varname,'valid_range','FLOAT',2,[-32768 32767]);
   %eval(['cdf{''',varname,'''}.valid_range = ncfloat([-32768 32767]);'])
end
%
for i=1:nbeams,
	varname = [VARNAMES(CORRELATION,:),int2str(i)];
	mexcdf('VARDEF',cdf,varname,'FLOAT',2,[0 1]);
   %eval(['cdf{''',varname,'''} = ncfloat(''ensemble'',''bin'');'])
	mexcdf('ATTPUT',cdf,varname,'units','CHAR',6,'counts');
   %eval(['cdf{''',varname,'''}.units = ''counts'';'])
	buf=sprintf('Beam %1i correlation',i);
	mexcdf('ATTPUT',cdf,varname,'long_name','CHAR',length(buf),buf);
	%eval(['cdf{''',varname,'''}.long_name = buf;'])
	mexcdf('ATTPUT',cdf,varname,'epic_code','LONG',1,1293+i);
   %eval(['cdf{''',varname,'''}.epic_code = nclong(1293+i);'])
	mexcdf('ATTPUT',cdf,varname,'_FillValue','FLOAT',1,1e35);
   %eval(['cdf{''',varname,'''}.FillValue = ncfloat(1e35);'])
	mexcdf('ATTPUT',cdf,varname,'valid_range','FLOAT',2,[0 255]);
   %eval(['cdf{''',varname,'''}.valid_range = ncfloat([0 255]);'])
end	
%
for i=1:nbeams,
	varname = [VARNAMES(INTENSITY,:),int2str(i)];
	mexcdf('VARDEF',cdf,varname,'FLOAT',2,[0 1]);
   %eval(['cdf{''',varname,'''} = ncfloat(''ensemble'',''bin'');'])
	mexcdf('ATTPUT',cdf,varname,'units','CHAR',6,'counts');
   %eval(['cdf{''',varname,'''}.units = ''counts'';'])
	buf=sprintf('Echo Intensity (AGC) Beam %1i',i);
	mexcdf('ATTPUT',cdf,varname,'long_name','CHAR',length(buf),buf);
	%eval(['cdf{''',varname,'''}.long_name = buf;'])
	mexcdf('ATTPUT',cdf,varname,'epic_code','LONG',1,1220+i);
   %eval(['cdf{''',varname,'''}.epic_code = nclong(1220+i);'])
   mexcdf('ATTPUT',cdf,varname,'_FillValue','FLOAT',1,1e35);
   %eval(['cdf{''',varname,'''}.FillValue = ncfloat(1e35);'])
	mexcdf('ATTPUT',cdf,varname,'valid_range','FLOAT',2,[0 255]);
   %eval(['cdf{''',varname,'''}.valid_range = ncfloat([0 255]);'])
	mexcdf('ATTPUT',cdf,varname,'norm_factor','FLOAT',1,0.45);
   %eval(['cdf{''',varname,'''}.norm_factor = ncfloat(0.45);'])
	mcnote(cdf,varname,'normalization to db',notenum);	
	notenum=notenum+1;
end	
%
for i=1:nbeams,
	varname = [VARNAMES(GOOD,:),int2str(i)];
	mexcdf('VARDEF',cdf,varname,'FLOAT',2,[0 1]);
   %eval(['cdf{''',varname,'''} = ncfloat(''ensemble'',''bin'');'])
	mexcdf('ATTPUT',cdf,varname,'units','CHAR',6,'counts');
   %eval(['cdf{''',varname,'''}.units = ''counts'';'])
	buf=sprintf('Percent Good Beam %1i',i);
	mexcdf('ATTPUT',cdf,varname,'long_name','CHAR',length(buf),buf);
	%eval(['cdf{''',varname,'''}.long_name = buf;'])
	mexcdf('ATTPUT',cdf,varname,'epic_code','LONG',1,1240+i);
   %eval(['cdf{''',varname,'''}.epic_code = nclong(1220+i);'])
	mexcdf('ATTPUT',cdf,varname,'_FillValue','FLOAT',1,1e35);
   %eval(['cdf{''',varname,'''}.FillValue = ncfloat(1e35);'])
	mexcdf('ATTPUT',cdf,varname,'valid_range','FLOAT',2,[0 100]);
   %eval(['cdf{''',varname,'''}.valid_range = ncfloat([0 255]);'])
end	
%
mexcdf('VARDEF',cdf,'Hdg','FLOAT',1,0);
%cdf{'Hdg'} = ncfloat('ensemble');
mexcdf('ATTPUT',cdf,'Hdg','units','CHAR',7,'degrees');
%cdf{'Hdg'}.units = 'degrees';
mexcdf('ATTPUT',cdf,'Hdg','long_name','CHAR',12,'INST Heading');
%cdf{'Hdg'}.long_name = 'INST Heading';
mexcdf('ATTPUT',cdf,'Hdg','epic_code','LONG',1,1215);
%cdf{'Hdg'}.epic_code = nclong(1215);
mexcdf('ATTPUT',cdf,'Hdg','_FillValue','FLOAT',1,1e35);
%cdf{'Hdg'}.FillValue = ncfloat(1e35);
mexcdf('ATTPUT',cdf,'Hdg','valid_range','FLOAT',2,[0 359.99]);
%cdf{'Hdg'}.valid_range = ncfloat([0 359.99]);
%
mexcdf('VARDEF',cdf,'Ptch','FLOAT',1,0);
%cdf{'Ptch'} = ncfloat('ensemble');
mexcdf('ATTPUT',cdf,'Ptch','units','CHAR',7,'degrees');
%cdf{'Ptch'}.units = 'degrees';
mexcdf('ATTPUT',cdf,'Ptch','long_name','CHAR',10,'INST Pitch');
%cdf{'Ptch'}.long_name = 'INST Pitch';
mexcdf('ATTPUT',cdf,'Ptch','epic_code','LONG',1,1216);
%cdf{'Ptch'}.epic_code = nclong(1216);
mexcdf('ATTPUT',cdf,'Ptch','_FillValue','FLOAT',1,1e35);
%cdf{'Ptch'}.FillValue = ncfloat(1e35);
mexcdf('ATTPUT',cdf,'Ptch','valid_range','FLOAT',2,[-20 20]);
%cdf{'Ptch'}.valid_range = ncfloat([-20 20]);
%
mexcdf('VARDEF',cdf,'Roll','FLOAT',1,0);
%cdf{'Roll'} = ncfloat('ensemble');
mexcdf('ATTPUT',cdf,'Roll','units','CHAR',7,'degrees');
%cdf{'Roll'}.units = 'degrees';
mexcdf('ATTPUT',cdf,'Roll','long_name','CHAR',9,'INST Roll');
%cdf{'Roll'}.long_name = 'INST Roll';
mexcdf('ATTPUT',cdf,'Roll','epic_code','LONG',1,1217);
%cdf{'Roll'}.epic_code = nclong(1217);
mexcdf('ATTPUT',cdf,'Roll','_FillValue','FLOAT',1,1e35);
%cdf{'Roll'}.FillValue = ncfloat(1e35);
mexcdf('ATTPUT',cdf,'Roll','valid_range','FLOAT',2,[-20 20]);
%cdf{'Roll'}.valid_range = ncfloat([-20 20]);
%
mexcdf('VARDEF',cdf,'Tx','FLOAT',1,0);
%cdf{'Tx'} = ncfloat('ensemble');
mexcdf('ATTPUT',cdf,'Tx','units','CHAR',7,'degrees');
%cdf{'Tx'}.units = 'degrees';
mexcdf('ATTPUT',cdf,'Tx','long_name','CHAR',27,'ADCP Transducer Temperature');
%cdf{'Tx'}.long_name = 'ADCP Transducer Temperature';
mexcdf('ATTPUT',cdf,'Tx','epic_code','LONG',1,3017);
%cdf{'Tx'}.epic_code = nclong(3017);
mexcdf('ATTPUT',cdf,'Tx','_FillValue','FLOAT',1,1e35);
%cdf{'Tx'}.FillValue = ncfloat(1e35);
mexcdf('ATTPUT',cdf,'Tx','valid_range','FLOAT',2,[-5 40]);
%cdf{'Tx'}.valid_range = ncfloat([-5 40]);
%
mexcdf('VARDEF',cdf,'xmitc','FLOAT',1,0);
%cdf{'xmitc'} = ncfloat('ensemble');
mexcdf('ATTPUT',cdf,'xmitc','units','CHAR',4,'amps');
%cdf{'xmitc'}.units = 'amps';
mexcdf('ATTPUT',cdf,'xmitc','long_name','CHAR',16,'transmit current');
%cdf{'xmitc'}.long_name = 'transmit current';
mexcdf('ATTPUT',cdf,'xmitc','_FillValue','FLOAT',1,1e35);
%cdf{'xmitc'}.FillValue = ncfloat(1e35);
mexcdf('VARDEF',cdf,'xmitv','FLOAT',1,0);
mexcdf('ATTPUT',cdf,'xmitv','units','CHAR',5,'volts');
mexcdf('ATTPUT',cdf,'xmitv','long_name','CHAR',16,'transmit voltage');
mexcdf('ATTPUT',cdf,'xmitv','_FillValue','FLOAT',1,1e35);
%cdf{'xmitv'} = ncfloat('ensemble');
%cdf{'xmitv'}.units = 'volts';
%cdf{'xmitv'}.long_name = 'transmit voltage';
%cdf{'xmitv'}.FillValue = ncfloat(1e35);
mexcdf('VARDEF',cdf,'dac','LONG',1,0);
mexcdf('ATTPUT',cdf,'dac','units','CHAR',6,'counts');
mexcdf('ATTPUT',cdf,'dac','long_name','CHAR',10,'DAC output');
mexcdf('ATTPUT',cdf,'dac','_FillValue','LONG',1,1e35);
%cdf{'dac'} = nclong('ensemble');
%cdf{'dac'}.units = 'counts';
%cdf{'dac'}.long_name = 'DAC output';
%cdf{'dac'}.FillValue = nclong(1e35);
mexcdf('VARDEF',cdf,'VDD3','LONG',1,0);
mexcdf('ATTPUT',cdf,'VDD3','units','CHAR',5,'volts');
mexcdf('ATTPUT',cdf,'VDD3','long_name','CHAR',17,'battery voltage 3');
mexcdf('ATTPUT',cdf,'VDD3','_FillValue','LONG',1,1e35);
%cdf{'VDD3'} = nclong('ensemble');
%cdf{'VDD3'}.units = 'volts';
%cdf{'VDD3'}.long_name = 'battery voltage 3';
%cdf{'VDD3'}.FillValue = nclong(1e35);
mexcdf('VARDEF',cdf,'VDD1','LONG',1,0);
mexcdf('ATTPUT',cdf,'VDD1','units','CHAR',5,'volts');
mexcdf('ATTPUT',cdf,'VDD1','long_name','CHAR',17,'battery voltage 1');
mexcdf('ATTPUT',cdf,'VDD1','_FillValue','LONG',1,1e35);
%cdf{'VDD1'} = nclong('ensemble');
%cdf{'VDD1'}.units = 'volts';
%cdf{'VDD1'}.long_name = 'battery voltage 1';
%cdf{'VDD1'}.FillValue = nclong(1e35);
mexcdf('VARDEF',cdf,'VDC','LONG',1,0);
mexcdf('ATTPUT',cdf,'VDC','units','CHAR',5,'volts');
mexcdf('ATTPUT',cdf,'VDC','long_name','CHAR',3,'VDC');
mexcdf('ATTPUT',cdf,'VDC','_FillValue','LONG',1,1e35);
%cdf{'VDC'} = nclong('ensemble');
%cdf{'VDC'}.units = 'volts';
%cdf{'VDC'}.long_name = 'VDC';
%cdf{'VDC'}.FillValue = nclong(1e35);

mexcdf('ENDEF',cdf);  %line 848, no varputs before endef!!
fclose(fid);	% close file to force a rewind

%
% ------- load up the data ------
%
fid = fopen(infile,'r');

% load in the depths for each bin
%status = mexcdf('VARPUT', cdfid, varid, start, count, value, autoscale)
status=mexcdf('VARPUT',cdf,'D',0,nbins,depths);
%cdf{'D'}(:) = depths;

% mark for desired data and designate containers
flags = zeros(1,32); 
flags(2)=1;	% flag for ensemble number
flags(3:9)=ones(1,7); % flag for time
flags(12)=1; % speed of sound
flags(14)=1; % heading
flags(15)=1; % pitch
flags(16)=1; % roll
flags(18)=1; % temperature
flags(25)=1; % xmit current
flags(26)=1; % xmit voltage
flags(27)=1; % DAC
flags(29)=1; % VDD3
flags(30)=1; % VDD1
flags(31)=1; % VDC
i=0;
readidx=0;
% define some more things
time_greg=zeros(nens,6);
if exist('minens')~=1,
   minens = 1;
elseif minens < 1,
   minens = 1;
end
if exist('maxens')~=1,
   maxens = nens;
elseif maxens > nens,
   maxens = nens;
end

while 1,
	ens_start = ftell(fid);
	if ens_start < 0, break; end
if (readidx >= minens) & (readidx < maxens),
	% skip to the location of variable leader
	if fseek(fid, offsets(2), 'cof') < 0, break; end
	junk = rdvlead(fid, 0, flags);
	if ~isempty(junk),
		% sort and store
		ensnum = junk(1);
      mexcdf('VARPUT',cdf,'Rec',i,1,junk(1));
      %cdf{'Rec'}(i) = junk(1);
      % fix the year, should work for the next 90 years...
      if junk(2) > 90, 
         junk(2)=junk(2)+1900;
      else
         junk(2)=junk(2)+2000;
      end
     	time_greg(i+1,:) = [junk(2:6) junk(7)+junk(8)/100];
		time_jul=julian([junk(2:6) junk(7)+junk(8)/100]);
      mexcdf('VARPUT',cdf,'TIM',i,1,time_jul);
      %cdf{'TIM'}(i) = time_jul;
      mexcdf('VARPUT',cdf,'sv',i,1,junk(9));
      %cdf{'sv'}(i) = junk(9);
		mexcdf('VARPUT',cdf,'Hdg',i,1,junk(10)./100);
      %cdf{'Hdg'}(i) = junk(10)./100;
		mexcdf('VARPUT',cdf,'Ptch',i,1,junk(11)./100);
      %cdf{'Ptch'}(i) = junk(11)./100;
      mexcdf('VARPUT',cdf,'Roll',i,1,junk(12)./100);
      %cdf{'Roll'}(i) = junk(12)./100;
		mexcdf('VARPUT',cdf,'Tx',i,1,junk(13)./100);
      %cdf{'Tx'}(i) = junk(13)./100;
		mexcdf('VARPUT',cdf,'xmitc',i,1,junk(14).*0.019);
      %cdf{'xmitc'}(i) = junk(14).*0.019;
		mexcdf('VARPUT',cdf,'xmitv',i,1,junk(15).*0.556);
      %cdf{'xmitv'}(i) = junk(15).*0.556;
		mexcdf('VARPUT',cdf,'dac',i,1,junk(16));
      %cdf{'dac'}(i) = junk(16);
		mexcdf('VARPUT',cdf,'VDD3',i,1,junk(17).*0.097);
      %cdf{'VDD3'}(i) = junk(15).*0.097;
		mexcdf('VARPUT',cdf,'VDD1',i,1,junk(18).*0.032);
      %cdf{'VDD1'}(i) = junk(18).*0.032;
		mexcdf('VARPUT',cdf,'VDC',i,1,junk(19).*0.307);
      %cdf{'VDC'}(i) = junk(19).*0.307;
	end
	
	% get the main data (vel, corr, etc)
	junk=zeros(nbins,nbeams);
	fill=ones(1,nbeams).*(1e35);
	for type=3:6,
		pos=ftell(fid);
		% skip to the location of the next data type, 
		if fseek(fid, ens_start+offsets(type)-pos, 'cof') < 0, 
			break; 
		end
		if fread(fid,1,'int16') ~= rec_ids(type),
			disp([longnames(type,:),' data ID not found'])
		else
			% read 'em
			for j=1:nbins,
				[dummy, n] = fread(fid,nbeams,read_types(type,:));
				if n == nbeams, 
					junk(j,:) = dummy'; 
				else
					junk(j,:) = fill;
				end
			end
			% last minute massage
			if type == VELOCITY,
				% change the fill flag to be consistent
				dummy = find(junk == -32768);
				junk(dummy) = ones(size(dummy)).*(1e35);
			end
			% write 'em
			for j=1:nbeams,
				varname = [VARNAMES(type,:),int2str(j)];
            mexcdf('VARPUT',cdf,varname,[i 0],[1 nbins],junk(:,j)');
            %cdf{varname}(i,:) = junk(:,j);
			end
		end
	end
	i=i+1;
end	
readidx=readidx+1;
	% jump to next ensemble
	pos=ftell(fid);
	nskip=nbytes-(pos-ens_start)+2;	% add 2 for checksum
	if fseek(fid,nskip,'cof') < 0; break; end
   if readidx<1000 & ~rem(readidx,100), 
      disp(sprintf('%d ensembles read, %d converted in %d sec',readidx-1,i,toc)), 
   end
	if readidx>1000 & ~rem(readidx,1000), disp(sprintf('%d ensembles read, %d converted in %d sec',readidx-1,i,toc)), end	
	if readidx>maxens break; end
end

fclose(fid);

mexcdf('CLOSE',cdf);
%cdf=close(cdf);

disp('Conversion complete')
disp(sprintf('%d seconds elapsed while processing',toc))
disp(sprintf('%d was the number of the last ensemble read',ensnum))
