www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/cg_model_wizard.m
function varargout = cg_model_wizard(action, varargin) %CG_MODEL_WIZARD Model import/creation wizard % % CG_MODEL_WIZARD provides the cards and interface functions required by % xregwizard to display the model import wizard in cage % % [OK, OUT] = XREGWIZARD(FIGPARENT , TITLE, {@cg_model_wizard 'cardxxx'}, localdata); % Copyright 2000-2011 The MathWorks, Inc. and Ford Global Technologies, Inc. switch lower(action) case 'cardtwo' % select models to import [varargout{1:nargout}] = i_createCardTwo(varargin{:}); case 'cardthree' % signal assignment [varargout{1:nargout}] = i_createCardThree(varargin{:}); case 'cardfour' % enter formula for function model [varargout{1:nargout}] = i_createCardFour(varargin{:}); end %------------------------------------------------------------------------ % CARD TWO FUNCTIONS BELOW %------------------------------------------------------------------------ %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function layout = i_createCardTwo(fh, iFace, localData) % Have we been called to create the layout or simply update? if isa(fh, 'xregcontainer') layout = fh; layoutUD = get(layout, 'UserData'); else check = uicontrol('Parent', fh,... 'Callback', {@i_automatic, iFace},... 'Style', 'checkbox',... 'String', 'Automatically assign/create inputs', ... 'Value', 0,... 'Visible', 'off'); button = uicontrol('Parent', fh,... 'Callback', {@i_selectall, iFace},... 'Style', 'pushbutton',... 'String', 'Select All',... 'Visible', 'off'); txModels = uicontrol('Parent', fh,... 'Style', 'text',... 'String', 'Select models:',... 'Visible', 'off',... 'HorizontalAlignment', 'left'); list = mbcwidgets.Table1D( 'list', 'Parent', fh, 'SelectionMode', 'MultiRow' ); cols = {'Model Name', 'Inputs', 'Description'}; width = [100 270 190]; list.Peer.setColumnData( cols ); list.Peer.setColumnWidths( width ); layout = xreggridbaglayout(fh,... 'dimension', [7 2], ... 'rowsizes', [15 2 -1 10 5 25 5], ... 'colsizes', [65 -1], ... 'border', [7 0 7 7], ... 'gapx', 20, ... 'mergeblock', {[1 1] [1 2]}, ... 'mergeblock', {[3 3] [1 2]}, ... 'mergeblock', {[5 7] [1 1]}, ... 'elements', {txModels [] list [] [] button [], ... [] [] [] [] [] check [] }); layoutUD.autoCheck = check; layoutUD.txModels = txModels; layoutUD.ModelList = list; layoutUD.nextFcn = @i_cardTwoNext; layoutUD.finishFcn = @i_cardTwoFinish; end if nargin > 2 layoutUD.models = localData.models; layoutUD.modptr = localData.modptr; end feval(iFace.setFinishButton, 0); feval(iFace.setNextButton, 1); i_cardTwoUpdate(layoutUD, iFace); set(layout, 'UserData', layoutUD); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function i_cardTwoUpdate(layoutUD, ~) modelInfo = cell( 0, 3 ); % Set model information for i = 1:length(layoutUD.models) modelInfo{i,1} = getname(layoutUD.models{i}); Symbols = getsymbols(layoutUD.models{i}); varstr = sprintf( '%s, ', Symbols{:} ); modelInfo{i,2} = varstr(1:end-2); % This is the function string for cgfuncmodel, and the 'created by' info % for xregexportmodes. modelInfo{i,3} = description( layoutUD.models{i} ); end layoutUD.ModelList.Peer.setData( modelInfo ); layoutUD.ModelList.selectRows( 1 ); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function i_automatic(obj, ~, iFace) % when automatic wiring is checked flag = get(obj, 'Value'); if flag feval(iFace.setFinishButton, 1); feval(iFace.setNextButton, 0); else feval(iFace.setFinishButton, 0); feval(iFace.setNextButton, 1); end %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function i_selectall(~, ~, iFace) % select all models layoutUD = feval(iFace.getCardUserdata); layoutUD.ModelList.selectRows( 1:length(layoutUD.models) ); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function i_cardTwoFinish(layoutUD, iFace) %get the selected models indices = layoutUD.ModelList.getSelectedRows(); models = layoutUD.models(indices); layoutUD.CageModels = []; % Find existing models proj = get( cgbrowser, 'RootNode' ); modp = proj.getmodels(); modNames = pveceval( modp, @getname ); dd = get( cgbrowser, 'DataDictionary' ); for i = 1:length(models) M = models{i}; R = getranges(M); str = getname(M); if isempty(str) str = 'New_Model'; end %Now, we want to get the inputs sorted out. symbols = getsymbols(M); nf = length(symbols); Minput = null( xregpointer, 1, nf ); for j = 1:nf factorSymbol = symbols{j}; matchptr = dd.find(factorSymbol); if ~isempty(matchptr) %matches a variable in the dictionary, including aliases Minput(j) = matchptr; else index = find( strcmp( factorSymbol,modNames ) ); if ~isempty(index) %factor name matches a model Minput(j) = modp(index); else % nothing matched % and add a variable called factorSymbol Minput(j) = i_CreateNewVariable( dd, factorSymbol, R(:,j) ); end end end if ~isempty(layoutUD.modptr) modptr = layoutUD.modptr; %update the model inside the modexpr modptr.info = modptr.set('model',M); modptr.info = modptr.set('ptrlist' , Minput); else % when a new model is being created cagemod = cgmodexpr; cagemod = setname(cagemod , str); cagemod = set(cagemod , 'model' , M); cagemod = set(cagemod , 'ptrlist' , Minput); layoutUD.CageModels{i} = cagemod; end end outputUD.CageModels= layoutUD.CageModels; feval(iFace.setOutputData, outputUD); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function [nextCardID, localData] = i_cardTwoNext(layoutUD, ~) % get selected models indices = layoutUD.ModelList.getSelectedRows(); % check for no selections if (length(indices)==1 && indices==-1) || isempty(indices) uiwait(errordlg('You must select at least one model before continuing.', ... 'Model Selection Error', 'modal')); nextCardID = []; localData = []; return end models = layoutUD.models(indices); localData.models = models; localData.modptr = layoutUD.modptr; nextCardID = @i_createCardThree; %------------------------------------------------------------------------ % CARD THREE FUNCTIONS BELOW %------------------------------------------------------------------------ %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function layout = i_createCardThree(fh, iFace, localData) % Have we been called to create the layout or simply update? if isa(fh, 'xregcontainer') layout = fh; layoutUD = get(layout, 'UserData'); else % Create the card List = mbcwidgets.Table1D( 'list',.... 'Parent', fh,... 'SelectionMode', 'SingleRow',... 'SelectionChangedCallback', {@i_ModelInputSelectionChanged, iFace} ); List.Peer.setColumnData( {'Model Input','Assigned Input'} ); List.Peer.setColumnWidths( [120 120] ); selbutton= xregGui.iconuicontrol('parent',fh,... 'imageFile',cgrespath('leftarrow.bmp'),... 'transparentColor', [0 255 0],... 'ToolTip','Assign Input',... 'visible','off',... 'callback',{@i_select,iFace}); delbutton = xregGui.iconuicontrol('parent',fh,... 'imageFile',cgrespath('delete.bmp'),... 'transparentColor', [0 255 0],... 'ToolTip','Unassign Input',... 'visible','off',... 'callback',{@i_unselect,iFace}); titleText = uicontrol('Parent',fh,... 'Style','text',... 'Visible','off',... 'HorizontalAlignment','left',... 'String','Assign Cage items to use as the model inputs:'); % listbox with all variables and models namelist = cgtools.exprList(... 'Parent', fh, ... 'DisplayHeaderRow', true,... 'DisplayTypeColumn', false,... 'ItemHeaderText', 'Available Inputs' ); namelist.addListeners( handle.listener( namelist, 'SelectionChanged', {@i_SelectedCageItemChanged, iFace} ) ); layout = xreggridbaglayout( fh,... 'Dimension', [6, 3],... 'Rowsizes', [15 -1 25 10 25 -1],... 'Colsizes', [-1 25 -1],... 'gapx', 25,... 'gapy', 2,... 'border', [7 7 7 7],... 'Mergeblock', {[2 6], [1 1]},... 'Mergeblock', {[2 6], [3 3]},... 'Mergeblock', {[1 1], [1 3]},... 'Elements', {titleText, [], []; List, [], namelist; [], selbutton, []; [], [], []; [], delbutton, []; [], [], []} ); layoutUD.List = List; layoutUD.namelist = namelist; layoutUD.selbutton = selbutton; layoutUD.delbutton = delbutton; set(layout,'packstatus','on'); end if nargin >2 layoutUD.models = localData.models; layoutUD.modptr = localData.modptr; end % fill the card with information layoutUD = i_cardThreeUpdate(layoutUD, iFace); set(layout, 'UserData', layoutUD); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function layoutUD = i_cardThreeUpdate(layoutUD, iFace) % fill the rhs list layoutUD = i_InputList(layoutUD); % And then fill the lhs list if ~isempty(layoutUD.modptr) % We are rewiring an existing model - get everythng from the model. pExistingModel = layoutUD.modptr; inputPtrs = pExistingModel.getinputs(); Symbols = getsymbols( pExistingModel.get('model') ); else % We have a new model - need to do some 'guessing' of inputs. models = layoutUD.models; Symbols = cellfun( @getsymbols, models, 'UniformOutput', false ); Symbols = unique( vertcat( Symbols{:} ) ); pDD = get(cgbrowser, 'DataDictionary'); inputPtrs = null( xregpointer, length(Symbols), 1 ); for n = 1:length(Symbols) pExistingVariable = pDD.find( Symbols{n} ); if ~isempty( pExistingVariable ) inputPtrs(n) = pExistingVariable; end end end layoutUD.Symbols = Symbols; layoutUD.matchedInputs = inputPtrs; %Update the list based on these Symbols/inputPtrs i_updateList( layoutUD ); % Select stuff layoutUD.selectedIndex = 1; layoutUD.List.selectRows( 1 ); % Sync selections in each list i_SyncLists( layoutUD ); % Make sure the UnSelect button is correct given the left list selection iEnableUnSelectButton( layoutUD ); layoutUD.finishFcn = @i_cardThreeFinish; % enable the finish button, disable the next button feval(iFace.setNextButton, 'off'); feval(iFace.setFinishButton, 'on'); % -------------------------------------------------------- function i_updateList( layoutUD ) Symbols = layoutUD.Symbols; inputPtrs = layoutUD.matchedInputs; numSymbols = length(Symbols); listData= cell( numSymbols, 2 ); listIcons(1:numSymbols,1) = {''}; listData(:,1) = Symbols; hasMatch = isvalid( inputPtrs ); if any( hasMatch ) listData(hasMatch,2) = pveceval( inputPtrs(hasMatch), @getname ); listIcons(hasMatch) = pveceval( inputPtrs(hasMatch), @(e)cgrespath(iconfile(e)) ); end layoutUD.List.Peer.setData( listData ); layoutUD.List.Peer.setIconData( listIcons, 1); % -------------------------------------------------------- function i_SyncLists( layoutUD ) % Synchronize the selection in the right hand list based on the selection % in the left hand list. Also make sure the Select and unSelect buttons are % correctly enabled. % Get the matched Cage variable for the selected model input. pSelectedInput = layoutUD.matchedInputs( layoutUD.selectedIndex ); % if pSelectedInput is null then this input has nothing assigned. In this % case we won't update the right hand list. It is possible that the user % has selected the item they want on that list first, and removing that % selection is annoying. if ~isnull( pSelectedInput ) set( layoutUD.namelist, 'SelectedItems', pSelectedInput ); end % As we may have changed the selection in the right hand list we need to % correctly enable/disable the Select button. iEnableSelectButton( layoutUD ); % -------------------------------------------------------- function iEnableUnSelectButton( layoutUD ) % If the matched input is NULL then nothing is matched and we disable the % unselect button. pSelectedInput = layoutUD.matchedInputs( layoutUD.selectedIndex ); if isnull( pSelectedInput ) unselectButtonStatus = 'off'; else unselectButtonStatus = 'on'; end set( layoutUD.delbutton, 'Enable', unselectButtonStatus ); % -------------------------------------------------------- function iEnableSelectButton( layoutUD ) % We've selected no cage items in the rhs list - disable the 'Select' % button. if isempty( layoutUD.namelist.SelectedItems ) selectButtonStatus = 'off'; else selectButtonStatus = 'on'; end set( layoutUD.selbutton, 'Enable', selectButtonStatus ); % -------------------------------------------------------- % function i_InputList % -------------------------------------------------------- function layoutUD = i_InputList(layoutUD) %Set up a list of available inputs to the exportmodel proj = get(cgbrowser, 'RootNode'); pVariables = proj.getvars(); pModels = proj.getmodels(); if ~isempty( layoutUD.modptr ) % If we are wiring an existing model we cannot use that model, or models % that contain that model, as inputs to this model. allowedModels = @(m)~anymember( layoutUD.modptr, [address(m); getptrs(m)] ); pModels = pfilter( pModels, allowedModels ); end pInputs = [pVariables, pModels]; set( layoutUD.namelist, 'Items', pInputs ); if isempty( pInputs ) set(layoutUD.selbutton,'Enable', 'off'); end % -------------------------------------------------- % function i_select % -------------------------------------------------- function i_select(~, ~, iFace) layoutUD = feval(iFace.getCardUserdata); pInput = get( layoutUD.namelist, 'SelectedItems' ); layoutUD = i_SetSelection( layoutUD, pInput ); feval(iFace.setCardUserdata, layoutUD); % -------------------------------------------------- % function i_unselect % -------------------------------------------------- function i_unselect(~, ~, iFace) layoutUD = feval(iFace.getCardUserdata); layoutUD = i_SetSelection( layoutUD, xregpointer ); feval(iFace.setCardUserdata, layoutUD); %------------------------------------------------------------------------ function layoutUD = i_SetSelection( layoutUD, pInput ) % Get the current selection selectedIndex = layoutUD.selectedIndex; layoutUD.matchedInputs( selectedIndex ) = pInput; %Update the list based on new matchedPtrs i_updateList( layoutUD ); % Since we changed the selection (either changed or removed a match we need % to update the enabled status of the Unselect button. iEnableUnSelectButton( layoutUD ); % restore the selection layoutUD.List.selectRows( layoutUD.selectedIndex ); %------------------------------------------------------------------------ % Callbacks from the signal list %------------------------------------------------------------------------ function i_ModelInputSelectionChanged(~, evt, iFace) layoutUD = feval(iFace.getCardUserdata); layoutUD.selectedIndex = evt.data.SelectedDataRows; % Select the current matched item in the right-hand list i_SyncLists( layoutUD ) % Make sure the UnSelect button is correct given the left list selection iEnableUnSelectButton( layoutUD ); feval(iFace.setCardUserdata, layoutUD); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function i_SelectedCageItemChanged(~, ~, iFace) layoutUD = iFace.getCardUserdata(); % As we changed the selection in the right hand list we need to correctly % enable/disable the Select button. iEnableSelectButton( layoutUD ); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function i_cardThreeFinish(layoutUD, iFace) %get the selected models models = layoutUD.models; pDD = get( cgbrowser, 'DataDictionary'); % Initialize the output CageModels = {}; % A lookup table for the input variables we create. createdInputs = struct(); for n = 1:length( models ) M = models{n}; S = getsymbols( M ); R = getranges( M ); modelName = getname( M ); if isempty( modelName ) modelName = 'model'; end modelInputPtrs = null( xregpointer, 1, length(S) ); for factorIndex = 1:length( S ) factorSymbol = S{factorIndex}; ind = strcmp( layoutUD.Symbols, factorSymbol ); inputPtr = layoutUD.matchedInputs( ind ); if isnull( inputPtr ) % We have no matched input - if we already created a variable % for this symbol we will use that, otherwise we'll create a % new variable. if isfield( createdInputs, factorSymbol ) inputPtr = createdInputs.(factorSymbol); else inputPtr = i_CreateNewVariable( pDD, factorSymbol, R(:,factorIndex) ); createdInputs.(factorSymbol) = inputPtr; end end modelInputPtrs(factorIndex) = inputPtr; end if ~isempty(layoutUD.modptr) modptr = layoutUD.modptr; %update the model inside the modexpr modptr.info = modptr.set('model',M); modptr.info = modptr.set('ptrlist' , modelInputPtrs); else % when a new model is being created cagemod = cgmodexpr; cagemod = setname(cagemod, modelName); cagemod = set(cagemod, 'model' , M); cagemod = set(cagemod, 'ptrlist' , modelInputPtrs); CageModels{n} = cagemod; end end outputUD.CageModels= CageModels; feval(iFace.setOutputData, outputUD); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function layout = i_createCardFour(fh, iFace, localData) if isa(fh, 'xregcontainer') layout = fh; else txPrompt = uicontrol('Parent', fh,... 'Style', 'text',... 'HorizontalAlignment','left',... 'String', 'Enter formula for function model (e.g. ratio = x/y):',... 'Visible','off'); txEdFormula = uicontrol('Parent', fh,... 'Style', 'edit',... 'HorizontalAlignment','left',... 'BackgroundColor',[1 1 1],... 'Visible','off'); layout = xreggridbaglayout(fh,... 'dimension', [4 1],... 'rowsizes', [-1 15 20 -1],... 'gapy', 2, ... 'border', [30 0 30 0], ... 'elements', {[] txPrompt txEdFormula []}); layoutUD.txEdFormula = txEdFormula; layoutUD.nextFcn = @i_cardFourNext; if nargin > 2 layoutUD.models = localData.models; layoutUD.modptr = localData.modptr; if ~isempty(layoutUD.modptr) % if we are adjusting an existing function model rhs = get(layoutUD.models{1},'function'); name = getname(layoutUD.models{1}); set(layoutUD.txEdFormula, 'String', [name ' = ' rhs]); end else layoutUD.models = []; layoutUD.modptr = []; end set(layout, 'UserData', layoutUD); end feval(iFace.setFinishButton, 'off'); feval(iFace.setNextButton, 1); %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function [nextCardID, localData] = i_cardFourNext(layoutUD, iFace) [OK, layoutUD] = i_Parse(layoutUD, iFace); if OK localData.models = layoutUD.models; localData.modptr = layoutUD.modptr; nextCardID = @i_createCardTwo; else nextCardID = []; localData = []; end %------------------------------------------------------------------------ % %------------------------------------------------------------------------ function [ok, layoutUD]=i_Parse(layoutUD, iFace) ok = 0; string = get(layoutUD.txEdFormula,'String'); if isempty(string) uiwait( errordlg('You must enter a formula string.' , ... 'Function Model Error' , 'modal') ); return end eqindx = strfind(string,'='); % If there is no '=' sign then eqindx will be empty. if isempty(eqindx) uiwait( errordlg('Your formula should include an equals sign.' , ... 'Function Model Error' , 'modal') ); return end % split on the '=' name = string(1:eqindx-1); func = string(eqindx+1:end); model = cgfuncmodel; model = setname( model, name ); [model, ok, msg] = setfunction( model, func ); if ok layoutUD.models = {model}; feval(iFace.setCardUserdata, layoutUD); else uiwait( errordlg(msg , 'Function Model Error' , 'modal') ); end %------------------------------------------------------------------------ function newVal = i_CreateNewVariable( dd, name, range ) [dd.info, newVal] = add(dd.info, name); newVal.info = newVal.set('range', range(:).'); newVal.info = newVal.set('value', range(1) ); newVal.info = newVal.set('setpoint', mean(range) );