www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+mbcmodelview/+testplan/Actions.m
classdef Actions < handle %mbcmodelview.testplan.Actions test plan actions % Copyright 2015-2016 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (SetAccess=private) %MessageService test plan message service MessageService end properties(SetAccess=private) %EditModel edit model of currently selected stage EditModel %EditInputs edit inputs of currently selected stage EditInputs %EditDesign edit design of currently selected stage % The outer stage design is edited if no stage is selected EditDesign %NewResponse create new response model % Data is selected if no data is set up for test plan NewResponse %ViewDesign view data design of currently selected stage ViewDesign %ViewModel view model design of currently selected stage ViewModel %SummaryStats define summary statistics for outer stage SummaryStats %FitModels select new data and fit response models FitModels %EditData edit test plan data EditData %EditBoundary edit boundary models EditBoundary %ValidationData select validation data for test plan ValidationData %MakeTemplate make test plan template MakeTemplate %ExportPointByPoint export point-by-point models % Create optimizations, tradeoff, data sets ExportPointByPoint %Export2Simulink export response models to Simulink Export2Simulink %Export2CAGE export response models to CAGE % CAGE is openned if necessary Export2CAGE end properties (Access=private) %Listeners storage for listeners Listeners end methods function obj = Actions(MessageService) %Actions constructor obj.MessageService = MessageService; % input setup obj.EditInputs = mbcgui.actions.StatefulAction(@obj.onEditInputs, ... 'Edit &Inputs...', 'Edit inputs', []); % DoE actions obj.EditDesign = mbcgui.actions.StatefulAction(@obj.onEditDesign, ... 'Design &Experiment...', 'Design experiment', xregrespath('doe.bmp')); obj.ViewDesign = mbcgui.actions.StatefulAction(@obj.onViewDesign, ... 'View Design...', 'View design', xregrespath('doe.bmp')); % model setup actions obj.EditModel = mbcgui.actions.StatefulAction(@obj.onEditModel, ... 'Edit &Model...', 'Edit model', []); obj.ViewModel = mbcgui.actions.StatefulAction(@obj.onViewModel, ... 'View Model...', 'View model', []); obj.SummaryStats = mbcgui.actions.StatefulAction(@obj.onSummaryStats, ... '&Summary Statistics...', 'Summary statistics', []); % actions requiring data obj.NewResponse = mbcgui.actions.StatefulAction(@obj.onNewResponse, ... 'New &Response...', 'New response model', []); obj.FitModels = mbcgui.actions.StatefulAction(@obj.onFitModels, ... '&Fit Models...', 'Fit models', xregrespath('viewPlot.bmp')); obj.EditData = mbcgui.actions.StatefulAction(@obj.onEditData, ... 'Edit &Data...', 'Edit data', xregrespath('data.bmp')); obj.EditBoundary = mbcgui.actions.StatefulAction(@obj.onEditBoundary, ... 'Edit &Boundary...', 'Edit boundary models', xregrespath('bdryEdit.bmp')); obj.ValidationData = mbcgui.actions.StatefulAction(@obj.onValidationData, ... '&Validation Data...', 'Assign validation data', []); % export functions obj.ExportPointByPoint = mbcgui.actions.StatefulAction(@obj.onExportPointByPoint, ... 'E&xport Point-by-point Models...', 'Export point-by-point models', []); obj.Export2Simulink = mbcgui.actions.StatefulAction(@obj.onExport2Simulink, ... 'Export to &Simulink...', 'Export to Simulink', xregrespath('simulink_app_16.bmp')); obj.Export2CAGE = mbcgui.actions.StatefulAction(@obj.onExport2CAGE, ... 'Generate &Calibration...', 'Generate calibration', cgrespath('cage.bmp')); obj.Export2CAGE.TransparentColor = [255 0 255]; obj.MakeTemplate = mbcgui.actions.StatefulAction(@obj.onMakeTemplate, ... 'Make &Template', 'Make template', xregrespath('tptemplate.bmp')); obj.Listeners = event.listener(obj.MessageService,'NodeUpdated',@obj.onNodeUpdated); end % Actions function createMenus(obj,hParents,~) %createTestplanMenu create test plan and view menu for model browser createTestplanMenu(obj,hParents(1)) createViewMenu(obj,hParents(2)) end % createMenus function createTestplanMenu(obj,hParent) %createTestplanMenu create test plan menu for model browser AG = mbcgui.actions.ActionGroup([],'Set up test plan'); AG.Actions = [obj.EditInputs obj.EditModel obj.EditDesign obj.SummaryStats]; AG.MenuType = 'separate'; hMenu = createMenuItem(AG,hParent); hMenu(2).Accelerator = 'M'; % FitModels, Edt data, boundary and Validation data AG.Actions = [obj.FitModels,obj.EditData,obj.EditBoundary,obj.ValidationData]; createMenuItem(AG,hParent); AG.Actions = [obj.MakeTemplate,obj.ExportPointByPoint]; createMenuItem(AG,hParent); end % createTestplanMenu function createViewMenu(obj,hParent) %createViewMenu create test plan view menu for model browser AG = mbcgui.actions.ActionGroup([],'Set up test plan'); AG.Actions = [obj.ViewModel obj.ViewDesign]; createMenuItem(AG,hParent); end % createViewMenu function createToolbar(obj,hParent) %createToolbar create test plan toolbar createToolbutton(obj.EditDesign,hParent); AG = mbcgui.actions.ActionGroup([],'Set up test plan'); AG.Actions = [obj.FitModels,obj.EditData,obj.EditBoundary]; tb = createToolbutton(AG,hParent); tb(1).Separator = 'on'; AG.Actions = [obj.Export2Simulink,obj.Export2CAGE]; tb = createToolbutton(AG,hParent); tb(1).Separator = 'on'; tb = createToolbutton(obj.MakeTemplate,hParent); tb.Separator = 'on'; end % createToolbar function createWorkflowItems(obj,hWorkflow) %createWorkflowItems create workflow items in workflow panel AG = mbcgui.actions.ActionGroup([],'Workflow'); % could have New Model as well AG.Actions = obj.EditDesign; AG.MenuType = 'separate'; wf = createWorkflowItems(AG,hWorkflow); wf.Separator = 'on'; AG.Actions = obj.FitModels; wf = createWorkflowItems(AG,hWorkflow); wf.Separator = 'on'; AG.Actions = [obj.Export2Simulink,obj.Export2CAGE]; createWorkflowItems(AG,hWorkflow); end % createWorkflowItems function enable(obj) %enable enable actions ms = obj.MessageService; T = ms.Testplan; if ms.NumStages>1 % two-stage or point-by-point Stage= ms.CurrentStage; IsPointByPoint = ms.IsPointByPoint; if strcmp(ms.SelectionType,'model') % a model is selected obj.EditInputs.Enabled = false; obj.EditModel.Enabled = true; obj.SummaryStats.Enabled = true; obj.ViewModel.Enabled = true; if Stage==1 % if we are in the first stage of a 2 stage (local) we can't have % Summary Stats obj.SummaryStats.Enabled = false; elseif Stage>1 && IsPointByPoint % disable model menus for operating point models obj.EditModel.Enabled = false; obj.ViewModel.Enabled = false; obj.SummaryStats.Enabled = false; end else % a port is selected obj.EditModel.Enabled = false; obj.SummaryStats.Enabled = false; obj.ViewModel.Enabled = false; % Input port selected obj.EditInputs.Enabled = strcmp(ms.SelectionType,'inputs'); end else % one-stage test plan % can always edit inputs and model obj.EditModel.Enabled = true; obj.EditInputs.Enabled = true; obj.ViewModel.Enabled = true; obj.SummaryStats.Enabled = true; end % require data to use ValidationData, Boundary and View Design obj.ValidationData.Enabled = IsMatched(T); obj.EditBoundary.Enabled = IsMatched(T); obj.ViewDesign.Enabled = IsMatched(T); obj.ExportPointByPoint.Enabled = ms.NumStages==2 && nfactors(getModel(designdev(T))) ==2; end % enable end % public methods methods (Access=private) function onNodeUpdated(obj,~,~) %onNodeUpdated MessageService.NodeUpdated event handling enable(obj) end % onNodeUpdated function onEditModel(obj,~,~) %onEditModel edit model definition ms = obj.MessageService; if editing(ms) xregerror('Error','The model cannot be setup while the design editor or the data selection figure is open'); return end d = ms.DesignDev; m = getModel(d); [m,OK]= gui_ModelSetup(m); if OK ms.DesignDev = setmodel(d,m); % update test plan views update(ms); end end % onEditModel function onEditInputs(obj,~,~) %onEditInputs edit test plan inputs ms = obj.MessageService; ReadOnly= IsMatched(ms.Testplan) || editing(ms); if ms.NumStages>1 % dialog title for two-stage or point-by-point inputs Title= sprintf('%s Input Factor Setup',ms.StageName); else % dialog title for one-stage inputs Title= 'Input Factor Setup'; end Inputs = getInputs(ms.Testplan); done= false; while ~done [Inputs{ms.CurrentStage},OK] = gui_InputSetup(Inputs{ms.CurrentStage},'figure',~ReadOnly,Title); if OK AllInputs = cat(1,Inputs{:}); if OK && length( unique(getList(AllInputs,'Symbol')) ) ~= length(AllInputs) % check for unique symbols across all stages h= errordlg('Duplicate symbols in two-stage model','Input Error','modal'); uiwait(h); done= false; else done= true; end else done= true; end end if OK % update test plan inputs setInputs(ms.Testplan,Inputs); change(ms); end end % onEditInputs function onEditDesign(obj,~,~) %onEditDesign edit design ms = obj.MessageService; pTP= ms.Pointer; dStage= ms.DesignDev; if editing(ms,'data') xregerror('Error','The design editor cannot be used while the data selection figure is open'); return end initialTree = dStage.DesignTree; if isscalar(initialTree.designs) % create initial design and select it initialTree.designs{2} = initialTree.designs{1}; initialTree.parents(2) = 1; initialTree.CurrentIndex = 2; elseif ~isfield(initialTree,'CurrentIndex') % select last design by default initialTree.CurrentIndex = length(initialTree.designs); end designStage = ms.CurrentStage; if ms.NumStages>1 title = sprintf('Design Editor - [%s (%s)]',name(ms.Testplan),ms.StageName); else title = sprintf('Design Editor - [%s]',name(ms.Testplan)); end doeEditor = xregdesgui.Editor.create('Locked',true,... 'Title',title,... 'TreeStruct',initialTree,... 'CurrentStage',designStage); % create a design editor ms.EditMode = 'DoE'; % setup close listener doeEditor.UserData = event.listener(doeEditor,'Close',@closeDoE); registerSubFigure(ms,doeEditor.Figure); function closeDoE(doeEditor,evt) %closeEditor close DoE editor % ask user if they want to save their changes buttonName = questdlg('Do you want to save the changes you made to your design?', ... 'Keep changes','Yes','No','Cancel','Yes'); switch buttonName case 'Yes' % update DoE in test plan % grab a copy of the design tree dtree=doeEditor.TreeStruct; dAllStages = pTP.designdev; dStage = dAllStages(designStage); OldTree= dStage.DesignTree; OldDes= factorsettings(getdesign(dStage)); NewDes= factorsettings(dtree.designs{dtree.chosen}); if OldTree.chosen ~= dtree.chosen || size(OldDes,1)~=size(NewDes,1) || any(OldDes(:)~=NewDes(:)) % make best design model the default m = model(dtree.designs{dtree.chosen}); dtree.designs{1}= model(dtree.designs{1},m); end % update designdev in test plan dStage.DesignTree= dtree; dAllStages(designStage) = dStage; pTP.designdev(dAllStages); % clear edit mode and listeners ms.EditMode = ''; doeEditor.UserData = []; case 'No' % clear edit mode and listeners ms.EditMode = ''; doeEditor.UserData = []; case 'Cancel' % cancel close actions evt.CancelClose = true; end end % closeDoE end % onEditDesign function onNewResponse(obj,~,~) %#ok<INUSD> %onNewResponse create new response NewNode(MBrowser); end % onNewResponse function onViewDesign(obj,~,~) %onViewDesign view design ms = obj.MessageService; T = ms.Testplan; d = ms.DesignDev; dtree= d.DesignTree; if dtree.chosen if ms.CurrentStage < ms.NumStages % local designs % get the data X= getdata(T,'X',0); X=X{ms.CurrentStage}; des= dtree.designs{dtree.chosen}; m= model(des); dtree.designs= dtree.designs(1); tn= testnum(X); for i= 1:size(X,3) % create one design per operating point des= reinit(des,code(m,X{i})); des= name(des,sprintf('Test %2d',tn(i))); dtree.designs=[dtree.designs,{des}]; end dtree.parents=[0,ones(1,size(X,3))]; else % one-stage or global designs X= getdata(T,'X',0); if iscell(X) X=X{end}; end des= dtree.designs{dtree.chosen}; m = model(des); des = reinit(des,code(m,double(X))); des = name(des,'Selected Data'); dtree.designs=[dtree.designs(1),{des}]; dtree.parents= [0,1]; end % root node selected as best dtree.chosen = 1; % select the first design in the tree dtree.CurrentIndex = 2; designStage = ms.CurrentStage; if ms.NumStages>1 title = sprintf('Design Editor - [%s (%s)]',name(T),ms.StageName); else title = sprintf('Design Editor - [%s]',name(T)); end doeEditor = xregdesgui.Editor.create('Locked',true,... 'Title',title,... 'TreeStruct',dtree,... 'CurrentStage',designStage); % create a design editor ms.EditMode = 'DoE'; doeEditor.UserData = event.listener(doeEditor,'Close',@closeDoE); hDOE=doeEditor.Figure; registerSubFigure(ms,hDOE); ms.EditMode = 'DoE'; end function closeDoE(~,~) %closeDoE close DoE editor % clear edit mode and listeners ms.EditMode = ''; doeEditor.UserData = []; end % closeDoE end % onViewDesign function onViewModel(obj,~,~) %onViewModel view default model definition ms = obj.MessageService; d = ms.DesignDev; hFig= view(getModel(d)); if numstages(ms.Testplan)>1 set(hFig,'Name',['Default ' ms.StageName ' Model']); else set(hFig,'Name','Default Model'); end registerSubFigure(ms,hFig); end % onViewModel function onSummaryStats(obj,~,~) %onSummaryStats edit default summary statistics ms = obj.MessageService; d = ms.DesignDev; m= getModel(d); % setup gui [m,OK]= gui_SummaryStats(m); if OK d= setmodel(d,m); ms.DesignDev = d; end end % onSummaryStats function onFitModels(obj,~,~) %onFitModels fit models for test plan ms = obj.MessageService; if ~editing(ms) % can't define new data if data or design editor is open T = ms.Testplan; if IsMatched(T) resp= questdlg('Fitting models to new data will change all the test plan response models. Do you want to continue?',... 'Fit Models','Yes','No','No'); if ~strcmp(resp,'Yes') return end end % close other figures OK = ms.closeSubFigures; if ~OK return end busy(ms,'Fitting models to data') D= designdev(T); [des,index]= ActualDesign(D); if strcmp(name(des),'Actual Design') % delete actual design T = designdev(T,DeleteDesign(D,index)); xregpointer(T); end if numChildren(T)>0 % store current models in T.Responses T.Responses = children(T,@model); xregpointer(T); end % call data wizard datawizard(T); hData = xregdatagui.Editor.find('dataEditor'); if ~isempty(hData) && strcmp(hData.Visible,'on') ms.EditMode = 'data'; hList = addlistener(hData,'PostClose',@closeDataEditor); end idle(ms); else xregerror('Error', ... ['Fit models cannot be selected while the design editor ' ... 'or the data editor is open']); end function closeDataEditor(~,~) ms.EditMode = ''; % delete the listener delete(hList); end % closeDataEditor end % onFitModels function onValidationData(obj,~,~) %onValidationData define validation data for test plan ms = obj.MessageService; p = ms.Pointer; if ~editing(ms) % can't define validation data if data or design editor is open [ssf,ok] = ValDataWizard(p,'Select Data for Validation'); if ok % update validation data valdata(ms.Testplan,ssf); % force a complete redraw ms.change end else xregerror('Error', ... ['Valdation data cannot be selected while the design editor ' ... 'or the data selection figure is open']); end end % onValidationDatas function onExportPointByPoint(obj,~,~) %onExportPointByPoint export if canExport(obj) ms = obj.MessageService; if get(cgbrowser,'GUIExists') %define multimodel export through dialog [CreateItems,ok] = guiMultiModel(ms.Testplan); else % will export to legacy file for multimodel tradeoff CreateItems = []; ok = true; end if ok mv_busy('Building point-by-point models...') drawnow; exportMultiModels(ms.Testplan,CreateItems); ms.update; end end end % onExportPointByPoint function onExport2Simulink(obj,~,~) %onExport2Simulink export to Simulink if canExport(obj) ms = obj.MessageService; % Check to see if we have asked to export a validated model if ~any(hasBestExportModel(ms.Testplan)) errordlg('You must validate the model before exporting','Error','modal'); else xreg_ExportTool(ms.Pointer); end end end % onExport2Simulink function OK = canExport(obj) T = obj.MessageService.Testplan; msg = ''; if numChildren(T)==0 msg = 'Your test plan has no response models. Fit models to data.'; elseif ~all(hasBestExportModel(T)) if strcmpi(type(T),'two-stage') msg = 'Create two-stage models for each response.'; else msg = 'Select best models for each response.'; end msg = sprintf('Your response models are not ready to export. %s',msg); end OK = isempty(msg); if ~OK errordlg( msg,'Export','modal'); end end function onExport2CAGE(obj,~,~) %onExport2CAGE export models to CAGE if canExport(obj) ms = obj.MessageService; mdls = getBestExportModel(ms.Testplan); if ~isempty(mdls) % open CAGE and export dialog cage; EXMdialog(ms.Testplan,mdls,get(MBrowser,'Figure')); end end end % onExport2CAGE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function onEditData(obj,~, ~) %onEditData edit test plan data ms = obj.MessageService; if ~editing(ms,'DoE') T= ms.Testplan; busy(ms) dataEditorExists = false; if editing(ms,'data') % bring data editor to front hData = findall(0,'Tag','dataEditor'); figure(hData); dataEditorExists = true; elseif ~IsMatched(T) % select initial data using wizard datawizard(T); change(ms); else % open data editor OldTP = T; pData = DataLinkPtr(T); oldTSSF = info(pData); % store current models in T.Responses T = setResponseModels(T); xregpointer(T); editData(ms, pData,OldTP,oldTSSF,false); end hData = mbcgui.Application.find('dataEditor'); if ~isempty(hData) && strcmp(hData.Visible,'on') && ~dataEditorExists % add listener to close data editor ms.EditMode = 'data'; hList = addlistener(hData,'PostClose',@closeFigure); end idle(ms); else xregerror('Error','Data cannot be selected while the design editor is open'); end function closeFigure(~,~) %closeFigure clear EditMode ms.EditMode = ''; % delete the listener delete(hList); end % closeFigure end % onEditData %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function onMakeTemplate(obj,~,~) %onMakeTemplate make test plan template ms = obj.MessageService; TemplateDialog(ms.Testplan); end % onMakeTemplate %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function onEditBoundary(obj,~,~) %onEditBoundary edit boundary models in boundary editor ms = obj.MessageService; pTP = ms.Pointer; busy(ms); broot = dataobject( boundarytree(ms.Testplan) ); hBdryEditor = xregbdrygui.Editor.create('Root',broot ); hBdryFigure = hBdryEditor.Figure; registerSubFigure( ms, hBdryFigure); % set up boundary editor close function hBdryEditor.UserData = [event.listener(hBdryEditor,'PostClose' ,@closeBdryEditor) event.listener(ms,'NodeUpdated' ,@updateBoundaryEditor)]; IsOpen = true; idle(ms); function closeBdryEditor(~,~) % make sure that the test plan is updated % prevent the boundary editor from being updated during close IsOpen = false; if ms.Pointer == pTP % update current model browser view if you are still on the same node change(ms); end % delete the listener hBdryFigure.UserData = []; end function updateBoundaryEditor(~,~) %updateBoundaryEditor update the boundary editor when the test %plan is updated if IsOpen && ms.Pointer == pTP % get latest boundary tree broot = dataobject( boundarytree(ms.Testplan) ); hBdryEditor.Root = broot; end end % updateBoundaryEditor end % onEditBoundary end end