function [minens, maxens, nens, trimFile] = goodends(theBeamFile,theMaskFile,trimFile)



%function [minens, maxens, nens, trimFile] = goodends(theBeamFile,theMaskFile,trimFile)

%Make an educated guess at the first good ensemble and the last good.
%This function performs a series of checks at the ends of the record:
%		1. If the number of good bins is greater than 75%
%		2. If the pitch and roll vary by less than 2 degrees
%		3. Based on the above criteria there are four possible asnwers, 
%			one for each of the four beams.  AS a last check see if one of those
%			answers also matches the recovery and deployment dates.
%			

%Input:

%	theBeamFile = the dmasked data file in beam coordinates

%	theMaskFile = the mask used to screen the data,
%						**must be the same dimensions as theBeamFile

%	trimFile = the shortened file to be produced by cutting

%		at the beginning and end of the ensemble record

%

%Outputs:

%	minens = minimum ensemble used to 

%	trimFile = the shortened file to be produced by cutting

%		at the beginning and end of the ensemble record


% Written by Jessica M. Cote
% for the U.S. Geological Survey
% Coastal and Marine Geology Program
% Woods Hole, MA
% http://woodshole.er.usgs.gov/
% Please report bugs to jcote@usgs.gov


%version
%updated 10-Aug-1999 16:20:42

ncquiet



%tell us what function is running

Mname=mfilename;

disp('')

disp([ Mname ' is currently running']);





if nargin < 1, help(mfilename), end



if nargin< 1, theBeamFile = ''; end
if nargin < 2, theMaskFile = ''; end

if nargin < 3, trimFile = ''; end


if isempty(theBeamFile), theBeamFile = '*'; end

if isempty(theMaskFile), theMaskFile = '*'; end

if isempty(trimFile), trimFile = '*'; end

% Get ADCP Beam filename.

if any(theBeamFile == '*')
	[theFile, thePath] = uigetfile(theBeamFile, 'Select ADCP Netcdf File:');
	if ~any(theFile), return, end
	if thePath(end) ~= filesep, thePath(end+1) = filesep; end
	theBeamFile = [thePath theFile];
end


% Get ADCP Mask filename.

if any(theMaskFile == '*')
	[theFile, thePath] = uigetfile(theMaskFile, 'Select ADCP Mask File:');
	if ~any(theFile), return, end
	if thePath(end) ~= filesep, thePath(end+1) = filesep; end
	theMaskFile = [thePath theFile];
end

[path,name,ext,ver]=fileparts(theBeamFile);
suggest=[name(1:end-1) 'T.cdf'];

% Get trimmed ADCP filename.

if any(trimFile == '*')
	[theFile, thePath] = uiputfile(suggest, 'Save the Trimmed ADCP File As:');
	if ~any(theFile), return, end
	if thePath(end) ~= filesep, thePath(end+1) = filesep; end
	trimFile = [thePath theFile];
end




f=netcdf(theMaskFile,'nowrite');

g=netcdf(theBeamFile,'nowrite');



dbin=f('bin');

nbins=dbin(:);



for k = 1:4

	vmask{k} = f{['vel' int2str(k)]};

end



CHUNK=100;

nens = size(f{'vel1'},1);

inens=ones(4,1);

oxens=ones(4,1);



	for k = 1:4;

		theVarname = ['vel' int2str(k)];

		disp([' checking ' theVarname ' ...']);

		p = vmask{k};

		m= size(p,1);

      m=m(1);

      i = 0;

      t=zeros(m,1);

      

      while i < m

		 	j = i+1:min(i+CHUNK,nens);

       	q=t(j,:);

         s = sum(p(j,:),2);

         %if # of bad bins (marked by a 1) is greater than 25%

       	bad = s > 0.25*nbins;	

       	q =  q | bad;  

       	t(j,:)= q;

       	i = i + CHUNK;

      end

         

      
      id=find(t==0);
      
      if isempty(id)
         id = NaN;
      end
      
      inens(k,:)=id(1);
      oxens(k,:)=id(end);
      
end	%for k=1:4 loop

   

   %will give conservative estimates for the min and max ensembles

   minens=min(inens);

   maxens=max(oxens);

   disp(['Based on the # of good bins, ' num2str(minens) ' is the first good ensemble']);

   disp(['and ' num2str(maxens) ' is the last good, out of ' num2str(nens) ' total ensembles'])

   disp(['from the file ' theMaskFile]);

   disp([' '])

   

    

     
%now let's check based on tilt
pitch=g{'Ptch'}(:);
pitch=pitch(minens:maxens);

        
roll=g{'Roll'}(:);

roll=roll(minens:maxens);
tnens=length(pitch);

   

dP=diff(pitch);

dr=diff(roll);

   

   %look for pitch and roll that vary by less than 2 degrees
   idP=find(abs(dP) < 2 & abs(dr) < 2);
   if isempty(idP)
      minp = 1;
   elseif isequal(idP(1),1) & ~isequal(idP(2),2)
      minp = idP(2);
   else
      minp = idP(1);
   end   

   

if idP(end) >= tnens
   maxp=tnens;

elseif idP(end) < maxens

   maxp=idP(end);
else

   maxp=NaN;
end

minens=minens+minp-1;
maxens=maxp;



   disp(['Based on pitch and roll, ' num2str(minens) ' is the first good ensemble']);

   disp(['and ' num2str(maxens) ' is the last good, out of ' num2str(nens) ' total ensembles'])

   disp(['in file ' trimFile])

   disp([' '])




%Needs recently created Netcdf file to run

   %some attributes may not be available in older files

   %let's check these results by getting time in gregorian

   time=g{'TIM'}(:);

   gtD=gregorian(time(minens));

   minT=datestr(datenum(gtD(1),gtD(2),gtD(3)),1);
   
   gtR=gregorian(time(maxens));
   maxT=datestr(datenum(gtR(1),gtR(2),gtR(3)),1);

   
   ddate=g.Deployment_date(:);

   rdate=g.Recovery_date(:);

   if ~isempty([ddate,rdate]);

      
      % If not deployment or recovery dates check the less conservative min and maxes
      if ~isequal(datenum(minT),datenum(ddate)) 
         for ii=2:4;
            inens=sort(inens);
            NgtD=gregorian(time(inens(ii)));
         	NminT=datestr(datenum(NgtD(1),NgtD(2),NgtD(3)),1);
            
            if isequal(datenum(minT),datenum(ddate)), 
               disp('The first good ensemble was chosen based on deployment date')
               disp(['Number of good bins, roll, and pitch gave ensemble ' num2str(minens) ' recorded on ' minT])
               minens=inens(ii);
            	minT=NminT;
					break            
      		else
         		disp('Could not match deployment date')
            end   
         end 
        end 
      

      if ~isequal(datenum(maxT),datenum(rdate))   

         for ii=1:3;
            oxens=sort(oxens);
            NgtR=gregorian(time(oxens(ii)));
         	NmaxT=datestr(datenum(NgtR(1),NgtR(2),NgtR(3)),1);
            
            if isequal(datenum(NmaxT),datenum(rdate)), 
            	disp('The last good ensemble was chosen based on recovery date')
               disp(['Number of good bins, roll, and pitch gave ensemble ' num2str(minens) ' recorded on ' minT])
            	maxens=oxens(ii);
            	maxT=NmaxT; 
               break            
      		else
         		disp('Could not match recovery date')   
      		end
      	end     
      end
      
      disp(' ')

      disp(['The first good ensmeble occurs at ' minT])

      disp(['and the recorded deployment date is ' ddate]);

         

      disp([' '])   

      disp(['The last good ensemble occurs at ' maxT])

      disp(['and the recorded recovery date is ' rdate]);

      
   end

   

   close(f)
   close(g)   

   
   %let's cut down the record based on the minens and maxens given

   disp('Trimming file');
   if ~isequal(1,minens) | ~isequal(maxens,nens)

   	nctrim(theBeamFile, trimFile, (minens:maxens), 'ensemble','isVerbose');

	end



   

thecomment='ensembles recorded pre and post deployment were trimmed by goodends.m';

history(trimFile,thecomment);