
%

%   Copyright 2012 The MathWorks, Inc.

classdef AsymmetricTest < coder.rtiostreamtest.Test
    %ASYMMETRICTEST Conducts the asymmetric test and/or draws 3D plot
    %   Takes the results from a ASYMMETRICCONDUCTOR and plots them on a 3D
    %   plot is production of a plot is explicitly enabled. It also makes
    %   sure that the data that is being passed to the profiler will not
    %   overflow devices buffer. It also conducts an incoming (target to
    %   PC) and outgoing (PC to target) profiling.
    %
    %   Parameters:
    %
    %       produce_plot -
    %           Whether or not to produce a 3D plot. If you want to produce
    %           a 3D plot make sure you have a good number of pcChunks and
    %           targChunks specified as input parameters, otherwise the
    %           plot will not have a good resolution.
    %           Note: ASYMMETRICCONDUCTOR also uses this parameter. If plot
    %           production is disable (by default it is), symmetric
    %           pcChunk/targChunks parts would be ignored, and the total
    %           data transmitted would be smaller than if a plot was to be
    %           produced.
    
    % Available parameters defined here
    properties (Constant)
        param_producePlot = 'produce_plot';
        param_skip        = 'skip';
        
        % The default parameter is in case the user doesn't specify
        % pcChunks and targChunks
        default_parameters = {'pcChunks', [64 128], 'targChunks', [64 128]}
        
        % Plot production is disabled by default (if not specifically
        % enabled by the user via the input parameters)
        default_producePlot = false;
    end
    
    properties (GetAccess = 'protected', SetAccess = 'protected')
        parameters = coder.rtiostreamtest.AsymmetricTest.default_parameters;
    end
    
    methods
        
        function this = AsymmetricTest(parameters)
            this = this@coder.rtiostreamtest.Test(coder.rtiostreamtest.Test.message('TitleAsymmetricTest'));
            this.skip = coder.rtiostreamtest.Test.getSetting(parameters, coder.rtiostreamtest.AsymmetricTest.param_skip, this.skip);
            if nargin == 1
                % If user overrides any of the default parameters, take it
                % into account
                this.parameters = coder.rtiostreamtest.Test.setSettings( ...
                    this.parameters, parameters);
            end
        end
        
        function runTest(this, connection, parameters)
            
            % Initialize the progress bar
            this.resetProgress();
            this.progress(0);
            
            % Merge the parameters that are being passed to this method
            new_parameters = coder.rtiostreamtest.Test.setSettings(this.parameters, parameters);
            producePlot = coder.rtiostreamtest.Test.getSetting(new_parameters, this.param_producePlot, this.default_producePlot);
                        
            % Initialize
            outgoing = coder.rtiostreamtest.AsymmetricConductor( ...
                coder.rtiostreamtest.AverageTest( ...
                coder.rtiostreamtest.BandwidthOutgoingTest() ...
                ) ...
                );
            % Perform test
            [X, Y, Z] = outgoing.runTest(connection, new_parameters);
            
            if producePlot
                figure
                
                % Plot
                S1 = subplot(1,2,1,'replace');
                surf (X, Y, Z, 'EdgeColor','none');
                
                alpha(0.95);
                legend( coder.rtiostreamtest.Test.message('PlotAsymmTitleOutgoing') );
                xlabel( coder.rtiostreamtest.Test.message('PlotAsymmPCchunksOutgoing') );
                ylabel( coder.rtiostreamtest.Test.message('PlotAsymmTargChunksOutgoing') );
                zlabel( coder.rtiostreamtest.Test.message('PlotAsymmBandwidthOutgoing') );
                axis vis3d;
                hold on;
                zHandle = zlim;
            end
            
            % Set progress to 50%
            this.progress(0.5);
            
            % Initialize
            incoming = coder.rtiostreamtest.AsymmetricConductor( ...
                coder.rtiostreamtest.AverageTest( ...
                coder.rtiostreamtest.BandwidthIncomingTest() ...
                ) ...
                );
            
            % Perform test
            [X, Y, Z] = incoming.runTest(connection, new_parameters);
            
            if producePlot
                % Plot
                S2 = subplot(1,2,2,'replace');
                surf (X, Y, Z, 'EdgeColor','none');
                alpha(0.95);
                legend( coder.rtiostreamtest.Test.message('PlotAsymmTitleIncoming') );
                xlabel( coder.rtiostreamtest.Test.message('PlotAsymmPCchunksIncoming') );
                ylabel( coder.rtiostreamtest.Test.message('PlotAsymmTargChunksIncoming') );
                zlabel( coder.rtiostreamtest.Test.message('PlotAsymmBandwidthIncoming') );
                axis vis3d;
                hold on;
                zlim(zHandle)
                
                % Link both plots
                hlink = linkprop([S1 S2],{'CameraPosition','CameraUpVector'});
                key = 'graphics_linkprop';
                
                setappdata(S1,key,hlink);
                
                drawnow
            end
            
            % Set progress to 100%
            this.progress('done');
            
        end
        
    end
    
end

