www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cageview/+optimoutput/Actions.m

    classdef Actions < handle
    %Actions optimization output actions
    
    %  Copyright 2005-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.
    
    properties (SetAccess=private)
        %MessageService store for optimization output message service
        MessageService
        
        %SolutionSlice select solution slice
        SolutionSlice
        %ParetoSlice select Pareto slice
        ParetoSlice
        %WeightedObjectives select weighted objectives
        WeightedObjectives
        %SelectedSolution view all selected solutions
        SelectedSolution
        
        %IndexerActions action group for selecting indexing scheme
        %   (Solution, Pareto, WeightedObjectives, SelectedSolution)
        IndexerActions
        
        %EditTolerance edit constraint tolerance for display (1e-6)
        EditTolerance
        %InitializeSolution initialize selected solution for all runs
        InitializeSolution
        %SelectSolution select solution for current run and selected solution
        SelectSolution
        %SelectActions action group for selecting solution
        %   (InitializeSolution,SelectActions)
        SelectActions
        %EditWeights edit weights for WeightedObjectives view 
        EditWeights
        %ExportToDS export optimization results to dataset
        ExportToDS
        %FillTables fill table with optimization results
        FillTables
        %CreateSumOptimization create sum optimization initialized withpoint optimization results
        CreateSumOptimization
        %RetainOutput retain current solutions
        %  a new output node is created when optimization is rerun
        RetainOutput
    end
    
    properties(Access=private)
        %Listeners store
        Listeners
    end
    
    methods
        
        function obj = Actions(ms)
        %Actions constructor
        %   obj = cageview.optimoutput.Actions(ms)
        
        obj.MessageService = ms;
        
        %IndexerActions action group for selecting indexing scheme
        %   (Solution, Pareto, WeightedObjectives, SelectedSolution)
        AG = mbcgui.actions.ActionGroup('', '&Slice Direction');
        AG.MenuType = 'separate';
        
        obj.SolutionSlice = mbcgui.actions.ToggleAction(@obj.onSolutionSlice, ...
            '&Solution Slice', ...
            'Solution slice', ...
            cgrespath('optimsolution.bmp'));
        obj.ParetoSlice = mbcgui.actions.ToggleAction(@obj.onParetoSlice, ...
            '&Pareto Slice', ...
            'Pareto slice', ...
            cgrespath('optimpareto.bmp'));
        obj.WeightedObjectives = mbcgui.actions.ToggleAction(@obj.onWeightedObjectives, ...
            '&Weighted Objectives', ...
            'Weighted objective pareto slice', ...
            cgrespath('optimweightpareto.bmp'));
        obj.SelectedSolution = mbcgui.actions.ToggleAction(@obj.onSelectedSolution, ...
            'S&elected Solution', ...
            'Selected solution slice', ...
            cgrespath('optimbestsol.bmp'));
        AG.Actions = [obj.SolutionSlice obj.ParetoSlice obj.WeightedObjectives obj.SelectedSolution];
        % store action group
        obj.IndexerActions = AG;
        
        % edit constaint tolerance
        obj.EditTolerance = mbcgui.actions.StatefulAction(@obj.onEditTolerance,'Edit Constraint &Tolerance...',...
            '',[]);
        
        % select solution for multi-solution optimizations (multiobjective
        % and modal)
        AG = mbcgui.actions.ActionGroup('', '&Selected Solution');
        AG.MenuType = 'separatesubmenu';
        obj.InitializeSolution = mbcgui.actions.StatefulAction(@obj.onInitializeSolution,'&Initialize...',...
            '',[]);
        obj.SelectSolution = mbcgui.actions.StatefulAction(@obj.onSelectSolution,'&Select Current Solution',...
            'Select current solution',cgrespath('optimselbest.bmp'));
        AG.Actions = [obj.InitializeSolution obj.SelectSolution];
        obj.SelectActions = AG;
        
        %edit Pareto weights
        obj.EditWeights = mbcgui.actions.StatefulAction(@obj.onEditWeights,'&Edit Pareto Weights...',...
            'Edit pareto weights',cgrespath('optimeditweights.bmp'));
        % export results
        obj.ExportToDS = mbcgui.actions.StatefulAction(@obj.onExportToDS, 'E&xport to Data Set...',...
            'Export to data set',cgrespath('optimexportds.bmp'));
        obj.FillTables = mbcgui.actions.StatefulAction(@obj.onFillTables,'&Fill Tables...',...
            'Fill tables using optimal settings',cgrespath('optimfilltables.bmp'));        
        %create a sum optimization from point optimization results
        obj.CreateSumOptimization = mbcgui.actions.StatefulAction(@obj.onCreateSumOptimization,'&Create Sum Optimization',...
            '',cgrespath('Sigma.bmp'));      
        %retain output
        obj.RetainOutput = mbcgui.actions.StatefulAction(@obj.onRetainOutput,'&Retain Output',...
            '','');      
        
        ms = obj.MessageService;
        
        % Listener that updates enable status of best solution selectors
        obj.Listeners = [...
            event.listener(ms, 'ObjectChanged', @obj.onNodeChanged);...
            event.listener(ms, 'SelectedSolutionChanged', @obj.onCheckSelectedSolution);...
            event.listener(ms, 'ObjectChanged', @obj.onCheckSelectedSolution);...
            event.listener(ms, 'PreserveChanged', @obj.onCheckPreservedState);...
            event.listener(ms, 'ObjectChanged', @obj.onCheckPreservedState);...
            ];
        
        end
        
        function createViewMenu(obj,hViewMenu,MultiView)
        %create View menu
        %   createViewMenu(obj,hViewMenu,MultiView)
        %   includes menu for lower multiview
        createMenuItem(obj.IndexerActions,hViewMenu);
        MultiView.addViewMenuItems(hViewMenu);
        hm = createMenuItem(obj.EditTolerance,hViewMenu);
        hm.Separator = 'on';
        end
        
        function createSolutionMenu(obj,hSolutionMenu)
        %createSolutionMenu create solution menu
        
        %select solution and edit weights
        createMenuItem(obj.SelectActions,hSolutionMenu);
        createMenuItem(obj.EditWeights,hSolutionMenu);

        % export results and create sum
        hm=createMenuItem(obj.ExportToDS,hSolutionMenu);
        hm.Separator = 'on';
        createMenuItem(obj.FillTables,hSolutionMenu);
        createMenuItem(obj.CreateSumOptimization,hSolutionMenu);

        % retain output
        hm=createMenuItem(obj.RetainOutput,hSolutionMenu);
        hm.Separator = 'on';
        
        end
        
        function createToolbar(obj,hToolbar,MultiView)
        %createToolbar create optimization output toolbar
        %   includes toolbar items for lower multiview

        AG = mbcgui.actions.ActionGroup('', '&Slice Direction');
        AG.Actions = [obj.SolutionSlice obj.ParetoSlice obj.SelectedSolution obj.SelectSolution];

        createToolbutton(AG,hToolbar);

        % add view buttons
        btns = createToolbutton( MultiView.Actions.ChangeView,hToolbar);
        set(btns(1),'Separator','on');

        % export buttons
        tb = createToolbutton(obj.ExportToDS,hToolbar);
        tb.Separator = 'on';
        createToolbutton(obj.FillTables,hToolbar);
        
        end
        
        function createWorkflowItems(obj,hParent)
        AG = mbcgui.actions.ActionGroup('', 'Workflow');
        AG.Actions = [obj.FillTables,obj.CreateSumOptimization];
        createWorkflowItems(AG,hParent);
        end
        
        function OK = hasData(obj)
        %hasData messageservice has data
        ms = obj.MessageService;
        OK = ~isempty(ms) && ms.hasData;
        end
    end
    
    methods (Access=private)
        
        function onCheckSelectedSolution(obj,~,~)
        %onCheckSelectedSolution check action status selected solution 
        
        ms = obj.MessageService;
        hOut = ms.getOptimOutput;
        if getNumSolutions(hOut) == 1
            % single solution optimization - disable multisolution actions
            obj.SelectActions.Enabled = false;
        elseif hasSelectedSolution(hOut)
            % solution initialized
            obj.SelectActions.Enabled = true;
            obj.SelectSolution.Enabled = true;
        else
            % can't select a solution until solution is initialized
            obj.SelectActions.Enabled = true;
            obj.SelectSolution.Enabled = false;
        end
        end
        
        function onInitializeSolution(obj,~,~) 
        %onInitializeSolution initialize selected solution 
        %  select solution index for all runs
        ms = obj.MessageService;
        hOut = ms.getOptimOutput;
        [hOut, ok] = guiInitSelectedSolution(hOut);
        if ok
            ms.setOptimOutput(hOut, 'SelectedSolutionChanged');
        end
        end
        
        function onSelectSolution(obj,~,~)
        %onSelectSolution select solution
        
        ms = obj.MessageService;
        hOut = ms.getOptimOutput;
        if ms.hasFocusIndex
            hOut = setSelectedSolutionNumber(hOut, ms.getFocusRun, ms.getFocusSolution);
            ms.setOptimOutput(hOut, 'SelectedSolutionChanged');
        end

        end
        
        function onSolutionSlice(obj,~,~)
        %onSolutionSlice select solution slice
        %   toggle through different runs for current solution
        %   The solution index is fixed for multisolution optimizations
        
        if obj.hasData
            obj.MessageService.setCurrentSlice('solution');
        end
        end
        
        function onParetoSlice(obj,~,~)
        %onParetoSlice select Pareto slice
        %   toggle through Pareto solutions for current run
        if obj.hasData
            obj.MessageService.setCurrentSlice('pareto');
        end
        end        
        
        function onWeightedObjectives(obj,~,~)
        %onWeightedObjectives select weighted objectives view
        
        if obj.hasData
            obj.MessageService.setCurrentSlice('weightedsolution');
        end
        end
        
        function onSelectedSolution(obj,~,~)
        %onSelectedSolution display all selected solutions
        %  The Selected Solution for all runs is displayed
        
        if obj.hasData
            obj.MessageService.setCurrentSlice('selectedsolution');
        end
        end        

        function onEditWeights(obj,~,~)
        %onEditWeights edit weights for weighted objectives view
        ms = obj.MessageService;
        hOut = ms.getOptimOutput;
        [hOut, OK] = guiWeightsEditor(hOut);
        if OK
            ms.setOptimOutput(hOut, 'WeightsChanged');
        end

        end
        
        function onExportToDS(obj,~,~)
        %onExportToDS export results to a data set
        
        ms = obj.MessageService;
        
        % Get project and current output node
        pPROJ = ms.ProjectPointer;
        pOut = ms.OptimOutputPointer;
        
        % Get data set that is to be appended to
        obj = cgoptimdatasetfiller;
        [obj, setUpOK,ViewDataSet] = guiSetUp(obj, pOut, pPROJ);
        
        % Append optim results to the data set
        if setUpOK
            [success, statusmsg, datasetName] = fill(obj, pOut, pPROJ);
            % Add a status message
            if success
                if ~isempty(statusmsg)
                    uiwait(warndlg(statusmsg, 'Export to Data Set', 'modal'));
                end
                addTimedStatusMsg(cgbrowser,...
                    sprintf('Optimization results exported to %s', datasetName), 10);
                
                if ViewDataSet
                    % select the dataset
                    A = pPROJ.getConnections;
                    ind = find(A,'Name',datasetName);
                    gotonode(cgbrowser,A.pNode(ind));
                end
            else
                % unsuccessful export
                if isempty(statusmsg)
                    statusmsg = 'No data to export.';
                end
                uiwait(warndlg(statusmsg, 'Export to Data Set', 'modal'));
            end
        end
        
        end
        
        function onFillTables(obj,~,~)
        %onFillTables fill tables with optimization output
        ms = obj.MessageService;
        
        hOut = ms.getOptimOutput;
        pOut = address(hOut);
        pOutNode = ms.Pointer;
        % Get CAGE project
        pPROJ = ms.ProjectPointer;
        
        pOptimNode = ms.Pointer.Parent;
        pOptim = pOptimNode.getdata;
        
        % Choose tables and optimization results to fill them. Get the saved table
        % filler if it exists.
        otf = getTableFiller(hOut);
        if isempty(otf)
            otf = cgoptimtablefiller;
        end
        F = cgfillsetup.TableFiller(otf,pPROJ,pOptim, pOut );
        OK = F.wizard;
        
        
        if OK
            % do specified table filling with a waitbar
            DOWAITBAR = true;
            [fillstat, fillmsg] = F.doFill(DOWAITBAR);
            
            % Check to see if all the tables have been filled correctly. Inform the
            % user either way. This could also change the current view.
            summarizeFillStatus(F.Filler, fillstat, fillmsg, pPROJ);
            
            if ms.Pointer == pOutNode
                % if still at output node (the selected node could change in the table
                % fill process to a table or tradeoff)
                ms.setOptimOutput(pOut.info, 'ObjectPropertyChanged');
            end
            
        end
        
        end
        
        function onCreateSumOptimization(obj,~,~)
        %onCreateSumOptimization create a sum optimization from point optimization results
        
        ms = obj.MessageService;
        nd = ms.Pointer;
        OptNode = info(nd.Parent);
        SumNd = createSumOptimization(OptNode,nd);
        gotonode(cgbrowser,address(SumNd));
        
        end        
        
        function onRetainOutput(obj,~,~)
        %onRetainOutput retain current solution
        %  rerunning the optimization results in a new output node
        
        ms = obj.MessageService;
        pNode = ms.Pointer;
        pNode.setPreserved(true);
        
        % Refresh the node on the tree to change the icon
        cgb = cgbrowser;
        cgb.doDrawTree(pNode,'update');
        
        % Force UI update by pretending the output object has altered
        hOut = ms.getOptimOutput;
        ms.setOptimOutput(hOut, 'PreserveChanged');
        end

        function onEditTolerance(obj,~,~)
        %onEditTolerance edit constraint tolerance for display
        ms = obj.MessageService;
        hOut = ms.getOptimOutput;
        [hOut, OK] = guiEditConstraintTol(hOut);
        if OK
            ms.setOptimOutput(hOut, 'FeasibleToleranceChanged');
        end
        end
        
        function onCheckPreservedState(obj,~,~)
        %onCheckPreservedState check the RetainOutput state
        ms = obj.MessageService;
        % Can't "preserve" an already preserved node
        obj.RetainOutput.Enabled = ~isnull(ms.Pointer) && ~isPreserved(ms.Node);
        end
        
        function onNodeChanged(obj,~,~)
        %onNodeChanged MessageService NodeChanged event 
        ms = obj.MessageService;
        
        pPointOptim = getdata( info(Parent(ms.Node)) );
        Data = getinitialvaluedata(info(pPointOptim));
        DataSize = cellfun(@(x) size(x,2), Data);
        maxSize = max(DataSize);
        obj.CreateSumOptimization.Enabled = maxSize==1;
        end
        
    end
    
end