www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+mbcmodelview/+global/MessageService.m
classdef MessageService < mbcmodelview.ModelMessageService %MessageService one-stage and response feature MessageService % Copyright 2015-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (SetAccess=private) %CurrentNode selected node in model tree CurrentNode end properties(Dependent,SetAccess=private) %Title standard title is the name of the response Title %NumChildren number of children NumChildren CurrentIndex end methods function obj = MessageService %MessageService constructor % create an OutlierLine for sharing among users obj@mbcmodelview.ModelMessageService % create actions for model obj.Actions = mbcmodelview.global.NodeActions(obj); % right click on main line for a plot of sweep data in response % feature model plots obj.OutlierLine.AltClickCallBack = @obj.onPlotSweep; end function s = get.Title(obj) s = varname(obj.Model); end function n = get.NumChildren(obj) n = numChildren(info(obj.CurrentNode)); end function Index = get.CurrentIndex(obj) Index = find(obj.Pointer==children(info(obj.CurrentNode))); end end methods function updateNode(obj,p,pCurrent,ForceReset) %updateNode update selected node in MessageService % updateNode(obj,p,pCurrent,ForceReset) % p : main node (parent of alternatives, or tree node) % pCurrent : main node (selected alternative) if nargin<2 p=obj.Pointer; end if nargin>2 obj.CurrentNode = pCurrent; end if nargin<4 ForceReset = false; end NodeChanged = ForceReset || p~=obj.Pointer; p.InitModel; obj.Pointer = p; if isempty(obj.CurrentNode) obj.CurrentNode = p; end update(obj,NodeChanged) if NodeChanged fireNodeChanged(obj) end end function update(obj,NodeReset) %update main update method for MessageService % update(obj,NodeChanged) if nargin<2 NodeReset = false; end % store fit data mdev = info(obj.Pointer); [obj.XData,obj.YData,obj.DataOK]= FitData(mdev); obj.Model = model(mdev); % store boundary model obj.BoundaryModel = BoundaryModel(mdevtestplan(obj.ModelDev),obj.Model); % validation data store if isRespFeat(mdev); % no validation data for response feature nodes XValData = []; YValData = []; else [XValData,YValData]= getValidationData(mdev); end obj.ValidationXData= XValData; obj.ValidationYData = YValData; % store diagnostics statistics [obj.Diagnostics,obj.DiagnosticFactors,olIndex] = diagnosticStats(obj); % clear outlierlines and update with new default outliers clear(obj.OutlierLine); obj.OutlierLine.OutlierIndices = olIndex; % enable actions enable(obj.Actions); % send appropriate events if NodeReset fireNodeReset(obj) end fireNodeUpdated(obj) end function setupModel(obj,NewModel) %setupModel setup new model mdev = obj.ModelDev; try OldModel = obj.Model; OldName = name(OldModel); if any( strncmp( OldName,name( mdev ),length(OldName) ) ) && ~strcmp(name(NewModel),OldName) % using default model and node used model name so rename mdev = name(mdev,name(NewModel)); end %set new model and fit mdev = model(mdev,NewModel); fitmodel(mdev); % update everything, and fire node changed to broadcast that % model has changed update(obj) fireNodeChanged(obj) catch ME xregerror('Model Fit Error',ME.message); xregpointer(mdev); end end function refit(ms) %refit refit model refit(ms.ModelDev); update(ms); end function [mainString,shortString]= transformStrings(obj) %transformStrings strings to display transform at in desciptor % [mainString,shortString]= transformStrings(obj) bxcx=get(obj.Model,'boxcox'); if bxcx~=1 mainString = sprintf('Box-Cox = %g', bxcx); shortString = sprintf('%g', bxcx); else mainString = ''; shortString = ''; end end function restoreOutliers(obj,olindex) %restoreOutliers restore removed data if nargin<2 [olindex,OK]=restoreoutlierdlg(obj.ModelDev); OK = OK && ~isempty(olindex); else OK = ~isempty(olindex); end if OK restoreoutliers(obj.ModelDev,'single',olindex); % only a view required if status is the same update(obj) end end function addOutliers(obj,olindex) %addOutliers add new outliers % Apply the outliers addoutliers(obj.ModelDev,olindex); % only a view required if status is the same update(obj) end function [data,factors] = validationDiagnostics(ms) %validationDiagnostics validation diagnostics for ValidationData view if isempty(ms.ValidationXData) factors = {}; data = []; else % get new stats yhat = ms.Model(ms.ValidationXData); data = [(1:length(yhat))' double(ms.ValidationYData)-yhat yhat double(ms.ValidationYData) double(ms.ValidationXData) ]; inputNames = InputLabels(ms.Model); outputName = ResponseLabel(ms.Model); % make it a row inputNames= inputNames(:)'; output= getOutput(ms.Model); if ~isempty(output.Units) % add units to residuals units = sprintf(' [%s]',output.Units); else units = ''; end factors=[{'Obs. number',... ['Residuals',units],... ['Predicted ',outputName],... outputName},... inputNames]; end end function [data,factors,olIndex]= diagnosticStats(obj) %diagnosticStats scatterplot diagnostics and default outliers % [data,factors,olIndex]= diagnosticStats(obj) [data,factors,~,olIndex]= diagnosticStats(obj.ModelDev); end function showTestNumbers(obj,ax) %showTestNumbers show test numbers in axes % showTestNumbers(obj,ax) % delete any current test numbers txtH=findobj(ax,'Type','text',... 'Tag','TestNumText'); delete(txtH); if obj.ShowTestNumbers && obj.Status ShowTestNum(obj.ModelDev,ax); end end function [lineh,legLabels] = legendLabels(obj,AxHand) %legendLabels legend labels for axes tags = {'main line','BDPts','localfit','free knot line','rbf center mark','valdata'}; Types = InputFactorTypes(obj.Model); if length(find(Types==1)) > 1 % global model has >1 input factors allLabels = {'Data','Removed data','Predicted = Observed','Knot position','RBF center','Validation predictions'}; else % global model has only 1 input and we show the model fit allLabels = {'Data','Removed data','Model fit','Knot position','RBF center','Validation predictions'}; end % Throw out empty lines lineh = []; legLabels = {}; for i = 1:length(tags) h = findobj(AxHand,'Type','line','Tag',tags{i}); if ~isempty(h) && isgraphics(h) && ~isempty(get(h,'XData')) lineh = [lineh, h]; %#ok<AGROW> legLabels = [legLabels, allLabels(i)]; %#ok<AGROW> end end end function buildModels(obj) %buildmodels build models works on tree node not selected %alternative OK = buildmodels(info(obj.CurrentNode)); if OK % select the new best model and update obj.Pointer = bestmdev(obj.ModelDev); update(obj); % broadcast that model has changed fireNodeChanged(obj) end end function assignBest(obj) %assignBest assign node to best if obj.Status p= obj.CurrentNode; p.BestModel(obj.Pointer); update(obj); end end function selectAlternative(obj,Index,AssignBest) %selectAlternative select alternative model if ~isempty(Index) mdev = info(obj.CurrentNode); NewNode = children(mdev,Index); if nargin>2 && AssignBest && obj.Status % set best model p = obj.CurrentNode; p.BestModel(NewNode); end if NewNode~=obj.Pointer && closeSubFigures(obj) % may need to close sub figures % need to change selection mdev=info(NewNode); % model must be initialised InitModel(mdev); mdev= info(mdev); % model fit has been deferred - can we refit now [Deferred,~,CanUpdate]=isDeferred(mdev); if Deferred && CanUpdate % refit model refit(mdev); end % make sure new node is selected in list obj.Pointer = NewNode; update(obj); fireNodeChanged(obj) else % just update update(obj) end end end function [Data,Icons,ColHead] = childstats(ms) %childstats statistics for listview % [Data,Icons,ColHead] = childstats(ms) mdev = info(ms.CurrentNode); if numChildren(mdev)>0 && ~isa(mdev,'mdevmlerf') [s,ColHead]= childstats(mdev); ColHead = [{'Name'},ColHead, {'Best Model'}]; Icons = children(mdev,@iconfile)'; Data = [ children(mdev,@name)' num2cell(s) num2cell(children(mdev)==bestmdev(mdev))' ]; else Data = []; Icons = {}; ColHead = {}; end end function [description,ic] = listHeader(ms) %#ok<MANU> %listHeader header for lisview % [description,ic] = listHeader(ms) ic = 'gloreg.bmp'; description = 'Alternative Models'; end function plotSweep(obj,XGlobal,YObserved,DataIndex) %plotSweep plot sweep data for response feature m= obj.Model; yhat= EvalModel(m,XGlobal); plocal= obj.Pointer.Parent; while plocal~=0 && ~isa(plocal.model,'localmod') % find local modeldev node plocal= plocal.Parent; end if plocal==0 return end presp= plocal.Parent; [XData,YData,DataOK]= plocal.FitData(DataIndex); XG= obj.XData; YData(~DataOK,1)= NaN; Xg = XG{DataIndex}; Xgc= code(m,Xg); fh= figure('NumberTitle','off',... 'Name',fullname(obj.ModelDev),... 'Tag','DisplayPlots'); ax= axes('Parent',fh); plot(XData(:,1),YData,'o','bd','Parent',ax); set(get(ax,'Title'),... 'String',['Test ',sprintf('%3d',testnum(XData))],... 'FontWeight','Bold') set(get(ax,'YLabel'),... 'Interpreter','none',... 'String',presp.name); % Display Experimental Point (Natural and Code values) dispstr= [char(get(m,'symbol')) blanks(size(XG,2))' num2str(Xg','%10.4g')... blanks(size(XG,2))' num2str(Xgc','%5.2f')]; str1=num2str(YObserved,'%7.3f'); str2=num2str(yhat,'%5.3f'); strn=char(str1,str2); s1=['Observed : ';'Predicted : ']; dispstr=char([s1,strn],'',dispstr); th=text('Parent',ax,... 'Units','norm','Position',[0.95,0.02],... 'String',dispstr,.... 'FontName','Courier New',... 'FontSize',9,... 'Interpreter','none',... 'HorizontalAlignment','right','VerticalAlignment','bottom'); tpos= get(th,'Extent'); Note= plocal.SweepNotes(DataIndex); lineLength = 30; if ~isempty(Note) % add sweep note if appropriate if size(Note,1)==1 && length(Note)>lineLength % note is one long line Note = [Note, blanks(lineLength-rem(length(Note),lineLength))]; Note = reshape(Note,lineLength,length(Note)/lineLength); Note=Note'; end text('Parent',ax,... 'Units','norm','Position',[0.95,0.04+tpos(4)],... 'String',Note,.... 'FontName','Courier New',... 'FontSize',9,... 'Interpreter','none',... 'HorizontalAlignment','right','VerticalAlignment','bottom'); end end function msg = selectModelFigure(obj) %selectModelFigure p= obj.CurrentNode; pbest= children(info(p),@bestmdev); pbest=[pbest{:}]; if any(pbest==0) unvalmdev=children(info(p),find(pbest==0),@name); msg = char('You must select a best model for all sub-models ',... 'before selecting a best model. ',... 'The following sub-models do not have a best model:',... unvalmdev{:}); else % dependence on Model Browser hFig= get(MBrowser,'Figure'); hSelectionFig= Validate_OneStage('create',p,hFig); if isgraphics(hSelectionFig) % register figure with message service % need to update when done list = event.listener(hSelectionFig,'ObjectBeingDestroyed',@(h,evt) obj.update); setappdata(hSelectionFig,'MBCSelectionClosed',list) obj.registerSubFigure(hSelectionFig); end msg = ''; end end end methods (Access=private) function onPlotSweep(obj,hLine,~) %onPlotSweep right click callback to plot sweep ax= get(hLine,'Parent'); % find the point in the line that we have clicked on. pos=get(ax,'CurrentPoint'); pos=pos(1,1:2); xdata=get(hLine,'XData'); ydata=get(hLine,'YData'); metric=((xdata-pos(1))./diff(get(ax,'XLim'))).^2 + ... ((ydata-pos(2))./diff(get(ax,'YLim'))).^2; [~,SelectedPoint]=min(metric); if ~isempty(SelectedPoint) % find index to data point indices = find(obj.DataOK); DataIndex = indices(SelectedPoint); % observed y data yobs= double(obj.YData(obj.DataOK)); yobs= yobs(DataIndex); % predicted y x=double(obj.XData); xp= x(obj.DataOK,:); xp= xp(DataIndex,:); % plot sweep plotSweep(obj,xp,yobs,DataIndex); end end end end