From fe96fb1404f4e87f500ccb27871ec0398e3f425a Mon Sep 17 00:00:00 2001
From: Lewin Probst <info@emirror.de>
Date: Mon, 18 Nov 2019 17:12:15 +0100
Subject: [PATCH] The residuals plot has been replaced by divergence of gps to
 calculated distance in seconds.

---
 .../+trajectoryOutput/hideLeftSidebarPlots.m  | 10 ++--
 .../+trajectoryOutput/showLeftSidebarPlots.m  |  6 +--
 .../tableGeneratedTracksSelect.m              | 17 ++-----
 lib/+artoa/+controller/+track/run.m           |  5 +-
 lib/+artoa/+data/calculateTimeDivergence.m    | 31 +++++++++++
 lib/+artoa/+float/calculateTrajectory.m       | 51 +++++++++++++++++--
 lib/+artoa/+gui/+track/trajectoryOutput.m     | 20 ++++----
 .../+trajectory/plotTimeDivergenceToGps.m     | 30 +++++++++++
 8 files changed, 136 insertions(+), 34 deletions(-)
 create mode 100644 lib/+artoa/+data/calculateTimeDivergence.m
 create mode 100644 lib/+artoa/+trajectory/plotTimeDivergenceToGps.m

diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/hideLeftSidebarPlots.m b/lib/+artoa/+controller/+track/+trajectoryOutput/hideLeftSidebarPlots.m
index 09d65df..fba43fc 100644
--- a/lib/+artoa/+controller/+track/+trajectoryOutput/hideLeftSidebarPlots.m
+++ b/lib/+artoa/+controller/+track/+trajectoryOutput/hideLeftSidebarPlots.m
@@ -4,10 +4,10 @@ function [] = hideLeftSidebarPlots()
 
 global artoaGui;
 
-%% Hide residuals plot
-structfun(@delete, artoaGui.trajectoryOutput.residualsHandles);
-artoaGui.trajectoryOutput.legendResiduals.Visible = 'off';
-artoaGui.trajectoryOutput.axesTrajectoryResiduals.Visible = 'off';
+%% Hide time divergence plot
+structfun(@delete, artoaGui.trajectoryOutput.timeDivergenceHandles);
+artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence.Visible = 'off';
+artoaGui.trajectoryOutput.legendTrajectoryTimeDivergence.Visible = 'off';
 artoaGui.trajectoryOutput.selectTrajectoryHint.Visible = 'on';
 %% Hide velocities plot
 structfun(@delete, artoaGui.trajectoryOutput.horizontalVelocitiesHandles);
@@ -15,7 +15,7 @@ artoaGui.trajectoryOutput.legendHorizontalVelocities.Visible = 'off';
 artoaGui.trajectoryOutput.axesHorizontalVelocities.Visible = 'off';
 artoaGui.trajectoryOutput.selectTrajectoryHintHorizontalVelocities.Visible = 'on';
 %% Hide vertical velocities plot
-structfun(@delete, artoaGui.trajectoryOutput.verticalVelocitiesHandles);
+%structfun(@delete, artoaGui.trajectoryOutput.verticalVelocitiesHandles);
 artoaGui.trajectoryOutput.legendVerticalVelocities.Visible = 'off';
 artoaGui.trajectoryOutput.axesVerticalVelocities.Visible = 'off';
 artoaGui.trajectoryOutput.selectTrajectoryHintVerticalVelocities.Visible = 'on';
diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/showLeftSidebarPlots.m b/lib/+artoa/+controller/+track/+trajectoryOutput/showLeftSidebarPlots.m
index 146b217..0e4e587 100644
--- a/lib/+artoa/+controller/+track/+trajectoryOutput/showLeftSidebarPlots.m
+++ b/lib/+artoa/+controller/+track/+trajectoryOutput/showLeftSidebarPlots.m
@@ -4,9 +4,9 @@ function [] = showLeftSidebarPlots()
 
 global artoaGui;
 
-%% Show residuals plot
-artoaGui.trajectoryOutput.axesTrajectoryResiduals.Visible = 'on';
-artoaGui.trajectoryOutput.legendResiduals.Visible = 'on';
+%% Show time divergence plot
+artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence.Visible = 'on';
+artoaGui.trajectoryOutput.legendTrajectoryTimeDivergence.Visible = 'on';
 artoaGui.trajectoryOutput.selectTrajectoryHint.Visible = 'off';
 %% Show velocities plot
 artoaGui.trajectoryOutput.axesHorizontalVelocities.Visible = 'on';
diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/tableGeneratedTracksSelect.m b/lib/+artoa/+controller/+track/+trajectoryOutput/tableGeneratedTracksSelect.m
index 00ffa06..f6fe69d 100644
--- a/lib/+artoa/+controller/+track/+trajectoryOutput/tableGeneratedTracksSelect.m
+++ b/lib/+artoa/+controller/+track/+trajectoryOutput/tableGeneratedTracksSelect.m
@@ -52,12 +52,12 @@ artoa.controller.track.trajectoryOutput.emphasizeSelectedTrajectory();
 %% Show plots
 artoa.controller.track.trajectoryOutput.showLeftSidebarPlots();
 
-%% Plot residuals
+%% Plot time divergence
 [ ...
-    artoaGui.trajectoryOutput.residualsHandles, ...
-    artoaGui.trajectoryOutput.legendResiduals ...
-] = artoa.trajectory.plotResiduals( ...
-    artoaGui.trajectoryOutput.axesTrajectoryResiduals, ...
+    artoaGui.trajectoryOutput.timeDivergenceHandles, ...
+    artoaGui.trajectoryOutput.legendTrajectoryTimeDivergence ...
+] = artoa.trajectory.plotTimeDivergenceToGps( ...
+    artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence, ...
     artoaWorkspace.trajectoryOutput.trajectories{selectedRow(1)} ...
 );
 
@@ -71,13 +71,6 @@ artoa.controller.track.trajectoryOutput.showLeftSidebarPlots();
 );
 
 %% Plot vertical velocities
-[ ...
-    artoaGui.trajectoryOutput.verticalVelocitiesHandles, ...
-    artoaGui.trajectoryOutput.legendVerticalVelocities ...
-] = artoa.trajectory.plotVerticalVelocities( ...
-    artoaGui.trajectoryOutput.axesVerticalVelocities, ...
-    artoaWorkspace.trajectoryOutput.trajectories{selectedRow} ...
-);
 
 %% Replace track parameter
 if artoaWorkspace.trajectoryOutput.updateTrackParameterWindow
diff --git a/lib/+artoa/+controller/+track/run.m b/lib/+artoa/+controller/+track/run.m
index 247ae5a..04a2e01 100644
--- a/lib/+artoa/+controller/+track/run.m
+++ b/lib/+artoa/+controller/+track/run.m
@@ -68,10 +68,12 @@ pressureAndDate = { ...
     trajectoryDates, ...
     trajectoryClockError, ...
     trajectoryResiduals, ...
-    trajectoryVelocities ...
+    trajectoryVelocities, ...
+    trajectoryTimeDivergenceToGps ...
 ] = artoa.float.calculateTrajectory( ...
     artoaWorkspace.float, ...
     pressureAndDate, ...
+    artoaWorkspace.satData, ...
     artoaWorkspace.toaData, ...
     artoaWorkspace.filteredSoundsources, ...
     artoaWorkspace.trackParameter, ...
@@ -100,6 +102,7 @@ trajectoryObject.date = trajectoryDates;
 trajectoryObject.clockError = trajectoryClockError;
 trajectoryObject.residuals = trajectoryResiduals;
 trajectoryObject.velocities = trajectoryVelocities;
+trajectoryObject.timeDivergenceToGps = trajectoryTimeDivergenceToGps;
 
 %% Generate trajectory id
 if isempty(artoaWorkspace.trajectoryOutput.trajectories)
diff --git a/lib/+artoa/+data/calculateTimeDivergence.m b/lib/+artoa/+data/calculateTimeDivergence.m
new file mode 100644
index 0000000..77c8026
--- /dev/null
+++ b/lib/+artoa/+data/calculateTimeDivergence.m
@@ -0,0 +1,31 @@
+function [timeDivergence, usedIndices] = calculateTimeDivergence(pPositionSet1, pPositionSet2, pSoundVelocity)
+%CALCULATETIMEDIVERGENCE Summary of this function goes here
+%   Detailed explanation goes here
+
+%% Setup variables
+timeDivergence = [];
+usedIndices = [];
+
+%% Parameter check
+if isempty(pPositionSet1) || isempty(pPositionSet2)
+    return;
+end
+%% Calculate distance between sets
+for i = 1:size(pPositionSet1, 1)
+    if any(isnan(pPositionSet1(i, :))) || any(isnan(pPositionSet2(i, :)))
+        usedIndices = [usedIndices; false];
+        continue;
+    end
+    timeDivergence = [
+        timeDivergence; ...
+        artoa.data.calculateGeodist(pPositionSet1(i, :), pPositionSet2(i, :)) ...
+    ];
+    usedIndices = [usedIndices; true];
+end
+
+%% Divide by sound velocity
+timeDivergence = timeDivergence / (pSoundVelocity/1000);
+usedIndices = logical(usedIndices);
+
+end
+
diff --git a/lib/+artoa/+float/calculateTrajectory.m b/lib/+artoa/+float/calculateTrajectory.m
index c4971c1..e837eec 100644
--- a/lib/+artoa/+float/calculateTrajectory.m
+++ b/lib/+artoa/+float/calculateTrajectory.m
@@ -1,4 +1,4 @@
-function [trajectory, trajectoryDates, trajectoryClockError, trajectoryResiduals, trajectoryVelocities] = calculateTrajectory(pFloatDetails, pPressureAndDate, pToaData, pSoundsources, pTrackingParameter, pSoundVelocity, pLeapsecondsMatrix)
+function [trajectory, trajectoryDates, trajectoryClockError, trajectoryResiduals, trajectoryVelocities, trajectoryTimeDivergenceToGps] = calculateTrajectory(pFloatDetails, pPressureAndDate, pSatData, pToaData, pSoundsources, pTrackingParameter, pSoundVelocity, pLeapsecondsMatrix)
 %CALCULATETRAJECTORY Calculates the trajectory using the given details.
 %   Applies all required corrections to the data and calculates the trajectory
 %   segment by segment afterwards.
@@ -204,14 +204,19 @@ trajectory = [];
 trajectoryDates = [];
 trajectoryClockError = [];
 trajectoryResiduals = struct();
+trajectoryTimeDivergenceToGps = struct();
 for i = 1:length(involvedSoundsourceNames)
     trajectoryResiduals.(involvedSoundsourceNames{i}) = [];
+    trajectoryTimeDivergenceToGps.(involvedSoundsourceNames{i}) = [];
 end
 trajectoryVelocities = struct();
 trajectoryVelocities.horizontalTotal = [];
 trajectoryVelocities.horizontalLongitude = [];
 trajectoryVelocities.horizontalLatitude = [];
 trajectoryVelocities.vertical = [];
+% trajectoryTimeDivergenceToGps = struct();
+% trajectoryTimeDivergenceToGps.duration = [];
+% trajectoryTimeDivergenceToGps.date = [];
 
 %% Calculate for every combination
 for oCombination = 1:size(soundsourceCombinations, 1)
@@ -255,7 +260,11 @@ for oCombination = 1:size(soundsourceCombinations, 1)
     end
     
     % calculate horizontal velocities
-    [segmentHorizontalVelocityTotal, segmentHorizontalVelocityLatitude, segmentHorizontalVelocityLongitude] = artoa.data.horvelo( ...
+    [ ...
+        segmentHorizontalVelocityTotal, ...
+        segmentHorizontalVelocityLatitude, ...
+        segmentHorizontalVelocityLongitude ...
+    ] = artoa.data.horvelo( ...
         segmentPositions(:, 1), ...
         segmentPositions(:, 2), ...
         pTrackingParameter.interpolationInterval/24*86400 ...
@@ -272,6 +281,42 @@ for oCombination = 1:size(soundsourceCombinations, 1)
         'average' ...
     );
     trajectoryVelocities.vertical = [trajectoryVelocities.vertical; segmentVerticalVelocity];
+    
+    % calculate time divergence to gps
+    % get all sat dates
+    satDates = artoa.convert.dmy2rd(pSatData.day_sat, pSatData.month_sat, pSatData.year_sat);
+    % get all dates that intersect with segment
+    [~, index, ~] = intersect(round(segmentDates), round(satDates));
+    intersectedSegmentPositions = segmentPositions(index, :);
+    intersectedSegmentDates = segmentDates(index, :);
+    satPositions = [pSatData.lat_sat(index), pSatData.lon_sat(index)];
+    % get all soundsources of segment
+    segmentSoundsources = artoa.data.extractSoundsourcesFromStruct( ...
+        strsplit(soundsourceCombinations.soundsources{oCombination}), ...
+        pSoundsources ...
+    );
+    for oSoundsource = 1:length(segmentSoundsources)
+        currentSoundsource = segmentSoundsources{oSoundsource};
+        % calculate divergence for soundsource position
+        [soundsourceDivergence, ~] = artoa.data.calculateTimeDivergence( ...
+            repmat(currentSoundsource.position, size(intersectedSegmentPositions, 1), 1), ...
+            intersectedSegmentPositions, ...
+            pSoundVelocity(oCombination, oSoundsource) ...
+        );
+        [gpsDivergence, usedIndices] = artoa.data.calculateTimeDivergence( ...
+            repmat(currentSoundsource.position, size(satPositions, 1), 1), ...
+            satPositions, ...
+            pSoundVelocity(oCombination, oSoundsource) ...
+        );
+        if isempty(usedIndices) || isempty(soundsourceDivergence) || isempty(gpsDivergence)
+            continue;
+        end
+        difference = (soundsourceDivergence(usedIndices) - gpsDivergence);
+        trajectoryTimeDivergenceToGps.(currentSoundsource.sourcename) = [ ...
+            trajectoryTimeDivergenceToGps.(currentSoundsource.sourcename);
+            segmentDates(usedIndices), difference
+        ];
+    end
 end
 
-return
\ No newline at end of file
+end
\ No newline at end of file
diff --git a/lib/+artoa/+gui/+track/trajectoryOutput.m b/lib/+artoa/+gui/+track/trajectoryOutput.m
index b8ce341..b24bff4 100644
--- a/lib/+artoa/+gui/+track/trajectoryOutput.m
+++ b/lib/+artoa/+gui/+track/trajectoryOutput.m
@@ -77,25 +77,25 @@ artoaGui.trajectoryOutput.axesTrajectoryOutput = artoaGui.figures.trajectoryOutp
 
 %% Left sidebar
 
-%% Residuals
+%% Time divergence to GPS
 
-artoaGui.trajectoryOutput.frameAxesResiduals = uipanel( ...
-    'Title', 'Residuals', ...
+artoaGui.trajectoryOutput.frameAxesTimeDivergence = uipanel( ...
+    'Title', 'Time divergence to GPS', ...
     'Units', 'normalized', ...
     'BackgroundColor', 'white', ...
     'Position', [leftSidebarLeft, .675, leftSidebarWidth, .3] ...
 );
 
-artoaGui.trajectoryOutput.axesTrajectoryResiduals = axes(artoaGui.trajectoryOutput.frameAxesResiduals);
-artoaGui.trajectoryOutput.axesTrajectoryResiduals.Position = [.15 .15 .8 .8];
-xlabel(artoaGui.trajectoryOutput.axesTrajectoryResiduals, 'Message Date');
-ylabel(artoaGui.trajectoryOutput.axesTrajectoryResiduals, 'TOA residuals [s]');
-grid(artoaGui.trajectoryOutput.axesTrajectoryResiduals, 'on');
-artoaGui.trajectoryOutput.axesTrajectoryResiduals.Visible = 'off';
+artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence = axes(artoaGui.trajectoryOutput.frameAxesTimeDivergence);
+artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence.Position = [.15 .15 .8 .8];
+xlabel(artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence, 'Message Date');
+ylabel(artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence, 'Time divergence [s]');
+grid(artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence, 'on');
+artoaGui.trajectoryOutput.axesTrajectoryTimeDivergence.Visible = 'off';
 
 % Setup hint to select trajectory
 artoaGui.trajectoryOutput.selectTrajectoryHint = uicontrol( ...
-    'Parent', artoaGui.trajectoryOutput.frameAxesResiduals, ...
+    'Parent', artoaGui.trajectoryOutput.frameAxesTimeDivergence, ...
     'Style', 'text', ...
     'String', 'No trajectory selected', ...
     'FontSize', 8, ...
diff --git a/lib/+artoa/+trajectory/plotTimeDivergenceToGps.m b/lib/+artoa/+trajectory/plotTimeDivergenceToGps.m
new file mode 100644
index 0000000..9813f6c
--- /dev/null
+++ b/lib/+artoa/+trajectory/plotTimeDivergenceToGps.m
@@ -0,0 +1,30 @@
+function [handleTimeDivergenceToGps, handleLegend] = plotTimeDivergenceToGps(pAxesHandle, pTrajectory)
+%PLOTTIMEDIVERGENCETOGPS Summary of this function goes here
+%   Detailed explanation goes here
+
+%% Setup return variables
+handleTimeDivergenceToGps = struct();
+
+%% Get required data
+fnames = fieldnames(pTrajectory.timeDivergenceToGps);
+legendText = {};
+
+%% Clear axes
+cla(pAxesHandle);
+
+%% Plot data
+hold(pAxesHandle, 'on');
+for i = 1:length(fnames)
+    current =  pTrajectory.timeDivergenceToGps.(fnames{i});
+    x = current(:, 1);
+    y = current(:, 2);
+    handleTimeDivergenceToGps.(fnames{i}) = plot(pAxesHandle, x, y, '.-');
+    legendText{i} = fnames{i};
+end
+hold(pAxesHandle, 'off');
+
+%% Setup legend
+handleLegend = legend(pAxesHandle, legendText);
+
+end
+
-- 
GitLab