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

    classdef TwoStageMessageService < mbcmodelview.local.MessageService
    %ModelMessageService
    
    %  Copyright 2014-2015 The MathWorks, Inc. and Ford Global Technologies, Inc.
    

    properties (Dependent,SetAccess=private)
        TwoStage
    end
    
    events(NotifyAccess=private)
       ModelChanged 
    end    
    
    methods
        function obj = TwoStageMessageService
        %TwoStageMessageService constructor
        obj@mbcmodelview.local.MessageService
        % create actions for model
        obj.Actions = mbcmodelview.local.NodeActions(obj);
        
        end
        
        function TS = get.TwoStage(ms)
        
        TS = BestModel(ms.ModelDev);
        
        end
        
    end
    
    methods
        
        function setupModel(obj,NewModel)
        %setupModel setup new model
        
        pOldLocal= obj.Pointer;
        pTwoStage= obj.Pointer.Parent;
        TSold= pTwoStage.model;
        
        set(NewModel,'DatumType',get(TSold,'DatumType'));
        TP = mdevtestplan(obj.ModelDev);
        m= model(TP);
        TS= xregtwostage(NewModel,m);
        pTwoStage.model(TS);
        % copy current outliers
        TSoutliers= pTwoStage.outliers;
        pTwoStage.outliers(pOldLocal.outliers);
        
        OldMdev = info(pOldLocal);
        try
            pNewLocal= pTwoStage.makechildren;
            % set old model and outliers back
            pTwoStage.model(TSold);
            pTwoStage.outliers(TSoutliers);
            
            if pNewLocal.numChildren>0 && ismember(DatumType(NewModel),1:2)
                % have to update datumlink
                pdatum= pNewLocal.children(1);
                pTwoStage.AssignData('data',pdatum);
                pNewLocal.UpdateLinks(1);
            end
            
            % now move back to local node
            pNewLocal.name(name(NewModel));
            
            % Framework and model browser needs to know about the new node
            evtData.NewPointer = pNewLocal;
            evtData.OldPointer = pOldLocal;
            notify(obj,'ModelChanged',xregEventData(evtData));
            
            updateNode(obj,pNewLocal);
            
        catch ME
            % model fit failed
            % reselect node
            xregpointer(OldMdev);
            xregerror('Model Fit Error',ME.message);
        end
        
        end
        
        function modelUpdated(ms)
        %updateLocalModel updated local model
        
        ms.NeedsUpdate = 2;
        update(ms);
        
        end
        
        function updateFit(obj)
        %updateFit update dependent fits
        if obj.NeedsUpdate
            UpdateLinks(obj.ModelDev,obj.NeedsUpdate);
            obj.NeedsUpdate = 0;
            update(obj);
        end
        end
        
        function msg = mle(ms)
        %mle estimate MLE two-stage model
        
        if ms.NeedsUpdate
            updateFit(ms);
        end
        msg = '';
        
        TS= BestModel(ms.ModelDev);
        if isempty(TS)
            selrf= SelectRF(ms.Model);
            if ~isempty(selrf)
                TSModels= twostage(ms.ModelDev,selrf);
                if ~isempty(TSModels)
                    BMInd= validate(ms.ModelDev);
                    if ~isempty(BMInd)
                        % select best model
                        BestModel(ms.ModelDev,BMInd);
                        mledialog(ms.ModelDev,'Calculate MLE for global covariances');
                        update(ms);
                    else
                        msg = 'No two-stage model available. Lack of degrees of freedom is the most likely cause.';
                    end
                else
                    msg = 'No two-stage model available. Lack of degrees of freedom is the most likely cause.';
                end
            else
                msg = 'No two-stage model available. Insufficient response features to reconstruct two-stage model.';
            end
        else
            mledialog(ms.ModelDev,'Calculate MLE for global covariances');
            update(ms);
        end
        
        
        end
        
        function buildModels(obj)
        %buildModels build models for all global models
        
        updateFit(obj);
        
        m= model(mdevtestplan(obj.ModelDev));
        [mlist,OK]=xreg_modeltemplates('create',m,obj.NumTests);
        if OK
            m= xregCreateModel(@xregmulti,m,'models',mlist);
            
            [GlobalCriteria,OK] = guiSelectCriteria(m);
            if OK
                CreateAlternativeModels(obj.ModelDev,mlist,GlobalCriteria);
                update(obj)
            end
        end
        
        end
        
        function assignBest(ms)
        %assignBest assign best two-stage model
        
        mdev= ms.ModelDev;
        st= children(mdev,@status);
        if status(mdev) && any([st{:}])
            pThisResponse= Parent(mdev);
            BestModel(info(pThisResponse),ms.Pointer);
            if pThisResponse.childindex==1 && get(model(mdev),'datumtype')
                prf= children(mdev);
                pdatum= pThisResponse.datumlink;
                if pdatum~= prf(1)
                    % local model has the datum
                    pThisResponse.AssignData('Data',prf(1));
                    % update datum links
                    UpdateLinks(ms.ModelDev,1);
                    
                    TP= pThisResponse.mdevtestplan;
                    if numChildren(TP)>1
                        msgbox('The datum model has changed. All responses using datum links have been updated',...
                            'Datum Model','modal');
                    end
                end
            end
        else
            xregerror('Best Model Error','Two-stage model needs updating');
        end
        end
        
        function msg = selectModelFigure(ms)
        %selectModelFigure select best model using model selection figure
        
        mbH= MBrowser;

        msg = '';
        p= ms.Pointer;
        if mle_best(ms.ModelDev) && ~ms.NeedsUpdate
            hFig= Validate_mle('create',p,mbH.Figure);
            ms.registerSubFigure(hFig);
        else
            if ~isempty(p.children)
                pbest= p.children(@bestmdev);
                pbest=[pbest{:}];
                if any(pbest==0)
                    unvalmdev=p.children(pbest==0,@name);
                    msg = char('You must validate all submodels ',...
                        'before validating this model',...
                        'The following sub-models have not been validated:',...
                        unvalmdev{:});
                    return
                end
            end
            
            RFNames= children(ms.ModelDev,@name);
            [selrf,~]=SelectRF(ms.Model);
            
            if size(selrf,1)>0
                if ms.NeedsUpdate
                    % do we need to update links
                    UpdateLinks(ms.ModelDev,ms.NeedsUpdate);
                    
                    ms.NeedsUpdate=0;
                end
                
                Nf= length(get(ms.Model,'values'));
                if length(RFNames)>Nf
                    RFNames(1:length(RFNames)-Nf)=[];
                end
                
                %Find longest RFNames
                maxlen = 0;
                for i=1:length(RFNames)
                    maxlen = max(maxlen,length(RFNames{i}));
                end
                % Construct formating string based o the max length
                formatstr = sprintf('%%-%ds ',maxlen);
                
                % construct List
                List=cell(size(selrf,1),1);
                for i=1:size(selrf,1)
                    List{i}= sprintf(formatstr,RFNames{selrf(i,:)});
                end
                
                hSelectionFig= validate_local('create',p,selrf,List,mbH.Figure);
                
                % need to update when done
                if isgraphics(hSelectionFig,'figure')
                    list = event.listener(hSelectionFig,'ObjectBeingDestroyed',@(h,evt) ms.update);
                    setappdata(hSelectionFig,'MBCSelectionClosed',list)
                    ms.registerSubFigure(hSelectionFig);
                end
            else
               msg = ['There are insufficient independent response features',...
                    ' available to reconstruct this local model'];
            end
            
        end
        
        end
    end
    
    methods (Access=protected)
        function s = getStatus(obj)
        if isvalid(obj.Pointer)
            s =  localstatus(obj.ModelDev,obj.CurrentTest);
        else
            s = 0;
        end
        end
        
    end
    
    
end