www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/mv_ValidationTool.m
function varargout= mv_ValidationTool(Action,varargin) %MV_VALIDATIONTOOL Base model selection GUI tool for Model-Based Calibration Toolbox % % This function must be extended before use % see Validate_OneStage, % Validate_Local, % Validate_TwoStage, % Validate_mle % Validate_Indpt % for examples of usage. % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. if isa(Action,'char') switch lower(Action) case 'create' % create GUI [varargout{1:2}] = i_Create(varargin{:}); case 'getviewparent' % Get the handle to the parent panel for views varargout{1} = i_GetViewPanel(varargin{:}); case 'view' % changes validation view (e.g. from sweep plots to Dial-Up) i_ChangeView(varargin{:}); case 'resize' case 'add' % add views to validation tool i_AddViews(varargin{:}); case 'statstable' % creates stats table i_StatsTable(varargin{:}); case 'set' % set view userdata i_SetView(varargin{:}); case 'get' % get view user data [varargout{1:nargout}]= i_GetView(varargin{:}); case 'close' % close figure i_Close; case 'print' i_Print case 'select' i_Select(varargin{:}); case 'selectbest' % select best model i_SelectBest(varargin{:}); case 'selectall' i_SelectAll(varargin{:}); case 'attachlayout' % attach a layout to a card i_attachLayout(varargin{:}) case 'setmessage' i_setsbarstring(varargin{:}); case 'setwaitbar' i_setwaitbar(varargin{:}); case 'setcreatemessage' i_setcreatemessage(varargin{1}); case 'updatemodels' i_UpdateModels(varargin{:}) case 'updateview' i_UpdateView(varargin{:}); case 'updateranges' iUpdateRanges(varargin{:}) end end %---------------------------------------------------- % SUBFUNCTION I_CREATE %---------------------------------------------------- function [hFig, hViewPanel] = i_Create(Vfile,p,Models,ParFig,NumPages) % now creates a figure with a gridLayout inside ([3 1] = main pane, butons, status bar) % main pane is a split layout for Cards (top) and ListView (btm) % check for other open validation tools and close them validationguis=findobj(allchild(0),'flat','Tag','ValidationTool'); if ~isempty(validationguis) figure(validationguis(1)); resp= questdlg('Another validation tool is already open. Do you want to close this figure?',... 'Validation','Yes','No','No'); if strcmp(resp,'Yes') delete(validationguis(1)); else hFig=[]; hViewPanel=[]; return end end % put title on window name= ['Model Selection for ',p.fullname]; hFig = xregfigure('Units','pixels',... 'IntegerHandle','off',... 'HandleVisibility','callback',... 'NumberTitle','off',... 'Name',name,... 'MenuBar','none',... 'Color',get(0,'DefaultUicontrolBackgroundColor'),... 'DefaultAxesFontSize',8,... 'PaperPositionMode','Auto',... 'PaperOrientation','landscape',... 'CloseRequestFcn','',... 'Tag','ValidationTool',... 'Visible','off',... 'RendererMode','manual'); xregpersistfigpos(hFig,'defaultpos',[257 49 1024 904]); xregmoveonscreen(hFig); fPos=get(hFig,'Position'); % menus for the figure hM=xregmenutool('create',hFig,... 'Label',{'&File'},'position',1); xregmenutool('create',hM,... 'Label',{'&Print','&Close'},... 'CallBack',{{@i_Print,hFig},@(h,e) close(hFig)},... 'Tag',{'print','close'},... 'Accelerator',{'P','W'}); hV=xregmenutool('create',hFig,... 'Label',{'&View'},'position',2); % register this figure for the "window" menu on MBRowser xregwinlist(hFig); % Create a default help menu mv_helpmenu(hFig); % Create empty toolbar tbPanel = mbcgui.container.layoutpanel(... 'Parent', hFig, ... 'BorderType', 'beveledin'); ud.hToolbar=xregGui.uitoolbar(tbPanel,'ResourceLocation', xregrespath); set(tbPanel, 'LayoutComponent', ud.hToolbar); % buttons for bottom of figure Strings= {'Assign Best', 'Select All'}; CallBacks= {'''SelectBest''', '''SelectAll'''}; for i=1:length(Strings) ud.Btns(i)= uicontrol('Parent',hFig,... 'Style','push',... 'Callback',[mfilename,'(',CallBacks{i},')'],... 'String',Strings{i}); end if length(Models)==1, set(ud.Btns(1:2),'Enable','off'); end; % log scaling text ud.scaleText = uicontrol('Parent',hFig,... 'HorizontalAlignment','right',... 'Style','text',... 'Enable','inactive'); %----------------Create the ListView---------------% lvPanel = mbcgui.container.layoutpanel(... 'Parent', hFig, ... 'Tag','lvPanel',... 'BorderType', 'beveledin'); % listview title (uicontrol text) [listViewTextPanel, listViewText] = mbcgui.container.createTextPanel(... 'Parent', lvPanel, ... 'BorderType', 'beveledout'); set(listViewText, ... 'FontSize',12,... 'ForegroundColor',[.4 .2 .8],... 'String',[' Model List for ', p.fullname]); % listview h = mbcwidgets.List('Parent',lvPanel,... 'Editable',false,... 'IconTransparentColor',[255 0 255],... 'IconLocation',xregrespath,... 'SelectionMode','MultiRow'); h.Peer.setBorder([]) ud.ListView= h; % statusbar [sbarpanel, ud.statusBar] = mbcgui.container.createTextPanel(... 'Parent', hFig); % waitbar ud.waitbar=xregGui.waitbar('parent',hFig); % find out how tall the status bar needs to be to contain current font size. fontHeight = get(listViewText,'Extent'); % note that room for text is statusHeight - 2 textHeight = fontHeight(4)+2; % try to get splitlayout showing all models splitPos=fPos(4)-200; desiredSize= 25*min(length(Models),5); desiredSplit=[splitPos-desiredSize, desiredSize]; hViewPanel = mbcgui.container.layoutpanel(... 'Parent', hFig, ... 'Visible','off',... 'BorderType', 'beveledin', ... 'Tag', 'ValidationViewPanel'); ud.ViewPanel = hViewPanel; %text item to tell user that views are being created CreationText = uicontrol('Parent',ud.ViewPanel,... 'Style','text',... 'Enable','inactive',... 'String','Generating available views...',... 'HorizontalAlignment','left',... 'Visible','off'); % ----------------------- setup the layouts -----------------------------% grd = xreggridlayout(lvPanel,... 'packstatus', 'off', ... 'dimension',[2 1],... 'elements',{listViewTextPanel, h},... 'correctalg','on',... 'rowsizes',[textHeight, -1]); set(lvPanel, 'LayoutComponent', {grd}); %--------------Card layout----------------------% ud.TabObj=xregcardlayout(ud.ViewPanel,... 'numcards',NumPages); ud.createcard=xregcardlayout(ud.ViewPanel,'numcards',2); CreationLyt = xreglayerlayout(ud.ViewPanel,'elements',{CreationText},'border',[10 10 10 10]); attach(ud.createcard,CreationLyt,1); attach(ud.createcard,ud.TabObj,2); set(ud.ViewPanel, 'LayoutComponent', {ud.createcard}); % split layout for card layout and listview splitLyt = xregsplitlayout(hFig,... 'orientation','ud',... 'top',ud.ViewPanel,... 'bottom',lvPanel,... 'minwidth',[460 85],... 'split',desiredSplit,... 'dividerstyle','flat',... 'dividerwidth',4); mainLyt=xreggridbaglayout(hFig,'dimension',[9, 6],... 'rowsizes',[35, 2, -1, 10, 5, 15, 5, 10, 20],... 'colsizes',[10 90 10 90 -1 150],... 'mergeblock',{[1 1],[1 6]},... 'mergeblock',{[3 3],[1 6]},... 'mergeblock',{[5 7],[2 2]},... 'mergeblock',{[5 7],[4 4]},... 'mergeblock',{[6 6],[5 6]},... 'mergeblock',{[9 9],[1 5]},... 'elements',{tbPanel, [],[],[],[],[];... [],[],[],[],[],[];... splitLyt, [],[],[],[],[];... [],[],[],[],[],[];... [],ud.Btns(1),[],ud.Btns(2),[],[];... [],[],[],[],ud.scaleText,[];... [],[],[],[],[],[];... [],[],[],[],[],[];... sbarpanel,[],[],[],[],ud.waitbar}); hFig.LayoutManager = mainLyt; set(mainLyt,'packstatus','on'); % common userdata ud.ParFig= ParFig; ud.p= p; ud.Models= Models; ud.ViewMenu= hV; ud.mfile= Vfile; ud.CurrentView= 1; ud.View = []; % have a pointer to an "OK" flag for changing views % link it to figure so when figure closes, pointer is freed ud.changeViewFlag = xregGui.RunTimePointer(1); LinkToObject(ud.changeViewFlag,ParFig); % set userdata for this (the validation) figure set(hFig,'UserData',ud); return %---------------------------------------------------- % SUBFUNCTION I_ADDVIEW %---------------------------------------------------- function i_AddViews(hFig,View) ud= get(hFig,'UserData'); start = length(ud.View); if isempty(ud.View) && ~iscell(View), % hope it's a relevant structure and off we go ud.View{1} = View; elseif isempty(ud.View) && iscell(View), ud.View = View; elseif ~iscell(View) ud.View= [ud.View,{View}]; else ud.View= [ud.View,View]; end ud.hToolbar.setRedraw(false); for i = start+1:length(ud.View) % Add menu item MenuLabel = ud.View{i}.Name; MenuCallBk = @(s,e) mv_ValidationTool('view',hFig,i); uimenu('Parent',ud.ViewMenu,... 'Label',MenuLabel,... 'Callback',MenuCallBk); % Add toolbar icon ttpString = strrep(ud.View{i}.Name,'&',''); xregGui.uitoggletool(ud.hToolbar, ... 'ImageFile', ud.View{i}.Icon, ... 'TooltipString', ttpString, ... 'ClickedCallback', MenuCallBk, ... 'TransparentColor', [0 255 0]); end % Set first toolbar button to be depressed Btns = get(ud.hToolbar,'Children'); set(Btns(1),'State','on'); ud.hToolbar.setRedraw(true); ud.hToolbar.drawToolBar; % set callbacks for list set(ud.ListView,'SelectionChangedCallback',{@i_ListView,hFig}); ud.Listener = handle.listener(ud.ListView.Peer,'ActionPerformed',@i_SelectBest); set(get(hFig,'LayoutManager'),'packstatus','on'); set(hFig,'UserData',ud,'Visible','on'); set(ud.hToolbar,'Visible','on'); set(ud.TabObj,'Visible','on'); %---------------------------------------------------- % SUBFUNCTION I_CHANGEVIEW %---------------------------------------------------- function i_ChangeView(hFig,Index) ud= get(hFig,'UserData'); set(ud.ViewPanel,'Visible','on'); % if flag = 0 we are currently in the process of changing views if ~ud.changeViewFlag.info % bail out return else % set flag to show we are busy ud.changeViewFlag.info = 0; View= ud.View{Index}; % the second figure menu has a check by the current view hV=xregmenutool('find',hFig,2); % change checked view menus set(get(hV,'Children'),'Checked','off'); xregmenutool('set',hV,Index,'check','on'); % listview multiselect status Selected = ud.ListView.getSelectedRows; if View.MultiSelect set(ud.ListView,'SelectionMode','MultiRow'); ud.ListView.selectRows(Selected) else set(ud.ListView,'SelectionMode','SingleRow'); if ~isempty(Selected) ud.ListView.selectRows(Selected(1)) end end % the 'select all' and 'assign best' buttons if length(ud.Btns)>1 if ~View.MultiSelect || length(ud.Models)==1 set(ud.Btns(2),'Enable','off') else set(ud.Btns(2),'Enable','on'); end end ud.CurrentView= Index; ud.View{Index}=View; % change tab set(ud.TabObj,'currentcard',Index); set(hFig,'UserData',ud); set(ud.statusBar,'String',''); % get model [ModelInfo,ModelList]= i_ModelSelect(hFig,ud,View); % and run view on it feval(View.mfile,'view',ud.ViewPanel,View,ModelInfo,ModelList); if ~isgraphics(hFig) % Figure was closed during the view change, so don't try to % complete the rest of the actions return end figure(hFig) % switch help menu to new one using info in View structure % add the validation help entries % where are we coming from?? switch lower(ud.mfile) case 'validate_indpt' helpMenuStr = '&Model Evaluation Tool Help'; helpTag = 'xreg_modelEvaluation'; otherwise helpMenuStr = '&Model Selection Tool Help'; helpTag = 'xreg_modelSelection'; end if isfield(View,'helpmenus') mv_helpmenu(hFig,[{helpMenuStr,helpTag}; View.helpmenus]); else mv_helpmenu(hFig,{helpMenuStr,helpTag}); end % set state of toolbar toggle buttons % need to set current 'on' if view changed from menus Btns = get(ud.hToolbar,'Children'); for i=[1:Index-1,Index+1:length(Btns)] set(Btns(i),'State','off'); end set(Btns(Index),'State','on'); % set flag to show we have finished ud.changeViewFlag.info = 1; end %---------------------------------------------------- % SUBFUNCTION I_ATTACHLAYOUT %---------------------------------------------------- function i_attachLayout(hFig,Lyt, cardNum) % different display creation funcs return an invisible, unpacked layout. % attach it to a card and set unpack it ud= get(hFig,'UserData'); Tab=ud.TabObj; % Set the view to parent to the View panel. Hopefully the views are % already parented to this, but we need to make sure. set(Lyt, 'Parent', ud.ViewPanel); % Attach to view card layout attach(Tab, Lyt, cardNum); return %---------------------------------------------------- % SUBFUNCTION I_GETVIEW %---------------------------------------------------- function [View,ModelInfo,ModelList]= i_GetView(hFig) if isgraphics(hFig, 'uipanel') ... && strcmp(get(hFig, 'Tag'), 'ValidationViewPanel') % Accept the view panel as the "handle to validation tool" hFig = ancestor(hFig, 'figure'); end ud= get(hFig,'UserData'); View= ud.View{ud.CurrentView}; if nargout>1 [ModelInfo,ModelList]= i_ModelSelect(hFig,ud,View); end %---------------------------------------------------- % SUBFUNCTION I_SETVIEW %---------------------------------------------------- function i_SetView(hFig,NewView) if isgraphics(hFig, 'uipanel') ... && strcmp(get(hFig, 'Tag'), 'ValidationViewPanel') % Accept the view panel as the "handle to validation tool" hFig = ancestor(hFig, 'figure'); end ud= get(hFig,'UserData'); ud.View{ud.CurrentView}= NewView; set(hFig,'UserData',ud); %---------------------------------------------------- % SUBFUNCTION I_LISTVIEW %---------------------------------------------------- function i_ListView(~,~,hFig) % get figure handle ud=get(hFig,'UserData'); View= ud.View{ud.CurrentView}; % get modelinfo [ModelInfo,ModelList]= i_ModelSelect(hFig,ud,View); % and update view feval(View.mfile,'view',hFig,View,ModelInfo,ModelList); %---------------------------------------------------- % SUBFUNCTION I_SELECTBEST %---------------------------------------------------- function i_SelectBest(varargin) % get fig handle hFig= findobj(allchild(0),'flat','Tag','ValidationTool'); hFig= hFig(1); ud=get(hFig,'UserData'); % choose best if length(ud.ListView.getSelectedRows)==1 ud.BestModel= i_ChooseBest(hFig); set(hFig,'UserData',ud); end function i_Select(hFig,ModNo) ud=get(hFig,'UserData'); View= ud.View{ud.CurrentView}; ud.ListView.selectRows(ModNo); [ModelInfo,ModelList]= i_ModelSelect(hFig,ud,View); feval(View.mfile,'view',hFig,View,ModelInfo,ModelList); %---------------------------------------------------- % SUBFUNCTION I_SELECTALL %---------------------------------------------------- function i_SelectAll(hFig) if nargin==0 hFig= findobj(allchild(0),'flat','Tag','ValidationTool'); end ud=get(hFig,'UserData'); View= ud.View{ud.CurrentView}; h= ud.ListView; h.selectRows(1:h.getRowCount); [ModelInfo,ModelList]= i_ModelSelect(hFig,ud,View); feval(View.mfile,'view',hFig,View,ModelInfo,ModelList); %---------------------------------------------------- % SUBFUNCTION I_MODELSELECT %---------------------------------------------------- function [ModelInfo,ModelList]= i_ModelSelect(varargin) if nargin==0 hFig= findobj(allchild(0),'flat','Tag','ValidationTool'); hFig= hFig(1); ud= get(hFig,'UserData'); View= ud.View{ud.CurrentView}; else [~,ud,View]= deal(varargin{:}); end h= ud.ListView; ModNo = h.getSelectedRows; if isempty(ModNo); % multiselection may mean that no items are selected % so select the first one h.selectRows(1); ModNo= 1; end % assign Best - disable if more than one model is selected if length(ModNo)>1 || length(ud.Models)==1 set(ud.Btns(1),'Enable','off') else set(ud.Btns(1),'Enable','on') end drawnow update if View.MultiSelect % multi select is supported ModelList = h.getData; ModelList = ModelList(ModNo,1); if length(ModNo)>5 ModNo=ModNo(1:5); h.selectRows(ModNo); ModelList = ModelList(1:5); uiwait(warndlg('Too many models selected. Only the first 5 are displayed',... 'Model Selection','modal')); end else % single selection ModelList{1} = h.getDataAt(ModNo-1,0); end % call the child function (e.g. Validate_twostage) to get the modelinfo ModelInfo= feval(ud.mfile,'select',ud.Models,ModNo,ud.p); %---------------------------------------------------- % SUBFUNCTION I_CHOOSEBEST %---------------------------------------------------- function BestItem= i_ChooseBest(hFig) if nargin==0 hFig= findobj(allchild(0),'flat','Tag','ValidationTool'); hFig= hFig(1); end ud= get(hFig,'UserData'); h= ud.ListView; BestItem= h.getSelectedRows; for i=1:h.getRowCount if i==BestItem [~,im] = iconfile(ud.Models{i}); else im = iconfile(ud.Models{i}); end h.Peer.setIconData( fullfile(xregrespath,im),i-1,0); end if length(ud.Models)>1 set(ud.statusBar,'String',['The best model is ''',h.getDataAt(BestItem-1,0),'''']); end BestItem = double(BestItem); %---------------------------------------------------- % SUBFUNCTION I_STATSTABLE %---------------------------------------------------- function i_StatsTable(hFig,ModelList,ColHead,s,~) ud= get(hFig,'UserData'); h= ud.ListView; pos= get(hFig,'Position'); set(ud.statusBar,'String','Calculating Validation Statistics'); % get width available for listview listWidth=pos(3); % adjust width for points/pixel ratio OldUnits= get(0,'Units'); spix= get(0,'ScreenSize'); set(0,'Units','points'); spos= get(0,'ScreenSize'); set(0,'Units',OldUnits); wid= listWidth*spos(3)/spix(3); % calculate width for model label mc=char(ModelList); hT= uicontrol('Parent', hFig, 'Units','points','Style','text','String',mc(1,:)); tsize= get(hT,'Extent'); msize= max(min(tsize(3)+30,wid*.3),144); delete(hT) % Column Headers for stats wid = zeros(1,length(ColHead)+1); wid(1) = msize; for i=1:length(ColHead) IsUpper= upper(ColHead{i})==ColHead{i}; w= 10*sum(IsUpper)+6*sum(~IsUpper); wid(i+1)= max(w,70); end sok= ~all(~isfinite(s)); if ~all(sok) s= s(:,sok); ColHead= ColHead(sok); wid = wid(sok); end % index of best into cell array of TS models bm= ud.p.bestmdev; if ~isnumeric(bm) && bm~=0 % i.e. isa pointer bname= bm.name; BMind = find(strcmp(bname,ModelList)); if isempty(BMind) BMind = 0; end else bname=''; BMind= bm; end IconData = cell(length(ModelList),1); for i=1:length(ModelList) IconData{i} = xregrespath( iconfile(ud.Models{i}) ); end if ~isempty(s) % add stats to listview % make into formatted string Data = [ModelList(:) num2cell(s)]; else Data = ModelList(:); for i=1:length(ModelList) if strcmp(ModelList{i},bname); BMind= i; end end end h.Peer.setColumnData([{'Model'} ColHead]); h.Peer.setColumnWidths(wid); h.Peer.setData(Data,IconData); if BMind==0 % by default choose first element in list h.selectRows(1) elseif h.getRowCount>=BMind h.selectRows(BMind) end % set up best model ud.BestModel= i_ChooseBest(hFig); set(ud.statusBar,'String',''); set(hFig,'UserData',ud); %---------------------------------------------------- % SUBFUNCTION I_PRINT %---------------------------------------------------- function i_Print(~,~,fig) if nargin<3 fig = gcbf; end [View,~,ModelList]= i_GetView(fig); p = get(MBrowser,'CurrentNode'); TitleStr = char(['Model Selection for: ' p.fullname],char(ModelList)); feval(View.mfile,'print',View,TitleStr) %---------------------------------------------------- % SUBFUNCTION I_CLOSE %---------------------------------------------------- function i_Close hFig= mvf('ValidationTool'); figure(hFig(1)) ud= get(hFig(1),'UserData'); p= ud.p; ch= p.children; DoClose = true; if ~isempty(ch); drawnow BestName= getDataAt(ud.ListView,ud.BestModel-1,0); Resp= questdlg(char('Do you want to select the model: ',... [' ''',BestName,''''],... 'as the best model?'),... 'Model Selection','Yes','No','Cancel','Yes'); switch lower(Resp) case 'yes' % call particular close function (e.g. Validate_TwoStage) feval(ud.mfile,'close',hFig(1),p,double(ud.BestModel)); case 'no' % restore modeldev status if we have change it for p.undovalidate; otherwise DoClose = false; end mbH= MBrowser; if mbH.CurrentNode==p && p== mbH.treeview('current') % update current model browser view if you are still on the same node mbH.ViewNode; % update listview (to show best model as blue icon) mbH.listview; mbH.doDrawText; end end if DoClose p.history('clear'); if isgraphics(hFig) delete(hFig) end figure(ud.ParFig); else figure(hFig) end function i_setsbarstring(newstring) hFig= mvf('ValidationTool'); ud= get(hFig(1),'UserData'); set(ud.statusBar,'String',newstring); function i_setwaitbar(varargin) hFig= mvf('ValidationTool'); ud= get(hFig(1),'UserData'); set(ud.waitbar,varargin{:}); function i_setcreatemessage(state) hFig= mvf('ValidationTool'); ud= get(hFig(1),'UserData'); if state set(ud.createcard,'currentcard',1); set(hFig,'CloseRequestFcn',''); else set(ud.createcard,'currentcard',2); set(hFig,'CloseRequestFcn',[mfilename,'(''close'')']); end %-------------------------------------------------------------------------- function i_UpdateModels(Models) % doesn't update views hFig= mvf('ValidationTool'); ud= get(hFig(1),'UserData'); % set models ud.Models = Models; set(hFig(1),'UserData',ud); %-------------------------------------------------------------------------- function i_UpdateView(hFig) ud= get(hFig,'UserData'); % if flag = 0 we are currently in the process of changing views if ud.changeViewFlag.info View= ud.View{ud.CurrentView}; % set flag to show we are busy ud.changeViewFlag.info = 0; % get model [ModelInfo,ModelList]= i_ModelSelect(hFig,ud,View); % and run view on it feval(View.mfile,'view',hFig,View,ModelInfo,ModelList); ud.changeViewFlag.info = 1; end function iUpdateRanges(hFig) %update ranges for plots in surface and cross section viewers % this is mainly for localmulti ud= get(hFig,'UserData'); CView = ud.CurrentView; for i=1:length(ud.View) % temporarily change views ud.CurrentView = i; set(hFig,'UserData',ud); % call updateranges on view feval(ud.View{i}.mfile,'updateranges',ud.ViewPanel); ud= get(hFig,'UserData'); end % change view back to current one ud.CurrentView = CView; set(hFig,'UserData',ud); function hPanel = i_GetViewPanel(hFig) ud = get(hFig,'UserData'); hPanel = ud.ViewPanel;