function [results, initialResults, variationResults] = calculateByOffsetVariations(pPreparedData, pCurrentCombination, pFloatReferenceTime, pSoundVelocity, pTrackingParameter, pOffsetVariations) %CALCULATEERRORELLIPSES Summary of this function goes here % Detailed explanation goes here %% Create all combinations of offsets that should be calculated offsetVariations = [ ... pOffsetVariations; ... 0, 0 ... ]; variations = cell(4, 1); variationResults = cell(4, 1); soundsources = strsplit(pCurrentCombination.soundsources{1}, ' '); for i = 1:length(offsetVariations) variations{i} = pPreparedData; % apply variations to the data for k = 1:length(soundsources) variations{i}.(soundsources{k}).toa = variations{i}.(soundsources{k}).toa + offsetVariations(i, k); end variationResults{i} = struct(); [variationResults{i}.positions, variationResults{i}.dates] = helperCalculateCombinationSegment(variations{i}); % create date vector that contains all common dates if (i == 1) intersectedDates = variationResults{i}.dates; else intersectedDates = intersect(intersectedDates, variationResults{i}.dates); end end %% Prepare return variables results = cell(1, length(intersectedDates)); initialResults = variationResults(end); %% Calculate covariance for every date of the initial results for i = 1:length(variationResults{end}.dates) results{i} = struct(); observations = NaN(length(variationResults), 2); for k = 1:length(variationResults) selection = variationResults{k}.dates == variationResults{end}.dates(i); if sum(selection) ~= 1 continue; end observations(k, :) = variationResults{k}.positions(selection, :); end results{i}.date = variationResults{end}.dates(i); results{i}.observations = observations; % get covariance matrix results{i}.covarianceMatrix = cov(observations); % eigendecomposition [results{i}.V, results{i}.D] = eig(results{i}.covarianceMatrix); end variationResults = variationResults(1:end - 1); %% Helper functions function [segmentPositions, segmentDates] = helperCalculateCombinationSegment(pCustomizedToaData) [ ... segmentPositions, ... segmentDates, ... ~, ... ~ ... ] = artoa.trajectory.calculateCombinationSegment( ... pCustomizedToaData, ... pCurrentCombination, ... pFloatReferenceTime, ... pSoundVelocity, ... pCurrentCombination.backwardTracking, ... false ... ); % remove NaNs from segment validPositions = all(~isnan(segmentPositions), 2); segmentPositions = segmentPositions(validPositions, :); segmentDates = segmentDates(validPositions); end end