www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/mv_PEVView.m

    function varargout= mv_PEVView(Action,varargin)
%MV_PEVVIEW Prediction Error Variance Graphical Viewer
%

%  Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc.


hFig= mvf('mvPEVView');
PR = xregGui.PointerRepository;
if ~isempty(hFig)
    ptrID = PR.stackSetPointer(hFig, 'watch');
end

switch lower(Action)
    case 'create'
        varargout{1}=i_Create(varargin{:});
    case 'close'
        % Figure is deleted when base model is changed or on Exit Main GR
        fh= findobj(allchild(0),'flat','Tag','mvPEVView');
        delete(fh(1));
        fh= findobj(allchild(0),'flat','Tag','mvOptM');
        if ~isempty(fh)
            delete(fh(1));
        end
    case 'update'
        i_Update(varargin{:});
    case 'print'
        i_Print(hFig);
end
if ~isempty(hFig) && isgraphics(hFig)
    PR.stackRemovePointer(hFig, ptrID);
end

%-------------------------------------------------------------------
% SUBFUNCTION i_Create
%-------------------------------------------------------------------
function hFig=i_Create(m,X, bdryModel )

if nargin == 1 || isempty( X )
    des= m;
    if isoptimcapable(des)
        des= InitStore(des);
    end
    m= model(des);
    X= factorsettings(des);
else
    des=[];
end

if nargin < 3,
    bdryModel = [];
end

% Find any other DialUp Figures to determine defaults
hFig= findobj(allchild(0),'flat','Tag','mvPEVView');
if ~isempty(hFig);
    hFig=hFig(1);
    ud= get(hFig,'UserData');
    if nfactors(ud.Model)== nfactors(m)
        i_Update(hFig,m,X,des);
        figure(hFig);
        return
    else
        delete(hFig)
    end
end

fPos= [50 50 850 600];
hFig= xregfigure('Name','Prediction Error Variance Viewer',...
    'Position',fPos,...
    'Tag','mvPEVView',...
    'HandleVisibility','callback',...
    'Resize','on',...
    'Visible','off',...
    'Renderer','zbuffer',...
    'PaperPositionMode','auto',...
    'CloseRequestFcn',[mfilename,'(''close'')'],...
    'DefaultAxesFontSize',8,...
    'DefaultTextFontSize',8);

xregpersistfigpos(hFig);
xregmoveonscreen(hFig);

labels= get(m,'symbol');

% ============ set up layouts ====================
listTitle = uicontrol('Parent', hFig,...
    'Style','text',...
    'HorizontalAlignment','left',...
    'String','Input factors:',...
    'Visible','off');

% listctrl
bl_listCtrl = xregborderlayout(hFig,...
    'packstatus','off',...
    'visible','off',...
    'border',[0 0 0 0]);

hnd.lhsPane = xreggridbaglayout(hFig);

% the axis factors
hnd.factorsPane = xreggridbaglayout(hFig);

% together with axis (eventually) in center
hnd.rhsPane = xregborderlayout(hFig,...
    'south',hnd.factorsPane,...
    'innerborder',[60 100 30 30]);
% the whole dial-up display
hnd.splitPane = xregborderlayout(hFig,...
    'border',[10 10 10 10],...
    'west',hnd.lhsPane,...
    'center',hnd.rhsPane,...
    'innerborder',[280 0 0 0]);
hnd.mainPane = xregborderlayout(hFig,...
    'center',hnd.splitPane);

% make a LISTCTRL object
hnd.listCtrl = xreglistctrl(hFig,...
    'visible','on',...
    'cellborder',2,...
    'border',4,...
    'cellheight',18);
set(bl_listCtrl,'center',hnd.listCtrl);

% -------------------------------------
%      Factor Selectors
% -------------------------------------
hnd.factor(1)=uicontrol('Style','popupmenu',...
    'Parent',hFig,...
    'String',' ',...
    'BackgroundColor','w',...
    'Visible','on',...
    'Value',1,...
    'Tag','1');
hnd.text(1)=uicontrol('Style','text',...
    'Parent',hFig,...
    'Position',[0 0 90 15],...
    'String','X-axis factor:',...
    'Visible','on',...
    'UserData',{});
hnd.factor(2)=uicontrol('Style','popupmenu',...
    'Parent',hFig,...
    'String',' ',...
    'Value',2,...
    'BackgroundColor','w',...
    'Visible','off',...
    'UserData',0,...
    'Tag','2');
hnd.text(2)=uicontrol('Style','text',...
    'Parent',hFig,...
    'Position',[0 0 90 15],...
    'String','Y-axis factor:',...
    'Visible','off',...
    'UserData',{});
hnd.factor(3)=uicontrol('Style','popupmenu',...
    'Parent',hFig,...
    'String',' ',...
    'Value',3,...
    'BackgroundColor','w',...
    'Visible','off',...
    'Tag','3');
hnd.text(3)=uicontrol('Style','text',...
    'Parent',hFig,...
    'Position',[0 0 90 15],...
    'String','Time factor:',...
    'Visible','off',...
    'UserData',{});
% put names of Input Controls into factor lists
set(hnd.factor,'String',labels);

set(hnd.factorsPane,'dimension',[2 5], ...
    'gapx',20,...
    'border', [0 0 0 60], ...
    'colsizes',[-1 90 90 90 -1],...
    'rowsizes',[15 25],...
    'elements',{[],[], ...
    hnd.text(1),hnd.factor(1), ...
    hnd.text(2),hnd.factor(2), ...
    hnd.text(3),hnd.factor(3), ...
    [],[]});

nf= nfactors(m);
set(hnd.factor(1),'Callback', {@i_ExecuteCB, hFig, @i_Exclusive, 1});
if nf>=2
    set(hnd.factor(2),'Callback',{@i_ExecuteCB, hFig, @i_Exclusive, 2});
end
if nf>=3
    set(hnd.factor(3),'Callback',{@i_ExecuteCB, hFig, @i_Exclusive, 3});
end
% -------------------------------------
%      END Factor Selectors
% -------------------------------------

% SEE WHICH PLOTS WILL BE POSSIBLE
if nf<2
    DisplayTypes= {'2-D plot'};
    PlotVal=1;
elseif nf<3
    DisplayTypes= {'2-D plot','Surface','Contour plot'};
    PlotVal=2;
else
    DisplayTypes= {'2-D plot','Surface','Contour plot','Movie'};
    PlotVal=2;
end

% GENERAL PLOT CONTROLS
hnd.envText=uicontrol('Parent',hFig,...
    'Position',[1 1 60 15],...
    'Style','text',...
    'HorizontalAlignment','left',...
    'Value',0,...
    'String','Clipping envelope:');
hnd.Envelope=uicontrol('Parent',hFig,...
    'Position',[1 1 30 18],...
    'Style','edit',...
    'HorizontalAlignment','left',...
    'Value',0,...
    'String','1',...
    'UserData',1,...
    'Callback',{@i_ExecuteCB, hFig, @i_Envelope},...
    'BackgroundColor','w', ...
    'Tag', 'clipping_envelope');
hnd.Clip=uicontrol('Parent',hFig,...
    'Position',[1 1 70 15],...
    'Style','check',...
    'HorizontalAlignment','left',...
    'Value',0,...
    'String','Clip plot',...
    'Callback',{@i_ExecuteCB, hFig, @i_Plot});
hnd.Constraints=uicontrol('Parent',hFig,...
    'Position',[1 1 70 15],...
    'Style','check',...
    'HorizontalAlignment','left',...
    'Value',0,...
    'String','Apply constraints',...
    'Callback',{@i_ExecuteCB, hFig, @i_Plot});
hnd.BoundaryModel=uicontrol('Parent',hFig,...
    'Position',[1 1 70 15],...
    'Style','check',...
    'HorizontalAlignment','left',...
    'Value',0,...
    'String','Apply boundary model',...
    'Callback',{@i_ExecuteCB, hFig, @i_Plot});

hnd.genControls = xreggridbaglayout(hFig,...
    'dimension',[5,4],...
    'mergeblock', {[3, 3], [1, 4]}, ...
    'mergeblock', {[4, 4], [1, 4]}, ...
    'elements',{ ...
    [], [], [], []; ...
    hnd.Clip, [], hnd.envText, hnd.Envelope; ...
    hnd.Constraints, [], [], []; ...
    hnd.BoundaryModel, [], [], []; ...
    [], [], [], []}, ...
    'correctalg','on',...
    'gap',5,...
    'rowsizes',[-1 18 18 18 -1],...
    'colsizes',[100 -1 100 30]);

% LISTBOX FOR DISPLAYTYPE
choiceFrame=mbcgui.container.layoutpanel(...
    'Parent', hFig,...
    'BorderType', 'etchedin', ...
    'Title','Display type');
hnd.dispType = uicontrol('Parent',choiceFrame,...
    'Style','listbox',...
    'Visible','on',...
    'String',DisplayTypes,...
    'BackgroundColor','w',....
    'Value',PlotVal,...
    'Callback', {@i_ExecuteCB, hFig, @i_PlotStyle});

% SPECIFIC BUTTONS IN CARD LAYOUT
udv.V=[];
udv.labels=1;
udv.fill=0;

hnd.Contour= uicontrol('Parent',choiceFrame,...
    'Visible','off',...
    'Style','push',...
    'UserData',udv,...
    'String','Contours...',...
    'Callback',{@i_ExecuteCB, hFig, @i_EditContours});

if ~isempty(des) && numConstraints(des)>0
    set(hnd.Constraints,'Value',1);
    if PlotVal==2
        udv.V=[];
        udv.labels=0;
        udv.fill=1;
        set(hnd.Contour,'UserData',udv,'Visible','on');
    end
else
    set(hnd.Constraints,'Enable','off');
end

% Check for a boundary model and enable or disable check box for clipping
% to the boundary model
if isempty( bdryModel ),
    set(hnd.BoundaryModel,'Enable','off');
else
    set(hnd.BoundaryModel,'Enable','on');
end

hnd.Replay= uicontrol('Parent',choiceFrame,...
    'Visible','off',...
    'Style','push',...
    'String','Replay',...
    'Callback',{@i_ExecuteCB, hFig, @i_Replay});

frameps.text = uicontrol('Style','text',...
    'String','Frame/sec',...
    'Visible','off',...
    'HorizontalAlignment','left',...
    'Parent',choiceFrame);
hnd.framePS=mbcgui.widget.Spinner('Parent', choiceFrame,...
    'Visible','off',...
    'Min',1,...
    'Max',20,...
    'Value',2,...
    'ClickIncrement',1);


% card layout for contour, movie replay
hnd.controlsCard = xregcardlayout(choiceFrame,...
    'numcards',4,...
    'currentcard',PlotVal);
card3=xreggridbaglayout(choiceFrame,...
    'dimension',[2,3],...
    'colsizes',[-1 75 -1],...
    'rowsizes',[-1 25],...
    'elements',{[],[],[],hnd.Contour});
tempcard=xreggridbaglayout(choiceFrame,...
    'dimension',[3,2],...
    'rowsizes',[-1 20 -1],...
    'elements',{[],frameps.text,[],[],hnd.framePS,[]});
card4=xreggridbaglayout(choiceFrame,...
    'dimension',[2,5],...
    'colsizes',[-1 65 -1 110 -1],...
    'rowsizes',[-1 25],...
    'elements',{[],[],...
    [],hnd.Replay,...
    [],[],...
    [],tempcard,...
    [],[]});
attach(hnd.controlsCard, card3, 3);
attach(hnd.controlsCard, card4, 4);


% FRAME FOR LISTBOX & CARDS
hnd.plotType = xregborderlayout(choiceFrame,...
    'center',hnd.dispType,...
    'south',hnd.controlsCard,...
    'innerborder',[0 35 0 0], ...
    'border', [10 10 10 5]);
set(choiceFrame, 'LayoutComponent', {hnd.plotType});


%------------------OPTIMALITY---------------------------
optimalityFrame = mbcgui.container.layoutpanel(...
    'Parent', hFig,...
    'BorderType', 'etchedin', ...
    'title','Optimality criteria');

hnd.optimVals = mbcgui.table.InfoPane('Parent', optimalityFrame, ...
    'TitleText', {'Criteria', 'Value'}, ...
    'SplitPosition', .4, ...
    'BorderType', 'beveledin');
locLabel = uicontrol('Parent', optimalityFrame, ...
    'Style', 'text', ...
    'HorizontalAlignment', 'left', ...
    'String', 'Location of G value:', ...
    'Enable', 'inactive');
hnd.GLoc = mbcwidgets.Table2D('numeric', ...
    'parent', optimalityFrame,...
    'ShowHeaderSelection', false);
hnd.GLoc.Peer.setRowHeaderWidth(50);
hnd.GLoc.Peer.setCornerString('Factor');
hnd.optimality=uicontrol('Parent',optimalityFrame,...
    'Style','pushbutton',...
    'String','Calculate...',...
    'Callback',{@i_ExecuteCB, hFig, @i_Optimality});

hnd.optimGrid= xreggridbaglayout(optimalityFrame,...
    'dimension',[4,3],...
    'colratios',[1.5 1 0],...
    'colsizes', [-1 -1 65], ...
    'rowsizes', [15 -1 7 25], ...
    'mergeblock', {[1 1], [2 3]}, ...
    'mergeblock', {[2 2], [2 3]}, ...
    'mergeblock', {[1 2], [1 1]}, ...
    'gapx', 10, ...
    'border', [10 10 10 5], ...
    'elements',{hnd.optimVals, [], [], [], ...
    locLabel, hnd.GLoc, [], [], ...
    [], [], [], hnd.optimality});
set(optimalityFrame,'LayoutComponent', {hnd.optimGrid});


set(hnd.lhsPane,...
    'dimension',[8,1],...
    'elements',{...
    listTitle,bl_listCtrl,[],...
    hnd.genControls,[],...
    choiceFrame,[],optimalityFrame},...
    'rowsizes',[17,-1,5,83,5,-1,10,150]);


%------------------------- AXES ----------------------------
hnd.Axes=axes('Parent',hFig,...
    'Units','pixels',...
    'Position',[1 1 100 100],...
    'Box','on',...
    'NextPlot','replacechildren');
set(hnd.rhsPane,'center',hnd.Axes);

hnd.ColorBar = mbcwidgets.ColorBar('parent', hFig, ...
    'visible', 'off', ...
    'RangeEditable', false);
hnd.ColorBarCard = xregcardlayout(hFig, ...
    'numcards', 2, ...
    'border', [30 0 0 0]);
attach(hnd.ColorBarCard, hnd.ColorBar, 2);
set(hnd.rhsPane,'east',hnd.ColorBarCard,...
    'innerborder',[60 100 30 30]);

hnd.DispTable=[];
ud.Hand = hnd;

% OTHER USERDATA FIELDS
ud.Movie=[];
ud.Design= des;
ud.Model=  m;
ud.BdryModel = bdryModel;
ud.DesignX= X;
ud.OldValues = invcode(m,zeros(1,nf))';
ud.OldG=[];
ud.FigPos = [];
set(hFig,'UserData',ud)

xreg3dmenu('init')
xregwinlist(hFig);
% add help menu
mv_helpmenu(hFig,{'&PEV Viewer Help','xreg_PEVview'});

hFig.LayoutManager =  hnd.mainPane;
set(hnd.mainPane,'packstatus','on');
set(hFig,'Visible','on');

% vis on/off the factor controls then populate the listCtrl and the axes
i_PlotStyle(hFig,1);



%-------------------------------------------------------------------
% SUBFUNCTION i_GetValues
%-------------------------------------------------------------------
function [x,XVar,YVar,TVar]=i_GetValues(hFig)
ud = get(hFig,'UserData');
h=ud.Hand;

x= get(h.listCtrl,'Values');
% returns cell array, each celement is the Input factor vector
XVar = get(h.factor(1),'Value');
YVar = get(h.factor(2),'Value');
TVar = get(h.factor(3),'Value');



%-------------------------------------------------------------------
% SUBFUNCTION i_Controls (making/re-making the input controls)
%-------------------------------------------------------------------
function i_Controls(hFig,Start)

ud = get(hFig,'UserData');
h = ud.Hand;
m = ud.Model;

DispType= get(h.dispType,'Value');

[x,XVar,YVar,TVar]=i_GetValues(hFig);

% at startup
if nargin>1 && Start
    x = cell(nfactors(m),1);
end

switch DispType
    case 1
        % 2-D plot
        YVar=[];
        TVar=[];
    case {2,3}
        % surface, contour
        TVar=[];
end

% CHECK if factor selectors have come visible ON
% maybe they have same vals as other selectors
numActive = length([XVar,YVar,TVar]);
factors = get(h.factor,'Value');
if length(factors)>1, factors = [factors{:}]; end;
factors = factors(1:numActive);

% work out default values
[L,U]= range(m);

% =============================================================
%                MAKING NEW CONTROLS
% =============================================================
labels= get(m,'symbol');
%NewVal ={};
NewControls = {};
listpanel = get(h.listCtrl,'frame');
for inputNum = 1:nfactors(m)
    if ~any(inputNum==factors) % if inputNum NOT any of the factors
        if length(x{inputNum})~=1
            %        NewVal= {NewVal{:},(L(inputNum)+U(inputNum))/2};
            tmp = xregclickinput(listpanel,...
                'name',labels{inputNum},...
                'Min',L(inputNum),'Max',U(inputNum),...
                'ClickIncrement',10^(floor(log10(abs(U(inputNum) - L(inputNum))))-1));
            set(tmp,'Value',(L(inputNum)+U(inputNum))/2);
            NewControls = [NewControls, {tmp}]; %#ok<AGROW>
        else
            %         NewVal= {NewVal{:},x{inputNum}};
            tmp = xregclickinput(listpanel,...
                'name',labels{inputNum},...
                'Min',L(inputNum),'Max',U(inputNum),...
                'ClickIncrement',10^(floor(log10(abs(U(inputNum) - L(inputNum))))-1));
            set(tmp,'Value',x{inputNum});
            NewControls = [NewControls,{tmp}]; %#ok<AGROW>
        end
    elseif isempty(x{inputNum}) ||  length(x{inputNum})==1
        % DispType=2=table can have size of 1
        if ~isempty(TVar) && inputNum==TVar
            N= 5; %num movie frames
        else
            N=21;
        end
        tmp = xregrangeinput(listpanel,'name',labels{inputNum},...
            'value',linspace(L(inputNum),U(inputNum),N));
        NewControls = [NewControls,{tmp}]; %#ok<AGROW>
    else %everything is okay!
        tmp = xregrangeinput(listpanel,'name',labels{inputNum},...
            'value',x{inputNum});
        NewControls = [NewControls,{tmp}]; %#ok<AGROW>
    end
end
set(h.listCtrl,'controls',NewControls);
set(h.listCtrl,'Callback',{@i_ExecuteCB, hFig, @i_CheckVal});

% now display the plot
i_Plot(hFig);

%-------------------------------------------------------------------
% SUBFUNCTION i_Exclusive (exclusivity for factor controls)
%-------------------------------------------------------------------
function i_Exclusive(hFig,factorNum)
% exclusive factor choice from popupmenu selectors
ud= get(hFig,'UserData');
h = ud.Hand;

facs = get(h.factor,'Value');
if length(facs)>1, facs = [facs{:}]; end;
% what if < 3 inputs??
numControls = size(h.listCtrl);
if numControls < length(facs)
    facs = facs(1:numControls);
end

if length(unique(facs))~=length(facs)
    % h.factor(factorNum) is the one just changed
    % keep this the same and change another factor
    change = setdiff(find(facs==facs(factorNum)),factorNum);
    numEls = length(get(h.factor(change(1)),'String'));
    freeEls = setdiff(1:numEls,facs);
    if ~isempty(freeEls)
        set(h.factor(change),'Value',freeEls(1));
    end
end
% now redraw input controls
i_Controls(hFig);

%-------------------------------------------------------------------
% SUBFUNCTION i_PlotStyle (called by listBox: vis on/off for factor controls)
%-------------------------------------------------------------------
function i_PlotStyle(hFig,Start)
% set factors vis on vis off, then go make new controls i_Controls

ud= get(hFig,'UserData');
h = ud.Hand;

NewType= get(h.dispType,'Value');
set(h.controlsCard,'currentcard',NewType);

set([h.factor(1),h.text(1)],'Visible','on');

% switch on/off print menu (off for movie)
printMenuH = findobj(ud.Hand.File,'Tag','printmenu');

switch NewType
    case 1
        set([h.factor(2),h.text(2)],'Visible','off');
        set([h.factor(3),h.text(3)],'Visible','off');
        set(printMenuH,'Enable','on');
        xreg3dmenu('2dmenus');
    case {2,3}
        set([h.factor(2),h.text(2)],'Visible','on');
        set([h.factor(3),h.text(3)],'Visible','off');
        set(printMenuH,'Enable','on');
        if NewType==2
            xreg3dmenu('3dmenus');
        else
            xreg3dmenu('2dmenus');
        end
    case 4
        set([h.factor(2),h.text(2)],'Visible','on');
        set([h.factor(3),h.text(3)],'Visible','on');
        % switch off print menu
        set(printMenuH,'Enable','off');
        xreg3dmenu('3dmenus');
end
set(hFig,'UserData',ud);

% now set up correct input controls
% this will call i_Plot
if nargin>1
    i_Controls(hFig,Start);
else
    i_Controls(hFig);
end


%-------------------------------------------------------------------
% SUBFUNCTION i_Plot
%-------------------------------------------------------------------
function i_Plot(hFig)
ud= get(hFig,'UserData');
h = ud.Hand;

PlotStyle= get(h.dispType,'Value');

[Values,XVar,YVar,TVar] = i_GetValues(hFig);

labels = get(h.listCtrl,'Name');
Xlab= labels{XVar};

mv_rotate3d(ud.Hand.Axes,'off')
xregorbit3d(hFig,'off');
set(ud.Hand.Axes,'XLimMode','auto','YLimMode','auto')

% contour for clipping and clip yes/no
EnvVal= get(h.Envelope,'UserData');
Clip= get(h.Clip,'Value');

if isgraphics(h.Light)
    [ud.Setup.viewaz,ud.Setup.viewel]=view(h.Axes);
end
ud.Setup.CurView= get(h.Axes,'View');


ok=rankcheck(ud.Design) & isoptimcapable(ud.Design);


USE_CBAR = false;
if ok
    switch PlotStyle
        case 1
            if isgraphics(h.Light)
                ud.Setup.lightpos=get(h.Light,'Position');
            end
            [PEV,~,Xg] = pevgrid(ud.Design,Values,1);
            if Clip
                PEV(PEV>EnvVal)=NaN;
            end     
            
            in = i_GetBoundaryValues(ud, Xg, size(PEV), 1);
            if ~isempty(in)
                PEV(~in) = NaN;
            end

            delete(get(h.Axes,'Children'));
            reset(h.Axes);
            
            plot(Values{XVar},squeeze(PEV),'Parent',h.Axes);
            set(h.Axes,'XGrid','on','YGrid','on');
            set(get(h.Axes,'XLabel'),'String',Xlab,'Interpreter','none')
            set(get(h.Axes,'YLabel'),'String','Predicted Error Variance')
            ud.Movie = [];
            set(h.Axes,'Box','on');
            if ud.Setup.viewaz~=0 || ud.Setup.viewel~=90
                view(h.Axes,2);
                [ud.Setup.viewaz,ud.Setup.viewel] = view(h.Axes);
                ud.Setup.CurView= get(h.Axes,'View');
            end

        case {2,3}
            Ylab= labels{YVar};

            [PEV,X,Xg] = pevgrid(ud.Design,Values,1);
            PEV2=PEV;

            % Compute the boundary (if required)
            bdry = i_GetBoundaryValues(ud, Xg, size(PEV2), 0);
            
            if isgraphics(h.Light)
                ud.Setup.lightpos=get(ud.Hand.Light,'Position');
            end
            
            if PlotStyle==2
                set(h.Axes,'ZLimMode','auto')
                ud=i_SurfacePlot(X{XVar},X{YVar},PEV2,ud,EnvVal,Clip,bdry);
                set(get(h.Axes,'XLabel'),'String',Xlab,'Interpreter','none')
                set(get(h.Axes,'YLabel'),'String',Ylab,'Interpreter','none')
                set(get(h.Axes,'ZLabel'),'String','Predicted Error Variance')

                if ud.Setup.viewaz==0 && ud.Setup.viewel==90
                    view(h.Axes,3);
                    [ud.Setup.viewaz,ud.Setup.viewel]=view(h.Axes);
                    ud.Setup.CurView= get(h.Axes,'View');
                end

                set(hFig,'UserData',ud);
            else
                if isgraphics(h.Light)
                    ud.Setup.lightpos=get(h.Light,'Position');
                end
                delete(get(h.Axes,'Children'));
                reset(h.Axes);
                repack(ud.Hand.mainPane)

                udv= get(h.Contour,'UserData');
                V= udv.V;
                if isempty(V)
                    hp=plot(squeeze(PEV2),'Parent',h.Axes);
                    V= get(h.Axes,'YTick');
                    if length(V)<10;
                        Vd=V(2)-V(1);
                        V= V(1):Vd/5:V(end);
                    end
                    delete(hp);
                end
                if Clip && length(V)>1
                    V(V>EnvVal)=[];
                end
                
                if ~isempty(bdry)
                    PEV2(bdry>0) = NaN;
                end
                
                if ~isempty(V) && any(isfinite(PEV2(:)));

                    set(hFig,'CurrentAxes',h.Axes);
                    EnvCol= 'k-';
                    if udv.fill
                        if isempty(bdry) && ~Clip
                            EnvCol= 'w-';
                        end
                        [c,hc]=contourf(h.Axes,squeeze(X{XVar}),squeeze(X{YVar}),squeeze(PEV2),V);
                    else
                        [c,hc]=contour(h.Axes,squeeze(X{XVar}),squeeze(X{YVar}),squeeze(PEV2),V);
                    end
                    set(ud.Hand.Axes,'XGrid','on','YGrid','on');

                    % label contours (inline labels)
                    if ~isempty(c) && udv.labels   
                        clabel(c,hc,'color','k');
                    else
                        % Use a colorbar
                        USE_CBAR = true;
                    end

                else
                    EnvCol= 'k-';
                    set(h.Axes,...
                        'Box','on',...
                        'XLim',Values{XVar}([1 end]),'YLim',Values{YVar}([1 end]))
                end
                if isfinite(EnvVal) && EnvVal>0
                    np=get(h.Axes,'NextPlot');
                    set(h.Axes,'NextPlot','add');
                    [~,hc]=contour(h.Axes,squeeze(X{XVar}),squeeze(X{YVar}),squeeze(PEV),[EnvVal EnvVal],EnvCol);
                    set(hc,'LineWidth',2)
                    set(h.Axes,'NextPlot',np,'Box','on');
                end
                set(get(h.Axes,'XLabel'),'String',Xlab,'Interpreter','none');
                set(get(h.Axes,'YLabel'),'String',Ylab,'Interpreter','none');
                set(get(h.Axes,'Title'),'String','Prediction Error Variance');
                if ud.Setup.viewaz~=0 || ud.Setup.viewel~=90
                    view(h.Axes,2);
                    [ud.Setup.viewaz,ud.Setup.viewel]=view(h.Axes);
                    ud.Setup.CurView= get(h.Axes,'View');
                end
            end
            ud.Movie = [];
        case 4
            Ylab= labels{YVar};
            Tlab= labels{TVar};


            if isgraphics(h.Light)
                ud.Setup.lightpos=get(h.Light,'Position');
            end
            % Area for Movie GetFrame
            MovieFrame= get(ud.Hand.Axes,'Position');
            FigPos = get(hFig,'Position');
            ud.FigPos = FigPos;
            % make sure the movie frame is inside the figure
            MovieFrame(1:2) = max( MovieFrame(1:2),[1 1]);
            MovieFrame(3:4) = min( MovieFrame(3:4)*1.2,FigPos(3:4)-MovieFrame(1:2)-1);

            [PEV, X, Xg] = pevgrid(ud.Design,Values,1);
            PEV2=PEV;
            if Clip
                PEV2(PEV>EnvVal)=NaN;
            end

            % Compute the boundary (if required)
            bdry = i_GetBoundaryValues(ud, Xg, size(PEV), 0);
            
            s = struct('type','()','subs',{repmat({':'},length(Values),1)});
            s.subs{TVar}= 1;
            X{XVar}= subsref(X{XVar},s);
            X{YVar}= subsref(X{YVar},s);
            allh= findobj(get(h.Axes,'Children'));
            lh= ud.Hand.Light;
            if ~isempty(lh)
                allh=allh(allh~=lh);
            end
            delete(allh);
            set(h.Axes,'YLimMode','auto')
            hnd= plot(PEV2(:),'Parent',h.Axes);
            zlim=get(h.Axes,'YLim');
            set(h.Axes,'ZLimMode','manual','ZLim',zlim)
            delete(hnd);
            if ud.Setup.viewaz==0 && ud.Setup.viewel==90
                view(ud.Hand.Axes,3);
                [ud.Setup.viewaz,ud.Setup.viewel]=view(ud.Hand.Axes);
                ud.Setup.CurView= get(h.Axes,'View');
            end

            for i=1:length(Values{TVar})
                s.subs{TVar}= i;
                PEVt= subsref(PEV,s);
                if isempty(bdry)
                    ud = i_SurfacePlot(X{XVar},X{YVar},PEVt,ud,EnvVal,Clip);
                else
                    ud = i_SurfacePlot(X{XVar},X{YVar},PEVt,ud,EnvVal,Clip, subsref(bdry, s));
                end
                set(get(h.Axes,'XLabel'),'String',Xlab,'Interpreter','none')
                set(get(h.Axes,'YLabel'),'String',Ylab,'Interpreter','none')
                set(get(h.Axes,'ZLabel'),'String','Predicted Error Variance')

                tstr= sprintf('%s=%4.2f',Tlab,Values{TVar}(i));
                set(get(h.Axes,'Title'),'String',tstr)

                set(h.Axes,'ZLim',zlim)
                drawnow('expose');
                % Grab frame for movie
                M(i)= getframe(hFig,MovieFrame); %#ok<AGROW>
            end

            % Save Movie if more than one time value
            ud.Movie = M;
    end
    view(h.Axes,ud.Setup.CurView);
else
    delete(get(h.Axes,'Children'));
    reset(h.Axes);
    % add a text item explaining reason for display problem
    text(0.5,0.5,{'PEV is unavailable; either the design matrix is rank-deficient,';...
        'or the current model does not support PEV calculations.'},...
        'Parent',h.Axes,'HorizontalAlignment','center')
end

if USE_CBAR
    setRange(h.ColorBar, get(h.Axes, 'CLim'));
    set(h.ColorBarCard, 'currentcard', 2);
    set(h.rhsPane, 'innerborder', [60 100 90 30]);
else
    set(h.ColorBarCard, 'currentcard', 1);
    set(h.rhsPane, 'innerborder', [60 100 30 30]);
end

set(hFig,'UserData',ud);


function bdry = i_GetBoundaryValues(ud, Xg, Size, ConFcn)
if nargin<4
    % Just check whether points are inside or not
    ConFcn = 1;
end

% Compute the boundary (if required)
h = ud.Hand;
designCon = constraints( ud.Design );
useDesignCon = get( h.Constraints,   'Value')  && ~isempty( designCon );
useBdryModel = get( h.BoundaryModel, 'Value' ) && ~isempty( ud.BdryModel );
if useDesignCon || useBdryModel
    % Xg is in coded units. However to evaluate any constraints or
    % boundary models we need to convert in natural units.
    Xg = invcode( ud.Model, Xg );
    
    % Design constraint
    if useDesignCon
        designCon = reset( designCon );
        if ConFcn==0
            b1 = constraintDistance(designCon, Xg);
        else
            [~,b1] = isInside(designCon, Xg);
        end
    end
    
    % Boundary constraint
    if useBdryModel
        if ConFcn==0
            b2 = constraintDistance(ud.BdryModel, Xg);
        else
            b2 = isInside(ud.BdryModel, Xg, true(size(Xg, 1),1));
        end
    end
    
    % Combine chosen pieces
    if useDesignCon && useBdryModel
        if ConFcn==0
            bdry = max( b1, b2 );
        else
            bdry = b1 & b2;
        end
    elseif useDesignCon % && ~useBdryModel
        bdry = b1;
    else % if ~useDesignCon && useBdryModel
        bdry = b2;
    end
    bdry = reshape( bdry, Size );
else
    % NO constraints
    bdry = [];
end










%-------------------------------------------------------------------
% SUBFUNCTION i_SurfacePlot
%-------------------------------------------------------------------
function [ud,hs]=i_SurfacePlot(X,Y,PEV,ud,EnvVal,PevClip,Bdry)
lh= ud.Hand.Light;

Col= 'w';
if PevClip,
    Col = 'k';
end

BdryClip = nargin >= 7 && ~isempty( Bdry );

Clip = BdryClip | PevClip;

if BdryClip && PevClip,
    pevBdry = PEV - EnvVal;
    bdryRange = max( Bdry(:) ) - min( Bdry(:) );
    pevRange = max( pevBdry(:) ) - min( pevBdry(:) );
    Bdry = max( Bdry/bdryRange, pevBdry/pevRange );
elseif PevClip,
    Bdry = PEV - EnvVal;
end

PEVClipped = PEV;


hFig= get(ud.Hand.Axes,'Parent');
np=get(ud.Hand.Axes,'NextPlot');
delete(get(ud.Hand.Axes,'Children'));

if Clip,
    PEVClipped(Bdry>0) = NaN;
    hs = xregsurfaceb( squeeze( X ), squeeze( Y ), squeeze( PEV ), ...
        squeeze( Bdry ), squeeze( PEV ), ...
        'DisplayExterior','off',...
        'FaceColor','interp',...
        'EdgeColor','none',...
        'FaceLighting','gouraud',...
        'BackFaceLighting','reverselit',...
        'Parent',ud.Hand.Axes);
else
    hs=surf(squeeze(X),squeeze(Y),squeeze(PEV),squeeze(PEV),...
        'FaceColor','interp',...
        'EdgeColor','none',...
        'FaceLighting','gouraud',...
        'BackFaceLighting','reverselit',...
        'Parent',ud.Hand.Axes);
end

set(ud.Hand.Axes,'NextPlot','add');
set(hFig,'CurrentAxes',ud.Hand.Axes);
if any(isfinite(PEVClipped(:)))
    % add a contour at clipped PEV value
    [~,hc]=contour3(ud.Hand.Axes,squeeze(X),squeeze(Y),squeeze(PEVClipped),[EnvVal EnvVal],'w-');
    % 
    set(hc,'LineWidth',2,'LineColor',Col);
end
set(ud.Hand.Axes,'NextPlot',np);
if isempty(lh)
    % try to guess some positions for a light
    lims= get(ud.Hand.Axes,{'XLim','YLim','ZLim'});
    ud.Setup.lightpos=[lims{1}(1),mean([lims{2}(1),lims{2}(2)]),lims{3}(2)];
end

ud.Hand.Light=light('Parent',ud.Hand.Axes,...
    'Position',ud.Setup.lightpos,...
    'Color','w',...
    'Style','local');
    
if strcmp(get(ud.Hand.LightMenu,'Checked'),'off')
    set(ud.Hand.Light,'Visible','off');
end
set(hFig,'UserData',ud);
xreg3dmenu('updateplot')




%-------------------------------------------------------------------
% SUBFUNCTION i_CheckVal (call back on input controls)
%-------------------------------------------------------------------
function i_CheckVal(hFig)
% check if too many points requested
x=i_GetValues(hFig);
numPoints = prod(cellfun('length',x));
if numPoints > 50000
    errordlg('Too many plot points requested. Please input a smaller number.',...
        'Plot error','modal');
    drawnow;
else
    i_Plot(hFig);
end




%-------------------------------------------------------------------
% SUBFUNCTION i_Replay
%-------------------------------------------------------------------
function i_Replay(hFig)

ud= get(hFig,'UserData');
if ~isequal(ud.FigPos,get(hFig,'Position'))
    % figure size has changed - regenerate movie
    i_Plot(hFig)
    ud= get(hFig,'UserData');
    % now replay at the correct rate
end

% replay the movie if it exists
fps = get(ud.Hand.framePS,'Value');
if ~isempty(ud.Movie);
    movie(ud.Hand.Axes,ud.Movie,1,fps);
end

%-------------------------------------------------------------------
% SUBFUNCTION i_Optimality
%-------------------------------------------------------------------
function hFig=i_Optimality(ParFig)

ud= get(ParFig,'UserData');

ok=rankcheck(ud.Design) & isoptimcapable(ud.Design);
if ~ok
    hFig=[];
    return
end


hFig = findobj(allchild(0),'flat','Tag','mvOptM');
if isempty(hFig)
    figHeight = 300;
    figWidth = 270;
    hFig= xregfigure('Visible','off',...
        'Name','Optimality Calculations',...
        'Tag','mvOptM',...
        'HandleVisibility','callback',...
        'Resize','off');
    % centre optimality dialog in PEV figure
    xregcenterfigure(hFig,[figWidth,figHeight],ParFig);

    Gframe = mbcgui.container.layoutpanel(...
        'Parent', hFig, ...
        'Title', 'G-optimal value locations', ...
        'BorderType', 'etchedin');
    
    h.hDlgCritVals = mbcgui.table.InfoPane('Parent', hFig, ...
        'SplitPosition', .4, ...
        'TitleText', {'Criteria', 'Value'}, ...
        'BorderType', 'beveledin');
    h.hStartPoints = mbcgui.widget.Spinner('Parent', Gframe, ...
        'Min', 1, ...
        'Max', 20, ...
        'Rule', 'int', ...
        'Value', 4, ...
        'Callback', {@i_doGopt, hFig, ParFig});
    hStartLabel = xregGui.labelcontrol('parent', Gframe, ...
        'ControlSize', 50, ...
        'LabelSizeMode', 'absolute', ...
        'LabelSize', 140, ...
        'String', 'Number of starting points:', ...
        'Control', h.hStartPoints);
    h.hDlgGTable = mbcwidgets.Table1D('numeric',  ...
        'parent', Gframe, ...
        'SelectionMode', 'MultiRegion');
    closeBtn = uicontrol('Style','pushbutton',...
        'Parent',hFig,...
        'String','Close',...
        'Callback',{@i_deletefig, hFig});
    helpBtn = mv_helpbutton(hFig,'xreg_pev_optimality');

    Ggrid = xreggridbaglayout(Gframe, ...
        'packstatus', 'off', ...
        'dimension', [2 1], ...
        'rowsizes', [20 -1], ...
        'gapy', 5, ...
        'border', [10 10 10 5], ...
        'elements', {hStartLabel, h.hDlgGTable});
    set(Gframe, 'LayoutComponent', {Ggrid});
    Grid = xreggridbaglayout(hFig,...
        'dimension',[3,3],...
        'colsizes',[-1,65,65],...
        'rowsizes', [100 -1 25], ...
        'gap', 7, ...
        'mergeblock', {[1 1], [1 3]}, ...
        'mergeblock', {[2 2], [1 3]}, ...
        'border', [7 7 7 7], ...
        'elements',{h.hDlgCritVals, Gframe, [], ...
        [], [], closeBtn, [], [], helpBtn});

    hFig.LayoutManager = Grid;
    set(Grid, 'packstatus', 'on');

    h.Names = {'D';'V';'G';'A'};
    h.Values = {'';'';'';''};

    set(hFig,'UserData',h,'Visible','on')
else
    figure(hFig);
    h = get(hFig,'UserData');
end

PR = xregGui.PointerRepository;
ptrID = PR.stackSetPointer(hFig, 'watch');

NumPts = h.hStartPoints.Value;
[opt.D, ud.design] = dcalc(ud.Design);
[opt.V,ud.Design]= vcalc(ud.Design,1);
[~,ud.Design,X]= gcalc(ud.Design,1,'sample',NumPts);
opt.G = X(:,1);
X = X(:,2:end);
opt.A = acalc(ud.Design);

% Convert values into display strings
Use = true(size(h.Names));
for n = 1:length(h.Names);
    if ~isempty(opt.(h.Names{n}))
        h.Values{n} = sprintf('%.3g', opt.(h.Names{n})(1));
    else
        h.Values{n} = '';
        Use(n) = false;
    end
end
labels = get(ud.Model,'symbol');

Xunc = invcode(ud.Model,X);

% Update main gui
set(ud.Hand.optimVals, 'ListText', [h.Names(Use), h.Values(Use)]);
ud.Hand.GLoc.Peer.setTableData(Xunc(1,:)');
ud.Hand.GLoc.Peer.setRowData(labels);

% Update dialog
h.hDlgCritVals.ListText = [h.Names(Use), h.Values(Use)];
h.hDlgGTable.Peer.setData([opt.G,Xunc], [{'PEV'}, labels(:)']);

PR.stackRemovePointer(hFig, ptrID);

set(hFig,'UserData', h);
set(ParFig,'UserData',ud);


function i_deletefig(~, ~, hFig)
delete(hFig);


%-------------------------------------------------------------------
% SUBFUNCTION i_StartGOpt
%-------------------------------------------------------------------
function i_doGopt(hStartPoints, ~, hDlg, hPEVView)

PR = xregGui.PointerRepository;
ptrID = PR.stackSetPointer(hDlg, 'watch');
ud = get(hPEVView,'UserData');
h = get(hDlg,'UserData');
NumPts= hStartPoints.Value;

[~,~,G] = gcalc(ud.Design,1,'sample',NumPts);
X = G(:,2:end);
G = G(:,1);
labels = get(ud.Model,'symbol');
Xunc = invcode(ud.Model,X);

Gidx = strcmp('G', h.Names);
h.Values{Gidx} = sprintf('%.3g', G(1));
Use = ~cellfun('isempty', h.Values);

% Update main gui
set(ud.Hand.optimVals, 'ListText', [h.Names(Use), h.Values(Use)]);
ud.Hand.GLoc.Peer.setTableData(Xunc(1,:)');
ud.Hand.GLoc.Peer.setRowData(labels);


% Update dialog
h.hDlgCritVals.ListText = [h.Names(Use), h.Values(Use)];
h.hDlgGTable.Peer.setData([G,Xunc], [{'PEV'}, labels(:)']);

PR.stackRemovePointer(hDlg, ptrID);
set(hDlg, 'UserData', h);


%-------------------------------------------------------------------
% SUBFUNCTION i_Envelope
%-------------------------------------------------------------------
function i_Envelope(hFig)
ud = get(hFig, 'UserData');
if xregCheckIsNum(ud.Hand.Envelope,'range',[0 inf]);
    i_Plot(hFig);
end

%-------------------------------------------------------------------
% SUBFUNCTION i_Update
%-------------------------------------------------------------------
function i_Update(hFig,m,x,des, bdryModel )
ud= get(hFig,'UserData');

if nargin < 5,
    bdryModel = [];
end

if nargin >= 4
    if isoptimcapable(des)
        des= InitStore(des);
    end
    ud.Design= des;
    ud.Model= model(des);
    ud.DesignX= factorsettings(des);
else
    ud.Design= [];
    ud.Model= InitStore(m,x);
    ud.DesignX= x;
end
ud.Movie=[];
ud.BdryModel = bdryModel;

if isfield(ud.Hand,'Constraints')
    if ~isempty(des) && numConstraints(des)>0
        set(ud.Hand.Constraints,'Enable','on');
    else
        set(ud.Hand.Constraints,'Enable','off','Value',0);
    end
end
if isfield(ud.Hand,'BoundaryModel')
    if ~isempty( bdryModel )
        set(ud.Hand.BoundaryModel,'Enable','on');
    else
        set(ud.Hand.BoundaryModel,'Enable','off','Value',0);
    end
end
set(hFig,'UserData',ud,'CurrentAxes',ud.Hand.Axes);
i_Plot(hFig);

drawnow
% update optimality criteria
f=i_Optimality(hFig);
close(f);

%-------------------------------------------------------------------
% SUBFUNCTION i_Print
%-------------------------------------------------------------------
function i_Print(hFig)

TitleStr = 'Prediction Error Variance';

ud= get(hFig,'UserData');
DispType= get(ud.Hand.dispType,'Value');

if DispType~=4
        % currently not printing movie
        inputs = char(ud.Hand.listCtrl);
        inputs = {'Input Factors','',inputs{:}};

        fh = figure('Visible','off');
        lay = xreglayerlayout(fh,'border',[80 20 20 50]);
        font=get(0,'FixedWidthFontName');
        tH = axestext(fh,'units','pixels',...
            'fontweight','demi',...
            'fontName',font,...
            'interpreter','none',...
            'string',inputs);
        set(lay,'elements',{tH},'position',get(tH,'Extent'));

        % Need to make sure axes are visible or printlayout1 errors
        axVis = get(ud.Hand.Axes, 'Visible');
        set(ud.Hand.Axes, 'Visible','on');
        printlayout1(ud.Hand.Axes,lay,TitleStr);
        set(ud.Hand.Axes, 'Visible',axVis);
        close(fh);
end


% Callback execution wrapper that toggles the pointer to a watch before
% executing the callback.
function i_ExecuteCB(~, ~, hFig, CBFcn, varargin)
PR = xregGui.PointerRepository;
ptrID = PR.stackSetPointer(hFig, 'watch');

CBFcn(hFig, varargin{:});

PR.stackRemovePointer(hFig, ptrID);


function i_EditContours(hFig)
ud = get(hFig, 'UserData');
CVals = get(ud.Hand.Contour, 'UserData');
[CVals, OK] = mv_ContourValues(CVals);
if OK
    set(ud.Hand.Contour, 'UserData', CVals);
    i_Plot(hFig);
end