Skip to content
Snippets Groups Projects
horizontalVelocity.m 4.97 KiB
Newer Older
function [velocityTotal, velocityLatitude, velocityLongitude] = horizontalVelocity(pLatitude, pLongitude, pInterval, pMethod, pNop)

% 29 October 2003, HHFurey.   This routine does not account for
% discontinuous segments of track being passed, and therefore returns
% erroneous results.  Not true - data passed in is bad - some segments that
% are discontinuous are passed through with NaNs as filler, but others are not!
% Hmmm ... working on r023 as a test case, this has three discontinous segments
% of track.


if nargin < 4
  pMethod='average';
end

if nargin < 5
  pNop=1;
end
%save debug_02
%                       nautic miles in kilometers
nm_in_km=60*1.852;

velocityTotal=-9.99*ones(size(pLatitude))*NaN;
velocityLatitude=-9.99*ones(size(pLatitude))*NaN;
velocityLongitude=-9.99*ones(size(pLatitude))*NaN;

if strcmp(pMethod,'average');    % centered mean between point ix+nop and ix-nop, centered at ix
  for ix=1:length(pLatitude)
    if ~((ix-pNop < 1) | (ix+pNop > length(pLatitude)))
      if ~any(isnan(pLatitude([ix-pNop:ix+pNop])))
        dkm = artoa.data.calculateGeodist([pLatitude(ix-pNop) pLongitude(ix-pNop)] , [pLatitude(ix+pNop) pLongitude(ix+pNop)]);   %[m/s]
        velocityTotal(ix)=(dkm*1000)/(pInterval*2*pNop);
        velocityLatitude(ix)=((pLatitude(ix+pNop)-pLatitude(ix-pNop))*nm_in_km*1000)/(pInterval*2*pNop);
        velocityLongitude(ix)=((pLongitude(ix+pNop)-pLongitude(ix-pNop))*nm_in_km*1000*cos(pLatitude(ix)/180*pi))/(pInterval*2*pNop);
      end
    end
  end
elseif strcmp(pMethod,'backward');  % shifted means between points ix and ix-nop
  for ix=1:length(pLatitude)
    if ~(ix-pNop < 1)
      if ~any(isnan(pLatitude([ix-pNop,ix])))
        dkm=artoa.data.calculateGeodist([pLatitude(ix-pNop) pLongitude(ix-pNop)], [pLatitude(ix) pLongitude(ix)]);
        velocityTotal(ix)=(dkm*1000)/(pInterval*pNop);
        velocityLatitude(ix)=((pLatitude(ix)-pLatitude(ix-pNop))*nm_in_km*1000)/(pInterval*pNop);
        velocityLongitude(ix)=((pLongitude(ix)-pLongitude(ix-pNop))*nm_in_km*1000*cos(pLatitude(ix)/180*pi))/(pInterval*pNop);
      end
    end
  end
elseif strcmp(pMethod,'forward');   % shifted means between points ix and ix+nop
   for ix=1:length(pLatitude)
    if ~(ix+pNop > length(pLatitude))
      if ~any(isnan(pLatitude([ix,ix+pNop])))
        dkm=artoa.data.calculateGeodist([pLatitude(ix+pNop) pLongitude(ix+pNop)], [pLatitude(ix) pLongitude(ix)]);
        velocityTotal(ix)=(dkm*1000)/(pInterval*pNop);
        velocityLatitude(ix)=((pLatitude(ix+pNop)-pLatitude(ix))*nm_in_km*1000)/(pInterval*pNop);
        velocityLongitude(ix)=((pLongitude(ix+pNop)-pLongitude(ix))*nm_in_km*1000*cos(pLatitude(ix)/180*pi))/(pInterval*pNop);
      end
    end
 end
 elseif strcmp(pMethod,'spline');  % spline at 2hour intervals
	%  spline latitude and longitudes and calculate velocities
   %  dummies must be excluded for the spline
   resolution = 2;                   % this is the resolution at which spline will be performed
   step = pInterval/3600/24;          % interval lenght between successive data points [days]
   time = 0:step:length(pLatitude)*step;   % creates virtural time basis for raw data
   time = time(:);
   index = find(pLatitude<999);            % find dummies, might be different value within artoa
	pLatitude   = pLatitude(index); pLongitude=pLongitude(index); time = time(index);  % filter out dummies

	% new timebase: every 2 hours including first and last time
    if isempty(time)
        dummy = 3;
    end
	time_min = time(1);
   time_max = time(size(time,1)); % save for later
   %time_spl  = linspace(time_min, time_max,(time_max-time_min)*24/resolution+1 );  %  time basis for spline [days]
   %Corrected by T. Reynaud: 22/06/2005
   time_spl = time_min:resolution/24:time_max;
   time_spl  = time_spl(:);
   
	lat_spl_f = csape(time,pLatitude,[2 1]); 
	lat_spl   = fnval(lat_spl_f,time_spl);
	v_spl_f   = fnder(lat_spl_f);
	v_spl     = fnval(v_spl_f,time_spl) *60*1.852*1000/(3600*24) ; % [m/s]  
   
	lon_spl_f = csape(time,pLongitude,[2 1]); 
	lon_spl   = fnval(lon_spl_f,time_spl);
	u_spl_f   = fnder(lon_spl_f);
	u_spl     = fnval(u_spl_f,time_spl) .*cos(lat_spl/180*pi)*60*1.852*1000/(3600*24) ; % [m/s]  
   
   % subsample to original rate:
   %save debug_tr
   for i = 1:length(time)
%      indi(i) = find(time_spl == time(i));
%Modified by T.Reynaud: 22/03/2005
      indi(i) = find(abs(time_spl-time(i)) <= 0.000000000001);
   end
   
   %figure
   %title('control plot for spline function')
   %plot(lon_spl,lat_spl); hold on
   %plot(lon,lat,'rx');
   %zoom on;
   
   velocityLongitude(index) = u_spl(indi);
   velocityLatitude(index) = v_spl(indi);
   velocityTotal(index) = sqrt(u_spl(indi).^2 + v_spl(indi).^2);
   
end


%%%%%%%%%%%%% idea for faster calculation of 'cetered mean'

%v = NaN*ones(size(data(:,7)))
%v(2:length(data)-1,1) = data(1:length(data)-2,6)
%v(2:length(data)-1,2) = data(3:length(data),6)
%v = diff(v')'
%v = v*60*1.852*1000*100/3600/24