diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/createSoundsourceColorsPanel.m b/lib/+artoa/+controller/+edit/+timeOfArrival/createSoundsourceColorsPanel.m
index 90741b8a403d663f7c5b637094319aefe552edd9..1fb92da53c744b6706c7dce8a1aebaf9b452b706 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/createSoundsourceColorsPanel.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/createSoundsourceColorsPanel.m
@@ -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' ...
     );
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/plot.m b/lib/+artoa/+controller/+edit/+timeOfArrival/plot.m
index cffd326545b997b87089bea94c77fe410ad31ea1..c6d30c8947a3baa4eef6b40091cf961740611e3f 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/plot.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/plot.m
@@ -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
 
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/plotAppliedSoundsources.m b/lib/+artoa/+controller/+edit/+timeOfArrival/plotAppliedSoundsources.m
index b2c35458fe08c9c59b2a77fdec909838657f0612..8592c75bf3c371431583da8dc33ce944d909390a 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/plotAppliedSoundsources.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/plotAppliedSoundsources.m
@@ -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');
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/plotSoundsourceToaFromGps.m b/lib/+artoa/+controller/+edit/+timeOfArrival/plotSoundsourceToaFromGps.m
index 3f5eaa6bd52e7783d61a73f5868aad7fc790f478..1b21cab4d7c5415e37f1df01d0e84d82e91c1750 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/plotSoundsourceToaFromGps.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/plotSoundsourceToaFromGps.m
@@ -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
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/plotToaHistogram.m b/lib/+artoa/+controller/+edit/+timeOfArrival/plotToaHistogram.m
new file mode 100644
index 0000000000000000000000000000000000000000..4cced28a732ceff3142270f56b0800775b70c715
--- /dev/null
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/plotToaHistogram.m
@@ -0,0 +1,25 @@
+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
+
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/removeSoundSourceFromSelectedPoints.m b/lib/+artoa/+controller/+edit/+timeOfArrival/removeSoundSourceFromSelectedPoints.m
index be718ea1d005dab3bdb7dbc6ec762e0cdc5f0fbb..bd67d401c71c18d1f24577fd8930c216c92d0096 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/removeSoundSourceFromSelectedPoints.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/removeSoundSourceFromSelectedPoints.m
@@ -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
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/tableDuplicateToaSelection.m b/lib/+artoa/+controller/+edit/+timeOfArrival/tableDuplicateToaSelection.m
index 21a41b7459cc76f94115c610b22bed265742eee5..a42db7c4cc48f5226a6458c214508daea0988c6b 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/tableDuplicateToaSelection.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/tableDuplicateToaSelection.m
@@ -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];
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/updateDuplicateToaTable.m b/lib/+artoa/+controller/+edit/+timeOfArrival/updateDuplicateToaTable.m
index 5e5613933d4462d898eee8aae1e6b5f6333fe80e..0b71ebeb1ef4524c9f9305e21ac105150916891b 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/updateDuplicateToaTable.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/updateDuplicateToaTable.m
@@ -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;
 
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/updateLowerColormapBoundary.m b/lib/+artoa/+controller/+edit/+timeOfArrival/updateLowerColormapBoundary.m
index 1e1450971888b65da68797e04f394ed181c919ce..0c191ff7d4a0b39f3d847655c3466af1a0826c33 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/updateLowerColormapBoundary.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/updateLowerColormapBoundary.m
@@ -1,13 +1,29 @@
-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 = ...
     [ ...
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/updateUpperColormapBoundary.m b/lib/+artoa/+controller/+edit/+timeOfArrival/updateUpperColormapBoundary.m
index d5dacd5915de33099b7010aaf73315e4a39ec9f1..76ac6b6b62389d0b2544b2c2f3d3d1595d5a8393 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/updateUpperColormapBoundary.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/updateUpperColormapBoundary.m
@@ -1,13 +1,30 @@
-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 = ...
     [ ...
diff --git a/lib/+artoa/+controller/+edit/+timeOfArrival/withdrawSoundSourceToAllVisible.m b/lib/+artoa/+controller/+edit/+timeOfArrival/withdrawSoundSourceToAllVisible.m
index 3717b57da361ee94866d3b0d59301260054debe4..3f8cd8e43b1e392fc98cf44232e6b139fcd5ee48 100644
--- a/lib/+artoa/+controller/+edit/+timeOfArrival/withdrawSoundSourceToAllVisible.m
+++ b/lib/+artoa/+controller/+edit/+timeOfArrival/withdrawSoundSourceToAllVisible.m
@@ -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();
 
diff --git a/lib/+artoa/+controller/+file/loadArtoaIni.m b/lib/+artoa/+controller/+file/loadArtoaIni.m
index e13743b3e391c082830d6f792e1b9bf8fcda9ffa..3e147f4a431cc36b0385a6259427b3da4e9269a8 100644
--- a/lib/+artoa/+controller/+file/loadArtoaIni.m
+++ b/lib/+artoa/+controller/+file/loadArtoaIni.m
@@ -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
diff --git a/lib/+artoa/+data/extractSoundsourcesFromStruct.m b/lib/+artoa/+data/extractSoundsourcesFromStruct.m
new file mode 100644
index 0000000000000000000000000000000000000000..55b89edf1d01ecddcb621fb304a7843cdd66b95f
--- /dev/null
+++ b/lib/+artoa/+data/extractSoundsourcesFromStruct.m
@@ -0,0 +1,17 @@
+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
+
diff --git a/lib/+artoa/+gui/+edit/timeOfArrival.m b/lib/+artoa/+gui/+edit/timeOfArrival.m
index b74bd3b9949fc0a84b825d6d35550bcb0e36d2c5..484266c79737fb486021c06697b958565d39d712 100644
--- a/lib/+artoa/+gui/+edit/timeOfArrival.m
+++ b/lib/+artoa/+gui/+edit/timeOfArrival.m
@@ -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;
 
diff --git a/lib/+artoa/+soundsources/+colorregister/add.m b/lib/+artoa/+soundsources/+colorregister/add.m
new file mode 100644
index 0000000000000000000000000000000000000000..09c9ff6b5f788ef59552552e44c6b049096fa877
--- /dev/null
+++ b/lib/+artoa/+soundsources/+colorregister/add.m
@@ -0,0 +1,19 @@
+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
+
diff --git a/lib/+artoa/+soundsources/+colorregister/create.m b/lib/+artoa/+soundsources/+colorregister/create.m
new file mode 100644
index 0000000000000000000000000000000000000000..3e33b8f1251a95b414915d29051e230dd56bad0e
--- /dev/null
+++ b/lib/+artoa/+soundsources/+colorregister/create.m
@@ -0,0 +1,8 @@
+function [colorRegister] = create()
+%CREATE Summary of this function goes here
+%   Detailed explanation goes here
+
+colorRegister = {};
+
+end
+
diff --git a/lib/+artoa/+soundsources/+colorregister/getColorIndex.m b/lib/+artoa/+soundsources/+colorregister/getColorIndex.m
new file mode 100644
index 0000000000000000000000000000000000000000..589c741eda88235808e982c90b9194aabbe3b2f0
--- /dev/null
+++ b/lib/+artoa/+soundsources/+colorregister/getColorIndex.m
@@ -0,0 +1,11 @@
+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
+
diff --git a/lib/+artoa/+soundsources/+colorregister/remove.m b/lib/+artoa/+soundsources/+colorregister/remove.m
new file mode 100644
index 0000000000000000000000000000000000000000..e89e849a18e8a676518629925452e56dbf497c16
--- /dev/null
+++ b/lib/+artoa/+soundsources/+colorregister/remove.m
@@ -0,0 +1,10 @@
+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
+
diff --git a/lib/+artoa/+soundsources/+colorregister/updateColorRegister.m b/lib/+artoa/+soundsources/+colorregister/updateColorRegister.m
new file mode 100644
index 0000000000000000000000000000000000000000..bcacf9f52ebf4abe1e027e9c5da34928955110df
--- /dev/null
+++ b/lib/+artoa/+soundsources/+colorregister/updateColorRegister.m
@@ -0,0 +1,12 @@
+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
+
diff --git a/lib/+artoa/+soundsources/hasAppliedToa.m b/lib/+artoa/+soundsources/hasAppliedToa.m
new file mode 100644
index 0000000000000000000000000000000000000000..6a599a9648b864142da1e6ee9e6fcd38af4c7453
--- /dev/null
+++ b/lib/+artoa/+soundsources/hasAppliedToa.m
@@ -0,0 +1,8 @@
+function [hasAppliedToa] = hasAppliedToa(pSoundsourceName, pToaDataSoundsourcesCell)
+%HASAPPLIEDTOA Summary of this function goes here
+%   Detailed explanation goes here
+
+hasAppliedToa = any(strcmp(pToaDataSoundsourcesCell, pSoundsourceName));
+
+end
+