Skip to content
Snippets Groups Projects
Commit e0b32856 authored by leprob001's avatar leprob001
Browse files

Time of arrival window update.

+ Added soundsources/colorregister package that is used to assign a color
  to a specific sound source.
+ Added an edit field to the upper and lower boundary adjustment section
+ Added a histogram plot of the TOAs
/ The soundsource color legend shows only the color of an applied sound
  source, white otherwise.
parent 4b4440e3
No related branches found
No related tags found
No related merge requests found
Showing
with 288 additions and 30 deletions
......@@ -12,11 +12,12 @@ artoaGui.editTimeOfArrival.frameControlsSoundSourceColors = uipanel( ...
'Title', 'Soundsource colors', ...
'Units', 'normalized', ...
'BackgroundColor', 'white', ...
'Position', [.01 .4 width .5] ...
'Position', [.01 .65 width .25] ...
);
% add label and color for every sound source that is available
spaceTopAndBottom = .05;
spaceTopAndBottom = .1;
height = .08;
leftItemOffset = 0;
rightItemOffset = 0;
......@@ -27,15 +28,21 @@ fnames = fieldnames(soundsources);
isLeftItem = true;
for i = 1:length(fnames)
colorIndex = artoa.soundsources.colorregister.getColorIndex(fnames{i}, artoaWorkspace.soundsourceColorRegister);
if colorIndex == 0
color = [1 1 1];
else
color = artoaWorkspace.soundsourceColors(colorIndex, :);
end
if isLeftItem
offset = leftItemOffset;
marginLeft = 0;
leftItemOffset = leftItemOffset + 0.04;
leftItemOffset = leftItemOffset + height;
isLeftItem = false;
else
offset = rightItemOffset;
marginLeft = .5;
rightItemOffset = rightItemOffset + 0.04;
rightItemOffset = rightItemOffset + height;
isLeftItem = true;
end
artoaGui.editTimeOfArrival.labelSoundsourcesColors.(fnames{i}) = uicontrol( ...
......@@ -44,8 +51,8 @@ for i = 1:length(fnames)
'Style', 'text', ...
'FontSize', 8, ...
'Units', 'normalized', ...
'Position', [(marginLeft + .1) (1 - spaceTopAndBottom - offset) .1 .03], ...
'Background', artoaWorkspace.soundsourceColors(i, :) ...
'Position', [(marginLeft + .1) (1 - spaceTopAndBottom - offset) .1 height], ...
'Background', color ...
);
artoaGui.editTimeOfArrival.labelSoundsourcesColors.([fnames{i} 'c']) = uicontrol( ...
'Parent', artoaGui.editTimeOfArrival.frameControlsSoundSourceColors, ...
......@@ -53,7 +60,7 @@ for i = 1:length(fnames)
'Style', 'text', ...
'FontSize', 8, ...
'Units', 'normalized', ...
'Position', [(marginLeft + .25) (1 - spaceTopAndBottom - offset) .3 .03], ...
'Position', [(marginLeft + .25) (1 - spaceTopAndBottom - offset) .3 height], ...
'Background', [1 1 1], ...
'HorizontalAlignment', 'left' ...
);
......
......@@ -34,6 +34,7 @@ if isfield(artoaGui.editTimeOfArrival, 'scatterTimeOfArrival') ...
artoaGui.editTimeOfArrival.scatterTimeOfArrival.CData = c;
% update applied sound sources
artoa.controller.edit.timeOfArrival.plotAppliedSoundsources();
artoa.controller.edit.timeOfArrival.plotSoundsourceToaFromGps(artoaWorkspace.filteredSoundsources);
artoa.controller.edit.timeOfArrival.applyToaAxesToGpsAndSoundsources();
artoa.controller.edit.timeOfArrival.createSoundsourceColorsPanel();
linkaxes([ ...
......@@ -43,6 +44,7 @@ if isfield(artoaGui.editTimeOfArrival, 'scatterTimeOfArrival') ...
]);
% force toa scatter to be current axes of figure
artoaGui.figures.editTimeOfArrival.CurrentAxes = artoaGui.editTimeOfArrival.axesScatterTimeOfArrival;
zoom(artoaGui.figures.editTimeOfArrival, 'reset');
return
end
......@@ -56,14 +58,14 @@ artoaGui.editTimeOfArrival.scatterTimeOfArrival = scatter( ...
artoaGui.editTimeOfArrival.axesScatterTimeOfArrival, ...
x, ...
y, ...
[], ...
c, ... %'.', 'MarkerSize', 10 ...
artoa.data.getMember(artoaDataInput, {'ini', 'view', 'toapointsize'}, 36), ...
c, ...
'filled' ...
);
%% Set colormap
artoaGui.editTimeOfArrival.axesScatterTimeOfArrival.CLim = [0, 255];
colormap(artoaGui.editTimeOfArrival.axesScatterTimeOfArrival, flipud(colormap));
colormap(artoaGui.editTimeOfArrival.axesScatterTimeOfArrival, colormap);
%% Setup gui
......@@ -104,5 +106,6 @@ linkaxes([ ...
hold(artoaGui.editTimeOfArrival.axesScatterTimeOfArrival, 'off');
end
......@@ -2,7 +2,7 @@ function [] = plotAppliedSoundsources()
%PLOTAPPLIEDSOUNDSOURCES Summary of this function goes here
% Detailed explanation goes here
global artoaWorkspace artoaGui;
global artoaWorkspace artoaGui artoaDataInput;
%% Initialize required variables
x = [];
......@@ -14,11 +14,19 @@ c = [];
fnames = fieldnames(artoaWorkspace.filteredSoundsources);
for i = 1:length(fnames)
% estimate the color to be used
if artoa.soundsources.hasAppliedToa(fnames{i}, artoaWorkspace.toaData.soundSource)
[colorIndex, artoaWorkspace.soundsourceColorRegister] = ...
artoa.soundsources.colorregister.add(fnames{i}, artoaWorkspace.soundsourceColorRegister);
soundsourceColor = artoaWorkspace.soundsourceColors(colorIndex, :);
else
soundsourceColor = [1 1 1];
end
selection = logical(artoaWorkspace.toaData.status == 1) ...
& logical(strcmp(artoaWorkspace.toaData.soundSource, fnames{i}));
x = [x; artoaWorkspace.toaData.toaDate(selection)];
y = [y; artoaWorkspace.toaData.toa(selection)];
c = [c; repmat(artoaWorkspace.soundsourceColors(i, :), length(artoaWorkspace.toaData.toaDate(selection)), 1)];
c = [c; repmat(soundsourceColor, length(artoaWorkspace.toaData.toaDate(selection)), 1)];
end
%% If the plot exists, just update the values
......@@ -37,7 +45,7 @@ hold(artoaGui.editTimeOfArrival.axesAppliedSoundsources, 'on');
artoaGui.editTimeOfArrival.scatterAppliedSoundsources = scatter( ...
artoaGui.editTimeOfArrival.axesAppliedSoundsources, ...
x, y, [], c, 'filled' ...
x, y, artoa.data.getMember(artoaDataInput, {'ini', 'view', 'toapointsize'}, 36), c, 'filled' ...
);
hold(artoaGui.editTimeOfArrival.axesAppliedSoundsources, 'off');
......
......@@ -8,8 +8,42 @@ function [] = plotSoundsourceToaFromGps(pSoundsources)
global artoaDataInput artoaWorkspace artoaGui;
if isfield(artoaGui.editTimeOfArrival, 'axesToaFromGps') ...
&& isvalid(artoaGui.editTimeOfArrival.axesToaFromGps)
% update color
fnames = fieldnames(pSoundsources);
for o = 1:length(fnames)
if artoa.soundsources.hasAppliedToa(fnames{o}, artoaWorkspace.toaData.soundSource)
[colorIndex, artoaWorkspace.soundsourceColorRegister] = ...
artoa.soundsources.colorregister.add(fnames{o}, artoaWorkspace.soundsourceColorRegister);
for t = 1:length(artoaGui.editTimeOfArrival.textToaFromGps.(fnames{o}))
current = artoaGui.editTimeOfArrival.textToaFromGps.(fnames{o})(t);
current.Color = artoaWorkspace.soundsourceColors(colorIndex, :);
end
clear current;
% update scatter
artoaGui.editTimeOfArrival.scatterToaFromGps.(fnames{o}).MarkerEdgeColor = ...
artoaWorkspace.soundsourceColors(colorIndex, :);
else
% update text
for t = 1:length(artoaGui.editTimeOfArrival.textToaFromGps.(fnames{o}))
current = artoaGui.editTimeOfArrival.textToaFromGps.(fnames{o})(t);
current.Color = [1 1 1];
end
clear current;
% update scatter
artoaGui.editTimeOfArrival.scatterToaFromGps.(fnames{o}).MarkerEdgeColor = ...
[1 1 1];
end
end
return
end
artoaGui.editTimeOfArrival.axesToaFromGps = axes(artoaGui.figures.editTimeOfArrival);
artoaGui.editTimeOfArrival.scatterToaFromGps = struct();
artoaGui.editTimeOfArrival.textToaFromGps = struct();
hold(artoaGui.editTimeOfArrival.axesToaFromGps, 'on');
%% Collect required data
......@@ -20,6 +54,14 @@ yMin = min(artoaGui.editTimeOfArrival.axesScatterTimeOfArrival.YLim);
fnames = fieldnames(pSoundsources);
for o = 1:length(fnames)
% estimate the color to be used
if artoa.soundsources.hasAppliedToa(fnames{o}, artoaWorkspace.toaData.soundSource)
[colorIndex, artoaWorkspace.soundsourceColorRegister] = ...
artoa.soundsources.colorregister.add(fnames{o}, artoaWorkspace.soundsourceColorRegister);
soundsourceColor = artoaWorkspace.soundsourceColors(colorIndex, :);
else
soundsourceColor = [1 1 1];
end
% skip sound source if it went out of the water before the float range, or
% went in the water after the float range
soundSourceBegin = artoa.convert.dmy2rd(artoaDataInput.soundsources.(fnames{o}).begemis(3), ...
......@@ -46,17 +88,17 @@ for o = 1:length(fnames)
predictedToas(selection) = NaN;
clear selection;
scatter( ...
artoaGui.editTimeOfArrival.scatterToaFromGps.(fnames{o}) = scatter( ...
artoaGui.editTimeOfArrival.axesToaFromGps, ...
gpsDates, predictedToas, 50, ...
'MarkerEdgeColor', artoaWorkspace.soundsourceColors(o, :) ...
'MarkerEdgeColor', soundsourceColor ...
);
% use only every third gps date
gpsDates = gpsDates(1:3:end);
predictedToas = predictedToas(1:3:end);
text( ...
artoaGui.editTimeOfArrival.textToaFromGps.(fnames{o}) = text( ...
artoaGui.editTimeOfArrival.axesToaFromGps, ...
gpsDates, predictedToas, [' ' fnames{o}], ...
'HorizontalAlignment', 'left', ...
......@@ -64,7 +106,7 @@ for o = 1:length(fnames)
'FontName', 'Helvetica', ...¬
'FontSize', 10, ...¬
'FontWeight', 'demi', ...¬
'Color', artoaWorkspace.soundsourceColors(o, :) ...%[1 1 1] ...
'Color', soundsourceColor ...%[1 1 1] ...
);
% Soundsource lines
......
function [] = plotToaHistogram()
%PLOTTOAHISTOGRAM Summary of this function goes here
% Detailed explanation goes here
global artoaWorkspace artoaGui;
if isfield(artoaGui.editTimeOfArrival, 'axesToaHistogram') ...
&& isvalid(artoaGui.editTimeOfArrival.axesToaHistogram)
delete(artoaGui.editTimeOfArrival.axesToaHistogram);
end
artoaGui.editTimeOfArrival.axesToaHistogram = axes(artoaGui.editTimeOfArrival.frameToaHistogram);
artoaGui.editTimeOfArrival.plotToaHistogram = histogram( ...
artoaGui.editTimeOfArrival.axesToaHistogram, ...
artoaWorkspace.toaData.correlationHeight ...
);
xlabel(artoaGui.editTimeOfArrival.axesToaHistogram, 'Correlation height');
ylabel(artoaGui.editTimeOfArrival.axesToaHistogram, 'Count');
artoaGui.figures.editTimeOfArrival.CurrentAxes = artoaGui.editTimeOfArrival.axesScatterTimeOfArrival;
end
......@@ -23,8 +23,13 @@ artoaWorkspace.toaData.soundSource( ...
artoaWorkspace.editTimeOfArrival.userSelection ...
) = {''};
%% Update colorregister
artoaWorkspace.soundsourceColorRegister = artoa.soundsources.colorregister.updateColorRegister( ...
artoaWorkspace.soundsourceColorRegister, ...
artoaWorkspace.toaData.soundSource ...
);
% Update status to selected
%% Update status to selected
artoa.controller.edit.timeOfArrival.applyStatusToSelectedPoints(0);
%% Update duplicate toa table
......
......@@ -4,15 +4,14 @@ function [] = tableDuplicateToaSelection(~, event)
global artoaGui;
%% Get selected date
try
%% Get selected date
date = str2double(artoaGui.editTimeOfArrival.tableDuplicateAppliedToa.Data{event.Indices(1), 2});
toas = artoaGui.editTimeOfArrival.tableDuplicateAppliedToa.Data{event.Indices(1), 3};
toas = strsplit(toas, ' ');
%% Zoom to the selected points
%resetplotview(artoaGui.editTimeOfArrival.axesScatterTimeOfArrival,'InitializeCurrentView');
zoom(artoaGui.figures.editTimeOfArrival, 'reset');
artoaGui.editTimeOfArrival.axesScatterTimeOfArrival.XLim = [date - 25; date + 25];
artoaGui.editTimeOfArrival.axesScatterTimeOfArrival.YLim = [str2double(toas{1}) - 25; str2double(toas{end - 1}) + 25];
......
......@@ -13,7 +13,7 @@ toaData = artoaWorkspace.toaData;
tableData = {};
%% calculate duplicated data
%% Calculate duplicated data
for i = 1:length(fnames)
soundsource = artoaWorkspace.filteredSoundsources.(fnames{i});
......@@ -25,6 +25,9 @@ for i = 1:length(fnames)
end
end
%% Save to workspace
artoaWorkspace.duplicateAppliedToa = tableData;
%% Update table
artoaGui.editTimeOfArrival.tableDuplicateAppliedToa.Data = tableData;
......
function [] = updateLowerColormapBoundary()
function [] = updateLowerColormapBoundary(pFromInput)
%UPDATEUPPERCOLORMAPBOUNDARY Summary of this function goes here
% Detailed explanation goes here
global artoaGui;
%% When user changed the values of input fields
if nargin == 1 && pFromInput
upper = str2double(artoaGui.editTimeOfArrival.inputUpperBoundary.String);
if isnan(upper)
upper = 255;
end
lower = str2double(artoaGui.editTimeOfArrival.inputLowerBoundary.String);
if isnan(lower)
lower = 0;
end
% transfer values to slider
artoaGui.editTimeOfArrival.sliderLowerBoundary.Value = lower;
artoaGui.editTimeOfArrival.sliderUpperBoundary.Value = upper;
clear lower upper;
end
%% Get the values from the slider
lower = artoaGui.editTimeOfArrival.sliderLowerBoundary.Value;
upper = artoaGui.editTimeOfArrival.sliderUpperBoundary.Value;
lower = floor(artoaGui.editTimeOfArrival.sliderLowerBoundary.Value);
upper = floor(artoaGui.editTimeOfArrival.sliderUpperBoundary.Value);
%% Check if they overlap
if (lower >= upper)
......@@ -18,6 +34,10 @@ end
artoaGui.editTimeOfArrival.sliderLowerBoundary.Value = lower;
artoaGui.editTimeOfArrival.sliderUpperBoundary.Value = upper;
%% Update input fields
artoaGui.editTimeOfArrival.inputLowerBoundary.String = num2str(lower);
artoaGui.editTimeOfArrival.inputUpperBoundary.String = num2str(upper);
%% Update the color limit
artoaGui.editTimeOfArrival.axesScatterTimeOfArrival.CLim = ...
[ ...
......
function [] = updateUpperColormapBoundary()
function [] = updateUpperColormapBoundary(pFromInput)
%UPDATEUPPERCOLORMAPBOUNDARY Summary of this function goes here
% Detailed explanation goes here
global artoaGui;
%% When user changed the values of input fields
if nargin == 1 && pFromInput
upper = str2double(artoaGui.editTimeOfArrival.inputUpperBoundary.String);
if isnan(upper)
upper = 255;
end
lower = str2double(artoaGui.editTimeOfArrival.inputLowerBoundary.String);
if isnan(lower)
lower = 0;
end
% transfer values to slider
artoaGui.editTimeOfArrival.sliderLowerBoundary.Value = lower;
artoaGui.editTimeOfArrival.sliderUpperBoundary.Value = upper;
clear lower upper;
end
%% Get the values from the slider
lower = artoaGui.editTimeOfArrival.sliderLowerBoundary.Value;
upper = artoaGui.editTimeOfArrival.sliderUpperBoundary.Value;
lower = floor(artoaGui.editTimeOfArrival.sliderLowerBoundary.Value);
upper = floor(artoaGui.editTimeOfArrival.sliderUpperBoundary.Value);
%% Check if they overlap
if (upper <= lower)
......@@ -18,6 +35,10 @@ end
artoaGui.editTimeOfArrival.sliderLowerBoundary.Value = lower;
artoaGui.editTimeOfArrival.sliderUpperBoundary.Value = upper;
%% Update input fields
artoaGui.editTimeOfArrival.inputLowerBoundary.String = num2str(lower);
artoaGui.editTimeOfArrival.inputUpperBoundary.String = num2str(upper);
%% Update the color limit
artoaGui.editTimeOfArrival.axesScatterTimeOfArrival.CLim = ...
[ ...
......
......@@ -35,6 +35,12 @@ artoaWorkspace.toaData.soundSource(selection) = {''};
% apply status to selection
artoaWorkspace.toaData.status(selection) = 0;
%% Update colorregister
artoaWorkspace.soundsourceColorRegister = artoa.soundsources.colorregister.updateColorRegister( ...
artoaWorkspace.soundsourceColorRegister, ...
artoaWorkspace.toaData.soundSource ...
);
%% Update duplicate toa table
artoa.controller.edit.timeOfArrival.updateDuplicateToaTable();
......
......@@ -7,6 +7,7 @@ global artoaDataInput artoaWorkspace;
try
artoaDataInput.ini = artoa.load.tomlini('artoa.ini');
artoaWorkspace.soundsourceColors = artoaDataInput.ini.soundsourcecolors./255;
artoaWorkspace.soundsourceColorRegister = artoa.soundsources.colorregister.create();
catch ex
error([mfilename ': Reading artoa.ini failed with the following message: ' ex.message]);
end
......
function [extractedSoundsources] = extractSoundsourcesFromStruct(pSourcesToExtract, pSoundsources)
%EXTRACTSOUNDSOURCESFROMARRAY Summary of this function goes here
% Detailed explanation goes here
%% Initialize return variable
extractedSoundsources = {};
%% Get all soundsources
for i = 1:length(pSourcesToExtract)
try
extractedSoundsources{end + 1} = pSoundsources.(pSourcesToExtract{i});
catch
end
end
end
......@@ -178,10 +178,23 @@ clear columns;
artoa.controller.edit.timeOfArrival.createSoundsourceColorsPanel();
%% TOA Histogram
artoaGui.editTimeOfArrival.frameToaHistogram = uipanel( ...
'Title', 'TOA histogram', ...
'Units', 'normalized', ...
'BackgroundColor', 'white', ...
'Position', [.01 .45 width .15] ...
);
%% Update histogram
artoa.controller.edit.timeOfArrival.plotToaHistogram()
%% Colormap slider
artoaGui.editTimeOfArrival.frameControlsColormapSlider = uipanel( ...
'Title', 'Adjust TOA colormap', ...
'Title', 'Adjust colormap boundaries', ...
'Units', 'normalized', ...
'BackgroundColor', 'white', ...
'Position', [.01 .1 width .1] ...
......@@ -203,10 +216,20 @@ artoaGui.editTimeOfArrival.sliderUpperBoundary = uicontrol( ...
'Max', 255, ...
'Min', 0, ...
'Value', 255, ...
'Position', [.4 .6 .5 .2], ...
'Position', [.4 .6 .3 .2], ...
'Callback', 'artoa.controller.edit.timeOfArrival.updateUpperColormapBoundary();'...
);
artoaGui.editTimeOfArrival.inputUpperBoundary = uicontrol( ...
'Parent', artoaGui.editTimeOfArrival.frameControlsColormapSlider, ...
'String', '255', ...
'Style', 'edit', ...
'FontSize', 8, ...
'Units', 'normalized', ...
'Position', [.8 .6 .1 .2], ...
'CallBack', 'artoa.controller.edit.timeOfArrival.updateUpperColormapBoundary(true);' ...
);
artoaGui.editTimeOfArrival.textLowerBoundary = uicontrol( ...
'Parent', artoaGui.editTimeOfArrival.frameControlsColormapSlider, ...
'String', 'Lower', ...
......@@ -223,10 +246,20 @@ artoaGui.editTimeOfArrival.sliderLowerBoundary = uicontrol( ...
'Max', 255, ...
'Min', 0, ...
'Value', 0, ...
'Position', [.4 .2 .5 .2], ...
'Position', [.4 .2 .3 .2], ...
'Callback', 'artoa.controller.edit.timeOfArrival.updateLowerColormapBoundary();'...
);
artoaGui.editTimeOfArrival.inputLowerBoundary = uicontrol( ...
'Parent', artoaGui.editTimeOfArrival.frameControlsColormapSlider, ...
'String', '0', ...
'Style', 'edit', ...
'FontSize', 8, ...
'Units', 'normalized', ...
'Position', [.8 .2 .1 .2], ...
'CallBack', 'artoa.controller.edit.timeOfArrival.updateLowerColormapBoundary(true);' ...
);
%% Enable zoom
zoom on;
......
function [colorIndex, register] = add(pSoundsourceName, pRegister)
%REGISTERSOUNDSOURCE Summary of this function goes here
% Detailed explanation goes here
register = pRegister;
soundsourceLogical = strcmp(register, pSoundsourceName);
if ~any(soundsourceLogical)
emptyCellIndex = find(strcmp(register, {''}));
if ~isempty(emptyCellIndex)
register(emptyCellIndex) = {pSoundsourceName};
colorIndex = emptyCellIndex;
return;
end
register(end + 1) = {pSoundsourceName};
colorIndex = length(register);
else
colorIndex = find(soundsourceLogical);
end
function [colorRegister] = create()
%CREATE Summary of this function goes here
% Detailed explanation goes here
colorRegister = {};
end
function [colorIndex] = getColorIndex(pSoundsourceName, pRegister)
%GETCOLOR Summary of this function goes here
% Detailed explanation goes here
soundsourceLogical = strcmp(pRegister, pSoundsourceName);
if ~any(soundsourceLogical)
colorIndex = 0;
else
colorIndex = find(soundsourceLogical);
end
function [register] = remove(pSoundsourceName, pRegister)
%REMOVE Summary of this function goes here
% Detailed explanation goes here
register = pRegister;
soundsourceLogical = strcmp(register, pSoundsourceName);
register(soundsourceLogical) = {''};
end
function [register] = updateColorRegister(pRegister, pAppliedSoundsourceNames)
%UPDATECOLORREGISTER Summary of this function goes here
% Detailed explanation goes here
register = pRegister;
for i = 1:length(register)
if ~artoa.soundsources.hasAppliedToa(register{i}, pAppliedSoundsourceNames)
register = artoa.soundsources.colorregister.remove(register{i}, register);
end
end
end
function [hasAppliedToa] = hasAppliedToa(pSoundsourceName, pToaDataSoundsourcesCell)
%HASAPPLIEDTOA Summary of this function goes here
% Detailed explanation goes here
hasAppliedToa = any(strcmp(pToaDataSoundsourcesCell, pSoundsourceName));
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment