www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+mbcmodelview/+ptbypt/MessageService.m

    classdef MessageService < mbcmodelview.local.MessageService
    %MessageService message service for point-by-point models
    
    %  Copyright 2015-2015 The MathWorks, Inc. and Ford Global Technologies, Inc.
    
    
    properties (SetAccess=private)
        %BestIndex index to best model
        BestIndex = 1;
        %SummaryStats summary statistics for all models
        SummaryStats
        %SummaryStatsNames names of summary statistics
        SummaryStatsNames
        %AlternativeStatus fit status for all alternative models
        AlternativeStatus
    end
    
    properties(Dependent,SetAccess=private)
        %CurrentIndex index to selected model 
        CurrentIndex
        %AllModels cell array of all alternative models
        AllModels
        %AllFitted indicates whether all models are fitted (pre-15b)
        AllFitted
        %NumModels number of models
        NumModels 
    end
    
    properties (Access=private)
        pCurrentIndex = 1;
    end
    
    methods
        function obj = MessageService
        %MessageService - constructor
        
        % create actions for model
        obj.Actions = mbcmodelview.ptbypt.NodeActions(obj);
        
        end
        
        function index = get.CurrentIndex(obj)
        %CurrentIndex currently selected model
        index = obj.pCurrentIndex;
        end
        
        function set.CurrentIndex(obj,index)
        
        if ~obj.AllFitted && index~=obj.CurrentIndex
            updateLocalMulti(obj);
        end
        obj.Model = set(obj.Model,'CurrentIndex',double(index));
        obj.pCurrentIndex = double(index);
        end
        
        function mdls = get.AllModels(obj)
        %AllModels all models
        if ~obj.AllFitted
            updateLocalMulti(obj);
        end
        mdls = get(obj.Model,'localmultilist');
        
        end
        
        function OK = get.AllFitted(obj)
        %AllFitted all models are fitted (post 15b feature)
        OK = ~isempty(obj.Model) && get(obj.Model,'allfitted');
        
        end
        
        function n = get.NumModels(obj)
        %get.NumModels number of alternative models
        n = length(get(obj.Model,'models'));
        end
        
    end
    
    methods
        
        function setupModel(obj,NewModel)
        %setupModel setup new model
        
        clearmodels(obj.ModelDev);
        
        model(obj.ModelDev,NewModel);
        fitmodel(obj.ModelDev);
        
        update(obj);
        end
        
        function [s,ColHead] = alternativeStats(obj)
        %alternativeStats alternative statistics for listview
        
        if obj.AllFitted
            % use all stats as stored in updateLocalMulti
            ColHead = obj.SummaryStatsNames;
            s = obj.SummaryStats;
        else
            % just display the selection statistic
            [~,ColHead,s,~] = localsummary(obj.Model,2);
        end
        end
        
        function [OKmulti,ColHead,S] = updateLocalMulti(obj)
        %updateLocalMulti update local multi nodel to ensure all
        %alternatives are fitted
        Xs= obj.XData(obj.DataOK,:);
        Ys= obj.YData(obj.DataOK,1);
        if ~obj.AllFitted
            % pre-15b multimodel need to refit all alternatives
            
            [obj.Model,OKmulti,ColHead,SumStats]= listmodels(obj.Model,Xs,Ys);
            % update parameters in mdev_local so we only have to do this once
            UpdateParams(obj.ModelDev, obj.CurrentTest, allparameters(obj.Model), []);
            S= cat(1,SumStats{:});
        else
            % Alternative models all fitted
            [S,ColHead]= childstats(obj.Model);
            OKmulti = get(obj.Model,'weights')~=0;
        end
        % get list of models (as local models)
        Models= get(obj.Model ,'localmultilist');
        if ~isempty(obj.ValidationXData)
            % validation RMSE
            ValRMSE = NaN(length(Models),1);
            for i=1:length(Models)
                if OKmulti(i)
                    ValRMSE(i) = LocalValidationRMSE(obj.ModelDev,obj.CurrentTest,Models{i},obj.ValidationXData,obj.ValidationYData);
                end
            end
            ColHead = [ColHead {'Validation RMSE'}];
            S = [S ValRMSE];
        end
        
        obj.SummaryStats = S;
        obj.SummaryStatsNames = ColHead;
        obj.AlternativeStatus = OKmulti;
        
        end
        
        function [Data,Icons,ColHead] = childstats(ms)
        %childstats statistics for listview
        %    [Data,Icons,ColHead] = childstats(ms)
        
        
        [s,ColHead] = alternativeStats(ms);
        
        mdls = get(ms.Model,'models');
        mdlNames = cellfun(@name,mdls,'UniformOutput',false);
        
        ColHead = [{'Name'} ColHead {'Best Model'}];        

        % use local model icons
        Icons = cell(length(mdlNames),1);
        Icons(:) = { 'locreg.bmp' };
        Icons{ms.BestIndex} = 'best_locreg.bmp';
        
        % add best model checkboxes
        Best = false(length(mdlNames),1);
        Best(ms.BestIndex) = true;
        
        Data = [ mdlNames(:) num2cell(s) num2cell(Best)];        
        
        end
        
        function [description,ic] = listHeader(ms) %#ok<MANU>
        %listHeader header for lisview
        %    [description,ic] = listHeader(ms)
        
        ic = 'locreg.bmp';
        description = 'Alternative Local Models';
        
        end
        
        
        
        
        function selectModelFigure(obj)
        %selectModelFigure open model selection figure
        
        mbh = MBrowser;
        hSelect = Validate_LocalSelect('create',obj.Pointer,mbh.Figure,obj);
        
        list = event.listener(obj,'NodeUpdated',@(ms,evt) Validate_LocalSelect('update',obj.Pointer,hSelect));
        setappdata(hSelect,'MBCUpdateEval',list)

        registerSubFigure(obj,hSelect)

        end
        
        function selectAlternative(obj,Index,AssignBest)
        %selectAlternative select alternative models
        
        obj.CurrentIndex = Index;
        
        if nargin>2 && AssignBest && obj.Status
            obj.BestIndex = Index;
            UpdateParams(obj.ModelDev , obj.CurrentTest, allparameters(obj.Model), []);
        end
        update(obj)
        
        end
        
    end
    
    methods (Access=protected)
        

        function s = getStatus(obj)
        %getStatus status for current test
        
        % flag for whole test
        s =  localstatus(obj.ModelDev,obj.CurrentTest);
        if s
            % check the status of selected model
            obj.AlternativeStatus = get(obj.Model,'weights')~=0;
            s = obj.AlternativeStatus(obj.CurrentIndex);
        end
        
        end
        
        function resetModel(obj)
        %resetModel reset to best model
        if obj.pCurrentIndex ~= obj.BestIndex
            obj.pCurrentIndex = obj.BestIndex;
            obj.Model = set(obj.Model,'CurrentIndex',obj.BestIndex);
        end

        end
        
        function updateAlternativeStatistics(obj)
        %updateAlternativeStatistics set up alternative models for current test
        
        if obj.Status && obj.AllFitted 
            % all models fitted
            [obj.SummaryStats,obj.SummaryStatsNames] = AlternativeStatistics(obj.Model,obj.XData(obj.DataOK,:),obj.YData(obj.DataOK,:));
            if ~isempty(obj.ValidationXData)
                mdls = get(obj.Model,'models');
                ValRMSE = NaN(length(mdls),1);
                for i=1:length(mdls)
                    if obj.AlternativeStatus(i)
                        ValRMSE(i) = LocalValidationRMSE(obj.ModelDev,obj.CurrentTest,mdls{i},obj.ValidationXData,obj.ValidationYData);
                    end
                end
                obj.SummaryStatsNames = [obj.SummaryStatsNames {'Validation RMSE'}];
                obj.SummaryStats = [obj.SummaryStats ValRMSE];
            end
            
            obj.AlternativeStatus = ~isnan(get(obj.Model,'SelectionStatistic'));
        else
            % no alternative model fits available so defer until user needs
            % them
            obj.SummaryStats = [];
            obj.SummaryStatsNames = {};
            obj.AlternativeStatus = [];
        end        
        end
        
        function updateModel(obj,ForceReset)
        %updateModel update selected model 
        %   updateModel(obj,ForceReset)
        %
        %   updateModel is a template method called as part of the general
        %   MessageService update. The data (XData, YData) must match the
        %   fitting data.
        
        if nargin<2
            ForceReset = false;
        end
        updateModel@mbcmodelview.local.MessageService(obj,ForceReset)
        obj.BestIndex = get(obj.Model,'CurrentIndex');
        if ~ForceReset && obj.pCurrentIndex<=get(obj.Model,'nmodels')
            % select current model
            obj.Model = set(obj.Model,'CurrentIndex',obj.pCurrentIndex);
        else
            obj.pCurrentIndex = obj.BestIndex;
        end
        
        updateAlternativeStatistics(obj)
        
        end
        
    end
    
    
end