function buoy2epic ( buoylist, wind_or_water_flag, epic_key_file )
% BUOY2EPIC:  Takes list of buoy netcdf files, converts them into epic format.
%
% USAGE:  buoy2epic ( buoylist, output_cdf.wind_flag, epic_key_file );
%
% PARAMETERS:
%
%   buoylist:  
%      ascii list of buoy filenames (same as EPIC "pointer" files)
%   output_cdf.wind_flag:  
%      if present and equal to "wind", any "u", "v", "east" or "north"
%      variables will be treated as wind data, not ocean currents.
%      If equal to "water", then it is treated as ocean currents.
%   epic_key_file:
%      If present, this is the location of the epic key file.  If not present,
%      it is assumed that the file location is "/usr/local/lib/epic.key"
%
% EXAMPLE:
%
%   buoy2epic ( 'list_of_buoyfiles', 'wind', '/usr/local/etc/epic.key' );
%

clear global epic_key_data input_cdf output_cdf valid_range;

global epic_key_data;
global input_cdf;
global output_cdf;
global valid_range;


if ( nargin < 1 )
    disp ( 'need at least one input argument' );
    help buoy2epic;
    return;
elseif ( nargin < 2 )
    output_cdf.wind_flag = 0;
    output_cdf.water_flag = 1;
    epic_key_filename = '/usr/local/lib/epic.key';
elseif ( nargin == 2 )
    if ( strcmp(wind_or_water_flag,'wind') )
	output_cdf.wind_flag = 1;
	output_cdf.water_flag = 0;
        epic_key_filename = '/usr/local/lib/epic.key';
    elseif ( strcmp(wind_or_water_flag,'water') )
	output_cdf.wind_flag = 0;
	output_cdf.water_flag = 1;
        epic_key_filename = '/usr/local/lib/epic.key';
    else
	disp ( sprintf ( 'I don''t understand what ''%s'' means.', wind_or_output_cdf.water_flag ) );
	help buoy2epic
	return;
    end
elseif ( nargin == 3 )
    epic_key_filename = epic_key_file;
elseif ( nargin > 3 )
    disp ( 'too many input arguments' );
    help buoy2epic;
    return;
else
    disp ( 'unknown situation encountered.  I suggest you reboot and go to lunch.' );
    help buoy2epic;
    return;
end

status = get_epic_key_data ( epic_key_filename );
if ( status == -1 )
    fprintf ( '''get_epic_key_data'' failed.\n' );
    return;
end

status = setup_valid_ranges;
if ( status == -1 )
    fprintf ( '''setup_valid_ranges'' failed.\n' );
    return;
end

ptr_fid = fopen ( buoylist,'r' );
if ( ptr_fid == -1 )
    disp ( sprintf ( 'Can''t open %s.\n', buoylist ) );
    help buoy2epic;
    return;
end

buoy_file = fgetl ( ptr_fid );
while ( buoy_file ~= -1 )

    status = process ( buoy_file );
    if ( status == -1 )
	fprintf ( 2, '''process'' failed\n' );
        clear epic_key_data input_cdf output_cdf;
	return;
    end

    buoy_file = fgetl ( ptr_fid );

end
    

fclose ( ptr_fid );

return;



%
% process
% This function calls other functions to convert a single buoy file
function status = process ( buoy_filename )

global input_cdf output_cdf;

mexcdf ( 'setopts', 0 );

disp ( sprintf ( 'processing %s...\n', buoy_filename ) );

deblank ( buoy_filename );

status = analyze_input_file ( buoy_filename );
if ( status == -1 )
    fprintf ( 2, '''analyze_input_file'' failed\n' );
    return;
end

%
% split the filename from the file extension
[prefix,suffix] = strtok ( buoy_filename, '.' );

if ( input_cdf.number_of_depths == 1 )
    epic_filename = sprintf ( '%s-epic.cdf', prefix );
    input_cdf.depth_index = 1;

    status = write_outfile ( buoy_filename, epic_filename );
    if ( status == -1 )
	fprintf ( 2, '''write_outfile'' failed\n' );
	return;
    end

    status = fix_vardescript ( epic_filename );
    if ( status == -1 )
	fprintf ( 2, '''fix_vardescript'' failed\n' );
	return;
    end

    status = fix_inst_type ( epic_filename );
    if ( status == -1 )
	fprintf ( 2, '''fix_inst_type'' failed\n' );
	return;
    end

    status = set_valid_range ( epic_filename );
    if ( status == -1 )
	fprintf ( 2, '''fix_inst_type'' failed\n' );
	return;
    end

else
    for i = 1:input_cdf.number_of_depths
	epic_filename = sprintf ( '%s-d%d-epic.cdf', prefix, i );
	input_cdf.depth_index = i;
	status = write_outfile ( buoy_filename, epic_filename );
        if ( status == -1 )
	    fprintf ( 2, '''write_outfile'' failed\n' );
	    return;
        end

	status = fix_vardescript ( epic_filename );
        if ( status == -1 )
	    fprintf ( 2, '''fix_var_descript'' failed\n' );
	    return;
        end

        status = fix_inst_type ( epic_filename );
        if ( status == -1 )
	    fprintf ( 2, '''fix_inst_type'' failed\n' );
	    return;
        end

	status = set_valid_range ( epic_filename );
        if ( status == -1 )
	    fprintf ( 2, '''fix_valid_range'' failed\n' );
	    return;
        end

    end
end

%
% If we got this far, all must be ok
status = 1;

return;




%
% analyze_input_file
%
% Basically, this function should just count the number of
% depth dimensions in the input file.
function status = analyze_input_file ( buoyfile )
%disp ( sprintf ( '\tanalyze_input_file:  %s\n', buoyfile ) );

global input_cdf;

input_cdf.number_of_depths = 0;

[cdfid, status] = mexcdf ( 'open', buoyfile, 'nowrite' );
if ( status == -1 )
    fprintf ( 2, 'Couldn''t open %s.\n', buoyfile );
    return;
end

[ndims,nvars,natts,recdim,status] = mexcdf ( 'inquire', cdfid );
if ( status == -1 )
    fprintf ( 2, 'Couldn''t inquire into number in variables in %s.\n', buoyfile );
    return;
end

%
% loop thru each variable, looking for depth dimensions
for varid= 0:nvars-1

    [varname, datatype, ndims, dimids, natts, status] = mexcdf('VARINQ', cdfid, varid );
    if ( status == -1 )
        fprintf ( 2, 'Couldn''t inquire into varid %d in %s.\n', varid );
        return;
    end

    %
    % search each dimension for depth
    for dimid = 0:ndims-1
	[dimname, dimlength, status] = mexcdf('DIMINQ', cdfid, dimids(dimid+1));
	if ( status == -1 )
            fprintf ( 2, 'Couldn''t inquire as to dimname of dimid %d for %s in %s.\n', ...
			 dimids(dimid+1), varname, buoyfile );
            return;
        end

        if ( ~isempty(findstr('depth',dimname)) )
	    
	    input_cdf.vdepth_dimension(varid+1) = dimids(dimid+1);

	    %
	    % Now make sure that this particular depth has not been
	    % encountered earlier.  If it has, don't count it as a 
	    % "new" depth dimension
	    depth_was_not_encountered_earlier = 1;
	    for k = 0:varid-1
		if ( input_cdf.vdepth_dimension(k+1) == dimids(dimid+1) )
		    depth_was_not_encountered_earlier = 0;
		end
	    end

	    if ( depth_was_not_encountered_earlier )
		input_cdf.all_depth_dimids(input_cdf.number_of_depths+1) = dimids(dimid+1);
		input_cdf.number_of_depths = input_cdf.number_of_depths + 1;
	    end

	end % if ~isempty

    end % for dimid

end % for varid

status = mexcdf ( 'close', cdfid );
if ( status == -1 )
    fprintf ( 2, 'Couldn''t close %s.\n', buoyfile );
    return;
end


%
% If we got this far, all must be ok.
status = 1;

return;








%
% This function actually converts the buoy file to an epic file.
% If there was more than one depth dimension, then only those 
% variables with the current depth dimension will be copied into
% the output file.
function status = write_outfile ( buoyfile, epicfile)

global input_cdf;
global output_cdf;

disp ( sprintf ( '\t%s ==> %s', buoyfile, epicfile ) );

[ncid, status] = mexcdf ( 'create', epicfile, 'clobber' );
output_cdf.ncid = ncid;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  Could not create %s.\n', epicfile );
    return;
end

[ncid, status] = mexcdf ( 'open', buoyfile, 'nowrite' );
input_cdf.ncid = ncid;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  Could not open %s.\n', buoyfile );
    return;
end

status = write_global_atts;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  ''write_global_atts'' failed\n' );
    return;
end
status = write_dimension_defs;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  ''write_dimension_defs'' failed\n' );
    return;
end
status = write_coordinate_var_defs;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  ''write_coordinate_var_defs'' failed\n' );
    return;
end
status = write_coordinate_var_data;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  ''write_coordinate_var_data'' failed\n' );
    return;
end
status = write_coordinate_var_atts;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  ''write_coordinate_var_atts'' failed\n' );
    return;
end
status = write_data_vars;
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  ''write_data_vars'' failed\n' );
    return;
end



%
% All done.  Close out the files.
status = mexcdf ( 'close', input_cdf.ncid );
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  Could not close %s.\n', buoyfile );
    return;
end

status = mexcdf ( 'close', output_cdf.ncid );
if ( status == -1 )
    fprintf ( 2, 'write_outfile:  Could not close %s.\n', epicfile );
    return;
end


%
% If we got this far, all must be ok.
status = 1;
return;





%
% Grab the "name" attribute from each dependent variable,
% construct a colon-delimited list out of it.
function status = fix_vardescript ( epicfile )
%disp ( sprintf ( '\tfix_vardescript:  %s', epicfile) );

ncid = mexcdf('OPEN', epicfile, 'write');
if ( ncid == -1  )
    fprintf ( 2, 'Could not reopen %s to write VARDESCRIPT attribute.\n' );
    status = -1;
    return;
end

[dud, nvars, dud, dud, status] = mexcdf('INQUIRE', ncid);
if ( status == -1  )
    fprintf ( 2, 'Could not get number of variables from %s.\n', epicfile );
    return;
end

count = 0;
for varid = 0:nvars-1

    [varname, dud, ndims, dud, dud, status] = mexcdf('VARINQ', ncid, varid);
    if ( status == -1 )
        fprintf ( 2, 'fix_vardescript:  Could not inquire about varid %d, %s.\n', varid, epicfile );
        return;
    end

    if ( ndims == 4 )
	count = count+1;
        [short_name{count}, status] = mexcdf('ATTGET', ncid, varid, 'name' );
        if ( status == -1 )
            fprintf ( 2, 'fix_vardescript:  Could not get ''name'' attribute from %s, %s.\n', varname, epicfile );
            return;
	end
    end % if ndims==4

end % for varid

vardescript = short_name{1};
for i = 2:count
    vardescript = [vardescript, ':', short_name{i}];
end % for i


status = mexcdf('redef', ncid);
if ( status == -1 )
    fprintf ( 2, 'fix_vardescript:  Could not put %s back into define mode.\n', epicfile );
    return;
end

attname = 'VARDESCRIPT';
attlen = length(vardescript);
attvalue = vardescript;
status = mexcdf('ATTPUT', ncid, 'global', attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'fix_vardescript:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

status = mexcdf('endef', ncid);
if ( status == -1 )
    fprintf ( 2, 'fix_vardescript:  Could not end define mode for %s.\n', epicfile );
    return;
end

status = mexcdf('close', ncid);
if ( status == -1 )
    fprintf ( 2, 'fix_vardescript:  Could not close %s.\n', epicfile );
    return;
end

return;






function status = fix_inst_type ( epicfile )
%disp ( sprintf ( '\tfix_inst_type:  %s', epicfile) );

ncid = mexcdf('OPEN', epicfile, 'write');
if ( ncid == -1  )
    fprintf ( 2, 'fix_inst_type:  Could not reopen %s to fix ''serial_number'' attributes.\n' );
    status = -1;
    return;
end

[dud, nvars, dud, dud, status] = mexcdf('INQUIRE', ncid);
if ( status == -1  )
    fprintf ( 2, 'fix_inst_type:  Could not get number of variables from %s.\n', epicfile );
    return;
end

count = 0;
for varid = 0:nvars-1

    [varname, dud, ndims, dud, natts, status] = mexcdf('VARINQ', ncid, varid);
    if ( status == -1 )
        fprintf ( 2, 'fix_inst_type:  Could not inquire about varid %d, %s.\n', varid, epicfile );
        return;
    end

    if ( ndims == 4 )
        [instrument, status] = mexcdf('ATTGET', ncid, varid, 'serial_number' );
        if ( status == -1 )
	    ;
	else
	    count = count+1;
	    [t1,rest] = strtok(instrument);
	    [t2,rest] = strtok(rest);

	    %
	    %  if the first part is "T-", then it needs to be
	    %  concatenated.
	    if ( strcmp(t1,'T-') )
		fixed_instrument = sprintf ( '%s%s', t1, t2 );

                status = mexcdf('ATTPUT', ncid, varid, 'serial_number', 'char', length(fixed_instrument), fixed_instrument);
                if ( status == -1 )
                    fprintf ( 2, 'fix_inst_type:  Could not put ''%s'' as ''INST_TYPE'' for %s into input file.\n', fixed_instrument, varname );
                    return;
		else
		    disp ( sprintf ( '\t\tvarname:  replacing %s ''serial_number'' attribute value of ''%s'' with ''%s''.\n', varname, instrument, fixed_instrument ) );
                end

		instrument = fixed_instrument;



	    %
	    % Some instruments are coded as 'TR ???' and should be 'TR-???'
	    elseif ( strcmp(t1,'TR') )
		fixed_instrument = sprintf ( '%s-%s', t1, t2 );

                status = mexcdf('ATTPUT', ncid, varid, 'serial_number', 'char', length(fixed_instrument), fixed_instrument);
                if ( status == -1 )
                    fprintf ( 2, 'fix_inst_type:  Could not put ''%s'' as ''INST_TYPE'' for %s into input file.\n', fixed_instrument, varname );
                    return;
		else
		    disp ( sprintf ( '\t\tvarname:  replacing %s ''serial_number'' attribute value of ''%s'' with ''%s''.\n', varname, instrument, fixed_instrument ) );
                end

		instrument = fixed_instrument;
	    
	    %
	    % Some instruments are coded as 'EN ???' and should be 'EN-???'
	    elseif ( strcmp(t1,'EN') )
		fixed_instrument = sprintf ( '%s-%s', t1, t2 );

                status = mexcdf('ATTPUT', ncid, varid, 'serial_number', 'char', length(fixed_instrument), fixed_instrument);
                if ( status == -1 )
                    fprintf ( 2, 'fix_inst_type:  Could not put ''%s'' as ''INST_TYPE'' for %s into input file.\n', fixed_instrument, varname );
                    return;
		else
		    disp ( sprintf ( '\t\tvarname:  replacing %s ''serial_number'' attribute value of ''%s'' with ''%s''.\n', varname, instrument, fixed_instrument ) );
                end

		instrument = fixed_instrument;
	    
	    %
	    % Some instruments are coded as 'SC ???' and should be 'SC-???'
	    elseif ( strcmp(t1,'SC') )
		fixed_instrument = sprintf ( '%s-%s', t1, t2 );

                status = mexcdf('ATTPUT', ncid, varid, 'serial_number', 'char', length(fixed_instrument), fixed_instrument);
                if ( status == -1 )
                    fprintf ( 2, 'fix_inst_type:  Could not put ''%s'' as ''INST_TYPE'' for %s into input file.\n', fixed_instrument, varname );
                    return;
		else
		    disp ( sprintf ( '\t\tvarname:  replacing %s ''serial_number'' attribute value of ''%s'' with ''%s''.\n', varname, instrument, fixed_instrument ) );
                end

	    
		instrument = fixed_instrument;

	    %
	    % Some instruments are coded as 'TH ???' and should be 'TH-???'
	    elseif ( strcmp(t1,'TH') )
		fixed_instrument = sprintf ( '%s-%s', t1, t2 );

                status = mexcdf('ATTPUT', ncid, varid, 'serial_number', 'char', length(fixed_instrument), fixed_instrument);
                if ( status == -1 )
                    fprintf ( 2, 'fix_inst_type:  Could not put ''%s'' as ''INST_TYPE'' for %s into input file.\n', fixed_instrument, varname );
                    return;
		else
		    disp ( sprintf ( '\t\tReplacing %s ''serial_number'' attribute value of ''%s'' with ''%s''.\n', varname, instrument, fixed_instrument ) );
                end

		instrument = fixed_instrument;

	    end

	    all_instruments{count} = instrument;


	end
    end % if ndims==4

end % for varid

%
% Go thru the list, just looking for unique instruments to put into the
% INST_TYPE attribute.
unique_instruments = [];
ucount = 0;
for i = 1:count
    if ( isempty(find(strcmp(unique_instruments, all_instruments{i}))) )
	ucount = ucount+1;
	unique_instruments{ucount} = all_instruments{i};
    end
end



inst_type = unique_instruments{1};
for i = 2:ucount
    inst_type = [inst_type, ':', unique_instruments{i}];
end % for i


status = mexcdf('redef', ncid);
if ( status == -1 )
    fprintf ( 2, 'fix_inst_type:  Could not put %s back into define mode.\n', epicfile );
    return;
end

attname = 'INST_TYPE';
attlen = length(inst_type);
attvalue = inst_type;
status = mexcdf('ATTPUT', ncid, 'global', attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'fix_inst_type:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

status = mexcdf('endef', ncid);
if ( status == -1 )
    fprintf ( 2, 'fix_inst_type:  Could not end define mode for %s.\n', epicfile );
    return;
end

status = mexcdf('close', ncid);
if ( status == -1 )
    fprintf ( 2, 'fix_inst_type:  Could not close %s.\n', epicfile );
    return;
end

return;











%
% Sets up "valid_range" attribute for each variable,
% recomputes a valid maximum and minimum.
function status = set_valid_range ( epicfile )
%disp ( sprintf ( '\tset_valid_range:  %s', epicfile) );

global valid_range;

[ncid, status] = mexcdf('OPEN', epicfile, 'write');
if ( ncid == -1 )
    fprintf ( 2, 'set_valid_range:  Could not open %s.\n', epicfile );
    return;
end

[dud, num_vars, dud, dud, status] = mexcdf('INQUIRE', ncid);
if ( status == -1 )
    fprintf ( 2, 'set_valid_range:  Could not get number of variables for input file.\n' );
    return;
end

for varid = 0:num_vars-1

    [varname, dud, ndims, in_dimids, dud, status] = mexcdf('VARINQ', ncid, varid);
    if ( status == -1 )
        fprintf ( 2, 'set_valid_range:  Could not inquire about varid %d, input file.\n' );
        return;
    end

    if ( ndims == 4 )

        status = mexcdf ( 'endef', ncid );
        if ( ncid == -1 )
            fprintf ( 2, 'set_valid_range:  Could not end define mode for %s.\n', epicfile );
            return;
        end

        [data, status] = mexcdf('VARGET', ncid, varid, [0 0 0 0], [-1 -1 -1 -1] );;
        if ( status == -1 )
            fprintf ( 2, 'set_valid_range:  could not data from varid %d in input file.\n', varid );
            return;
        end

        status = mexcdf ( 'redef', ncid );
        if ( ncid == -1 )
            fprintf ( 2, 'set_valid_range:  Could not redefine %s.\n', epicfile );
            return;
        end

	[epic_code, status] = mexcdf('ATTGET', ncid, varid, 'epic_code' );
	if ( status == -1 )
            fprintf ( 2, 'set_valid_range:  Could not get epic code for %s.\n', varname );
            return;
	end

	valid_max = min( max(data(:)), valid_range.high(epic_code) );
	valid_min = max( min(data(:)), valid_range.low(epic_code) );

        status = mexcdf('ATTPUT', ncid, varid, 'maximum', 'float', 1, valid_max);
        if ( status == -1 )
            fprintf ( 2, 'set_valid_range:  Could not put maximum for varid %d.\n', varid );
            return;
        end

        status = mexcdf('ATTPUT', ncid, varid, 'minimum', 'float', 1, valid_min);
        if ( status == -1 )
            fprintf ( 2, 'set_valid_range:  Could not put minimum for varid %d.\n', varid );
            return;
        end

        this_valid_range = [valid_range.low(epic_code) valid_range.high(epic_code)];
        status = mexcdf('ATTPUT', ncid, varid, 'valid_range', 'float', 2, this_valid_range);
        if ( status == -1 )
            fprintf ( 2, 'set_valid_range:  Could not put valid_range for varid %d.\n', varid );
            return;
        end


    end % if ndims == 4

end % for varid

status = mexcdf ( 'endef', ncid );
if ( ncid == -1 )
    fprintf ( 2, 'set_valid_range:  Could not end define mode for %s.\n', epicfile );
    return;
end

status = mexcdf ( 'close', ncid );
if ( ncid == -1 )
    fprintf ( 2, 'set_valid_range:  Could not close %s.\n', epicfile );
    return;
end

return;






function status = setup_valid_ranges()

global valid_range;

valid_range.low = NaN * zeros(size(5000,1));
valid_range.high = NaN * zeros(size(5000,1));

%
% 7: sea level anomaly
epic_code = 7;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 2;

%
% 20:  temperature
epic_code = 20;
valid_range.low(epic_code) = -100;
valid_range.high(epic_code) = 100;

%
% 21:  air temperature
epic_code = 21;
valid_range.low(epic_code) = -100;
valid_range.high(epic_code) = 100;

%
% 25:  sea surface temperature
epic_code = 25;
valid_range.low(epic_code) = -100;
valid_range.high(epic_code) = 100;

%
% 40:  salinity
epic_code = 40;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 40;

%
% 50:  conductivity
epic_code = 50;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100;

%
% 55:  attenuation
epic_code = 55;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 10000;

%
% 56:  attenuation
epic_code = 56;
valid_range.low(epic_code) = -10;
valid_range.high(epic_code) = 10000;

%
% 60:  oxygen
epic_code = 60;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 20;

%
% 62:  oxygen %
epic_code = 62;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100;

%
% 70:  sigma-t
epic_code = 70;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100;

%
% 71:  sigma-theta
epic_code = 71;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100;

%
% 80:  sound velocity
epic_code = 80;
valid_range.low(epic_code) = 1000;
valid_range.high(epic_code) = 2000;

%
% 81:  correction factor
epic_code = 81;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 2;

%
% 100:  scan number 
epic_code = 100;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e20;

%
% number points in averate
epic_code = 105;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e20;

%
% transmission voltage 7
epic_code = 107;
valid_range.low(epic_code) = -5;
valid_range.high(epic_code) = 5;

%
% current speed
epic_code = 300;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1000;

%
% current direction
epic_code = 310;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 360;

%
% wind speed, cm/s
epic_code = 400;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100000;

%
% wind speed, m/s
epic_code = 401;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1000;

%
% wind gust, m/s
epic_code = 402;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 10000;

%
% wind direction
epic_code = 410;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 360;

%
% wind u, m/s
epic_code = 422;
valid_range.low(epic_code) = -200;
valid_range.high(epic_code) = 200;

%
% wind v, m/s
epic_code = 423;
valid_range.low(epic_code) = -200;
valid_range.high(epic_code) = 200;

%
% wind stress x
epic_code = 446;
valid_range.low(epic_code) = -10;
valid_range.high(epic_code) = 10;

%
% wind stress y
epic_code = 447;
valid_range.low(epic_code) = -10;
valid_range.high(epic_code) = 10;

%
% sdp
epic_code = 850;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 200;

%
% barometric pressure
epic_code = 915;
valid_range.low(epic_code) = 500;
valid_range.high(epic_code) = 1500;

%
% upward velocity
epic_code = 1204;
valid_range.low(epic_code) = -1000;
valid_range.high(epic_code) = 1000;

%
% east velocity
epic_code = 1205;
valid_range.low(epic_code) = -1000;
valid_range.high(epic_code) = 1000;

%
% north velocity
epic_code = 1206;
valid_range.low(epic_code) = -1000;
valid_range.high(epic_code) = 1000;

%
% vane angle
epic_code = 1403;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 360;

%
% compass
epic_code = 1404;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 360;

%
% bearing
epic_code = 1411;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 360;

%
% no code
epic_code = 1900;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1901;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1902;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1903;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1904;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1905;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1906;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1907;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% no code
epic_code = 1908;
valid_range.low(epic_code) = -1e20;
valid_range.high(epic_code) = 1e20;

%
% upper rotor speed counts
epic_code = 4000;
valid_range.low(epic_code) = -6000;
valid_range.high(epic_code) = 6000;

%
% upper rotor speed cm/s
epic_code = 4001;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1000;

%
% lower rotor speed counts
epic_code = 4002;
valid_range.low(epic_code) = -6000;
valid_range.high(epic_code) = 6000;

%
% lower rotor speed cm/s
epic_code = 4003;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1000;

%
% rotor speed difference
epic_code = 4004;
valid_range.low(epic_code) = -1000;
valid_range.high(epic_code) = 1000;

%
% rotor counts
epic_code = 4005;
valid_range.low(epic_code) = -6000;
valid_range.high(epic_code) = 6000;

%
% rotor speed
epic_code = 4006;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1000;

%
% steadiness
epic_code = 4009;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1000;

%
% transmission
epic_code = 4010;
valid_range.low(epic_code) = -5;
valid_range.high(epic_code) = 5;

%
% transmission %
epic_code = 4011;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100;

%
% transmission volts
epic_code = 4012;
valid_range.low(epic_code) = -5;
valid_range.high(epic_code) = 5;

%
% tiltx
epic_code = 4017;
valid_range.low(epic_code) = -45;
valid_range.high(epic_code) = 45;

%
% tilty
epic_code = 4018;
valid_range.low(epic_code) = -45;
valid_range.high(epic_code) = 45;

%
% average relative pressure
epic_code = 4020;
valid_range.low(epic_code) = -1e6;
valid_range.high(epic_code) = 1e6;

%
% average interval pressure
epic_code = 4022;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e6;

%
% average burst pressure
epic_code = 4023;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e6;

%
% u variance
epic_code = 4050;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e8;

%
% uv covariance
epic_code = 4051;
valid_range.low(epic_code) = -1e8;
valid_range.high(epic_code) = 1e8;

%
% v variance
epic_code = 4052;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e8;

%
% uw covariance
epic_code = 4053;
valid_range.low(epic_code) = -1e8;
valid_range.high(epic_code) = 1e8;

%
% vw covariance
epic_code = 4054;
valid_range.low(epic_code) = -1e8;
valid_range.high(epic_code) = 1e8;

%
% w variance
epic_code = 4055;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e8;

%
% period u
epic_code = 4056;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e20;

%
% period v
epic_code = 4057;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 1e20;

%
% average wave period
epic_code = 4060;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 30;

%
% average wave height
epic_code = 4061;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 100;

%
% wave direction 
epic_code = 4062;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 360;

%
% bass a
epic_code = 4070;
valid_range.low(epic_code) = -30000;
valid_range.high(epic_code) = 30000;

%
% bass b
epic_code = 4071;
valid_range.low(epic_code) = -30000;
valid_range.high(epic_code) = 30000;

%
% bass c
epic_code = 4072;
valid_range.low(epic_code) = -30000;
valid_range.high(epic_code) = 30000;

%
% bass d
epic_code = 4073;
valid_range.low(epic_code) = -30000;
valid_range.high(epic_code) = 30000;

%
% bad bass a
epic_code = 4074;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 400;

%
% bad bass b
epic_code = 4075;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 400;

%
% bad bass c
epic_code = 4076;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 400;

%
% bad bass d
epic_code = 4077;
valid_range.low(epic_code) = 0;
valid_range.high(epic_code) = 400;


status = 1;

return;





%
% This function writes the required epic global attributes and
% copies any other global attributes over as well.
function status = write_global_atts
%disp ( sprintf ( '\twrite_global_atts:') );

global input_cdf;
global output_cdf;

attname = 'DATA_TYPE';
status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 4, 'TIME' );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
    return;
end

attname = 'DATA_SUBTYPE';
status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 0, '' );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
    return;
end

%
% Data origin
% If not present in input file, use 'USGS'
attname = 'DATA_ORIGIN';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  No DATA_ORIGIN attribute to copy.\n\tAssuming "USGS" value.\n' );
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 4, 'USGS' );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end



%
% COORD_SYSTEM
attname = 'COORD_SYSTEM';
status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 12, 'GEOGRAPHICAL' );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
    return;
end


%
% WATER_MASS 
% If not present in input file, use ''
attname = 'WATER_MASS';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 0, '' );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% EXPERIMENT 
% If not present in input file, use ''
attname = 'EXPERIMENT';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 0, '' );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end



%
% PROJECT 
% If not present in input file, use ''
attname = 'PROJECT';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 0, '' );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% MOORING 
% If not present in input file, this is very very bad
attname = 'MOORING';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  Missing the MOORING attribute.  Bad! bad! bad!\n' );
    return
end


%
% DELTA_T
% If not present in input file, compute it.
attname = 'DELTA_T';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    [time, status] = mexcdf ( 'varget', input_cdf.ncid, 'time', [0], [-1] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t retrieve ''time'' for DELTA_T attribute.\n' );
        return;
    end
    [time2, status] = mexcdf ( 'varget', input_cdf.ncid, 'time2', [0], [-1] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t retrieve ''time'' for DELTA_T attribute.\n' );
        return;
    end
    time = time + time2/8.64e7;
    delta_t = mean(diff(time))*24*60;
    attval = sprintf ( '%.4f minutes', delta_t );
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', 'DELTA_T', 'char', length(attval), attval );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return
    end

end



%
% COMPOSITE 
% If not present in input file, use 0.  Files are not composite. 
attname = 'COMPOSITE';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'long', 1, [0] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% DATA_CMNT 
% If not present in input file, use ''
attname = 'DATA_CMNT';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 0, '' );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% POS_CONST 
% If not present in input file, use 0.  Assume constant position
attname = 'POS_CONST';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'long', 1, [0] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% DEPTH_CONST 
% If not present in input file, use 0.  Assume constant depth.
attname = 'DEPTH_CONST';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'long', 1, [0] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% WATER_DEPTH
% 
% If WATER_DEPTH isn't present, look for water_depth.  If that
% isn't present, we're dead in the water.
attname = 'WATER_DEPTH';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    [value, status] = mexcdf('attget', input_cdf.ncid, 'global', 'water_depth' );

    %
    % If not successful, bail out.  
    if ( status == -1 )
	fprintf ( 2, 'write_global_atts:  Could not find ''WATER_DEPTH'' or ''water_depth''.\n' );
	return;

    %
    % otherwise round to an integer
    else
	water_depth = round(value+0.5);
	status = mexcdf('attput', output_cdf.ncid, 'global', attname, 'long', 1, water_depth);
        if ( status == -1 )
            fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
            return;
        end

    end
end


%
% water_depth
% 
% If 'water_depth' isn't present, look for 'WATER_DEPTH'.  If that
% isn't present, we're dead in the water.
attname = 'water_depth';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    [value, status] = mexcdf('attget', input_cdf.ncid, 'global', 'WATER_DEPTH' );

    %
    % If not successful, bail out.  
    if ( status == -1 )
	fprintf ( 2, 'write_global_atts:  Could not find ''WATER_DEPTH'' or ''water_depth''.\n' );
	return;

    %
    % otherwise round to an integer
    else
	water_depth = value;
	status = mexcdf('attput', output_cdf.ncid, 'global', attname, 'float', 1, water_depth);
        if ( status == -1 )
            fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
            return;
        end

    end
end



%
% DESCRIPT 
% If not present in input file, use ''
attname = 'DESCRIPT';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', 0, '' );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% DRIFTER 
% If not present in input file, assume NOT to be a drifter
attname = 'DRIFTER';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'long', 1, [0] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end



%
% VAR_DESC, INST_TYPE
% These can't be done at this stage.  Postpone this until we already
% know what variables have been written to the file.




%
% FILL_FLAG 
% If not present in input file, assume there to be no fill values.
attname = 'FILL_FLAG';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
if ( status == -1 )
    status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'long', 1, [0] );
    if ( status == -1 )
        fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
        return;
    end
end


%
% VAR_FILL 
% If not present in input file, forget it.
attname = 'VAR_FILL';
status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );



%
% CREATION_DATE 
attname = 'CREATION_DATE';
the_date = datestr(now);
status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', length(the_date), the_date );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
    return;
end


%
% CONVENTIONS 
attname = 'CONVENTIONS';
attvalue = 'PMEL-EPIC/TIME_Series';
status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'char', length(attvalue), attvalue );
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
    return;
end


%
% Ok, now go thru the rest of the attributes.  If they match the name
% of any of the attributes above, ignore it.  Otherwise copy it.
attnames_already_done = { 'CREATION_DATE'; ...
			  'INST_TYPE'; ...
			  'DATA_TYPE'; ...
			  'CONVENTIONS'; ...
			  'DATA_SUBTYPE'; ...
			  'DATA_ORIGIN'; ...
			  'COORD_SYSTEM'; ...
			  'WATER_MASS'; ...
			  'EXPERIMENT'; ...
			  'PROJECT'; ...
			  'MOORING'; ...
			  'DELTA_T'; ...
			  'COMPOSITE'; ...
			  'DATA_CMNT'; ...
			  'POS_CONST'; ...
			  'DEPTH_CONST'; ...
			  'WATER_DEPTH'; ...
			  'water_depth'; ...
			  'DESCRIPT'; ...
			  'DRIFTER'; ...
			  'VAR_DESC'; ...
			  'FILL_FLAG'; ...
			  'VAR_FILL'; };
[ndims, nvars, natts, recdim, status] = mexcdf('inquire', input_cdf.ncid);
if ( status == -1 )
    fprintf ( 2, 'write_global_atts:  couldn''t get number of global attributes.\n' );
    return;
end
for attnum = 0:natts-1
    [attname, status] = mexcdf('attname', input_cdf.ncid, 'global', attnum);
    if ( status  == -1 )
        fprintf ( 2, 'write_global_atts:  Could not get name of global att %d from input file.\n', attnum );
        return;
    end

    if ( isempty(strcmp(attnames_already_done,attname)) )
        status = mexcdf ( 'attcopy', input_cdf.ncid, 'global', attname, output_cdf.ncid, 'global' );
        if ( status == -1 )
            status = mexcdf ( 'attput', output_cdf.ncid, 'global', attname, 'long', 1, [0] );
            if ( status == -1 )
                fprintf ( 2, 'write_global_atts:  couldn''t write %s attribute.\n', attname );
                return;
            end
        end
    end % if isempty

end % for attnum

status = 1;
return;




%
% Define the dimensions of the new file.  They will be
% "time", "lat", "lon", and "depth".  There will be only
% one depth dimension here, whereas in the input file,
% there may have been many.
function status = write_dimension_defs

global input_cdf;
global output_cdf;



%
% time first
[dimid, status] = mexcdf('dimid', input_cdf.ncid, 'time');
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not get time dimension dimid.\n' );
    return;
end
input_cdf.dimid(1) = dimid;

[name, length, status] = mexcdf('DIMINQ', input_cdf.ncid, 'time');
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not get length of time.\n' );
    return;
end
output_cdf.time_size = length;

status = mexcdf('dimdef', output_cdf.ncid, 'time', output_cdf.time_size);
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not define time in output cdf file.\n' );
    return;
end

output_cdf.dimid(1) = status;




%
% We should already have the depth dimid on hand
input_cdf.dimid(2) = input_cdf.all_depth_dimids(input_cdf.depth_index);
status = mexcdf('dimdef', output_cdf.ncid, 'depth', [1]);
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not define depth in output cdf file.\n' );
    return;
end

output_cdf.dimid(2) = status;




%
% latitude 
[lat_dimid, status] = mexcdf('dimid', input_cdf.ncid, 'lat');
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not get lat dimension dimid.\n' );
    return;
end
input_cdf.dimid(3) = lat_dimid;

status = mexcdf('dimdef', output_cdf.ncid, 'lat', [1]);
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not define lat in output cdf file.\n' );
    return;
end

output_cdf.dimid(3) = status;




%
% longitude 
[lon_dimid, status] = mexcdf('dimid', input_cdf.ncid, 'lon');
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not get lat dimension dimid.\n' );
    return;
end
input_cdf.dimid(4) = lon_dimid;

status = mexcdf('dimdef', output_cdf.ncid, 'lon', [1]);
if ( status == -1 )
    fprintf ( 2, 'write_dimension_defs:  could not define lat in output cdf file.\n' );
    return;
end

output_cdf.dimid(4) = status;



return;










%
% Now define the coordinate variables.  These are
% time, time2, depth, lat, and then lon.  Well,
% "time2" really isn't a coordinate variable, but
% let's define it now anyway.
function status = write_coordinate_var_defs

global input_cdf output_cdf;

status = mexcdf('vardef', output_cdf.ncid, 'time', 'long', 1, output_cdf.dimid(1) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_defs:  Could not define time.\n' );
    return;
end

status = mexcdf('vardef', output_cdf.ncid, 'time2', 'long', 1, output_cdf.dimid(1) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_defs:  Could not define time2.\n' );
    return;
end

status = mexcdf('vardef', output_cdf.ncid, 'depth', 'float', 1, output_cdf.dimid(2) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_defs:  Could not define depth.\n' );
    return;
end

status = mexcdf('vardef', output_cdf.ncid, 'lat', 'float', 1, output_cdf.dimid(3) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_defs:  Could not define lat.\n' );
    return;
end

status = mexcdf('vardef', output_cdf.ncid, 'lon', 'float', 1, output_cdf.dimid(4) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_defs:  Could not define lon.\n' );
    return;
end



return;





%
% Extract the lat, lon, depth, and time data from
% the input file and write to the output file.
function status = write_coordinate_var_data

%disp ( sprintf ( '\twrite_coordinate_var_data:') );

global input_cdf output_cdf;

status = mexcdf ( 'endef', output_cdf.ncid );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not end def stage on ouput file.\n' );
    return;
end

[time_dimid, status] = mexcdf('dimid', input_cdf.ncid, 'time');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time id from input file.\n' );
    return;
end

[name, time_size, status] = mexcdf('diminq', input_cdf.ncid, time_dimid ); 
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time size from input file.\n' );
    return;
end

[input_varid, status] = mexcdf('varid', input_cdf.ncid, 'time');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time varid from output file.\n' );
    return;
end

[output_varid, status] = mexcdf('varid', output_cdf.ncid, 'time');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time varid from output file.\n' );
    return;
end


[time, status] = mexcdf('varget', input_cdf.ncid, input_varid, [0], [time_size]);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time data from input file.\n' );
    return;
end


status = mexcdf('varput', output_cdf.ncid, output_varid, [0], [time_size], time);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not put time data input output file.\n' );
    return;
end




%
% time2
[input_varid, status] = mexcdf('varid', input_cdf.ncid, 'time2');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time2 varid from output file.\n' );
    return;
end

[output_varid, status] = mexcdf('varid', output_cdf.ncid, 'time2');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time2 varid from output file.\n' );
    return;
end


[time2, status] = mexcdf('varget', input_cdf.ncid, input_varid, [0], [time_size]);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get time2 data from input file.\n' );
    return;
end


status = mexcdf('varput', output_cdf.ncid, output_varid, [0], [time_size], time2);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not put time2 data into output file.\n' );
    return;
end


%
% depth
[current_dimname, dud, status] = mexcdf( ...
	  'diminq', ...  
	  input_cdf.ncid, ...
	  input_cdf.all_depth_dimids(input_cdf.depth_index) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get current depth dimname.\n' );
    return;
end

[input_varid, status] = mexcdf('varid', input_cdf.ncid, current_dimname);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get current depth varid.\n' );
    return;
end

[output_varid, status] = mexcdf('varid', output_cdf.ncid, 'depth');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get output depth varid.\n' );
    return;
end

[depth, status] = mexcdf('varget', input_cdf.ncid, input_varid, [0], [1]);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get input depth value.\n' );
    return;
end

%
% For some moronic reason, depth is often not given the correct value.
% Often, the "sensor_depth" attribute has the correct value.  So
% we get that attribute for each variable defined for this particular
% depth dimension, compare it to the given depth value.  If they are
% the same, no problem.  If they are different, use the "sensor_depth"
% value and tell the user.
[sensor_depth, status] = get_sensor_depth ( input_cdf.ncid, ...
					    input_cdf.all_depth_dimids(input_cdf.depth_index) );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  ''get_sensor_depth'' failed.\n' );
    return;
end

if ( sensor_depth ~= depth ) 
    fprintf ( 2, '\tsensor depth %6.2f does not equal variable depth %6.2f, ', ...
	      sensor_depth, ...
	      depth );
    fprintf ( 2, 'using sensor depth.\n' );
end
depth = sensor_depth;

status = mexcdf('varput', output_cdf.ncid, output_varid, [0], [1], depth);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not put depth data into output file.\n' );
    return;
end




%
% lat
[input_varid, status] = mexcdf('varid', input_cdf.ncid, 'lat');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get lat varid from input file.\n' );
    return;
end

[output_varid, status] = mexcdf('varid', output_cdf.ncid, 'lat');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get lat varid from output file.\n' );
    return;
end


[lat, status] = mexcdf('varget', input_cdf.ncid, input_varid, [0], [1]);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get lat data from input file.\n' );
    return;
end


status = mexcdf('varput', output_cdf.ncid, output_varid, [0], [1], lat);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not put lat data into output file.\n' );
    return;
end



%
% lon
[input_varid, status] = mexcdf('varid', input_cdf.ncid, 'lon');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get lon varid from input file.\n' );
    return;
end

[output_varid, status] = mexcdf('varid', output_cdf.ncid, 'lon');
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get lon varid from output file.\n' );
    return;
end


[lon, status] = mexcdf('varget', input_cdf.ncid, input_varid, [0], [1]);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not get lon data from input file.\n' );
    return;
end

if ( lon > 0 )
    lon = lon*-1;
end

status = mexcdf('varput', output_cdf.ncid, output_varid, [0], [1], lon);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_data:  Could not put lon data into output file.\n' );
    return;
end

disp ( sprintf ( '\t\tdepth = %8.4f, lat = %8.4f, lon = %8.4f.', depth, lat, lon ) );


return;





%
% Get the depth attribute value for all variables defined at the
% current depth dimension.
function [sensor_depth, status] = get_sensor_depth ( ncid, depth_dimid )
%disp ( sprintf ( '\tget_sensor_depth:  stub routine') );

global input_cdf;

depth_count = 0;

[dud, num_vars, dud, dud, status] = mexcdf('INQUIRE', input_cdf.ncid);
if ( status == -1 )
    fprintf ( 2, 'get_sensor_depth:  Could not get number of variables for input file.\n' );
    return;
end


for varid = 0:num_vars-1

    [varname, dud, ndims, in_dimids, dud, status] = mexcdf('VARINQ', input_cdf.ncid, varid);
    if ( status == -1 )
        fprintf ( 2, 'get_sensor_depth:  Could not inquire about varid %d, input file.\n' );
        return;
    end

    %
    % Don't bother if it is a coordinate variable.
    if ( ndims == 4 )

	depth_match_found = 0;
	depth_match_found = ~isempty(find(in_dimids == depth_dimid));
	if ( depth_match_found )
	    depth_count = depth_count+1;
	    [depths(depth_count), status] = mexcdf('ATTGET', ncid, varid, 'sensor_depth' );
	    if ( status == -1 )
                fprintf ( 2, 'get_sensor_depth:  Could not get sensor depth for %s.\n', varname );
                return;
	    end
	end % if depth_match_found
     


    end % if ndims == 4

end % for varid

%
% Check for consistency.  
for i = 2:depth_count
    if ( depths(i) ~= depths(i-1) )
	fprintf ( 2, '\t\tSome of the sensor depths are not the same.\n' );
	fprintf ( 2, '\t\tYou will probably have to do this file by hand.\n' );
	status = -1;
	return;
    end
end


sensor_depth = depths(1);


return;













%
% Writes out epic compliant attributes for coordinate variables.
function status = write_coordinate_var_atts

%disp ( sprintf ( '\twrite_coordinate_var_atts:') );
global output_cdf;


status = mexcdf ( 'redef', output_cdf.ncid );
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put output file back into define mode.\n' );
    return;
end


%
% time
varname = 'time';
[varid, status] = mexcdf('VARID', output_cdf.ncid, varname);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not get time varid from output file.\n' );
    return;
end

attname = 'FORTRAN_format';
attvalue = 'F10.2';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

attname = 'units';
attvalue = 'True Julian Day';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'type';
attvalue = 'EVEN';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'epic_code';
attvalue = 624;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'long', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%d'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end




%
% time2
varname = 'time2';
[varid, status] = mexcdf('VARID', output_cdf.ncid, varname);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not get %s varid from output file.\n', varname );
    return;
end

attname = 'FORTRAN_format';
attvalue = 'F10.2';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

attname = 'units';
attvalue = 'msec since 0:00 GMT';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'type';
attvalue = 'EVEN';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'epic_code';
attvalue = 624;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'long', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%d'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end




%
% depth
varname = 'depth';
[varid, status] = mexcdf('VARID', output_cdf.ncid, varname);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not get %s varid from output file.\n', varname );
    return;
end

attname = 'FORTRAN_format';
attvalue = 'F10.2';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

attname = 'units';
attvalue = 'm';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'type';
attvalue = 'EVEN';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'epic_code';
attvalue = 3;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'long', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%d'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end




%
% lat
varname = 'lat';
[varid, status] = mexcdf('VARID', output_cdf.ncid, varname);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not get %s varid from output file.\n', varname );
    return;
end

attname = 'FORTRAN_format';
attvalue = 'F10.2';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

attname = 'units';
attvalue = 'degrees_north';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'type';
attvalue = 'EVEN';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'epic_code';
attvalue = 500;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'long', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%d'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end



%
% lon
varname = 'lon';
[varid, status] = mexcdf('VARID', output_cdf.ncid, varname);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not get %s varid from output file.\n', varname );
    return;
end

attname = 'FORTRAN_format';
attvalue = 'F10.2';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end

attname = 'units';
attvalue = 'degrees_west';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'type';
attvalue = 'EVEN';
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%s'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end


attname = 'epic_code';
attvalue = 502;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'long', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_coordinate_var_atts:  Could not put ''%d'' as ''%s'' for %s into input file.\n', attvalue, attname, varname );
    return;
end







return;

















%
% Write out the dependent variables. 
function status = write_data_vars
 
global input_cdf output_cdf;

%disp ( sprintf ( '\twrite_data_vars:') );

[dud, num_old_vars, dud, dud, status] = mexcdf('INQUIRE', input_cdf.ncid);
if ( status == -1 )
    fprintf ( 2, 'write_data_vars:  Could not get number of variables from input file.\n' );
    return;
end
    
for varid = 0:num_old_vars-1
    
    [varname, dud, ndims, in_dimids, natts, status] = mexcdf('VARINQ', input_cdf.ncid, varid);
    if ( status == -1 )
        fprintf ( 2, 'write_data_vars:  Could not inquire about varid %d in input file.\n', varid );
        return;
    end

    %
    % If there are less than 4 dimensions, it is a coordinate variable, and we should ignore it.
    if ( ndims == 4 )

        %
	% check the depth dimension for THIS output file against the dimids for the current
	% variable.  If there is a match, then the current variable belongs in the current
	% output file.
	depth_match_found = 0;
	if ( ~isempty ( find ( in_dimids == input_cdf.all_depth_dimids(input_cdf.depth_index) ) ) )
	    depth_match_found = 1;
	end % if ~isempty

	if ( depth_match_found )

	    input_cdf.buoy_varname = varname;
	    status = match_varname;
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  ''match_varname'' failed.\n' );
		return;
	    end

	    disp ( sprintf ( '\t\tbuoy name %s ==> epic name %s', input_cdf.buoy_varname, output_cdf.epic_varname ) );

            status = mexcdf('VARDEF', output_cdf.ncid, output_cdf.epic_varname, 'float', 4, output_cdf.dimid );
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  Could not define %s in output file.\n', input_cdf.epic_varname );
		return;
	    end

            out_varid = status;
	    status = write_epic_var_atts ( out_varid );
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  ''write_epic_var_atts'' failed.\n' );
		return;
	    end
	    status = write_other_var_atts ( varid, out_varid );
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  ''write_other_var_atts'' failed.\n' );
		return;
	    end

	    %
	    % end define stage so we can write the data.
	    % Then go back to define mode to handle next variable.
	    status = mexcdf ( 'endef', output_cdf.ncid );
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  could not end define stage for output file.\n' );
		return;
	    end
	    
	    status = write_epic_var_data ( varid, out_varid );
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  ''write_epic_var_data'' failed.\n' );
		return;
	    end

	    status = mexcdf ( 'redef', output_cdf.ncid );
	    if ( status == -1 )
		fprintf ( 2, 'write_data_vars:  could not reenter define stage for output file.\n' );
		return;
	    end



	end % if depth_match_found

    end % if ndims == 4

end % for varid

return;








%
% Write the particular epic attributes for the
% dependent variables.
function status = write_epic_var_atts ( varid )
%disp ( 'write_epic_var_atts:  ' );

global output_cdf;

attname = 'epic_code';
attvalue = output_cdf.epic_code;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'long', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_atts:  could not write %s attribute for varid %d in output file.\n', attname, varid );
    return;
end


attname = 'name';
attvalue = output_cdf.short_name;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_atts:  could not write %s attribute for varid %d in output file.\n', attname, varid );
    return;
end


attname = 'long_name';
attvalue = output_cdf.long_name;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_atts:  could not write %s attribute for varid %d in output file.\n', attname, varid );
    return;
end


attname = 'generic_name';
attvalue = output_cdf.generic_name;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_atts:  could not write %s attribute for varid %d in output file.\n', attname, varid );
    return;
end


attname = 'FORTRAN_format';
attvalue = output_cdf.fortran_format;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_atts:  could not write %s attribute for varid %d in output file.\n', attname, varid );
    return;
end


attname = 'units';
attvalue = output_cdf.units;
attlen = length(attvalue);
status = mexcdf('ATTPUT', output_cdf.ncid, varid, attname, 'char', attlen, attvalue);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_atts:  could not write %s attribute for varid %d in output file.\n', attname, varid );
    return;
end


return;










%
% Copy non-epic attributes for each variable.
function status = write_other_var_atts ( in_varid, out_varid )
%disp ( 'write_other_var_atts:  ' );

global input_cdf output_cdf;

[varname, dud, dud, dud, natts, status] = mexcdf('VARINQ', input_cdf.ncid, in_varid );
if ( status == -1 )
    fprintf ( 2, 'write_other_var_atts:  could not get number of attributes for varid %d in input file.\n', varid );
    return;
end


for attnum = 0:natts-1

    [attname, status] = mexcdf('ATTNAME', input_cdf.ncid, in_varid, attnum);
    if ( status == -1 )
        fprintf ( 2, 'write_other_var_atts:  could not get attname of attribute %d for varid %d in input file.\n', attnum, varid );
	return;
    end

    if (   strcmp ( attname, 'name' ) ...
	 | strcmp ( attname, 'long_name' ) ... 
	 | strcmp ( attname, 'generic_name' ) ... 
	 | strcmp ( attname, 'FORTRAN_format' ) ... 
	 | strcmp ( attname, 'units' ) ... 
	 | strcmp ( attname, 'epic_code' ) )
	;
    else
	status = mexcdf('ATTCOPY', input_cdf.ncid, in_varid, attname, output_cdf.ncid, out_varid);
        if ( status == -1 )
            %fprintf ( 2, 'write_other_var_atts:  could not copy %s from input file to output file.\n\ttrying ATTGET and ATTPUT\n', attname );
            %return;

	    [value, status] = mexcdf('ATTGET', input_cdf.ncid, in_varid, 'minimum');
	    if ( status == -1 )
                fprintf ( 2, 'write_other_var_atts:  could not ATTGET %s from input file\n', attname );
		return
	    end

	    status = mexcdf('ATTPUT', output_cdf.ncid, out_varid, 'minimum', 'float', length(value), value);
	    if ( status == -1 )
                fprintf ( 2, 'write_other_var_atts:  could not ATTPUT %s to output file\n', attname );
		return
	    end

        end
    end % if strcmp
   
end % for attnum

return;











%
% Copy dependent variable data from input file to output file.
% It may be necessary to do a units transformation.
function status = write_epic_var_data ( in_varid, out_varid )
%disp ( 'write_epic_var_data:  ' );

global input_cdf output_cdf;

[data, status] = mexcdf('VARGET', input_cdf.ncid, in_varid, [0 0 0 0], [-1 -1 -1 -1] );;
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_data:  could not data from varid %d in input file.\n', in_varid );
    return;
end

[data, status] = convert_to_new_units ( data, input_cdf.ncid, in_varid, output_cdf.epic_code );
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_data:  ''convert_to_new_units'' failed.\n' );
    return;
end

status = mexcdf('VARPUT', output_cdf.ncid, out_varid, [0 0 0 0], [-1 -1 -1 -1], data);
if ( status == -1 )
    fprintf ( 2, 'write_epic_var_data:  could not put data into varid %d in output file.\n', out_varid );
    return;
end

return;



%
% If the input units differ from the output units, we may have to
% do a units conversion on the data.
function [out_data, status] = convert_to_new_units ( data, ncid, varid, epic_code )

global input_cdf output_cdf;


%
% We may do a premature return in case there is nothing to do, so set the return
% values now.
out_data = data;
status = 1;

epic_units = deblank ( output_cdf.units );

[buoy_units, status] = mexcdf('ATTGET', input_cdf.ncid, varid, 'units');
if ( status == -1 )
    fprintf ( 2, 'convert_to_new_units:  could not retrieve buoy units for varid %d in input file.\n', varid );
    return;
end
buoy_units = deblank ( buoy_units );


%
% temperature
% No conversion necessary for C <==> celcius, etc.
if ( (epic_code == 20 ) & strcmp(buoy_units,'deg c') & (strcmp(epic_units,'C')) )

    return;

elseif ( (epic_code==20 ) & strcmp(buoy_units,'celcius') )
 
    return;

elseif ( (epic_code==20 ) & strcmp(buoy_units,'celsius') )
 
    return;

elseif ( (epic_code==20 ) & strcmp(buoy_units,'deg.celc') )
 
    return;


%
% air temperature
elseif ( (epic_code==21 ) & strcmp(buoy_units,'celcius') )
 
    return;

elseif ( (epic_code==21 ) & strcmp(buoy_units,'celsius') )
 
    return;

elseif ( (epic_code==21 ) & strcmp(buoy_units,'deg.celc') )
 
    return;


%
% SST
elseif ( (epic_code==25 ) & strcmp(buoy_units,'celcius') )
 
    return;

elseif ( (epic_code==25 ) & strcmp(buoy_units,'celsius') )
 
    return;

elseif ( (epic_code==25 ) & strcmp(buoy_units,'deg.celc') )
 
    return;


%
% salinity
elseif ( (epic_code==40) & strcmp(buoy_units,'ppt') & strcmp(epic_units,'PPT') ) 

    return



%
% 50:  conductivity
elseif ( (epic_code==50) & strcmp(buoy_units,'mmho/cm') & strcmp(epic_units,'mmho/cm') ) 

    return;

%
% 50:  conductivity
elseif ( (epic_code==50) & strcmp(buoy_units,'mmhos/cm') & strcmp(epic_units,'mmho/cm') ) 

    return;

%
% 50:  conductivity
elseif ( (epic_code==50) & strcmp(buoy_units,'s/m') & strcmp(epic_units,'mmho/cm') ) 

    out_data = out_data * 10;
    return;


%
% 55:  attenuation
elseif ( (epic_code==55) & strcmp(buoy_units,'1/m') & strcmp(epic_units,'m-1') ) 

    return


%
% 70:  sigmat_t
elseif ( (epic_code==70) & strcmp(buoy_units,'sigma') & strcmp(epic_units,'kg m-3') ) 

    return

%
% 71:  sigmat_theta
elseif ( (epic_code==71) & strcmp(buoy_units,'sigma') & strcmp(epic_units,'kg m-3') ) 

    return

%
% 80:  sound speed
elseif ( (epic_code==80) & strcmp(buoy_units,'m/s') & strcmp(epic_units,'m s-1') ) 

    return

%
% 81:  correction factor, don't even bother
elseif ( (epic_code==81) )

    return


%
% 300: water  speed
elseif ( (epic_code==300) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'cm s-1') ) 

    return



%
% 300: water  speed
elseif ( (epic_code==300) & strcmp(buoy_units,'meters/sec') & strcmp(epic_units,'cm s-1') ) 

    out_data = out_data * 100;
    return

%
% 300: water  speed
elseif ( (epic_code==300) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'m s-1') ) 

    out_data = out_data * 1e-2;
    return


%
% 310: water direction
elseif ( (epic_code==310) & strcmp(buoy_units,'deg') & strcmp(epic_units,'degrees') ) 

    return


%
% 401: wind direction
elseif ( (epic_code==401) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'m s-1') ) 

    out_data = out_data * 1e-2;
    return

%
% 401: wind direction
elseif ( (epic_code==401) & strcmp(buoy_units,'meters/sec') & strcmp(epic_units,'m s-1') ) 

    return


%
% 410: wind direction
elseif ( (epic_code==410) & strcmp(buoy_units,'deg') & strcmp(epic_units,'degrees') ) 

    return

%
% 422: wind u
elseif ( (epic_code==422) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'m s-1') ) 
    
    out_data = out_data * 1e-2;
    return;

%
% 422: wind u
elseif ( (epic_code==422) & strcmp(buoy_units,'meters/sec') & strcmp(epic_units,'m s-1') ) 
    
    return;

%
% 423: wind v
elseif ( (epic_code==423) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'m s-1') ) 
    
    out_data = out_data * 1e-2;
    return;

%
% 423: wind v
elseif ( (epic_code==423) & strcmp(buoy_units,'meters/sec') & strcmp(epic_units,'m s-1') ) 
    
    out_data = out_data * 1e-2;
    return;

%
% 850: sdp
elseif ( (epic_code==850) & strcmp(buoy_units,'mbars') & strcmp(epic_units,'mbar') ) 

    return

%
% 915: atmos press
elseif ( (epic_code==915) & strcmp(buoy_units,'mbars') & strcmp(epic_units,'mbar') ) 

    return

%
% 915: atmos press
elseif ( (epic_code==915) & strcmp(buoy_units,'millibars') & strcmp(epic_units,'mbar') ) 

    return


%
% 1204: vertical
elseif ( (epic_code==1204) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'cm/s') ) 

    return

%
% 1205: east
elseif ( (epic_code==1205) & strcmp(buoy_units,'meters/sec') & strcmp(epic_units,'cm/s') ) 

    out_data = out_data * 100;;
    return

%
% 1205: east
elseif ( (epic_code==1205) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'cm/s') ) 

    return


%
% 1206: north
elseif ( (epic_code==1206) & strcmp(buoy_units,'meters/sec') & strcmp(epic_units,'cm/s') ) 

    out_data = out_data * 100;
    return

%
% 1206: north
elseif ( (epic_code==1206) & strcmp(buoy_units,'cm/s') & strcmp(epic_units,'cm/s') ) 

    return


%
% 1404: something
elseif ( (epic_code==1404) & strcmp(buoy_units,'ang.deg.') & strcmp(epic_units,'degreeM') ) 

    return


%
% 4010: transmission
elseif ( (epic_code==4010) & strcmp(buoy_units,'volts') & strcmp(epic_units,'volts') ) 

    return


%
% 4011: transmission percent
elseif ( (epic_code==4011) & strcmp(buoy_units,'percent') )

    return

%
% 4017: tiltx
elseif ( (epic_code==4017) & strcmp(buoy_units,'ang.deg.') & strcmp(epic_units,'degrees') ) 

    return

%
% 4018: tilty
elseif ( (epic_code==4018) & strcmp(buoy_units,'ang.deg.') & strcmp(epic_units,'degrees') ) 

    return

%
% 4023: pressure
elseif ( (epic_code==4023) & strcmp(buoy_units,'mbars') )

    return

%
% 4060: wave period
elseif ( (epic_code==4060) & strcmp(buoy_units,'seconds') & strcmp(epic_units,'s') )

    return

%
% 4061: wave height
elseif ( (epic_code==4061) & strcmp(buoy_units,'meters') & strcmp(epic_units,'m') )

    return


%
% 4062: wave direction
elseif ( (epic_code==4062) & strcmp(buoy_units,'ang.deg.') & strcmp(epic_units,'degrees') )

    return

else
    fprintf ( 2, '\nepic code = %d, buoy units = %s, epic units = %s\n', epic_code, buoy_units, epic_units );
    fprintf ( 2, 'don''t know what to do...\n' );
    fprintf ( 2, 'You will need to check the ''convert_to_new_units'' function and add code to handle this.\n\n\n\n' )
    fprintf ( 2, 'The code fragment should look something like...\n\n' );
    fprintf ( 2, '  elseif ( (epic_code=????) & strcmp(buoy_units,''xxx') & strcmp(epic_units,''yyy'') ) \n' );
    fprintf ( 2, '      out_data = out_data * zzz;  % scale the data apropriately\n\n\n' );

    status = -1;
    return;


end 







return;



