classdef ColorGraphFuxin < AbstractGraph
%COLORGRAPHFUXIN is a variant of ColorGraph, which generates graphs with
% seeds and unaries using color information. This class is derived from
% AbstractGraph. To undestand how unaries are generated, its worth seeing
% how AbstractGraph.prepare_graphs() calls create_unaries() in this class
% to compute unary values.
%
% @authors:     Fuxin Li
% @contact:     ahumayun@cc.gatech.edu
% @affiliation: Georgia Institute of Technology
% @date:        Fall 2013 - Summer 2014

    properties
        precompute
    end

    methods
        function obj = ColorGraphFuxin(seg_obj, segm_index)
            obj.init(seg_obj, segm_index);

            obj.precompute.bg_unary_values = [];
            obj.precompute.clr_unary_hash = {};
            obj.precompute.clr_unary_values = {};
        end

        function create_unaries(obj, graph_sub_method, seed_sets)
            switch graph_sub_method
                case 'internal'
                    obj.generate_color_unaries('internal', seed_sets);
                case 'external'
                    obj.generate_color_unaries('external', seed_sets);
                case 'external2'
                    obj.generate_color_unaries('external2',seed_sets);
                case 'subframe'
                    error('ColorGraph:compute_graph', ...
                          '''subframe'' not implemented yet');
                otherwise
                    error('ColorGraph:compute_graph', ...
                          '''%s'' is an invalid graph method', ...
                          graph_sub_method);
            end
        end

        function generate_color_unaries(obj, internal_external, seed_sets)
            inside_frame = ~obj.seg_obj.sp_frame_set;

            funcs = create_unary_aux_funcs(obj, internal_external);

            [bg_unary_values, clr_unary_vals] = ...
                precompute_return_data(obj, funcs, seed_sets, ...
                                       inside_frame, internal_external);

            % find the offset according to the number of unary graphs
            % already added to graph_unaries_all
            ofst = size(obj.graph_unaries_all.nonlambda_s,2);

            % initialize the matrices for holding all the unaries (see the
            % comment for this structure in AbstractGraph.prepare_graphs())
            obj.graph_unaries_all.nonlambda_s = ...
                [obj.graph_unaries_all.nonlambda_s, zeros(size(seed_sets))];
            obj.graph_unaries_all.nonlambda_t = ...
                [obj.graph_unaries_all.nonlambda_t, zeros(size(seed_sets))];
            obj.graph_unaries_all.lambda_s = ...
                [obj.graph_unaries_all.lambda_s, zeros(size(seed_sets))];
            obj.graph_unaries_all.lambda_t = ...
                [obj.graph_unaries_all.lambda_t, zeros(size(seed_sets))];

            % iterate over all seed locations
            for i = 1:size(seed_sets, 2)
                if strcmp(internal_external, 'internal')
                    [nonlambda_s, lambda_t] = internal_color(obj, ...
                                                   seed_sets(:,i), ...
                                                   clr_unary_vals(:,i));

                    obj.graph_unaries_all.nonlambda_s(:,ofst+i) = ...
                                                               nonlambda_s;
                    obj.graph_unaries_all.lambda_t(:,ofst+i) = lambda_t;
                elseif strcmp(internal_external,'external')
                    [nonlambda_s, nonlambda_t, lambda_s, lambda_t] = ...
                        external_color(obj, seed_sets(:,i), ...
                                       inside_frame, bg_unary_values, ...
                                       clr_unary_vals(:,i), ...
                                       funcs.parametric_func, ...
                                       funcs.frame_cost_func);

                    obj.graph_unaries_all.nonlambda_s(:,ofst+i) = ...
                                                               nonlambda_s;
                    obj.graph_unaries_all.nonlambda_t(:,ofst+i) = ...
                                                               nonlambda_t;
                    obj.graph_unaries_all.lambda_s(:,ofst+i) = lambda_s;
                    obj.graph_unaries_all.lambda_t(:,ofst+i) = lambda_t;
                else
                    [nonlambda_s, nonlambda_t, lambda_s, lambda_t] = ...
                        external_color2(obj, seed_sets(:,i), ...
                                       inside_frame, bg_unary_values, ...
                                       clr_unary_vals(:,i), ...
                                       funcs.parametric_func);

                    obj.graph_unaries_all.nonlambda_s(:,ofst+i) = ...
                                                               nonlambda_s;
                    obj.graph_unaries_all.nonlambda_t(:,ofst+i) = ...
                                                               nonlambda_t;
                    obj.graph_unaries_all.lambda_s(:,ofst+i) = lambda_s;
                    obj.graph_unaries_all.lambda_t(:,ofst+i) = lambda_t;
                end
            end
        end

        function [nonlambda_s, lambda_t] = internal_color(obj, ...
                                                fg_seeds, unary_values)
            % see the comment for these output matrices in
            % AbstractGraph.prepare_graphs()
            nonlambda_s = zeros(length(fg_seeds),1);
            lambda_t = zeros(length(fg_seeds),1);

            bground_pixels = ~fg_seeds;
            nonlambda_s(fg_seeds) = inf;
            nonlambda_s(bground_pixels) = unary_values(bground_pixels)*2;
            lambda_t(bground_pixels) = 1;
        end

        function [nonlambda_s, nonlambda_t, lambda_s, lambda_t] = ...
                external_color(obj, fg_seeds, inside_frame, ...
                               bg_unary_values, fg_unary_values, ...
                               parametric_func, frame_cost_func)
            % see the comment for these output matrices in
            % AbstractGraph.prepare_graphs()
            nonlambda_s = zeros(length(fg_seeds),1);
            nonlambda_t = zeros(length(fg_seeds),1);
            lambda_s = zeros(length(fg_seeds),1);
            lambda_t = zeros(length(fg_seeds),1);

            non_seed_pixels = inside_frame & ~fg_seeds;
            lambda_weights = parametric_func(non_seed_pixels);
            bground_pixels = ~(inside_frame | obj.seg_obj.sp_frame_set);

            % internal seed - topological constraint
            nonlambda_s(fg_seeds) = inf;
            % external seed - topological constraint
            nonlambda_t(bground_pixels) = inf;

            % not we dont need to add values because non_seed_pixels is a
            % subset of inside_frame and bground_pixels is outside
            % inside_frame
            nonlambda_t(non_seed_pixels) = bg_unary_values(non_seed_pixels) * 2;
            % unary potential reflecting similarity to fg_seeds pixels
            nonlambda_s(non_seed_pixels) = fg_unary_values(non_seed_pixels) * 2;
            % parametric potential
            lambda_s(non_seed_pixels) = lambda_weights;

            frame_cost = frame_cost_func(fg_seeds);

%           frame_cost = obj.frame_bg_bias(fg_seeds, size(obj.I));
            %frame_cost = 1;
            % always have some frame soft bias to belong in the background
            nonlambda_t(obj.seg_obj.sp_frame_set) = ...
                nonlambda_t(obj.seg_obj.sp_frame_set) + ...
                frame_cost*obj.SEED_FRAME_WEIGHT;
            % parametric potential
            lambda_t(non_seed_pixels) = lambda_weights;
        end

        function [nonlambda_s, nonlambda_t, lambda_s, lambda_t] = ...
                external_color2(obj, fg_seeds, inside_frame, ...
                               bg_unary_values, fg_unary_values, ...
                               parametric_func)
            % see the comment for these output matrices in
            % AbstractGraph.prepare_graphs()
            nonlambda_s = zeros(length(fg_seeds),1);
            nonlambda_t = zeros(length(fg_seeds),1);
            lambda_s = zeros(length(fg_seeds),1);
            lambda_t = zeros(length(fg_seeds),1);

            non_seed_pixels = ~fg_seeds;
            lambda_weights = parametric_func(non_seed_pixels);
            bground_pixels = ~(inside_frame | obj.seg_obj.sp_frame_set);

            % internal seed - topological constraint
            nonlambda_s(fg_seeds) = inf;
            % external seed - topological constraint
            nonlambda_t(bground_pixels) = inf;

            % not we dont need to add values because non_seed_pixels is a
            % subset of inside_frame and bground_pixels is outside
            % inside_frame
            nonlambda_t(non_seed_pixels) = bg_unary_values(non_seed_pixels) * 2;
            % unary potential reflecting similarity to fg_seeds pixels
            nonlambda_s(non_seed_pixels) = fg_unary_values(non_seed_pixels) * 2;
            % parametric potential
            lambda_s(non_seed_pixels) = lambda_weights;

%             frame_cost = frame_cost_func(fg_seeds);
%
% %           frame_cost = obj.frame_bg_bias(fg_seeds, size(obj.I));
%             %frame_cost = 1;
%             % always have some frame soft bias to belong in the background
%             nonlambda_t(obj.seg_obj.sp_frame_set) = ...
%                 nonlambda_t(obj.seg_obj.sp_frame_set) + ...
%                 frame_cost*obj.SEED_FRAME_WEIGHT;
            % parametric potential
            lambda_t(non_seed_pixels) = lambda_weights;
        end

        function [bg_unary_values, clr_unary_vals] = ...
                precompute_return_data(obj, funcs, seed_sets, ...
                                       inside_frame, unary_desc)

            % precompute the non-changing bg color unary values
            if isempty(obj.precompute.bg_unary_values)
                % unary potential reflecting similarity to bground pixels
                bndry_for_estimation = funcs.bndry_est_func(inside_frame);
                obj.precompute.bg_unary_values = ...
                    funcs.color_unary_func(bndry_for_estimation);
            end
            bg_unary_values = obj.precompute.bg_unary_values;

            seed_hash = num2str(sum(getByteStreamFromArray(seed_sets)));
%            seed_hash = DataHash(seed_sets, ...
%                                 obj.seg_obj.other_params.hash_params);
            % check if this seed type has not already been computed
            precomputed_unary_idx = find(strcmp(seed_hash, ...
                                         obj.precompute.clr_unary_hash));
            % precompute the fg color unary values
            if isempty(precomputed_unary_idx)
                clr_unary_values = zeros(size(seed_sets));
                % iterate over all seeds - compute unary values for each sp
                for i = 1:size(seed_sets, 2)
                    clr_unary_values(:,i) = ...
                        funcs.color_unary_func(seed_sets(:,i));
                end
                obj.precompute.clr_unary_values{end+1} = clr_unary_values;
                obj.precompute.clr_unary_hash{end+1} = seed_hash;
                precomputed_unary_idx = ...
                    length(obj.precompute.clr_unary_values);
            end
            clr_unary_vals = ...
                obj.precompute.clr_unary_values{precomputed_unary_idx};

            % if using the color segmenter for 'internal' type, normalize
            % by superpixel size
            if strcmpi(unary_desc, 'internal')
                clr_unary_vals = bsxfun(@rdivide, clr_unary_vals, ...
                                        obj.seg_obj.sp_data.sp_seg_szs);
            end
        end
    end
end


function y = cvx_isconstant( x )
y = testall( @cvx_isconstant, x );

% Copyright 2005-2016 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function varargout=lpcis2rf(varargin)
%
% For calling details please see v_lpcis2rf.m
%
% This dummy routine is included for backward compatibility only
% and will be removed in a future release of voicebox. Please use
% v_lpcis2rf.m in future and/or update with v_voicebox_update.m
%
%      Copyright (C) Mike Brookes 2018
%      Version: $Id: lpcis2rf.m 10863 2018-09-21 15:39:23Z dmb $
%
if nargout
    varargout=cell(1,nargout);
    [varargout{:}]=v_lpcis2rf(varargin{:});
else
    v_lpcis2rf(varargin{:});
end


function [vw, slices] = selectSliceCoords(vw)
%
%    [vw, selectedPositions] = selectSliceCoords(vw)
%
% Allow the user to use the mouse to set the three sliceNum editable text
% fields in the Volume view.
%
% The current selected position is stored in vw.ui.sliceNumFields.
% The values are also returned as the 2nd argument.
%

if ~strcmp(vw.viewType,'Volume') & ~strcmp(vw.viewType,'Gray')
  myErrorDlg('selectSliceCoords only for Volume view.');
end

% Get mouse input
[x,y] = ginput(1);
x=round(x);
y=round(y);

% Interpret mouse click according to current slice orientation
curSlice = viewGet(vw, 'Current Slice');
sliceOri=getCurSliceOri(vw);
switch sliceOri
  case 1				% axi (y=cor pos, x=sag pos)
    slices=[curSlice y x];
  case 2 				% cor (y=axi pos, x=sag pos)
    slices=[y curSlice x];
  case 3 				% sag (y=axi pos, x=cor pos)
    slices=[y x curSlice];
end

% Set the sliceNum editable text fields
for n=1:3
  set(vw.ui.sliceNumFields(n),'String',num2str(slices(n)));
end

return;

% Debug/Test

[VOLUME{1},selectedPosition] = selectSliceCoords(VOLUME{1});


function writechanloc(sqdfile,locfile,format,channum)
% WRITECHANLOC(SQD_FILE, LOCATION_FILE, FORMAT, CHANNEL_LIST); Writes the location of
% the sensors of the channels from the CHANNEL_LIST in the SQD_FILE to LOC_FILE
% following the FORMAT structure
% where FORMAT can be:
%     'xyz' : (Default) Matlab/EEGLAB Cartesian coordinates (NOT EGI Cartesian).
%             x is toward nose; y is toward left ear; z is toward vertex
% Default values:
%   LOCATION_FILE = './testsqd.xyz'
%   FORMAT = 'xyz'
%   CHANNEL_LIST = 0:156
%
% This is useful for analysing the data in EEGLAB toolbox
% Please see  http://sccn.ucsd.edu/eeglab for more details of the toolbox.
%
% Examples:
% If the path for the sqd-toolbox has been set properly and all of the files present
% (see README), there should be a sample raw sqd-file "testsqd.sqd" for testing. The
% sqd-file "testsqd.sqd" has data for 192 channels, 10 seconds of data and sampled
% at 1000Hz.
% 1. To read in channel location from "testsqd.sqd":
%   locationfile = 'testlocation.xyz';  % Filename for the location file to be created
%   sqdfilename  = 'testsqd.sqd';       % sqd-file to read the locations from
%   writechanloc(sqdfilename,locationfile); % Write location file
%   type(locationfile);                 % To verify
% 2. To read in channel location from "testsqd.sqd" for channels N1,N2,N3:
%   locationfile = 'testlocation.xyz';  % Filename for the location file to be created
%   sqdfilename  = 'testsqd.sqd';       % sqd-file to read the locations from
%   N1 = 1;N2 = 100;N3 = 101;           % Init channels to read
%   writechanloc(sqdfilename,locationfile,'xyz',[N1,N2,N3]); % Write location file
%   type(locationfile);                 % To verify
%
% See also,
% @chanhandle/writechanloc

% Note:
% This function is just a wrapper around @chanhandle/writechanloc
% Error correction is taken care by respective functions

% Init input arguments
switch nargin
case 0
    error('Atleast one input - SQDFILENAME required');
case 1
    locfile = 'testsqd.xyz';
    format = 'xyz';
    channum = 0:156;
case 2
    format = 'xyz';
    channum = 0:156;
case 3
    channum = 0:156;
end;

chant = chanhandle(sqdfile,channum);    % get chanhandle
writechanloc(chant,locfile,format);     % Write file


% Author: Sergiy Iglin
% e-mail: iglin@kpi.kharkov.ua
% or: siglin@yandex.ru
% personal page: http://iglin.exponenta.ru
clear all % Rubik Cube Game Main File
scrsz = get(0,'ScreenSize');
pl = (scrsz(3)-460)/2; % left bound
pu = (scrsz(4)-460)/2; % upper bound
Cube = InitCube; % initialize the cube
hFig = figure('Position',[pl pu 460 460],...
  'Color',get(0,'DefaultUicontrolBackgroundColor'),...
  'Resize','off','MenuBar','none',...
  'NumberTitle','off','Name','Rubik Cube Game',...
  'WindowButtonMotionFcn','ChangePointer(hFig,Cube);');
hAxes = axes('Units','pixels','Position',[20 20 420 420],...
  'CameraPosition',[4.5 4 3.5],...
  'XLim',[-3.7 3.7],'YLim',[-3.7 3.7],'ZLim',[-3.7 3.7],...
  'XTickLabel','','YTickLabel','','ZTickLabel','',...
  'XTick',[],'YTick',[],'ZTick',[]);
hMenuGame = uimenu(hFig,'Label','Game');
hMenuNewGame = uimenu(hMenuGame,'Label','New Game',...
  'Callback','Cube=CreateNewGame(hAxes,Cube);');
hMenuExit = uimenu(hMenuGame,'Label','Exit',...
  'Callback','delete(hFig);','Separator','on');
hMenuHelp = uimenu(hFig,'Label','Help');
hMenuHow = uimenu(hMenuHelp,'Label','How to build the Rubik cube?',...
  'Callback','web jjorg.chem.unc.edu/personal/monroe/cube/rubik.html -browser');
hMenuAuthor = uimenu(hMenuHelp,'Label','Author','Separator','on',...
  'Callback','web iglin.exponenta.ru/All/Rubik.html -browser');
Cube = CreateNewGame(hAxes,Cube); % create new game and draw


function [varargout]=figuremax(varargin)

% function [hf]=figuremax(Cbg,Cdef)
% ------------------------------------------------------------------------
%
% This function opens a maximized figure window using the color settings
% specified.
%
%
%
% Kevin Mattheus Moerman
% gibbon.toolbox@gmail.com
%
% 30/09/2014
%------------------------------------------------------------------------

%%

switch nargin
    case 0
        Cbg='w';
        Cdef='white';
    case 1
        Cbg=varargin{1};
        Cdef='white';
    case 2
        Cbg=varargin{1};
        Cdef=varargin{2};
    case 3
        Cbg=varargin{1};
        Cdef=varargin{2};
end

figStruct.Color=Cbg; %Figure background color
figStruct.ColorDef=Cdef; %Setting colordefinitions

%Open custom figure
hf=cFigure(figStruct);

%Maximize figure window
maxFig(hf);

if nargout>0
    varargout{1}=hf;
end

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function [listRxns] = findRxnsPerTypeInMap(map, rxnType)
% Finds reaction names based on the type of reactions in the map. Useful
% to look for transport, catalysis or simple state_transition.
%
% USAGE:
%
%    [listRxns] = findTransRxns(map, rxnType)
%
% INPUTS:
%    map:           Map from CellDesigner parsed to MATLAB format
%    rxnType:       Reaction type as a String
%
% OUTPUT:
%    listRxns:      List of reactions indexes (1st column) and
%                   reaction names (2nd column)
%
% .. Author: - N.Sompairac - Institut Curie, Paris, 20/10/2017

    index = find(strcmp(map.rxnType, rxnType));
    listRxns(:,1) = num2cell(index);
    listRxns(:,2) = map.rxnName(index,1);

end


function box_behnken_test ( )

%*****************************************************************************80
%
%% BOX_BEHNKEN_TEST tests the BOX_BEHNKEN library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 October 2008
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'BOX_BEHNKEN_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the BOX_BEHNKEN library.\n' );

  box_behnken_test01 ( );
  box_behnken_test02 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'BOX_BEHNKEN_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


report_this_filefun(mfilename('fullpath'));

str = [];
[newmatfile, newpath] = uiputfile([ hodo '*.dat'], 'Save As'); %Syntax change Matlab Version 7, no window positioning on macs

s = [a.Longitude   a.Latitude  a.Date  a.Date.Month  a.Date.Day  a.Magnitude  a.Depth a.Date.Hour a.Date.Minute a(:,10) a(:,11) a(:,12) a(:,13) a(:,14)   ];
fid = fopen([newpath newmatfile],'w') ;
fprintf(fid,'%7.3f  %7.3f %6.2f %6.0f  %6.0f %6.1f %6.2f  %6.0f  %6.0f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f\n',s');
fclose(fid);
clear s
return


function [TS_DataMat,Operations] = FilterFeatures(TS_DataMat,Operations,cfnParams)
% FilterFeatures filters down to a reduced feature set
%-------------------------------------------------------------------------------
if isempty(fieldnames(cfnParams)) || isempty(cfnParams.reducedFeatureSet) || strcmp(cfnParams.reducedFeatureSet,'all')
    return
else
    opIDs = TS_GiveMeFeatureSet(cfnParams.reducedFeatureSet,Operations);
    keepMe = ismember(Operations.ID,opIDs);
    Operations = Operations(keepMe,:);
    TS_DataMat = TS_DataMat(:,keepMe);
    fprintf(1,'Only using %u features from the %s set...\n',sum(keepMe),cfnParams.reducedFeatureSet);
end

% Check there are some left:
numFeatures = height(Operations);
if numFeatures==0
    error('No features to do classification with...');
end

end


function varargout = lvd_EditLinearTangentModelGUI(varargin)
    % LVD_EDITLINEARTANGENTMODELGUI MATLAB code for lvd_EditLinearTangentModelGUI.fig
    %      LVD_EDITLINEARTANGENTMODELGUI, by itself, creates a new LVD_EDITLINEARTANGENTMODELGUI or raises the existing
    %      singleton*.
    %
    %      H = LVD_EDITLINEARTANGENTMODELGUI returns the handle to a new LVD_EDITLINEARTANGENTMODELGUI or the handle to
    %      the existing singleton*.
    %
    %      LVD_EDITLINEARTANGENTMODELGUI('CALLBACK',hObject,eventData,handles,...) calls the local
    %      function named CALLBACK in LVD_EDITLINEARTANGENTMODELGUI.M with the given input arguments.
    %
    %      LVD_EDITLINEARTANGENTMODELGUI('Property','Value',...) creates a new LVD_EDITLINEARTANGENTMODELGUI or raises the
    %      existing singleton*.  Starting from the left, property value pairs are
    %      applied to the GUI before lvd_EditLinearTangentModelGUI_OpeningFcn gets called.  An
    %      unrecognized property name or invalid value makes property application
    %      stop.  All inputs are passed to lvd_EditLinearTangentModelGUI_OpeningFcn via varargin.
    %
    %      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
    %      instance to run (singleton)".
    %
    % See also: GUIDE, GUIDATA, GUIHANDLES

    % Edit the above text to modify the response to help lvd_EditLinearTangentModelGUI

    % Last Modified by GUIDE v2.5 23-Apr-2021 16:29:22

    % Begin initialization code - DO NOT EDIT
    gui_Singleton = 1;
    gui_State = struct('gui_Name',       mfilename, ...
        'gui_Singleton',  gui_Singleton, ...
        'gui_OpeningFcn', @lvd_EditLinearTangentModelGUI_OpeningFcn, ...
        'gui_OutputFcn',  @lvd_EditLinearTangentModelGUI_OutputFcn, ...
        'gui_LayoutFcn',  [] , ...
        'gui_Callback',   []);
    if nargin && ischar(varargin{1})
        gui_State.gui_Callback = str2func(varargin{1});
    end

    if nargout
        [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    else
        gui_mainfcn(gui_State, varargin{:});
    end
    % End initialization code - DO NOT EDIT

    % --- Executes just before lvd_EditLinearTangentModelGUI is made visible.
function lvd_EditLinearTangentModelGUI_OpeningFcn(hObject, eventdata, handles, varargin)
    % This function has no output args, see OutputFcn.
    % hObject    handle to figure
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    % varargin   command line arguments to lvd_EditLinearTangentModelGUI (see VARARGIN)

    % Choose default command line output for lvd_EditLinearTangentModelGUI
    handles.output = hObject;

    centerUIFigure(hObject);

    linearTangentModel = varargin{1};
    setappdata(hObject,'linearTangentModel',linearTangentModel);

    setappdata(hObject,'plotDur',1.0);

    populateGUI(handles, linearTangentModel);

    % Update handles structure
    guidata(hObject, handles);

    % UIWAIT makes lvd_EditLinearTangentModelGUI wait for user response (see UIRESUME)
    uiwait(handles.lvd_EditLinearTangentModelGUI);

function populateGUI(handles, linearTangentModel)
    handles.aText.String = fullAccNum2Str(linearTangentModel.a);
    handles.aOptCheckbox.Value = double(linearTangentModel.varA);
    handles.aLbText.String = fullAccNum2Str(linearTangentModel.aLb);
    handles.aUbText.String = fullAccNum2Str(linearTangentModel.aUb);
    aOptCheckbox_Callback(handles.aOptCheckbox, [], handles);

    handles.aDotText.String = fullAccNum2Str(linearTangentModel.a_dot);
    handles.aDotOptCheckbox.Value = double(linearTangentModel.varADot);
    handles.aDotLbText.String = fullAccNum2Str(linearTangentModel.aDotLb);
    handles.aDotUbText.String = fullAccNum2Str(linearTangentModel.aDotUb);
    aDotOptCheckbox_Callback(handles.aDotOptCheckbox, [], handles);

    handles.bText.String = fullAccNum2Str(linearTangentModel.b);
    handles.bOptCheckbox.Value = double(linearTangentModel.varB);
    handles.bLbText.String = fullAccNum2Str(linearTangentModel.bLb);
    handles.bUbText.String = fullAccNum2Str(linearTangentModel.bUb);
    bOptCheckbox_Callback(handles.bOptCheckbox, [], handles);

    handles.bDotText.String = fullAccNum2Str(linearTangentModel.b_dot);
    handles.bDotOptCheckbox.Value = double(linearTangentModel.varBDot);
    handles.bDotLbText.String = fullAccNum2Str(linearTangentModel.bDotLb);
    handles.bDotUbText.String = fullAccNum2Str(linearTangentModel.bDotUb);
    bDotOptCheckbox_Callback(handles.bDotOptCheckbox, [], handles);

    % --- Outputs from this function are returned to the command line.
function varargout = lvd_EditLinearTangentModelGUI_OutputFcn(hObject, eventdata, handles)
    % varargout  cell array for returning output args (see VARARGOUT);
    % hObject    handle to figure
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Get default command line output from handles structure
    if(isempty(handles))
        varargout{1} = false;
    else
        varargout{1} = true;
        close(handles.lvd_EditLinearTangentModelGUI);
    end

    % --- Executes on button press in saveAndCloseButton.
function saveAndCloseButton_Callback(hObject, eventdata, handles)
    % hObject    handle to saveAndCloseButton (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    errMsg = {};
    if(isempty(errMsg))
        uiresume(handles.lvd_EditLinearTangentModelGUI);
    else
        msgbox(errMsg,'Errors were found while editing plugins.','error');
    end

function aText_Callback(hObject, eventdata, handles)
    % hObject    handle to aText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: get(hObject,'String') returns contents of aText as text
    %        str2double(get(hObject,'String')) returns contents of aText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'A Term';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.a = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.a);

        msgbox(errMsg,'Invalid A Term','error');
    end

    % --- Executes during object creation, after setting all properties.
function aText_CreateFcn(hObject, eventdata, handles)
    % hObject    handle to aText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    empty - handles not created until after all CreateFcns called

    % Hint: edit controls usually have a white background on Windows.
    %       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end

    % --- Executes on button press in aOptCheckbox.
function aOptCheckbox_Callback(hObject, eventdata, handles)
    % hObject    handle to aOptCheckbox (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hint: get(hObject,'Value') returns toggle state of aOptCheckbox
    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');
    linearTangentModel.varA = logical(hObject.Value);

    if(hObject.Value)
        handles.aLbText.Enable = 'on';
        handles.aUbText.Enable = 'on';
    else
        handles.aLbText.Enable = 'off';
        handles.aUbText.Enable = 'off';
    end

function aLbText_Callback(hObject, eventdata, handles)
    % hObject    handle to aLbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: get(hObject,'String') returns contents of aLbText as text
    %        str2double(get(hObject,'String')) returns contents of aLbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'A Term Lower Bound';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.aLb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.aLb);

        msgbox(errMsg,'Invalid A Term Lower Bound','error');
    end

    % --- Executes during object creation, after setting all properties.
function aLbText_CreateFcn(hObject, eventdata, handles)
    % hObject    handle to aLbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    empty - handles not created until after all CreateFcns called

    % Hint: edit controls usually have a white background on Windows.
    %       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end

function aUbText_Callback(hObject, eventdata, handles)
    % hObject    handle to aUbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: get(hObject,'String') returns contents of aUbText as text
    %        str2double(get(hObject,'String')) returns contents of aUbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'A Term Upper Bound';
    lb = linearTangentModel.aLb;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.aUb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.aUb);

        msgbox(errMsg,'Invalid A Term Upper Bound','error');
    end

    % --- Executes during object creation, after setting all properties.
function aUbText_CreateFcn(hObject, eventdata, handles)
    % hObject    handle to aUbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    empty - handles not created until after all CreateFcns called

    % Hint: edit controls usually have a white background on Windows.
    %       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end

function aDotText_Callback(hObject, eventdata, handles)
    % hObject    handle to aDotText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: get(hObject,'String') returns contents of aDotText as text
    %        str2double(get(hObject,'String')) returns contents of aDotText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'A Dot';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.a_dot = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.a_dot);

        msgbox(errMsg,'Invalid A Dot','error');
    end

    % --- Executes during object creation, after setting all properties.
function aDotText_CreateFcn(hObject, eventdata, handles)
    % hObject    handle to aDotText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    empty - handles not created until after all CreateFcns called

    % Hint: edit controls usually have a white background on Windows.
    %       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end

    % --- Executes on button press in aDotOptCheckbox.
function aDotOptCheckbox_Callback(hObject, eventdata, handles)
    % hObject    handle to aDotOptCheckbox (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hint: get(hObject,'Value') returns toggle state of aDotOptCheckbox
    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');
    linearTangentModel.varADot = logical(hObject.Value);

    if(hObject.Value)
        handles.aDotLbText.Enable = 'on';
        handles.aDotUbText.Enable = 'on';
    else
        handles.aDotLbText.Enable = 'off';
        handles.aDotUbText.Enable = 'off';
    end

function aDotLbText_Callback(hObject, eventdata, handles)
    % hObject    handle to aDotLbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: get(hObject,'String') returns contents of aDotLbText as text
    %        str2double(get(hObject,'String')) returns contents of aDotLbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'A Dot Lower Bound';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.aDotLb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.aDotLb);

        msgbox(errMsg,'Invalid A Dot Lower Bound','error');
    end

    % --- Executes during object creation, after setting all properties.
function aDotLbText_CreateFcn(hObject, eventdata, handles)
    % hObject    handle to aDotLbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    empty - handles not created until after all CreateFcns called

    % Hint: edit controls usually have a white background on Windows.
    %       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end

function aDotUbText_Callback(hObject, eventdata, handles)
    % hObject    handle to aDotUbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)

    % Hints: get(hObject,'String') returns contents of aDotUbText as text
    %        str2double(get(hObject,'String')) returns contents of aDotUbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'A Dot Upper Bound';
    lb = linearTangentModel.aDotLb;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.aDotUb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.aDotUb);

        msgbox(errMsg,'Invalid A Dot Upper Bound','error');
    end

    % --- Executes during object creation, after setting all properties.
function aDotUbText_CreateFcn(hObject, eventdata, handles)
    % hObject    handle to aDotUbText (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    empty - handles not created until after all CreateFcns called

    % Hint: edit controls usually have a white background on Windows.
    %       See ISPC and COMPUTER.
    if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
    end

% --- Executes on button press in plotLinearTangentButton.
function plotLinearTangentButton_Callback(hObject, eventdata, handles)
% hObject    handle to plotLinearTangentButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');
    duration = str2double(handles.durationToPlot.String);

    t0 = linearTangentModel.getT0();
    t = linspace(t0,t0+duration,500);
    y = NaN(1,length(t));

    for(i=1:length(t))
        y(i) = linearTangentModel.getValueAtTime(t(i));
    end

    y = rad2deg(y);

    hAx = axes(figure());
    plot(hAx, t, y);
    grid(hAx,'minor');
    xlabel('DT [sec]');
    ylabel('Polynomial Value [deg]');

function durationToPlot_Callback(hObject, eventdata, handles)
% hObject    handle to durationToPlot (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of durationToPlot as text
%        str2double(get(hObject,'String')) returns contents of durationToPlot as a double
    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'Duration to Plot';
    lb = 0;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(not(isempty(errMsg)))
        oldPlotDur = getappdata(handles.lvd_EditLinearTangentModelGUI,'plotDur');
        handles.durationToPlot.String = fullAccNum2Str(oldPlotDur);

        msgbox(errMsg,'Invalid Plotting Duration','error');
    end

% --- Executes during object creation, after setting all properties.
function durationToPlot_CreateFcn(hObject, eventdata, handles)
% hObject    handle to durationToPlot (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function bText_Callback(hObject, eventdata, handles)
% hObject    handle to bText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of bText as text
%        str2double(get(hObject,'String')) returns contents of bText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'B Term';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.b = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.b);

        msgbox(errMsg,'Invalid B Term','error');
    end

% --- Executes during object creation, after setting all properties.
function bText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to bText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in bOptCheckbox.
function bOptCheckbox_Callback(hObject, eventdata, handles)
% hObject    handle to bOptCheckbox (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of bOptCheckbox
    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');
    linearTangentModel.varB = logical(hObject.Value);

    if(hObject.Value)
        handles.bLbText.Enable = 'on';
        handles.bUbText.Enable = 'on';
    else
        handles.bLbText.Enable = 'off';
        handles.bUbText.Enable = 'off';
    end

function bLbText_Callback(hObject, eventdata, handles)
% hObject    handle to bLbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of bLbText as text
%        str2double(get(hObject,'String')) returns contents of bLbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'B Term Lower Bound';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.bLb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.bLb);

        msgbox(errMsg,'Invalid B Term Lower Bound','error');
    end

% --- Executes during object creation, after setting all properties.
function bLbText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to bLbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function bUbText_Callback(hObject, eventdata, handles)
% hObject    handle to bUbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of bUbText as text
%        str2double(get(hObject,'String')) returns contents of bUbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'B Term Upper Bound';
    lb = linearTangentModel.bLb;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.bUb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.bUb);

        msgbox(errMsg,'Invalid B Term Upper Bound','error');
    end

% --- Executes during object creation, after setting all properties.
function bUbText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to bUbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function bDotText_Callback(hObject, eventdata, handles)
% hObject    handle to bDotText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of bDotText as text
%        str2double(get(hObject,'String')) returns contents of bDotText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'B Dot Term';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.b_dot = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.b_dot);

        msgbox(errMsg,'Invalid B Dot Term','error');
    end

% --- Executes during object creation, after setting all properties.
function bDotText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to bDotText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in bDotOptCheckbox.
function bDotOptCheckbox_Callback(hObject, eventdata, handles)
% hObject    handle to bDotOptCheckbox (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of bDotOptCheckbox
    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');
    linearTangentModel.varBDot = logical(hObject.Value);

    if(hObject.Value)
        handles.bDotLbText.Enable = 'on';
        handles.bDotUbText.Enable = 'on';
    else
        handles.bDotLbText.Enable = 'off';
        handles.bDotUbText.Enable = 'off';
    end

function bDotLbText_Callback(hObject, eventdata, handles)
% hObject    handle to bDotLbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of bDotLbText as text
%        str2double(get(hObject,'String')) returns contents of bDotLbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'B Dot Term Lower Bound';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.bDotLb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.bDot);

        msgbox(errMsg,'Invalid B Dot Term Lower Bound','error');
    end

% --- Executes during object creation, after setting all properties.
function bDotLbText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to bDotLbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function bDotUbText_Callback(hObject, eventdata, handles)
% hObject    handle to bDotUbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of bDotUbText as text
%        str2double(get(hObject,'String')) returns contents of bDotUbText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

    linearTangentModel = getappdata(handles.lvd_EditLinearTangentModelGUI,'linearTangentModel');

    errMsg = {};

    value = str2double(get(hObject,'String'));
    enteredStr = get(hObject,'String');
    numberName = 'B Dot Term Upper Bound';
    lb = linearTangentModel.bDotLb;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(value, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(isempty(errMsg))
        linearTangentModel.bDotUb = value;
    else
        hObject.String = fullAccNum2Str(linearTangentModel.bDotUb);

        msgbox(errMsg,'Invalid B Dot Term Upper Bound','error');
    end

% --- Executes during object creation, after setting all properties.
function bDotUbText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to bDotUbText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


data_path = '/home/ftp/Coldog/Dataset/toflow/vimeo_septuplet/sequences';
noise_path = '/home/ftp/Coldog/Dataset/toflow/vimeo_septuplet/sequences_blur';
if ~exist(noise_path, 'dir')
  mkdir(noise_path);
end
videos = dir(data_path);
total_num = 91701;
count = 0;
disp('Start bluring...')
for i=1:length(videos)
    if strcmp(videos(i).name, '.') || strcmp(videos(i).name, '..')
        continue
    end
    seps = dir(fullfile(data_path, videos(i).name));
    for j=1:length(seps)
        if strcmp(seps(j).name, '.') || strcmp(seps(j).name, '..')
            continue
        end
        blur_input(fullfile(data_path, videos(i).name, seps(j).name), fullfile(noise_path, videos(i).name, seps(j).name))
        count = count + 1;
        if mod(count,500)==0
            disp(['  Processed ',num2str(count/total_num*100), '%'])
        end
    end
end
disp(['  Processed ',num2str(count/total_num*100), '%'])


classdef NodesCalculatorFactory < handle
    methods (Access = public, Static)
        function obj = create(cParams)
            switch cParams.nvert
                case 4
                    obj = QuadrilateralNodesCalculator(cParams);
                case 6
                    obj = HexagonalNodesCalculator(cParams);
            end
        end
    end
end


function speedup_fg(sp, host, port)
% SPEEDUP_FG(SP, HOST, PORT)
%
% Speeds up Flightgear's simulation speed by a factor SP over socket
% connection (HOST, PORT).
% Run Flightgear on HOST (e.g. '127.0.0.1' = localhost) with
% parameter "--props = PORT".
%
% SP = 1: Realtime
% SP = 2: Realtime speeded up by factor 2
% ...

import java.net.Socket
import java.io.*

fg_socket = Socket(host, port);
out = PrintWriter(fg_socket.getOutputStream(), true);

out.println(sprintf('set /sim/speed-up %2.1f\r\n', sp));

out.close();
fg_socket.close();

end


function [list, path]=sct_tools_ls(fname, keeppath, keepext, folders,arborescence,select)
% [list, path]=sct_tools_ls(fname, keeppath?, keepext?, folders?,recursive?)
% Example: sct_tools_ls('ep2d*')
% example 2: sct_tools_ls('*',[],[],1) --> folders only
% example 3: sct_tools_ls('*',[],[],2) --> files only

if nargin < 2, keeppath=0; end
if nargin < 3, keepext=1; end
if nargin < 4 || isempty(folders), folders=0; end
if nargin < 6 || isempty(select), select=0; end
if nargin < 5, arborescence=0; end

% [list, path]=sct_tools_ls('*T.txt);
list=dir(fname);
[path,name,ext]= fileparts(fname);
path=[path filesep]; name = [name ext];
if strcmp(path,filesep)
    path=['.' filesep];
end

if folders==1
    list=list(cat(1,list.isdir));
elseif folders==2
    list=list(~cat(1,list.isdir));
end

% sort by name
list=sort_nat({list.name})';

% remove files starting with .
list(cellfun(@(x) strcmp(x(1),'.'), list))=[];
if keeppath
    for iL=1:length(list)
        list{iL}=[path list{iL}];
    end
end
pathcur = path;
path = repmat({path},[length(list),1]);

if ~keepext
    list=cellfun(@(x) sct_tool_remove_extension(x,keeppath),list,'UniformOutput',false);
end

if arborescence
    listdir = sct_tools_ls(pathcur,1,1,1);
    for idir = 1:length(listdir)
        [listidir, pathidir]=sct_tools_ls([listdir{idir} filesep name], keeppath, keepext, folders,arborescence,0);
        list = [list; listidir];
        path = cat(1,path, pathidir{:});
    end
end

if select, list=list{select}; end


function [opts, imdb] = model_setup(varargin)

% Copyright (C) 2015 Tsung-Yu Lin, Aruni RoyChowdhury, Subhransu Maji.
% All rights reserved.
%
% This file is part of the BCNN and is made available under
% the terms of the BSD license (see the COPYING file).

% setup ;

opts.seed = 1 ;
opts.batchSize = 128 ;
opts.numEpochs = 100;
opts.momentum = 0.9;
opts.learningRate = 0.001;
opts.numSubBatches = 1;
opts.keepAspect = true;
opts.useVal = false;
opts.fromScratch = false;
opts.useGpu = 1 ;
opts.regionBorder = 0.05 ;
opts.numDCNNWords = 64 ;
opts.numDSIFTWords = 256 ;
opts.numSamplesPerWord = 1000 ;
opts.printDatasetInfo = false ;
opts.excludeDifficult = true ;
opts.datasetSize = inf;
% opts.encoders = {struct('name', 'rcnn', 'opts', {})} ;
opts.encoders = {} ;
opts.dataset = 'cub' ;
opts.csiqDir = 'dataset\CSIQ database';
opts.liveDir = 'dataset\databaserelease2';
opts.tidDir = 'dataset\TID2013';
opts.cliveDir = 'dataset\ChallengeDB_release';
opts.mliveDir = 'dataset\LIVEmultidistortiondatabase\To_Release';
opts.ilsvrcDir = '/home/tsungyulin/dataset/ILSVRC2014/CLS-LOC/';
opts.ilsvrcDir_224 = '/home/tsungyulin/dataset/ILSVRC2014/CLS-LOC-224/';
opts.suffix = 'baseline' ;
opts.prefix = 'v1' ;
opts.model  = 'imagenet-vgg-m.mat';
opts.modela = 'imagenet-vgg-m.mat';
opts.modelb = [];
opts.layer  = 14;
opts.layera = [];
opts.layerb = [];
opts.imgScale = 1;
opts.bcnnLRinit = false;
opts.bcnnLayer = 14;
opts.rgbJitter = false;
opts.dataAugmentation = {'none', 'none', 'none'};
opts.cudnn = true;
opts.nonftbcnnDir = 'nonftbcnn';
opts.batchNormalization = false;
opts.cudnnWorkspaceLimit = 1024*1024*1204;
opts.dataset_path = 'dataset\databaserelease2';

[opts, varargin] = vl_argparse(opts,varargin) ;

opts.expDir = sprintf('data/%s/%s-seed-%02d', opts.prefix, opts.dataset, opts.seed) ;
opts.nonftbcnnDir = fullfile(opts.expDir, opts.nonftbcnnDir);
opts.imdbDir = fullfile(opts.expDir, 'imdb') ;
opts.resultPath = fullfile(opts.expDir, sprintf('result-%s.mat', opts.suffix)) ;

opts = vl_argparse(opts,varargin) ;

if nargout <= 1, return ; end

% % Setup GPU if needed
% if opts.useGpu
%   gpuDevice(opts.useGpu) ;
% end

% -------------------------------------------------------------------------
%                                                            Setup encoders
% -------------------------------------------------------------------------

models = {} ;
modelPath = {};
for i = 1:numel(opts.encoders)
  if isstruct(opts.encoders{i})
    name = opts.encoders{i}.name ;
    opts.encoders{i}.path = fullfile(opts.expDir, [name '-encoder.mat']) ;
    opts.encoders{i}.codePath = fullfile(opts.expDir, [name '-codes.mat']) ;
    [md, mdpath] = get_cnn_model_from_encoder_opts(opts.encoders{i});
    models = horzcat(models, md) ;
    modelPath = horzcat(modelPath, mdpath);
%     models = horzcat(models, get_cnn_model_from_encoder_opts(opts.encoders{i})) ;
  else
    for j = 1:numel(opts.encoders{i})
      name = opts.encoders{i}{j}.name ;
      opts.encoders{i}{j}.path = fullfile(opts.expDir, [name '-encoder.mat']) ;
      opts.encoders{i}{j}.codePath = fullfile(opts.expDir, [name '-codes.mat']) ;
      [md, mdpath] = get_cnn_model_from_encoder_opts(opts.encoders{i}{j});
      models = horzcat(models, md) ;
      modelPath = horzcat(modelPath, mdpath);
%       models = horzcat(models, get_cnn_model_from_encoder_opts(opts.encoders{i}{j})) ;
    end
  end
end

% -------------------------------------------------------------------------
%                                                       Download CNN models
% -------------------------------------------------------------------------

for i = 1:numel(models)
    if ~exist(modelPath{i})
        error(['cannot find model ', models{i}]) ;
    end
end

% -------------------------------------------------------------------------
%                                                              Load dataset
% -------------------------------------------------------------------------

vl_xmkdir(opts.expDir) ;
vl_xmkdir(opts.imdbDir) ;

switch opts.dataset
    case 'live'
        opts.dataset_path = opts.liveDir;
    case 'clive'
        opts.dataset_path = opts.cliveDir;
    case 'csiq'
        opts.dataset_path = opts.csiqDir;
    case 'tid'
        opts.dataset_path = opts.tidDir;
    case 'mlive'
        opts.dataset_path = opts.mliveDir;
    otherwise
        error('Unknown dataset %s', opts.dataset) ;
end

imdbPath = fullfile(opts.imdbDir, sprintf('imdb-seed-%d.mat', opts.seed)) ;
if exist(imdbPath)
  imdb = load(imdbPath) ;
  if(opts.rgbJitter)
      opts.pca = imdb_compute_pca(imdb, opts.expDir);
  end
  return ;
end

switch opts.dataset
    case 'live'
        imdb = getLiveDatabase_train(opts.liveDir);
    case 'clive'
        imdb = getCliveDatabase_train(opts.cliveDir);
    case 'csiq'
        imdb = getCsiqDatabase_train(opts.csiqDir);
    case 'tid'
        imdb = getTIDDatabase_train(opts.tidDir);
    case 'mlive'
        imdb = getMLIVEDatabase_train(opts.mliveDir);
    otherwise
        error('Unknown dataset %s', opts.dataset) ;
end

save(imdbPath, '-struct', 'imdb') ;

if(opts.rgbJitter)
   opts.pca = imdb_compute_pca(imdb, opts.expDir);
end

if opts.printDatasetInfo
  print_dataset_info(imdb) ;
end

% -------------------------------------------------------------------------
function [model, modelPath] = get_cnn_model_from_encoder_opts(encoder)
% -------------------------------------------------------------------------
p = find(strcmp('model', encoder.opts)) ;
if ~isempty(p)
  [~,m,e] = fileparts(encoder.opts{p+1}) ;
  model = {[m e]} ;
  modelPath = encoder.opts{p+1};
else
  model = {} ;
  modelPath = {};
end

% bilinear cnn models
p = find(strcmp('modela', encoder.opts)) ;
if ~isempty(p)
  [~,m,e] = fileparts(encoder.opts{p+1}) ;
  model = horzcat(model,{[m e]}) ;
  modelPath = horzcat(modelPath, encoder.opts{p+1});
end
p = find(strcmp('modelb', encoder.opts)) ;
if ~isempty(p) && ~isempty(encoder.opts{p+1})
  [~,m,e] = fileparts(encoder.opts{p+1}) ;
  model = horzcat(model,{[m e]}) ;
  modelPath = horzcat(modelPath, encoder.opts{p+1});
end


classdef ImageProcessingTestsSuite < handle

    methods

        function obj = ImageProcessingTestsSuite()
            path = './tests/Source/ImageProcessingTests/ImageProcessingTests.m';
            suite = matlab.unittest.TestSuite.fromFile(path, 'Tag','ImageProcessing');
            results = suite.run;
            table(results)
        end

    end
end


function y = cvxdual( prob, name )

y = class( struct( 'problem_', prob, 'name_', name, 'attached_', false ), 'cvxdual', cvxobj );

% Copyright 2005-2016 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


%% OPT_BATCH_ITHACA uses the BATCH command to run the OPT code on Ithaca.
%
%  Discussion:
%
%    The OPT code is a function, so first we must write a script
%    called OPT_SCRIPT that runs the function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 March 2010
%
%  Author:
%
%    John Burkardt
%
  clear

  fprintf ( 1, '\n' );
  fprintf ( 1, 'OPT_BATCH_ITHACA\n' );
  fprintf ( 1, '  Run OPT_SCRIPT locally.\n' );
%
%  BATCH sends the script for execution.
%
  my_job = batch ( 'opt_script', ...
    'CaptureDiary', true, ...
    'FileDependencies', { 'quad_fun' }, ...
    'Configuration', 'ithaca_2009b', ...
    'CurrentDirectory', '/home/burkardt/matlab', ...
    'matlabpool', 4 );
%
%  WAIT pauses the MATLAB session til the job completes.
%
  wait ( my_job );
%
%  DIARY displays any messages printed during execution.
%
  diary ( my_job );
%
%  LOAD makes the script's workspace available:
%
%  z_star = optimal control.
%  PAR = problem parameters.
%  exit = positive if calculation was successful.
%
  load ( my_job );
%
%  On successful conclusion, display the plot.
%
  if ( 0 <= exit && isfield ( PAR, 'plot' ) )
    feval ( PAR.plot, z_star, PAR )
  end

%
%  DESTROY cleans up data about the job we no longer need.
%
  destroy ( my_job );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'OPT_BATCH_ITHACA\n' );
  fprintf ( 1, '  Normal end of execution.\n' );


function fighandle=newdfig(varargin)
% fighandle = newdfig(numfigs,figname)  create NEW Docked FIGures.
%   "fighandle" is a vector of handle numbers for the figures.
%   "numfigs" determines the number of figures to create.
%   "figname" is an optional string for each figure's name.
%   Examples:
%       newdfig('Title'), newdfig Title, newdfig
%       figh=newdfig(3); figh=newfig(2,'Title');

%   Copyright 2006 Mirtech, Inc.
%   created 08/27/2006  by Mirko Hrovat on Matlab Ver. 7.2
%   Mirtech, Inc.       email: mhrovat@email.com
numfigs=[];
ftitle=[];
if nargin~=0,
    for n=1:length(varargin),
        arg=varargin{n};
        if isnumeric(arg),
            numfigs=arg;
        elseif ischar(arg),
            ftitle=arg;
        end
    end  % for
end  % if nargin
if isempty(numfigs),    numfigs=1;  end
if isempty(ftitle),     ftitle='';  end

figh=zeros(1,numfigs);
for n=1:numfigs,
    figh(n)=figure('Name',ftitle,'WindowStyle','docked');
end

if nargout==1,
    fighandle=figh;
end


function test_bug1245

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY ft_multiplotER

% The issue: when inputting data where the corresponding layout consists of
% more channels than the to-be-plotted channels (specified in cfg.channel),
% and where those channels may have a different order of magnitude, the
% automatic scaling of the y-axis is incorrect, because the scale
% determination algorithm includes the channels that are excluded from the
% plotting

cd(dccnpath('/home/common/matlab/fieldtrip/data/test'))

%%
% this is one way of having ft_multiplotER select avg as the parameter
load bug1245.mat data cfg
data.avg = [];
figure
ft_multiplotER(cfg, data);

%%
% this is another one way of having ft_multiplotER select avg as the parameter
try
  load bug1245.mat data cfg
  cfg.parameter = 'avg';
  figure
  ft_multiplotER(cfg, data);
catch
  % this started failing from https://github.com/fieldtrip/fieldtrip/pull/524 onwards
  % and I don't mind this not working any more
end

%%
% but the data contains a 'trial' field, so better explicitly select that
load bug1245.mat data cfg
cfg.parameter = 'trial';
figure
ft_multiplotER(cfg, data);


function vw = volume3View(vw, loc, xHairs, quickUpdate)
% vw = volume3View(vw, <loc>, <xHairs>, <quickUpdate=1>);
%
% Refresh a volume '3-view': a 'BrainVoyager'-like
% 3-window view, showing sagittal, coronal, and axial slices, at the
% specified location. 'loc' should be a 3-vector containing, respectiveley,
% the Superior/Inferior, Anterior/Posterior, and Right/Left coordinates.
% (For most of the volume anatomies used, S/I range from 1-256, A/P and
% R/L ranges from 1-124.
%
% If omitted, 'loc' is taken from the vw.loc field, or
% failing this set to the middle of the volume.
%
% xHairs: if set to nonzero, will place crosshairs on the current location,
% otherwise will omit them (0 default).
%
% 3/06/03 by ras
% 12/03 ras: using imagesc instead of imshow for now to display
% views, since there's a trickyness in accurately detecting the
% clicked-on location of images put up using imshow.
% 01/04 ras: cleaned up a lot, added 'zoom' field to ui struct allowing
% zooming in on vAnat. (see also zoom3view)
% to do: re-merge ras_recomputeImage with the regular recomputeImage.
% 11/04 ras: added flipping axes option
% 01/07 ras, bw: various ROI display options; trying to make it sensible

%TODO: Remove the input argument 'quickUpdate' - is not used

if ~exist('vw', 'var') || isempty(vw)
    vw = getSelectedVolume;
end

if ~exist('loc','var') || length(loc)<3
    loc = getLocFromUI(vw);
else
    setLocInUI(vw, loc);
end
vw.loc = loc;

% get the ui struct from the view
ui = viewGet(vw,'ui');

if ~exist('xHairs','var')
    if isfield(ui, 'crosshairs') && ui.crosshairs==1
        xHairs = 1;
    else
        xHairs = 0;
    end
end

%%%%% check if window exists
winTag = ['3VolumeWindow: ',vw.name];
winExists = findobj('Tag',winTag);

% if window doesn't exist, open the window
if isempty(winExists)
    openRaw3ViewWindow;
else
    % if one or more 3-view figures exist, make the most recent one current
    figure(winExists(end));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ***** Refresh Window ***** %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
modeStr=['ui.',ui.displayMode,'Mode'];
mode = eval(modeStr);
cmap = mode.cmap;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% get images, apply phase/amp/param maps        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[vw, axi] = recompute3ViewImage(vw, loc(1), 1);
[vw, cor] = recompute3ViewImage(vw, loc(2), 2);
[vw, sag] = recompute3ViewImage(vw, loc(3), 3);

% not needed for anything, but memory is cheap and may be useful:
vw.ui.image = {axi cor sag};

% flip images if selected
if isfield(ui,'flipAP') && ui.flipAP==1
    sag = fliplr(sag);
    % update loc
end
if isfield(ui,'flipLR') && ui.flipLR==1
    axi = fliplr(axi);
    cor = fliplr(cor);
    % update loc
end

%%%%%%%%%%%%%%%%%%%%%
% put up each image %
%%%%%%%%%%%%%%%%%%%%%
if ~isempty(ui.underlayHandle) && ishandle(ui.underlayHandle(1))
    % handles exist, update image CData only
    set(ui.underlayHandle(1), 'CData', axi);
    set(ui.underlayHandle(2), 'CData', cor);
    set(ui.underlayHandle(3), 'CData', sag);
    quickUpdate = 1; % will bypass axes-related functions below
else
    % create image objects
    axes(ui.axiAxesHandle); cla; %#ok<*MAXES>
    vw.ui.underlayHandle(1) = image(axi);
    colormap(cmap); axis image, axis off

    axes(ui.corAxesHandle); cla;
    vw.ui.underlayHandle(2) = image(cor);
    colormap(cmap); axis image, axis off

    axes(ui.sagAxesHandle); cla;
    vw.ui.underlayHandle(3) = image(sag);
    colormap(cmap); axis image, axis off

    quickUpdate = 0; % will do zoom, text creation below
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% If creating axes, add text annotation, zoom   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if quickUpdate==0

    % zoom in on selected coords %
    if ~isfield(ui,'zoom')
        % initialize to full range if not set
        ui.zoom = [1 size(vw.anat,1);...
            1 size(vw.anat,2);...
            1 size(vw.anat,3)];
    else
        axis(ui.axiAxesHandle, [ui.zoom(3,:) ui.zoom(2,:)]);
        axis(ui.corAxesHandle, [ui.zoom(3,:) ui.zoom(1,:)]);
        axis(ui.sagAxesHandle, [ui.zoom(2,:) ui.zoom(1,:)]);
    end

    % set a callback for each image which dynamically updates
    % the location based on where the user clicks
    % callback:
    % vw = recenter3view(vw,[orientationFlag]);
    for i=1:3
        bdf = sprintf('%s=recenter3view(%s,%i); ',vw.name, vw.name, i);
        set(vw.ui.underlayHandle(i), 'ButtonDownFcn', bdf);
    end

    % Add titles to indicate directions (esp. L-R: radiological conventions)
    % TO DO: do this at window creation, making them text children of
    % invisible axes (can't use text uicontrols, since they can't use
    % the TeX markup for the arrows)
    txtcol = 'k';
    SIsz = ui.zoom(1,2) - ui.zoom(1,1);
    APsz = ui.zoom(2,2) - ui.zoom(2,1);
    LRsz = ui.zoom(3,2) - ui.zoom(3,1);
    minS = ui.zoom(1,1);
    minA = ui.zoom(2,1);
    minL = ui.zoom(3,1);

    axes(ui.sagAxesHandle);
    if isfield(ui,'flipAP') && ui.flipAP==1
        title('Pos \leftrightarrow Ant','FontSize',10,'Color',txtcol);
    else
        title('Ant \leftrightarrow Pos','FontSize',10,'Color',txtcol);
    end

    axes(ui.corAxesHandle);
    if isfield(ui,'flipLR') && ui.flipLR==1
        title('Right \leftrightarrow Left','FontSize',10,'Color',txtcol);
    else
        title('Left \leftrightarrow Right','FontSize',10,'Color',txtcol);
    end

    % the I/S and P/A directions for the cor, axial don't
    % get flipped...
    text(minL-0.2*LRsz,minS + 0.5*SIsz, 'Inf \leftrightarrow Sup', ...
        'FontSize', 10,  'HorizontalAlignment', 'center', ...
        'Rotation', 90, 'Color', txtcol);
    axes(ui.axiAxesHandle);
    text(minL-0.2*LRsz,minA + 0.5*APsz, 'Pos \leftrightarrow Ant', ...
        'FontSize', 10,  'HorizontalAlignment', 'center', ...
        'Rotation', 90, 'Color', txtcol);

    % set tags so we can find each of these axes later
    set(ui.sagAxesHandle, 'Tag', 'sagAxes');
    set(ui.corAxesHandle, 'Tag', 'corAxes');
    set(ui.axiAxesHandle, 'Tag', 'axiAxes');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              draw ROIs if selected            %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% remove any old ROI objects
hOld = findobj('Tag', sprintf('ROI_Handles_%s', viewGet(vw,'Name')));
delete(hOld);

% draw selected ROIs
if isfield(vw,'ui') & logical(ui.showROIs ~= 0) ...
        & ~isempty(vw.ROIs) & ~viewGet(vw, 'hideVolumeROIs')
	roiList = viewGet(vw, 'ROIsToDisplay');

    drawROIs3View(vw, roiList, ui.axiAxesHandle, 1, loc);
    drawROIs3View(vw, roiList, ui.corAxesHandle, 2, loc);
    drawROIs3View(vw, roiList, ui.sagAxesHandle, 3, loc);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% add crosshairs to each image to specify current location %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if xHairs
    vw = renderCrosshairs(vw, 1);
end

% Draw colorbar
f = [ui.displayMode,'Mode'];  % field name of display mode
cmap = ui.(f).cmap;
numGrays = ui.(f).numGrays;
numColors = ui.(f).numColors;
setColorBar(vw, [], [numGrays+1 numGrays+numColors]);

colormap(cmap);

% update the annotation text
curScan     = viewGet(vw, 'curscan');
annotation  = viewGet(vw, 'annotation', curScan);
set(ui.annotationHandle, 'String', annotation);

% lastly, deal with the god-awful global variable issue
if strncmp(vw.name, 'VOLUME', 6)
	updateGlobal(vw);
end

return
% /----------------------------------------------------------------/ %

% /----------------------------------------------------------------/ %
function loc = getLocFromUI(vw)
% reads off the axi,cor, and sag UI edit fields to
% get the current view location.
loc(1) = str2num(get(vw.ui.sliceNumFields(1),'String')); %#ok<*ST2NM>
loc(2) = str2num(get(vw.ui.sliceNumFields(2),'String'));
loc(3) = str2num(get(vw.ui.sliceNumFields(3),'String'));
return
% /----------------------------------------------------------------/ %

% /----------------------------------------------------------------/ %
function vw = setLocInUI(vw, loc)
% sets the current view location in the axi, cor, sag UI edit fields.
set(vw.ui.sliceNumFields(1), 'String', num2str(loc(1)));
set(vw.ui.sliceNumFields(2), 'String', num2str(loc(2)));
set(vw.ui.sliceNumFields(3), 'String', num2str(loc(3)));
return
% /----------------------------------------------------------------/ %

% /----------------------------------------------------------------/ %
function drawROIs3View(vw, roiList, axs, ori, loc)
% draw the ROIs, parsing the relevant settings, on the axes
% specified by [axs]. This is implemented a little differently
% from drawROIs or drawROIsPerim, in that it doesn't select a given
% orientation each time (which caused some extra time during refreshes).
% roiList is an array into the vw.ROIs field.
ui = vw.ui;

% build prefs for the outline function.
prefs.method = ui.roiDrawMethod;
prefs.axesHandle = axs;

for r = roiList
    R = vw.ROIs(r);
    if ~isempty(R.coords)
        prefs.color = R.color;
        if r==vw.selectedROI, prefs.color=viewGet(vw,'selRoiColor'); end

        switch ori
            case 1, pts = R.coords([2 3], R.coords(1,:)==loc(1));
            case 2, pts = R.coords([1 3], R.coords(2,:)==loc(2));
            case 3, pts = R.coords([1 2], R.coords(3,:)==loc(3));
        end
		if isempty(pts), continue; end

        if isfield(ui, 'flipLR') && ui.flipLR==1 && ori<3
            % L/R flip affects columns of axi + coronal, but not sag, orientations
            dims = viewGet(vw,'Size');
            pts(2,:) = dims(3) - pts(2,:);
        end

        % restrict to voxels within zoom range
		zoom = viewGet(vw, 'zoom');
		switch ori
			case 1, zoom = zoom([2 3],:);
			case 2, zoom = zoom([1 3],:);
			case 3, zoom = zoom([1 2],:);
		end
		ok =  pts(1,:) >= zoom(1,1) & pts(1,:) <= zoom(1,2) & ...
				   pts(2,:) >= zoom(2,1) & pts(2,:) <= zoom(2,2) ;
		pts = pts(:,ok);

        h = outline(pts, prefs);
        if ishandle(h)
            set(h, 'ButtonDownFcn', sprintf('recenter3view(%s,%i);',vw.name, ori));
			set(h, 'Tag', sprintf('ROI_Handles_%s', vw.name));
        end

    end
end

return


function varargout = compileAndRun(fname,varargin)
% Compile a Matlab function via emlmex and then run the compiled version.
% The function must reside in its own file and be eml compliant. See the
% help sections on emlmex for details.
%
% fname     - the string name of the function
% varargin  - arguments to the compiled function
%
% Example:
%
% [a b c] = compileAndRun('myfunction',X,Y,Z,3); % where X,Y,Z,3 are inputs
%           to 'myfunction', which returns three outputs.
%
%
% Matthew Dunham
% www.cs.ubc.ca/~mdunham

    if(~exist('emlmex','file'))
        error('emlmex could not be found');
    end

    clear mex;
    if(~exist(fname,'file'))
       error('%s could not be found',fname);
    end

    prevDirectory = pwd;
    cd(fileparts(which(fname)));
    try
        fprintf('\ncompiling %s...\n',fname);
        tic;
        emlmex(fname,'-eg',varargin);
        t = toc;
        fprintf('\ncompiled successfully in %g seconds\n',t);
    catch
        warning('compileAndRun:mex','\n\ncould not compile, performance might be slow.\n\n');
    end
    fprintf('\nexecuting function...\n');
    tic
    nout = nargout([fname,'.m']);
    varargout = {};
    if(nout == 0)
        feval(fname,varargin{:});
    elseif(nout < 0)
        varargout{1} = feval(fname,varargin{:});
    else
        out = '[';
        for i=1:nout
            out = [out,sprintf(' varargout{%d} ',i)]; %#ok
        end
        out = [out,']'];
        eval([out,' = ','feval(fname,varargin{:})']);
    end

    clear mex;
    delete([fname,'.',mexext]);
    cd(prevDirectory);
    t = toc;
    fprintf('\n%s ran in %g seconds.\n',fname,t);
end


function aedat = ImportSecGen2(aedat)
%{
This function works similarly to ImportAedat, but takes instead data from
SEC DVS Gen2. These .bin files have no header info, therefore they are not
compatible with ImportAedat.

Expects the aedat.importParams.filePath parameter to contain a .bin file.
If, however the suffix is not .bin, it assumes that it has been passed a
folder path and takes the most recent file in the folder.
%}

dbstop if error

% Unpack parameters
importParams = aedat.importParams;

%% Open the file

if ~isfield(importParams, 'filePath') || ~strcmp(importParams.filePath(end -3 : end), '.bin')
    % Open the newest file
    % Note: For this to work at the moment, matlab must already be in the
    % correct directory
    directoryListing = dir('*.bin');
    [~, fileIndex] = sort([directoryListing.datenum]);
    filePath = directoryListing(fileIndex(end)).name;
else
    filePath = importParams.filePath;
end

fileHandle = fopen(filePath, 'r');

if fileHandle == -1
    error('file not found')
end

% Go to the EOF to find out how long it is
fseek(fileHandle, 0, 'eof');

% Find the number of packets
numPacketsInFile = ftell(fileHandle) / 4;

%% Check parameters

% Check the startEvent and endEvent parameters - if present, this shall
% actually refer to packets.
if isfield(importParams, 'startPacket')
    startPacket = importParams.startPacket;
elseif isfield(importParams, 'startEvent')
    startPacket = importParams.startEvent;
else
    startPacket = 1;
end
if startPacket > numPacketsInFile
	error([	'The file contains ' num2str(numPacketsInFile) ...
			'; the startEvent/startPacket parameter is ' num2str(startPacket)]);
end
if isfield(importParams, 'endPacket')
    endPacket = importParams.endPacket;
elseif isfield(importParams, 'endEvent')
    endPacket = importParams.endEvent;
else
    endPacket = numPacketsInFile;
end

if endPacket > numPacketsInFile
	disp([	'The file contains ' num2str(numPacketsInFile) ...
			'; the endEvent/endPacket parameter is ' num2str(endPacket) ...
			'; reducing the endPacket parameter accordingly.']);
        endPacket = numPacketsInFile;
end
if startPacket >= endPacket
	error([	'The startEvent/Packet parameter is ' num2str(startEvent) ...
		', but the endEvent/Packet parameter is ' num2str(endEvent) ]);
end

if isfield(importParams, 'startTime')
    startTime = importParams.startTime * 1e6 / 2^10;
else
    startTime = 0;
end

if isfield(importParams, 'endTime')
    endTime = importParams.endTime * 1e6 / 2^10;
else
    endTime = inf;
end

numPacketsToRead = endPacket - startPacket + 1;

%% Read data

disp('Reading data ...')
fseek(fileHandle, 0, 'bof');
allPackets = uint32(fread(fileHandle, numPacketsToRead, 'uint32', 0, 'b'));

%% Prepare to unpack data

% Let's just do this iteratively for now; not sure how to matricise this,
% though see below for a half-baked attempt

%% Prepare data masks

majorTimeStampMask        = bin2dec('0000 0000 0011 1111 1111 1111 1111 1111');
minorTimeStampMask        = bin2dec('0000 0000 0000 1111 1111 1100 0000 0000');
columnAddressMask         = bin2dec('0000 0000 0000 0000 0000 0011 1111 1111');
majorRowAddressMask       = bin2dec('0000 0000 0011 1111 0000 0000 0000 0000');
minorRowAddressAndPolMask = bin2dec('0000 0000 0000 0000 1111 1111 1111 1111');

%This following oneshot mask allows the identification of events to add
%from the one-shot encoding
minorRowAndPolOneShotMask = uint16(2 .^ (0:15)');
oneShotPolarity = [true(8, 1); false(8, 1)];
oneShotMinorRowAddress = uint16(repmat((0:7)', 2, 1));

% Loop variables
numEventsProcessed = 0;
currentLengthOfEventVectors = 1024;
majorTimeStamp = 0;
timeStampOffset = 0;
columnAddress = uint16(0);
minorTimeStamp = uint32(0);

% Data arrays
timeStamp	= zeros(currentLengthOfEventVectors, 1, 'uint32');
x			= zeros(currentLengthOfEventVectors, 1, 'uint16');
y			= zeros(currentLengthOfEventVectors, 1, 'uint16');
polarity    = false(currentLengthOfEventVectors, 1);

%% Unpack events by iterating through packets

for packetIndex = startPacket : endPacket
    if mod(packetIndex, 10000) == 0
		disp(['packet: ' num2str(packetIndex) '; ' ...
              'file position: ' num2str(floor(packetIndex / 2^17)) ' MB; ' ...
              '(' num2str(floor((packetIndex - startPacket + 1) / (endPacket - startPacket + 1) * 100)) '%)'])
	end

    currentPacket = allPackets(packetIndex);
    packetCode = bitshift(currentPacket, -24);
    if packetCode == 102 % 0x66
        % Timestamp packet
        currentTimeStamp = bitand(currentPacket, majorTimeStampMask);
        if majorTimeStamp == 0
            timeStampOffset = currentTimeStamp - 1;
        end
        majorTimeStamp = bitshift(currentTimeStamp - timeStampOffset, 10);
    else
        % apply startTime only to the majorTimeStamp - note that rezero is
        % automatic in this import, so actually comparing to the
        % timeStampOffset

        if startTime <= timeStampOffset
            if endTime < timeStampOffset
                break
            end
            if packetCode == 153 % 0x99
                % Column address packet
                minorTimeStamp = bitshift(bitand(currentPacket, majorTimeStampMask), -10);
                columnAddress = uint16(bitand(currentPacket, columnAddressMask));
            elseif packetCode == 204 % 0xCC
                % Events packet
                majorRowAddress       = uint16(bitshift(bitand(currentPacket, majorRowAddressMask), -13));
                minorRowAndPolOneShot = uint16(bitand(currentPacket, minorRowAddressAndPolMask));
                minorRowAndPolLogical = logical(bitand(minorRowAndPolOneShot, minorRowAndPolOneShotMask));
                numNewEvents          = nnz(minorRowAndPolLogical);
                polarityNew           = oneShotPolarity(minorRowAndPolLogical);
                minorRowAddress       = oneShotMinorRowAddress(minorRowAndPolLogical);
                numEventsProcessed = numEventsProcessed + numNewEvents;
                while numEventsProcessed > currentLengthOfEventVectors
                    timeStamp	= [timeStamp;	zeros(currentLengthOfEventVectors, 1, 'uint32')];
                    x			= [x;			zeros(currentLengthOfEventVectors, 1, 'uint16')];
                    y			= [y;			zeros(currentLengthOfEventVectors, 1, 'uint16')];
                    polarity    = [polarity;	false(currentLengthOfEventVectors, 1)];
                    currentLengthOfEventVectors = currentLengthOfEventVectors * 2;
                end
                rangeStart = numEventsProcessed - numNewEvents + 1;
                timeStamp(rangeStart : numEventsProcessed) = majorTimeStamp + minorTimeStamp;
                x        (rangeStart : numEventsProcessed) = columnAddress;
                y        (rangeStart : numEventsProcessed) = majorRowAddress + minorRowAddress;
                polarity (rangeStart : numEventsProcessed) = polarityNew;

            else
                error('packet formation error')
            end
        end
    end
end

%% Crop the data arrays and pack

aedat.info.deviceAddressSpace = [640 480];

if numEventsProcessed > 0
    polarityArray = polarity;
    polarity = [];
    keepLogical = [true(numEventsProcessed, 1); false(currentLengthOfEventVectors - numEventsProcessed, 1)];
    polarity.timeStamp	= timeStamp(keepLogical);
    polarity.y			= y(keepLogical) - 8; % These subtractions are because of the 1-based encoding in the SEC packet format
    polarity.x			= x(keepLogical) - 1; % These subtractions are because of the 1-based encoding in the SEC packet format
    polarity.polarity	= polarityArray(keepLogical);
    aedat.data.polarity = polarity;

    % Find first and last time stamps
    aedat = FindFirstAndLastTimeStamps(aedat);

    % Add NumEvents field for each data type
    aedat = NumEventsByType(aedat);
end

disp('Import finished')

%% Half-baked approach to matricising computation
%{

msb = bitget(allPackets, 32);
secondMsb = bitget(allPackets, 31);

eventsLogical = msb & secondMsb;
columnLogical = msb & ~secondMsb;
timeStampLogical = ~msb & secondMsb;

timeStamps = zeros(numPackets, 1, 'uint32');
timeStamps(timeStampLogical) = bitshift(allPackets(timeStampLogical), 10);
timeStamps = FloodFillColumnDownwards(timeStamps);

%}


function selected = spm_eeg_select_event_ui(event)
% Allow the user to select an event using GUI
% Copyright (C) 2008-2012 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak
% $Id: spm_eeg_select_event_ui.m 5592 2013-07-24 16:25:55Z vladimir $

selected={};

if isempty(event)
    fprintf('no events were found\n');
    return
end

eventtype = unique({event.type});
Neventtype = length(eventtype);

% Two lists are built in parallel
settings={}; % The list of actual values to be used later
strsettings={}; % The list of strings to show in the GUI

for i=1:Neventtype
    sel = find(strcmp(eventtype{i}, {event.type}));

    numind = find(...
        cellfun('isclass', {event(sel).value}, 'double') & ...
        ~cellfun('isempty', {event(sel).value}));

    charind = find(cellfun('isclass', {event(sel).value}, 'char'));

    emptyind = find(cellfun('isempty', {event(sel).value}));

    if ~isempty(numind)
        numvalue = unique([event(sel(numind)).value]);
        for j=1:length(numvalue)
            ninstances = sum([event(sel(numind)).value] == numvalue(j));
            strsettings=[strsettings; {['Type: ' eventtype{i} ' ; Value: ' num2str(numvalue(j)) ...
                ' ; ' num2str(ninstances) ' instances']}];
            settings=[settings; [eventtype(i), {numvalue(j)}]];
        end
    end

    if ~isempty(charind)
        charvalue = unique({event(sel(charind)).value});
        if ~iscell(charvalue)
            charvalue = {charvalue};
        end
        for j=1:length(charvalue)
            ninstances = length(strmatch(charvalue{j}, {event(sel(charind)).value}, 'exact'));
            strsettings=[strsettings; {['Type: ' eventtype{i} ' ; Value: ' charvalue{j}...
                ' ; ' num2str(ninstances) ' instances']}];
            settings=[settings; [eventtype(i), charvalue(j)]];
        end
    end

    if ~isempty(emptyind)
        strsettings=[strsettings; {['Type: ' eventtype{i} ' ; Value: ; ' ...
            num2str(length(emptyind)) ' instances']}];
        settings=[settings; [eventtype(i), {[]}]];
    end
end

[selection,ok]= listdlg('ListString',strsettings, 'SelectionMode', 'multiple', 'Name', 'Select event', 'ListSize', [400 300]);

if ok
    selected=settings(selection, :);
else
    selected={};
end


function setOptsDoubleValueInObject(handles, options, optPropName, handlesFieldName)
    strValue = strtrim(get(handles.(handlesFieldName),'String'));

    if(~isempty(strValue)) %allow empty, implies default
        value = str2double(strValue);
    else
        value = NaN;
    end
    options.(optPropName) = value;


%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2 of the License, or
%  (at your option) any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; if not, write to the Free Software
%  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
function dividert
%DIVIDERT Unit test for the function DIVIDER.

%	O. Lemoine - March 1996.

N=500;

for k=1:N,
 [Nk,Mk]=divider(k);
 err(k)=abs(Nk*Mk-k);
end

if any(err),
 error('divider test 1 failed');
end;


function res = getset(this, parent, fieldname, ind, values)
% Generic method for getting and setting multiple fields of meeg struct
% FORMAT res = getset(this, parent, fieldname, ind, values)
% _______________________________________________________________________
% Copyright (C) 2008-2012 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak
% $Id: getset.m 6535 2015-08-25 11:45:26Z vladimir $

this = struct(this);

if nargin == 3 || ~isnumeric(ind)
    try
        ind = 1:numel(getfield(this, parent));
    catch
        res = [];
        return;
    end
end

% Get
if nargin <= 4
    res = cell(1, length(ind));
    for i = 1:length(ind)
        res{i} = getfield(this, parent, {ind(i)}, fieldname);
    end

    if isempty(res) || (all(cellfun('isclass', res, 'double') & (cellfun(@numel, res) == 1)))
        res = [res{:}];
    end

    if iscell(res) && (numel(res) == 1) && (numel(getfield(this, parent)) == 1) &&...
            strcmp(parent, 'trials') && strcmp(this.type, 'continuous')
        res = res{1};
    end

    return
end

% Set
if nargin == 5
    % This might fail in some pathological cases, but not in what it's
    % supposed to be used for.
    if (isnumeric(values) || islogical(values)) && (length(values) == length(ind))
        values = num2cell(values);
    end

    if iscell(values) && ~(numel(values)==1 || numel(values) == length(ind))
        error('Illegal assignment: cannot match values and indices.');
    end

    for i = 1:length(ind)
        if iscell(values)
            this = setfield(this, parent, {ind(i)}, fieldname, values{i});
        else
            this = setfield(this, parent, {ind(i)}, fieldname, values);
        end
    end
    % getset is sometimes used on subfields of meeg then checkmeeg should
    % not be used
    if all(isfield(this, {'type', 'Nsamples', 'Fsample', 'timeOnset'}))
        res = meeg(this);
    else
        res = this;
    end
end


function sdlfmKernDisplay(kern, spacing)

% SDLFMKERNDISPLAY Display parameters of the SDLFM kernel.
% FORMAT
% DESC displays the parameters of the switching dynamical latent force
% model kernel and the kernel type to the console.
% ARG kern : the kernel to display.
%
% FORMAT does the same as above, but indents the display according
% to the amount specified.
% ARG kern : the kernel to display.
% ARG spacing : how many spaces to indent the display of the kernel by.
%
% SEEALSO : sdlfmKernParamInit, modelDisplay, kernDisplay
%
% COPYRIGHT : Neil D. Lawrence, 2006
%
% MODIFICATIONS : Mauricio A. Alvarez, 2010.

% KERN

if nargin > 1
  spacing = repmat(32, 1, spacing);
else
  spacing = [];
end
spacing = char(spacing);
fprintf(spacing);
fprintf('SDLFM mass: %2.4f\n', kern.mass)
fprintf(spacing);
fprintf('SDLFM spring: %2.4f\n', kern.spring)
fprintf(spacing);
fprintf('SDLFM damper: %2.4f\n', kern.damper)
for i=1:kern.nlfPerInt
    for j=1:kern.nIntervals
        fprintf(spacing);
        fprintf('SDLFM inverse width %d interval %d: %2.4f (length scale %2.4f)\n', ...
           i,j, kern.inverseWidth(i,j), 1/sqrt(kern.inverseWidth(i,j)));
    end
end
for j=1:kern.nIntervals
    fprintf(spacing);
    fprintf('SDLFM switching point interval %d: %2.4f \n', ...
        j, kern.switchingTimes(j));
end
for i=1:kern.nlfPerInt
    for j=1:kern.nIntervals
        fprintf(spacing);
        fprintf('SDLFM sensitivity %d interval %d: %2.4f \n', ...
           i,j, kern.sensitivity(i,j));
    end
end
fprintf(spacing);
fprintf('System Characteristics:\n')
fprintf(spacing);
fprintf('SDLFM omega: %2.4f\n', kern.omega)
fprintf(spacing);
fprintf('SDLFM alpha: %2.4f\n', kern.alpha)
fprintf(spacing);
fprintf('SDLFM gamma: %2.4f\n', kern.gamma)
fprintf(spacing);
fprintf('SDLFM Damping Ratio: %2.4f\n', kern.zeta)
fprintf(spacing);
fprintf('SDLFM Undamped Natural Frequency: %2.4f\n', kern.omega_0)


function [system] = LoadStandingSystem(model, load_path)
    % Load the hybrid system model

    if nargin < 2
        load_path = [];
    end

    doubleStance = sys.domains.DoubleStance(model, load_path);
%     rightStance = sys.domains.RightStance(model, load_path);
%     leftStance = sys.domains.LeftStance(model, load_path);
%
%
%
%     leftImpact = RigidImpact('LeftImpact', rightStance, 'leftFootHeight'); % To leftStance
%     leftImpact.addImpactConstraint(struct2array(leftStance.HolonomicConstraints), load_path);
%
%     rightImpact = RigidImpact('RightImpact', leftStance, 'rightFootHeight'); % To rightStance
%     rightImpact.addImpactConstraint(struct2array(rightStance.HolonomicConstraints), load_path);
%
    io_control  = IOFeedback('IO');

    system = HybridSystem('atlas');
    system = addVertex(system, 'DoubleStance', 'Domain', doubleStance, ...
        'Control', io_control);
%     system = addVertex(system, 'RightStance', 'Domain', rightStance, ...
%         'Control', io_control);
%     system = addVertex(system, 'LeftStance', 'Domain', leftStance, ...
%         'Control', io_control);
%
%     srcs = {'RightStance'
%         'LeftStance'};
%
%     tars = {'LeftStance'
%         'RightStance'};
%
%     system = addEdge(system, srcs, tars);
%     system = setEdgeProperties(system, srcs, tars, ...
%         'Guard', {leftImpact, rightImpact});

end


function [features, labels, labelprobs, weights] = ...
    mcmcGetAllGoodSegments(imsegs, imdir, vclassifierSP, hclassifierSP, ...
    eclassifier, segclassifier, spdata, adjlist, edata, ncv)

for f = 1:numel(imsegs)
    k = mod(ceil(f/(numel(imsegs)/ncv)), ncv) + 1;
    disp([num2str(f) ': ' imsegs(f).imname])
    im = im2double(imread([imdir '/' imsegs(f).imname]));
    [features{f}, labels{f}, labelprobs{f}, weights{f}] = ...
        mcmcGenerateGoodSegments(im, imsegs(f), vclassifierSP, hclassifierSP, ...
        eclassifier, segclassifier(k), spdata{f}, adjlist{f}, edata{f});
end