classdef SliceViewerPanel < handle
%SliceViewerPanel uipanel viewer to SliceViewerPanelSource
%
% SliceViewerPanel plots the content from SliceViewerPanelSource (SVPS).
%
% Coordinate/Orientation in detail:
% zOrient = 1: Coronal,    abscissa = dim3 = zmesh, ordinate = dim2 = ymesh
% zOrient = 2: Sagittal,   abscissa = dim3 = zmesh, ordinate = dim1 = xmesh
% zOrient = 3: Transverse, abscissa = dim1 = xmesh, ordinate = dim2 = ymesh
% or think as this:
% zOrient = 1: image(zmesh, ymesh, Geometry.rhomw(slice,:,:))
% zOrient = 2: image(zmesh, xmesh, Geometry.rhomw(:,slice,:))
% zOrient = 3: image(xmesh, ymesh, Geometry.rhomw(:,:,slice))
%
% See also XTPS
%
% Author: Xiaohu Mo

%===============================================================================
    properties
        hSVPS           % handle to SliceViewerPanelSource
        zOrien          % scroll along which dimension: 1=S; 2=C; 3=T

        % TODO should be private
        % handles to gui objects
        hPanel
        hAxis
        hSlider
        hEdit
        hLineH          % horizontal TCS line
        hLineV          % vertical TCS line
        hImage          % image has CT and dose overlayed manually
        hCbar           % colorbar handle
        hROIs           % handle vector of overlay ROIs
        hDoseContours   % handle vector of overlay isodose lines
        hDoseLegend     % handle of legend of isodose lines
    end
%===============================================================================

%===============================================================================
    methods
%-------------------------------------------------------------------------------
        function obj = SliceViewerPanel(hSVPS, zOrien, hPanelParent) % Constructor returns object
            obj.hSVPS = hSVPS;
            obj.zOrien = zOrien;
            obj.hPanel = uipanel('Parent', hPanelParent);
            obj.hAxis = axes('Parent', obj.hPanel);
            obj.hSlider = uicontrol(obj.hPanel, 'Style','slider');
            obj.hEdit = uicontrol(obj.hPanel, 'Style','edit');
            obj.hImage = image('Parent', obj.hAxis);
            obj.hLineH = line('Parent', obj.hAxis, 'XData', [], 'YData', []);
            obj.hLineV = line('Parent', obj.hAxis, 'XData', [], 'YData', []);
            obj.hCbar = [];
            obj.hDoseContours = [];
            obj.hDoseLegend = [];

            % Callback passes 3 args: (obj, src, evt)
            set(obj.hSlider, 'Callback',	@obj.Slider_Callback);
            set(obj.hEdit, 'Callback',      @obj.Edit_Callback);

            % Properties
            axis(obj.hAxis, 'off');
            set(obj.hImage, 'CData', [], 'CDataMapping', 'scaled');
            set(obj.hLineH, 'HitTest', 'off', 'Color', 'red');
            set(obj.hLineV, 'HitTest', 'off', 'Color', 'red');
            set([obj.hPanel obj.hSlider obj.hEdit], ...
                'Background', get(get(obj.hPanel, 'Parent'), 'Color'));

            % Add Listener
            addlistener(obj.hSVPS, 'POI', 'PostSet', @obj.handleEvent);
            addlistener(obj.hSVPS, 'Geometry', 'PostSet', @obj.handleEvent);
            addlistener(obj.hSVPS, 'dosedisp', 'PostSet', @obj.handleEvent);
            addlistener(obj.hSVPS, 'ctWindow', 'PostSet', @obj.handleEvent);
            addlistener(obj.hSVPS, 'TCSVisible', 'PostSet', @obj.handleEvent);
        end % function SliceViewerPanel
%-------------------------------------------------------------------------------
        function set_layout(obj, src, evt)
        % Set widget positions and sizes
            set([obj.hPanel obj.hAxis obj.hSlider obj.hEdit], 'Unit', 'normalized');
            
            padding = [0.01 0.01];
            setPositionXY(obj.hAxis, [0 1], [0.1 1], padding);
            setPositionXY(obj.hSlider, [0 0.8], [0 0.1], padding, 1.5, 'characters');
            setPositionXY(obj.hEdit, [0.8 1], [0 0.1], padding, 1.5, 'characters');
        end
%-------------------------------------------------------------------------------
        function handleEvent(obj, src, evt)
            switch src.Name
                case 'POI'
                    obj.redraw_lines();
                    % redraw only changed dimension
                    if obj.hSVPS.POI(obj.zOrien) ~= obj.hSVPS.prev_POI(obj.zOrien)
                        obj.redraw_image();
%                         obj.redraw_contour();
                        obj.redraw_overlay();
                    end
                case {'Geometry' 'ctWindow' 'ROIdisp' 'dosedisp'}
                    % redraw all
                    obj.redraw_image();
%                     obj.redraw_contour();
                    obj.redraw_overlay();
                case 'TCSVisible'
                    % redraw line
                    obj.redraw_lines();
            end
        end
%-------------------------------------------------------------------------------
        function Slider_Callback(obj, src, evt)
        % check value, update Edit and Axis
            value = round(get(obj.hSlider, 'Value'));
            set(obj.hSlider, 'Value', value);
            set(obj.hEdit, 'String', num2str(value));
            obj.hSVPS.POI(obj.zOrien) = value;
        end % function Slider_Callback
%-------------------------------------------------------------------------------
        function Edit_Callback(obj, src, evt)
        % check value, update Slider and Axis
            value = round(str2double(get(obj.hEdit, 'String')));
            if value >= get(obj.hSlider, 'Min') && value <= get(obj.hSlider, 'Max')
                set(obj.hSlider, 'Value', value);
                set(obj.hEdit, 'String', num2str(value));
                obj.hSVPS.POI(obj.zOrien) = value;
            else % invalid input, set back to slider value
                value = get(obj.hSlider, 'Value');
                set(obj.hEdit, 'String', num2str(value));
            end
        end % function Edit_Callback
%-------------------------------------------------------------------------------
        function load_data(obj)
            set(obj.hSlider, 'Min', 1, 'Max', size(obj.hSVPS.Geometry.rhomw, obj.zOrien), 'Value', 1);
            set(obj.hSlider, 'SliderStep', [1 10] / size(obj.hSVPS.Geometry.rhomw, obj.zOrien));
            % set image coordinates, axis limits, DataAspectRatio
            switch obj.zOrien
                case 1
                    set(obj.hImage, 'XData', obj.hSVPS.Geometry.z, 'YData', obj.hSVPS.Geometry.y);
                    set(obj.hAxis, 'XLim', [min(obj.hSVPS.Geometry.z) max(obj.hSVPS.Geometry.z)]);
                    set(obj.hAxis, 'YLim', [min(obj.hSVPS.Geometry.y) max(obj.hSVPS.Geometry.y)]);
                    zoom(obj.hAxis, 'reset');
                    daspect(obj.hAxis, [obj.hSVPS.Geometry.voxel_size(3) obj.hSVPS.Geometry.voxel_size(2) 1]);
                case 2
                    set(obj.hImage, 'XData', obj.hSVPS.Geometry.z, 'YData', obj.hSVPS.Geometry.x);
                    set(obj.hAxis, 'XLim', [min(obj.hSVPS.Geometry.z) max(obj.hSVPS.Geometry.z)]);
                    set(obj.hAxis, 'YLim', [min(obj.hSVPS.Geometry.x) max(obj.hSVPS.Geometry.x)]);
                    zoom(obj.hAxis, 'reset');
                    daspect(obj.hAxis, [obj.hSVPS.Geometry.voxel_size(3) obj.hSVPS.Geometry.voxel_size(1) 1]);
                    set(obj.hAxis, 'YDir', 'reverse');
                case 3
                    set(obj.hImage, 'XData', obj.hSVPS.Geometry.x, 'YData', obj.hSVPS.Geometry.y);
                    set(obj.hAxis, 'XLim', [min(obj.hSVPS.Geometry.x) max(obj.hSVPS.Geometry.x)]);
                    set(obj.hAxis, 'YLim', [min(obj.hSVPS.Geometry.y) max(obj.hSVPS.Geometry.y)]);
                    zoom(obj.hAxis, 'reset');
                    daspect(obj.hAxis, [obj.hSVPS.Geometry.voxel_size(1) obj.hSVPS.Geometry.voxel_size(2) 1]);
                    set(obj.hAxis, 'YDir', 'reverse');
            end
            
            % default to volume center
            obj.hSVPS.POI = round(size(obj.hSVPS.Geometry.rhomw)/2);
            
            % set slider and edit control when manually set focus point
            slice = obj.hSVPS.POI(obj.zOrien);
            set(obj.hSlider, 'Value', slice);
            set(obj.hEdit, 'String', slice);
        end % function load_data
%-------------------------------------------------------------------------------
        function updateColorbar(obj)
        % only plot color on transvers axis
        if obj.zOrien ~= 3; return; end
       
        % delete old one
        delete(obj.hCbar);   obj.hCbar = [];
        switch lower(obj.hSVPS.dosedisp.mode)
            case {'isodose' 'isodoseline'}
                % get a sorted, valid dose level and colors
                valid_indices = find(obj.hSVPS.dosedisp.level > 0);
                if isempty(valid_indices); return; end
                dose_levels = obj.hSVPS.dosedisp.level(valid_indices);
                dose_colors = obj.hSVPS.dosedisp.color(valid_indices,:);
                [dose_levels iX] = sort(dose_levels);
                dose_labels = arrayfun(@(d)num2str(d), dose_levels, 'UniformOutput', false)';
                cmap = dose_colors(iX, :);
                
                colormap(cmap);
                set(obj.hAxis, 'CLim', [0 1]);
                obj.hCbar = colorbar('Peer', obj.hAxis, 'Location', 'SouthOutside');
                set(obj.hCbar, 'TickLength', [0 0], ...
                    'XTick', (0.5:numel(dose_levels)-0.5)/numel(dose_levels), ...
                    'XTickLabel', dose_labels);
            case 'colorwash'
                colormap(jet(256));
%                 set(obj.hAxis, 'CLim', [0 max(obj.hSVPS.optResults.dose{end}(:))]);
    % Grozomah
                set(obj.hAxis, 'CLim', [0 200]);
                obj.hCbar = colorbar('Peer', obj.hAxis, 'Location', 'SouthOutside');
        end
        end % function updateColorbar
%-------------------------------------------------------------------------------
        function updateAxis(obj)
            % save axis scaling
%             xlim = get(obj.hAxis, 'XLim');
%             ylim = get(obj.hAxis, 'YLim');
            
%             % redraw more if slice changed
%             if obj.hSVPS.POI(obj.zOrien) ~= obj.hSVPS.prev_POI(obj.zOrien)
%                 obj.redraw_image();
%                 obj.redraw_contour();
%             end
%             obj.redraw_lines();

            % restore axis scaling
%             set(obj.hAxis, 'XLim', xlim);
%             set(obj.hAxis, 'YLim', ylim);
        end
%-------------------------------------------------------------------------------
        function redraw_lines(obj)
            % P1 & P2 are the extent of the grid
            P1 = [min(obj.hSVPS.Geometry.y) min(obj.hSVPS.Geometry.x) min(obj.hSVPS.Geometry.z)];
            P2 = [max(obj.hSVPS.Geometry.y) max(obj.hSVPS.Geometry.x) max(obj.hSVPS.Geometry.z)];
            % F is the coordinate of the intersection of TCS planes
            F = [obj.hSVPS.Geometry.y(obj.hSVPS.POI(1)) ...
                obj.hSVPS.Geometry.x(obj.hSVPS.POI(2)) ...
                obj.hSVPS.Geometry.z(obj.hSVPS.POI(3))];
            
            switch obj.zOrien
                case 1
                    set(obj.hLineH, 'XData', [P1(3) P2(3)],   'YData', [F(2) F(2)]);
                    set(obj.hLineV, 'XData', [F(3) F(3)],   'YData', [P1(2) P2(2)]);
                case 2
                    set(obj.hLineH, 'XData', [P1(3) P2(3)],   'YData', [F(1) F(1)]);
                    set(obj.hLineV, 'XData', [F(3) F(3)],   'YData', [P1(1) P2(1)]);
                case 3
                    set(obj.hLineH, 'XData', [P1(2) P2(2)],   'YData', [F(1) F(1)]);
                    set(obj.hLineV, 'XData', [F(2) F(2)],   'YData', [P1(1) P2(1)]);
            end
            
            % Set visibility
            if obj.hSVPS.TCSVisible == true
                set(obj.hLineH, 'Visible', 'on');
                set(obj.hLineV, 'Visible', 'on');
            else
                set(obj.hLineH, 'Visible', 'off');
                set(obj.hLineV, 'Visible', 'off');
            end
        end
%-------------------------------------------------------------------------------
        function redraw_image(obj)
            slice = obj.hSVPS.POI(obj.zOrien);
            
            % get CT image
            switch obj.zOrien
                case 1
                    ctImage = imagescX((obj.hSVPS.Geometry.data(slice,:,:)), gray(256), obj.hSVPS.ctClim);
                case 2
                    ctImage = imagescX((obj.hSVPS.Geometry.data(:,slice,:)), gray(256), obj.hSVPS.ctClim);
                case 3
                    ctImage = imagescX((obj.hSVPS.Geometry.data(:,:,slice)), gray(256), obj.hSVPS.ctClim);
            end
            
            % set image to CT. Will re-set if need to blend with dose later.
            set(obj.hImage, 'CData',ctImage);

            % redraw dose
            delete(obj.hDoseContours);
            obj.hDoseContours = [];
            if ~isempty(obj.hSVPS.optResults)
                switch obj.zOrien
                    case 1
                        doseSlice = squeeze(obj.hSVPS.optResults.dose{end}(slice,:,:));
                        xaxis = obj.hSVPS.Geometry.z;
                        yaxis = obj.hSVPS.Geometry.y;
                    case 2
                        doseSlice = squeeze(obj.hSVPS.optResults.dose{end}(:,slice,:));
                        xaxis = obj.hSVPS.Geometry.z;
                        yaxis = obj.hSVPS.Geometry.x;
                    case 3
                        doseSlice = squeeze(obj.hSVPS.optResults.dose{end}(:,:,slice));
                        xaxis = obj.hSVPS.Geometry.x;
                        yaxis = obj.hSVPS.Geometry.y;
                end

                switch lower(obj.hSVPS.dosedisp.mode)
                    case {'isodoseline'}
                        if ~isempty(nonzeros(obj.hSVPS.dosedisp.level))
                            hold(obj.hAxis, 'on');
                            % sort dose levels before contourf
                            [tilde, sorted_indices]= sort(obj.hSVPS.dosedisp.level);
                            for idx = sorted_indices(:)'
                                % scalar of current dose level
                                dose_level = obj.hSVPS.dosedisp.level(idx);
                                if dose_level ~= 0
                                    % plot this contour level and append handles to list
                                    % [level level] is used to avoid single level ambiguity of contour
                                    [tilde, obj.hDoseContours(end+1)] = contour(obj.hAxis, ...
                                        xaxis, yaxis, ...
                                        doseSlice, [dose_level dose_level], ...
                                        '-', 'LineWidth', 2, ...
                                        'LineColor', obj.hSVPS.dosedisp.color(idx, :), ...
                                        'DisplayName', sprintf('%.1f', dose_level));
                                end
                            end
                            hold(obj.hAxis, 'off');
                        end
                    case 'isodose'
                        % Using transparency with contourf like this fails due to the overlay of patches:
                        % hPatches = findobj(obj.hDoseContours(end), 'Type', 'patch', '-property', 'FaceAlpha');
                        % set(hPatches, 'FaceAlpha', obj.hSVPS.dosedisp.alpha(idx));
                        if ~isempty(nonzeros(obj.hSVPS.dosedisp.level))
                            doseMap = ones(size(doseSlice));
                            alphaMap = zeros(size(doseSlice));
                            % sort dose levels
                            [tilde, sorted_indices]= sort(obj.hSVPS.dosedisp.level);
                            for idx = sorted_indices(:)'
                                % scalar of current dose level
                                dose_level = obj.hSVPS.dosedisp.level(idx);
                                % pixels below cmin will have alpha = 0
                                if dose_level ~= 0
                                    doseMap(doseSlice >= dose_level) = idx;
                                    alphaMap(doseSlice >= dose_level) = obj.hSVPS.dosedisp.alpha(idx);
                                end                                
                            end
                            % get the color
                            doseImage = zeros(size(doseSlice,1), size(doseSlice,2), 3);
                            R = obj.hSVPS.dosedisp.color(:, 1);
                            G = obj.hSVPS.dosedisp.color(:, 2);
                            B = obj.hSVPS.dosedisp.color(:, 3);
                            doseImage(:,:,1) = reshape(R(doseMap), size(doseSlice));
                            doseImage(:,:,2) = reshape(G(doseMap), size(doseSlice));
                            doseImage(:,:,3) = reshape(B(doseMap), size(doseSlice));
                            %
                            compImage = imblend(doseImage, alphaMap, ctImage, 1);
                            set(obj.hImage, 'CData', compImage);
                        end
                    case 'colorwash'
                        % Grozomah
%                         doseImage = imagescX(doseSlice, jet(256), [0 max(obj.hSVPS.optResults.dose{end}(:))]);
                        doseImage = imagescX(doseSlice, jet(256), [0 max(obj.hSVPS.optResults.dose{end}(:))/3]);
                        alphaMap = interp1([0; 40], [0; 1], doseSlice, 'linear', 1);
                        alphaMap = reshape(alphaMap, size(doseSlice));
                        compImage = imblend(doseImage, alphaMap, ctImage, 1);
                        set(obj.hImage, 'CData', compImage);
                end
            end
        end
%-------------------------------------------------------------------------------
        function redraw_contour(obj)
            % This function is not called anymore. See redraw_overlay for
            % the actual drawing of the contours
            
            slice = obj.hSVPS.POI(obj.zOrien);
    disp('Contour!!')
    
            delete(obj.hROIs);
            obj.hROIs = [];
            hold(obj.hAxis,'on');
            for i = 1:numel(obj.hSVPS.Geometry.ROIS)
                % skip if display == OFF
                if obj.hSVPS.Geometry.ROIS{i}.visible == false
                    continue;
                end
                
    
                switch obj.zOrien
                    case 1
                        curve_indices = find(obj.hSVPS.Geometry.ROIS{i}.Xcurves_slices == slice);
                        if ~isempty(curve_indices)
                            for curve_idx = curve_indices
                                obj.hROIs(end+1) = plot(obj.hAxis, ...
                                    obj.hSVPS.Geometry.ROIS{i}.Xcurves{curve_idx}(:,3), ...
                                    obj.hSVPS.Geometry.ROIS{i}.Xcurves{curve_idx}(:,2), ...
                                    '--', 'LineWidth', 2, 'Color', obj.hSVPS.Geometry.ROIS{i}.color);
                            end
                        end
                    case 2
                        curve_indices = find(obj.hSVPS.Geometry.ROIS{i}.Ycurves_slices == slice);
                        if ~isempty(curve_indices)
                            for curve_idx = curve_indices
                                obj.hROIs(end+1) = plot(obj.hAxis, ...
                                    obj.hSVPS.Geometry.ROIS{i}.Ycurves{curve_idx}(:,3), ...
                                    obj.hSVPS.Geometry.ROIS{i}.Ycurves{curve_idx}(:,1), ...
                                    '--', 'LineWidth', 2, 'Color', obj.hSVPS.Geometry.ROIS{i}.color);
                            end
                        end
                    case 3
%                         curve_indices = find(abs(obj.hSVPS.Geometry.ROIS{i}.curvesZ - obj.hSVPS.Geometry.z(slice)) < 1E-2);
                        curve_indices = find(obj.hSVPS.Geometry.ROIS{i}.Zcurves_slices == slice);
                        % skip if no curve found on current slice
                        if ~isempty(curve_indices)
                            for curve_idx = curve_indices
                                obj.hROIs(end+1) = plot(obj.hAxis, ...
                                    obj.hSVPS.Geometry.ROIS{i}.curves{curve_idx}(:,1), ...
                                    obj.hSVPS.Geometry.ROIS{i}.curves{curve_idx}(:,2), ...
                                    '--', 'LineWidth', 2, 'Color', obj.hSVPS.Geometry.ROIS{i}.color);
                            end
                        end
                end
            end
            
            hold(obj.hAxis,'off');
        end
%-------------------------------------------------------------------------------   
        function redraw_overlay(obj)
            slice = obj.hSVPS.POI(obj.zOrien);

            delete(obj.hROIs);
            obj.hROIs = [];
            hold(obj.hAxis,'on');
            
            for i = 1:numel(obj.hSVPS.Geometry.ROIS)
                % skip if display == OFF; first if statement checks if
                % 'visible' field has been created yet
%                 fprintf('ROI #%.0f', i)
                if isfield(obj.hSVPS.Geometry.ROIS{i},'visible')==false
                    continue;
                end
                
                if obj.hSVPS.Geometry.ROIS{i}.visible == false
%                     fprintf(' skipped!\n', i)
                    continue;
                end
%                 fprintf(' analyzed!\n', i)
                
                testIdxList=obj.hSVPS.Geometry.ROIS{i}.ind;
                matSize=size(obj.hSVPS.Geometry.data);
                [x,y,z] = ind2sub(matSize, testIdxList);
                
                a=zeros(matSize);
                a(testIdxList)=1;
%                 orthoslice(a, [0,1], 3)
%                 orthoslice(obj.hSVPS.Geometry.data, [0,500], 3)
                
%                 fprintf('ROI #%.0f \n', disp(obj.zOrien))
                switch obj.zOrien
                    case 1
                        curve_indices = find(x == slice);
                        if ~isempty(curve_indices)
                            for curve_idx = curve_indices
                                canvas=zeros(matSize(2),matSize(3));
                                idx=sub2ind([matSize(2),matSize(3)], y(curve_indices), z(curve_indices));
                                canvas(idx)=1;
                                
%                                 orthoslice(obj.hSVPS.Geometry.data, [0,1])
                                
%                                 sum(canvas(:))
                                B = bwboundaries(canvas);
                                numContours=length(B);
                                for contourI=1:numContours
                                    B_I = B{contourI};
                                    clear C
                                    % up-down (+ high)
                                    yshift= obj.hSVPS.Geometry.start(2) - 1.0*obj.hSVPS.Geometry.voxel_size(2);
                                    zshift= obj.hSVPS.Geometry.start(3) - 1.0*obj.hSVPS.Geometry.voxel_size(3);

                                    C(:,1)= yshift + (B_I(:,1))*obj.hSVPS.Geometry.voxel_size(1);
                                    C(:,2)= zshift + (B_I(:,2))*obj.hSVPS.Geometry.voxel_size(3);
                                    obj.hROIs(end+1) = plot(obj.hAxis, ...
                                        C(:,2), C(:,1), ...
                                        '-', 'LineWidth', 2, 'Color', obj.hSVPS.Geometry.ROIS{i}.color);
                                end
                            end
                        end % end of IF

                    case 2
                        curve_indices = find(y == slice);
                        if ~isempty(curve_indices)
                            for curve_idx = curve_indices
                                canvas=zeros(matSize(1),matSize(3));
                                idx=sub2ind([matSize(1),matSize(3)], x(curve_indices), z(curve_indices));
                                canvas(idx)=1;
                                
%                                 sum(canvas(:))
                                B = bwboundaries(canvas);
                                numContours=length(B);
                                for contourI=1:numContours
                                    B_I = B{contourI};
                                    clear C
                                    % up-down (+ high)
                                    xshift= obj.hSVPS.Geometry.start(1) - 1.0*obj.hSVPS.Geometry.voxel_size(1);
                                    zshift= obj.hSVPS.Geometry.start(3) - 1.0*obj.hSVPS.Geometry.voxel_size(3);

                                    C(:,1)= xshift + (B_I(:,1))*obj.hSVPS.Geometry.voxel_size(1);
                                    C(:,2)= zshift + (B_I(:,2))*obj.hSVPS.Geometry.voxel_size(3);
                                    obj.hROIs(end+1) = plot(obj.hAxis, ...
                                        C(:,2), C(:,1), ...
                                        '-', 'LineWidth', 2, 'Color', obj.hSVPS.Geometry.ROIS{i}.color);
                                end
                            end
                        end % end of IF
                        
                    case 3
                        curve_indices = find(z == slice);
                        if ~isempty(curve_indices)
                            for curve_idx = curve_indices
                                canvas=zeros(matSize(1),matSize(2));
                                idx=sub2ind([matSize(1),matSize(2)], x(curve_indices), y(curve_indices));
                                canvas(idx)=1;
                                
%                                 sum(canvas(:))
                                B = bwboundaries(canvas);
                                numContours=length(B);
                                for contourI=1:numContours
                                    B_I = B{contourI};
                                    clear C
                                    % up-down (+ high)
                                    yshift= obj.hSVPS.Geometry.start(2) - 1.0*obj.hSVPS.Geometry.voxel_size(2);
                                    xshift= obj.hSVPS.Geometry.start(1) - 1.0*obj.hSVPS.Geometry.voxel_size(1);

                                    C(:,1)= yshift + (B_I(:,1))*obj.hSVPS.Geometry.voxel_size(1);
                                    C(:,2)= xshift + (B_I(:,2))*obj.hSVPS.Geometry.voxel_size(2);
                                    obj.hROIs(end+1) = plot(obj.hAxis, ...
                                        C(:,2), C(:,1), ...
                                        '-', 'LineWidth', 2, 'Color', obj.hSVPS.Geometry.ROIS{i}.color);
                                end
                            end
                        end % end of IF
                end
            end
            
            hold(obj.hAxis,'off');
        end
%-------------------------------------------------------------------------------
    end % methods
%===============================================================================
end
