function new = bin(data,bincol,start,stop,binsize,bintype)
% bin.m
%
% Simple program for binning a data array into uniform bin sizes
% using a user-defined bin type (eg. 'mean', 'median', 'var').
% Data array is assumed to be column oriented: rows = observations
% and columns = variables.  Note, bins are centered on the bin
% values defined by start, stop and the bin size.
%
% Inputs:
%	data = data array to bin.
%	bincol = data column to use for setting the bins.
%	start = starting bin value.
%	stop = ending bin value.
%	binsize = bin size.
%	bintype = function to use in calculating the bins.
%
% Outputs:
%	new = final, binned data array.
%
% Examples:
%	new = bin([jd degC psu flr],1,jd(1),jd(end),1/60/24,'mean');
%	new = bin([db degC psu],1,2,100,2,'var');
%	new = bin(data,1,0,1,0.001,'median');
%
% Originally written by Andrew Barnard, circa ????, as binpre.m
% Modified by Christopher Wingard, Nov 2003 to be more general in use
% and somewhat more explanatory.

% Set initial parameters
% bin vector and bin window
binVector = [start:binsize:stop]';
nbins = length(binVector);
window = binsize / 2;
% new data array
new = zeros(nbins,size(data,2));
% binning flag
flag = zeros(nbins,1);

% bin the data
for i = 1:nbins
    % find the data that falls into a bin
    m = find(data(:,bincol) > binVector(i) - window ...
        & data(:,bincol) <= binVector(i) + window);
    if isempty(m) == 1 %if there is no data, set the bin flag ...
        flag(i) = 1;
    elseif length(m) == 1 % one value?, just use it then ... **
        new(i,:) = data(m,:);
    else % otherwise we bin
        if length(m) < 2 %Used to be 3, but that removed all data with only 2 data points in the depth bin 2/26/19 - RTR
            flag(i) = 1;
        else
            eval(['new(i,:) = ',bintype,'(data(m,:));'])
        end %if
    end %for
end

% clean up
% set the bin column equal to the binning vector
new(:,bincol) = binVector;
% mark empty bins as NaN
new(flag==1,:) = NaN; %commented this in to avoid zeros in the data (2/26/19 - RTR)

% ** this step is necessary in order to catch what would otherwise
% ** be a vector averaging, the default is column averaging for arrays
% ** and a single average for horizontal or vertical vectors.  That isn't
% ** what we want so I have to trap it out.