function [ret] = AlignTestData(TargetPositionFileName,DataqFileName,LogFileName,OutputFileName)

if(~exist(DataqFileName,'file'))
   error([DataqFileName ' does not exist']); 
end

if(~exist(LogFileName,'file'))
   error([LogFileName ' does not exist']); 
end



load(LogFileName);
[info data] = nReadDataq(DataqFileName);

DataqSampleRate = cast(info.sampleRatePerChannel,'double');
DataqNumDataPts = cast(info.numberOfSamplesWritten,'double');
DataqFileApproxLastSampleTime = cast(info.timeFileTrailerWritten,'double');
DataqFileOpenTime = cast(info.timeFileOpened,'double');
DataqTime_UnixEpochSeconds = DataqFileOpenTime + 1/DataqSampleRate*(0:DataqNumDataPts-1);
%DataqTime_UnixEpochSeconds =  (DataqFileApproxLastSampleTime-(DataqNumDataPts-1)/DataqSampleRate):1/DataqSampleRate:DataqFileApproxLastSampleTime;
DataqTime_DateNum = datenum(datetime(DataqTime_UnixEpochSeconds, 'convertfrom','posixtime'));
DataqRange = data{1}';
DataqForce = data{2}';
DataqLowerHydPressure = data{3}';
DataqUpperHydPressure = data{4}';
clear data info;


if(~exist(TargetPositionFileName,'file'))
   disp([TargetPositionFileName ' does not exist']); 
   TargetProfileData.t = (DataqTime_DateNum(2:end)-DataqTime_DateNum(2))*24*3600;
   TargetProfileData.pos = DataqRange(2:end);
else
    TargetProfileData = load(TargetPositionFileName);
end

t = TargetProfileData.t(1):1/DataqSampleRate:TargetProfileData.t(end);
TargetProfileRange = interp1(TargetProfileData.t,TargetProfileData.pos,t);
TargetProfileTime_DateNum = datenum(datetime(t+DataqTime_UnixEpochSeconds(1), 'convertfrom','posixtime'));


%Remove NaNs
idx = find(~isnan(SC_Range));
%idx = idx(18650:end);
Time_DateNum = [Time_DateNum(idx) Time_DateNum(idx(end))+(Time_DateNum(idx(1:2000))-Time_DateNum(idx(1)))];
%SC_Range = [SC_Range(idx) SC_Range(idx(end))*ones(1,2500)];
%SC_UpperPressure = [SC_UpperPressure(idx) zeros(1,2500)];
%SC_LowerPressure = [SC_LowerPressure(idx) zeros(1,2500)];

SC_Range(1) =  SC_Range(2);


figure
plot(DataqRange)
hold all
plot(SC_Range)


%First, adjust the vertical position approximately.
delta_range_max = max(SC_Range)-max(DataqRange);
delta_range_min = min(SC_Range)-min(DataqRange);
delta_range = (delta_range_max+delta_range_min)/2;
DataqRange = DataqRange+delta_range;
TargetProfileRange = TargetProfileRange+delta_range;


%%%
% At this point, if all logging was started before the motion profile was
% started, the target profile will be earliest in the time record, the
% Dataq data will be next, and the PTO measured data will be next.  So to
% correlate everything in time, first the target curve is advanced to find
% the maximum coorelation with the Dataq Data and adjusted to match.
% Subsequently, the Dataq Data is compared with the SC_Range data to
% determine the needed offset.  After this procedure, everything should be
% lined up and reported in the timeframe measured by pblog on the buoy.
%%%

%%% First, find out how much to advance the Dataq profile to match the
%%% SC_Range profile.
NumOfCorrelationsToCheck = length(SC_Range)-length(DataqRange);
RMSE = zeros(1,NumOfCorrelationsToCheck);
min_RMSE = realmax;  %Maximum real number in Matlab
timestep_delta = 0;
NumOfCorrelationsToCheck
for lag = 0:NumOfCorrelationsToCheck-1
    if(rem(lag,10) == 0)
      disp(['lag = ' num2str(lag)]);
    end  
    RMSE(lag+1) = sqrt(mean((DataqRange-SC_Range(lag+1:lag+length(DataqRange))).^2));
    if(RMSE(lag+1) < min_RMSE)
        min_RMSE = RMSE(lag+1);
        timestep_delta = lag+1;
    end
end

length(DataqRange)
DataqTime_DateNum = Time_DateNum(timestep_delta:timestep_delta+length(DataqRange)-1);


%%% Next, find out how much to advance the TargetProfile position profile to match the
%%% DataqRange  profile.
%

NumOfCorrelationsToCheck = length(DataqRange)-length(TargetProfileRange);
RMSE = zeros(1,NumOfCorrelationsToCheck);
min_RMSE = realmax;  %Maximum real number in Matlab
timestep_delta = 0;
for lag = 0:NumOfCorrelationsToCheck-1
    if(rem(lag,10) == 0)
      disp(['lag = ' num2str(lag)]);
    end  
    RMSE(lag+1) = sqrt(mean((TargetProfileRange-DataqRange(lag+1:lag+length(TargetProfileRange))).^2));
    if(RMSE(lag+1) < min_RMSE)
        min_RMSE = RMSE(lag+1);
        timestep_delta = lag+1;
    end
end
TargetProfileTime_DateNum = DataqTime_DateNum(timestep_delta:timestep_delta+length(TargetProfileRange)-1);


%Make Accurate least squares vertical adjustement over range of target
%profile


%Locate indices of DataqRange cooresponding to TargetProfileRange
DataqTime_idx = find(DataqTime_DateNum >= TargetProfileTime_DateNum(1));
DataqTime_idx = DataqTime_idx(1):DataqTime_idx(1)+length(TargetProfileTime_DateNum)-1;
%Search vertically (+/- 1") for best least squares fit
dRange = .01;
RangeAdjustementsToCheck = -1:dRange:1;  %Inches
RMSE = zeros(1,length(RangeAdjustementsToCheck));
min_RMSE = realmax;  %Maximum real number in Matlab
Range_delta = 0;
for lag = 1:length(RangeAdjustementsToCheck)
    if(rem(lag,10) == 0)
      disp(['lag = ' num2str(lag)  '  RangeDelta = ' num2str(RangeAdjustementsToCheck(lag))]);
    end
    RMSE(lag) = sqrt(mean((TargetProfileRange-(DataqRange(DataqTime_idx)+RangeAdjustementsToCheck(lag))).^2));
    if(RMSE(lag) < min_RMSE)
        min_RMSE = RMSE(lag);
        range_delta = RangeAdjustementsToCheck(lag);
    end
end
DataqRange = DataqRange + range_delta;


%Locate indices of SC_Range cooresponding to TargetProfileRange
SC_Range_idx = find(Time_DateNum >= TargetProfileTime_DateNum(1));
SC_Range_idx = SC_Range_idx(1):SC_Range_idx(1)+length(TargetProfileTime_DateNum)-1;
%Search vertically (+/- 1") for best least squares fit
dRange = .01;
RangeAdjustementsToCheck = -1:dRange:1;  %Inches
RMSE = zeros(1,length(RangeAdjustementsToCheck));
min_RMSE = realmax;  %Maximum real number in Matlab
range_delta = 0;
for lag = 1:length(RangeAdjustementsToCheck)
    if(rem(lag,10) == 0)
      disp(['lag = ' num2str(lag)  '  RangeDelta = ' num2str(RangeAdjustementsToCheck(lag))]);
    end
    RMSE(lag) = sqrt(mean((TargetProfileRange-(SC_Range(SC_Range_idx)+RangeAdjustementsToCheck(lag))).^2));
    if(RMSE(lag) < min_RMSE)
        min_RMSE = RMSE(lag);
        range_delta = RangeAdjustementsToCheck(lag);
    end
end
DataqRange = DataqRange - range_delta;
TargetProfileRange = TargetProfileRange - range_delta;


DataqTime_DateNum = DataqTime_DateNum(DataqTime_idx);
TM_Range = DataqRange(DataqTime_idx);
TM_Force = DataqForce(DataqTime_idx);
TM_LowerHydPressure = DataqLowerHydPressure(DataqTime_idx);
TM_UpperHydPressure = DataqUpperHydPressure(DataqTime_idx);
TM_TargetProfile = TargetProfileRange;

Time_DateNum = Time_DateNum(SC_Range_idx);

SC_Range = SC_Range(SC_Range_idx);
SC_LowerPressure = SC_LowerPressure(SC_Range_idx);
SC_UpperPressure = SC_UpperPressure(SC_Range_idx);

save(OutputFileName,'Time_DateNum','SC_Range','SC_LowerPressure','SC_UpperPressure','TM_TargetProfile','TM_Range','TM_Force','TM_LowerHydPressure','TM_UpperHydPressure');

ret = OutputFileName;

end


