function apply_derivative_boost(imgtype, varargin)
% Allows for recalculation of amplitude images from the fitted responses
% for each trial type. Necessary for calculating group statistics when
% using multiple basis functions
%
% :Usage:
% ::
%
%     function apply_derivative_boost(varargin)
%
% :NOTES:
%    DB estimation only works for 2 specific basis sets:
%    timeonly, with 2 parameters (canonical + time derivative)
%    timedispersion,' with 3 parameters (canonical hrf + temporal and spatial dispersion)
%
% This function loads the SPM.mat file in the current directory and uses
% the basis set specified in the loaded SPM structure.
%
% : Required Inputs:
% 	indicate whether images are'.img' or '.nii'
%
% :Optional Inputs:
%
%   **'amplitudes'**
%        will only create amping images (combination of betas
%        across basis functions)
%
%   **'contrasts'**
%        assumes that amping images are already created; will only
%        create contrast images
%
%   **'all'**
%        will run both the amplitudes and contrasts sections
%
%        In addition, 'amplitudes' now has two separate parts:
%          - The first uses Vince Calhoun's derivative boost (Calhoun, 2004) to
%             estimate amplitudes.  NOTE: *We have not worked out the scaling yet, so
%             I'm not sure this is working right*
%             To turn this OFF, enter 'nodb' as an optional argument
%
%          - The second way uses our HTW code to estimate height, time to peak,
%            width, and area under the curve (see Lindquist & Wager 2007 for
%            simulations using a version of this code).
%            It requires SCANlab specific functions, in SCN_Core_Support
%            (unlike the deriv. boost).
%            To turn this OFF, enter 'nohtw' as an optional argument
%
%   **'startend'**
%        followed by starting and ending values in seconds for amplitude
%        estimation window (for HTW estimation only).
%        If you do not enter this, it will show you a plot and ask you to pick
%        these values.
%        If you enter them here as inputs, you can skip the interactive step and
%        loop over subjects.
%
%   **'condition_numbers'**
%        followed by which index numbers in your list should
%        be used to calculate h, t, w from.  You should use this if you
%        are entering regressors of no interest, besides the intercepts.
%
% :Important for Contrasts:
%    disp('Using contrasts entered as F-contrasts. Assuming the first contrast vector in each F-contrast '
%
%    disp('is a contrast of interest across the CANONICAL basis function regressors.')
%
% :Examples:
% ::
%
%    % RUN THIS IN COMMAND WINDOW TO BATCH
%    subj = dir('06*')
%    for i = 1:length(subj), cd(subj(i).name), apply_derivative_boost, cd('..'); end
%
%    % ANOTHER BATCH EXAMPLE:
%    d = dir('remi*'); d = d(cat(2, d.isdir)); [mydirs{1:length(d)}] = deal(d.name)
%    for i = 1:length(mydirs), cd(mydirs{i}), apply_derivative_boost('all', 'nodb', 'startend', [4 15]), cd('..'); end
%
%    %An example for an event-related design, specifying condition numbers to get HTW from:
%    apply_derivative_boost('all', 'nodb', 'contrasts', 'condition_numbers', 1:14, 'startend', [4 10]);
%
%    % CALCULATE CONTRASTS ONLY ON ALREADY-ESTIMATED HTW IMAGES
%    apply_derivative_boost('contrasts','condition_numbers',1:14);
%

    imgtype = imgtype;
    spmname = fullfile(pwd, 'SPM.mat');     % SETUP INPUTS
    if ~exist(spmname, 'file'), error('You must be in an SPM 1st-level results directory with SPM5 SPM.mat file.'); end

    load(spmname);

    nbf = size(SPM.xBF.bf, 2);

    switch nbf
        case 2
            derivative_case = 'timeonly';
        case 3
            derivative_case = 'timedispersion';

        otherwise
            warning('Deriv. Boost only works for SPM canonical hrf with time or time + dispersion derivatives.  This SPM.mat doesn''t match those specs.');
    end

    % Not used; only for image eval function
    % boost = @(b) sign(b(1)) .* sqrt(sum(b .^ 2));

    docontrasts = 0;
    doamps = 0;
    nodb = 0;
    nohtw = 0;
    condition_numbers = [];
    do_downsample = [];          % downsample; default = 1 sec if units are seconds (1/dt)

    for i = 1:length(varargin)
        if ischar(varargin{i})
            switch varargin{i}
                % reserved keywords
                case 'all', docontrasts = 1; doamps = 1;

                case 'amplitudes', doamps = 1;

                case 'contrasts', docontrasts = 1;

                case 'nodb', nodb = 1; % skip DB estimation

                case 'nohtw', nohtw = 1; % skip HTW estimation

                case 'startend', startend = varargin{i + 1};  % starting and ending values in seconds for amplitude estimation window (for HTW estimation only).

                case 'condition_numbers',  condition_numbers = varargin{i + 1};

                case 'nodownsample', do_downsample = 0;

                case 'downsample', do_downsample = varargin{i + 1};

                otherwise, warning(['Unknown input string option:' varargin{i}]);
            end
        end
    end

    if isempty(do_downsample)
        % default downsampling
        do_downsample = round(1 ./ SPM.xBF.dt);
    end

    if ~(docontrasts || doamps)
        disp('Nothing to do! Enter ''contrasts'' ''amplitudes'' or ''all'' as input argument.');
        return
    end

    if doamps
        % ---------------------------------------------
        % ---------------------------------------------

        % ESTIMATE AMPLITUDES

        % ---------------------------------------------
        % ---------------------------------------------

        % ---------------------------------------------
        % FILE NAMES
        % ---------------------------------------------

        imgs = dir(sprintf(['beta*', imgtype])); imgs = char(imgs.name);
        n = size(imgs, 1);

        fprintf('Found %3.0f images', n); fprintf('\n');

        %load(spmname);
        nsess = length(SPM.Sess);
        fprintf('I think there are %3.0f sessions (runs)', nsess); fprintf('\n');

        if ~isempty(condition_numbers)
            wh_intercept = true(1, size(imgs, 1));  % exclude these
            wh_intercept(condition_numbers) = 0;
            wh_intercept = find(wh_intercept);

            fprintf('\nIncluding only these images: ');
            fprintf('%3.0f ', condition_numbers);
            fprintf('\n');

        else
            wh_intercept = SPM.xX.iB;
            fprintf('\nI think these images are intercepts, and am not using them: ');
            fprintf('%3.0f ', wh_intercept);
            fprintf('\n');
        end

        imgs(wh_intercept, :) = [];

        %not used; only when using image_eval_function
        %mask_img = './mask.img';

        n = size(imgs, 1);

        if n / nbf ~= round(n / nbf), error('Error!  Wrong number of images for the specified number of basis functions.'); end

        if nodb
            % skip Derivative Boost estimation and go straight to HTW
        else

            % ---------------------------------------------
            % CALCULATE
            % ---------------------------------------------
            cond_indx = 1;

            for i = 1: nbf : (n - nbf + 1)

                imgs_cond = imgs(i : i+nbf - 1, :);

                disp('Working on :')
                disp(imgs_cond)

                out_name = sprintf(['db_amplitude_%03d',imgtype ], cond_indx);

                % This code uses SCN lab tools to create images
                % ---------------------------------------------
                % %     y = image_eval_function(imgs_cond, boost, 'mask', mask_img, ...
                % %         'outimagelabels', {out_name});
                % ---------------------------------------------

                % This code uses SPM instead
                % ---------------------------------------------
                switch derivative_case
                    case 'timeonly'
                        spm_imcalc(imgs_cond, out_name, 'sign(i1) .* sqrt(i1.^2 + i2.^2)');
                    case 'timedispersion'
                        spm_imcalc(imgs_cond, out_name, 'sign(i1) .* sqrt(i1.^2 + i2.^2 + i3.^2)');
                    otherwise
                        error('Basis set is incompatible with DB estimation!');
                end

                fprintf('Created %s\n', out_name);
                % ---------------------------------------------

                cond_indx = cond_indx + 1;
            end

            % Get and save names
            db_amp_names = [];
            for i = 1:nsess
                sessnames = char(SPM.Sess(i).Fc.name);
                sessnames = [repmat(sprintf('Sess%02d_', i), size(sessnames, 1), 1) sessnames];
                db_amp_names = strvcat(db_amp_names, sessnames);
            end

            save db_amplitude_names db_amp_names
            disp(db_amp_names);
            disp(' ')
            disp('Saved DB amplitude condition names for each image in db_amplitude_names.mat');

            fprintf('\n*-----------------------------*\nApplied DB successfully\n*-----------------------------*\n')

        end

        if nohtw
            % skip this

        else

            % ---------------------------------------------
            % Estimated amplitude from fit: HTW
            % ---------------------------------------------
            % This code uses SCN lab tools to create images

            disp(' ')
            disp('Next: Estimating amplitude, time to peak, width, and area-under-curve images from fitted response using SCN lab code.')
            disp(' ')

            % downsample bf, if requested
            if do_downsample
                mytimeres = SPM.xBF.dt * do_downsample;
                SPM.xBF.bf = downsample(SPM.xBF.bf, do_downsample);

            else
                mytimeres = SPM.xBF.dt;
            end

            if exist('startend', 'var')
                % just check, and use input values
                if length(startend) ~= 2, error('Startend input must have two values, a starting and ending value in seconds for the amp. estimate window'), end
            else
                % Set range in sec
                htw_from_fit(SPM.xBF.bf, ones(size(SPM.xBF.bf, 2), 1), mytimeres, 'plot', 'verbose');

                disp(' ')
                disp('Enter the range in seconds within which to estimate peak amplitude.')
                disp('Example: type [2.5 9] and press return for a typical event-related setup.');
                disp('More sustained responses, like pain responses, may require a longer window.');
                disp('This estimates the amplitude of the IMPULSE RESPONSE, before convolution with the stimulus function')
                disp('so if you have an epoch design, a typical window of [2.5 9] sec is still appropriate.');
                disp('Also note: AUC images are calculated as the area under the curve within the window you specify.')
                disp(' ')

                startend = input('Enter your choice in [ ] and press return: ');
            end

            % Test your choice by showing you a plot
            htwfunction = @(b) htw_from_fit(SPM.xBF.bf, b, mytimeres, 'startval', startend(1), 'endval', startend(2), 'plot', 'verbose');
            htwfunction(ones(size(SPM.xBF.bf, 2), 1))
            drawnow

            % Create without plot option for loop through brain.
            htwfunction = @(b) htw_from_fit(SPM.xBF.bf, b, mytimeres, 'startval', startend(1), 'endval', startend(2));

            disp('Check the screen for a plot of your choice of window.')
            disp(' ')

            % ---------------------------------------------
            % CALCULATE
            % ---------------------------------------------
            cond_indx = 1;

            for i = 1: nbf : (n - nbf + 1)

                imgs_cond = imgs(i : i+nbf - 1, :);

                disp('Working on :')
                disp(imgs_cond)

                clear out_name
                out_name{1} = sprintf(['htw_amplitude_%03d',imgtype], cond_indx);
                out_name{2} = sprintf(['htw_time_to_peak_%03d',imgtype], cond_indx);
                out_name{3} = sprintf(['htw_width_%03d',imgtype], cond_indx);
                out_name{4} = sprintf(['htw_area_under_curve_%03d',imgtype], cond_indx);

                % ---------------------------------------------
                [h, t, w, auc] = image_eval_function(imgs_cond, htwfunction, 'mask', ['mask', imgtype], ...
                    'outimagelabels', out_name);

                h;t;w;auc;  % we need the outputs above to tell it to write 4 images.
                % ---------------------------------------------

                cond_indx = cond_indx + 1;
            end

            % Get and save names
            htw_amp_names = [];
            for i = 1:nsess
                sessnames = char(SPM.Sess(i).Fc.name);
                sessnames = [repmat(sprintf('Sess%02d_', i), size(sessnames, 1), 1) sessnames];
                htw_amp_names = strvcat(htw_amp_names, sessnames);
            end

            if ~exist(fullfile(pwd, 'db_amplitude_names.mat'), 'file')
                save db_amplitude_names htw_amp_names
            else
                save db_amplitude_names -append htw_amp_names
            end
            disp(htw_amp_names);
            disp(' ')
            disp('Saved HTW amplitude condition names for each image in db_amplitude_names.mat');

            fprintf('\n*-----------------------------*\nApplied HTW estimation successfully\n*-----------------------------*\n')

        end

    end  % amplitudes

    % ---------------------------------------------
    % ---------------------------------------------

    % CREATE CONTRAST FOR THIS SUBJECT

    % ---------------------------------------------
    % ---------------------------------------------

    if docontrasts

        % Load contrast vectors

        % -----------------------------------------
        %load(spmname);
        % nsess = length(SPM.Sess);

        % Define which indices to exclude from contrasts
        if ~isempty(condition_numbers)
            nconvals = length(SPM.xCon(1).c(:, 1));  % test contrast
            wh_intercept = true(1, nconvals);  % exclude these
            wh_intercept(condition_numbers) = 0;
            wh_intercept = find(wh_intercept);

            fprintf('\nIncluding only these images: ');
            fprintf('%3.0f ', condition_numbers);
            fprintf('\n');

        else
            wh_intercept = SPM.xX.iB;
            fprintf('\nI think these images are intercepts, and am not using them: ');
            fprintf('%3.0f ', wh_intercept);
            fprintf('\n');
        end

        if ~isfield(SPM, 'xCon')
            error('Enter F-contrasts first, with the first contrast vector in each F-contrast the contrast across the CANONICAL basis function.');
        else
            disp('Using contrasts entered as F-contrasts. Assuming the first contrast vector in each F-contrast ')
            disp('is a contrast of interest across the CANONICAL basis function regressors.')
        end

        wh_F = strmatch('F', char(SPM.xCon.STAT), 'exact');

        if isempty(wh_F), error('No F-contrasts entered yet.'); end

        % All sets of contrast images
        % ------------------------------------------
        ampimgs_name = sprintf(['db_amplitude_*',imgtype]);

        ampimgs = dir(ampimgs_name); ampimgs = char(ampimgs.name);

        if ~isempty(ampimgs)
            contrast_image_names_dbamp = calc_contrasts(ampimgs_name, ampimgs, wh_F, SPM, wh_intercept, nbf);
        else
            disp(['Checked for but did not find: ']);
        end

        % HTW amplitude
        % ------------------------------------------
        ampimgs_name = sprintf(['htw_amplitude_*',imgtype]);

        ampimgs = dir(ampimgs_name); ampimgs = char(ampimgs.name);

        if ~isempty(ampimgs)
            contrast_image_names_htwamp = calc_contrasts(ampimgs_name, ampimgs, wh_F, SPM, wh_intercept, nbf);
        else
            disp(['Checked for but did not find: ' ampimgs_name]);
        end

        % HTW time
        % ------------------------------------------
        ampimgs_name = sprintf(['htw_time_to_peak_*',imgtype]);

        ampimgs = dir(ampimgs_name); ampimgs = char(ampimgs.name);

        if ~isempty(ampimgs)
            contrast_image_names_htwtime = calc_contrasts(ampimgs_name, ampimgs, wh_F, SPM, wh_intercept, nbf);
        else
            disp(['Checked for but did not find: ' ampimgs_name]);
        end

        % HTW width
        % ------------------------------------------
        ampimgs_name = sprintf(['htw_width_*',imgtype]);

        ampimgs = dir(ampimgs_name); ampimgs = char(ampimgs.name);

        if ~isempty(ampimgs)
            contrast_image_names_htwwid = calc_contrasts(ampimgs_name, ampimgs, wh_F, SPM, wh_intercept, nbf);
        else
            disp(['Checked for but did not find: ' ampimgs_name]);
        end

        % HTW area
        % ------------------------------------------
        ampimgs_name = sprintf(['htw_area_under_curve_*',imgtype]);

        ampimgs = dir(ampimgs_name); ampimgs = char(ampimgs.name);

        if ~isempty(ampimgs)
            contrast_image_names_htwarea = calc_contrasts(ampimgs_name, ampimgs, wh_F, SPM, wh_intercept, nbf);
        else
            disp(['Checked for but did not find: ' ampimgs_name]);
        end

        check_it = whos('contrast_image_names*');

        if isempty(check_it)
            disp('No valid images found to create contrasts on');

        else
            save('db_amplitude_names', '-append', 'contrast_image_names*');
            disp('Saved lists of contrast image names in db_amplitude_names.mat');
        end

    end

    %% INLINE

end  % main function

function contrast_image_names = calc_contrasts(ampimgs_name, ampimgs, wh_F, SPM, wh_intercept, nbf)

    n = size(ampimgs, 1);

    fprintf('Found %3.0f images:\n', n);
    disp(ampimgs)

    disp('Reading image data.')
    V = spm_vol(ampimgs);
    vols = spm_read_vols(V);

    % spm_check_registration(ampimgs);
    % colormap jet

    contrast_image_names = [];

    for i = 1:length(wh_F)

        name = SPM.xCon(wh_F(i)).name;
        disp(['Calculating contrast on: ' name])
        original_name = name;

        name = deblank(name);
        wh_bad = (name == ' ' | name == ',' | name == '.' | name == '^' | name == '~' | name == '''' | name == ':' | name == '*' | name == '%' | name == ';' | name == '@' | name == '&');
        name(wh_bad) = [];

        name = ['con_', ampimgs_name(1:8), '_', name, imgtype];

        c = SPM.xCon(wh_F(i)).c(:, 1);
        c(wh_intercept) = [];
        c = c(1 : nbf : end);

        if length(c) ~= n, error('Contrast is wrong length for some reason!  Coding error in this function?  Or wrong number of db_amplitude images.'); end

        fprintf('Contrast values: ')
        fprintf('%01d ', c)
        fprintf('\n')

        % calculate and save

        contrast_image_calc(name, c, vols, V, original_name)

        disp(['Written: ' name]);

        contrast_image_names = strvcat(contrast_image_names, name);

        disp(' ');

    end

    fprintf('\n*-----------------------------*\nContrasts Done successfully!\n*-----------------------------*\n')
    spm_check_registration(contrast_image_names);

end

function contrast_image_calc(Q, myc, vols, V, original_name)

    % FROM:
    % function contrast_image(Q, myc)
    %
    % Tor Wager
    %
    % Creates a contrast image called Q (do not include path)
    % Given a list of img files P (spm format, with path)
    % and a contrast vector myc
    % In the directory of 1st image in P.

    if ~(length(myc) == size(vols,4))
        error('Contrast vector length is not equal to number of image files.')
    end

    myc2 = zeros(size(vols));

    for i = 1:length(myc)
        myc2(:,:,:,i) = myc(i);
    end

    cvol = vols .* myc2;
    cvol = sum(cvol,4);

    % -------------------------
    % write
    % -------------------------
    dd = fileparts(V(1).fname);
    Q = fullfile(dd, Q);
    Vo = V(1);
    Vo.fname = Q;
    Vo.descrip = ['Contrast ' original_name];

    spm_write_vol(Vo,cvol);

end


function t = calcInitial( Deriv, X, xi)
%CALCINITIAL Calculate the initial guess for the line search.
%
%   Wrapper function for calcInitial_mex.c
%
%   See also calcGradient, calcFunction
%

%   GeomCG Tensor Completion. Copyright 2013 by
%   Michael Steinlechner
%   Questions and contact: michael.steinlechner@epfl.ch
%   BSD 2-clause license, see LICENSE.txt

    t = -calcInitial_mex( Deriv.subs', Deriv.vals, ...
                          X.core.data, X.U{1}', X.U{2}', X.U{3}',...
                          xi.Y_tilde.data, xi.U1_tilde', xi.U2_tilde', xi.U3_tilde');

end


function select3dtool(arg)
%SELECT3DTOOL A simple tool for interactively obtaining 3-D coordinates
%
% SELECT3DTOOL(FIG) Specify figure handle
%
% Example:
%   surf(peaks);
%   select3dtool;
%   % click on surface

if nargin<1
   arg = gcf;
end

if ~ishandle(arg)
   feval(arg);
   return;
end

%% initialize gui %%
fig = arg;
figure(fig);

uistate = uiclearmode(fig);
[tool, htext] = createUI;
hmarker1 = line('marker','o','markersize',10,'markerfacecolor','k','erasemode','xor','visible','off');
hmarker2 = line('marker','o','markersize',10,'markerfacecolor','r','erasemode','xor','visible','off');

state.uistate = uistate;
state.text = htext;
state.tool = tool;
state.fig = fig;
state.marker1 = hmarker1;
state.marker2 = hmarker2;
setappdata(fig,'select3dtool',state);
setappdata(state.tool,'select3dhost',fig);

set(fig,'windowbuttondownfcn','select3dtool(''click'')');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function off

state = getappdata(gcbf,'select3dtool');

if ~isempty(state)
    delete(state.tool);
end

fig = getappdata(gcbf,'select3dhost');

if ~isempty(fig) && ishandle(fig)
    state = getappdata(fig,'select3dtool');
    uirestore(state.uistate);
    delete(state.marker1);
    delete(state.marker2);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function click

[p, v, vi] = select3d;
state = getappdata(gcbf,'select3dtool');

if ~ishandle(state.text)
    state.text = createUI;
end

if ~ishandle(state.marker1)
    state.marker1 = [];
end

if ~ishandle(state.marker2)
    state.marker2 = [];
end

setappdata(state.fig,'select3dtool',state);

if isempty(v)
    v = [nan nan nan];
    vi = nan;
    set(state.marker2,'visible','off');
else
    set(state.marker2,'visible','on','xdata',v(1),'ydata',v(2),'zdata',v(3));
end

if isempty(p)
    p = [nan nan nan];
    set(state.marker1,'visible','off');
else
    set(state.marker1,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));
end

% Update tool and markers
set(state.text,'string',createString(p(1),p(2),p(3),v(1),v(2),v(3),vi));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [fig, h] = createUI

pos = [200 200 200 200];

% Create selection tool %
fig = figure('handlevisibility','off','menubar','none','resize','off',...
    'numbertitle','off','name','Select 3-D Tool','position',pos,'deletefcn','select3dtool(''off'')');

h = uicontrol('style','text','parent',fig,'string',createString(0,0,0,0,0,0,0),...
    'units','norm','position',[0 0 1 1],'horizontalalignment','left');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [str] = createString(px,py,pz,vx,vy,vz,vi)

str = sprintf('  Position:\n  X  %f\n  Y:  %f\n  Z:  %f  \n\n  Vertex:\n  X:  %f\n  Y:  %f\n  Z:  %f  \n\n  Vertex Index:\n  %d',px,py,pz,vx,vy,vz,vi);


%% (Internal) Plot the area under the ROC curve
%
%       plot_auc( areas, pvalues, strTitle, strLegend, bPrint, fig_hdl)
%
%
% Arguments:
%
%      + areas: string to parse
%
%      + pvalues: string to parse
%
%      + strTitle: string to parse
%
%      + strLegend: string to parse
%
%      + bPrint: string to parse
%
%      + fig_hdl: string to parse
%
% Example:
%
%
% See also ECGwrapper
%
% Author: Mariano Llamedo Soria (llamedom at frba.utn.edu.ar)
% Version: 0.1 beta
% Birthdate  : 30/7/2014
% Last update: 30/7/2014
% Copyright 2008-2015
%
function plot_auc( areas, pvalues, strTitle, strLegend, bPrint, fig_hdl)

if( nargin < 4  )
    strLegend = [];
end

if( nargin < 3  )
    strTitle = [];
end

if( nargin < 5 || isempty(bPrint) )
    bPrint = false;
end

if( size(areas,1) ~= 3 )
    error('areas should have lower CI - mean Area - upper CI in the rows')
end

if( nargin < 6 || isempty(fig_hdl) )
    fig_hdl = figure();
else
    fig_hdl = figure(fig_hdl);
%     clf(fig_hdl);
end

areas2plot = size(areas,2);
Xvalues = [ ];
Yvalues = [ ];
significance_levels = [0.05 0.01 0.001];
significance_levels_str = {'0.05' '0.01' '0.001'};

box_dist = 1;
box_width = box_dist* 2/3;
box_loc = 1:box_dist:box_dist*areas2plot;
box_height_k = 0.75;
colors = my_colormap(areas2plot);
areas_min = min(min(areas));
areas_max = max(max(areas));
areas_range = areas_max - areas_min;

if(bPrint)
    strFontName = 'LMRoman12';
    FontSizeTitle = 22;
    FontSizeLabel = 20;
    FontSizeTick = 18;
else
    strFontName = 'Helvetica';
    FontSizeTitle = 12;
    FontSizeLabel = 12;
    FontSizeTick = 10;
end

axes_hdl = gca();
% cla(axes_hdl);

xlim([0 (box_dist*areas2plot)+box_dist])
% ylim([areas_min - 0.1*areas_range  areas_max + 0.2*areas_range ])

hold on

for ii = 1:areas2plot

    box_height = box_height_k * (areas(3,ii) - areas(1,ii));
    this_colour = colors( 1+rem(ii-1, size(colors,1)),:);
    plot( box_loc(ii) + [-box_width/4 box_width/4], [areas(3,ii) areas(3,ii)], 'Color', this_colour, 'LineWidth', 2 );
    plot( box_loc(ii) + [-box_width/4 box_width/4], [areas(1,ii) areas(1,ii)], 'Color', this_colour, 'LineWidth', 2 )
    plot( [box_loc(ii) box_loc(ii)], [areas(3,ii) areas(1,ii)], 'Color', this_colour, 'LineWidth', 2 )
    fill( box_loc(ii) + [-box_width/2 -box_width/2 box_width/2 box_width/2], areas(2,ii) + [ -box_height/2 box_height/2 box_height/2 -box_height/2], this_colour, 'EdgeColor',  this_colour );
    text( box_loc(ii), areas(2,ii), num2str(areas(2,ii), '%3.2f'), 'HorizontalAlignment', 'center', 'FontName', strFontName, 'FontSize', FontSizeTick, 'Color', (1-this_colour));

end

for ii = 1:(areas2plot-1)
    for jj = ii+1:areas2plot
        if( pvalues(ii,jj) < 0.05 )
            y_loc = max(areas(3,ii), areas(3,jj)) + (0.05*areas_range);
            if( bPrint )
                plot( [box_loc(ii) box_loc(ii) box_loc(jj) box_loc(jj)], y_loc + (0.02*areas_range) * [0 1 1 0], 'LineWidth', 1 , 'Color', [0 0 0] );
            else
                plot( [box_loc(ii) box_loc(ii) box_loc(jj) box_loc(jj)], y_loc + (0.02*areas_range) * [0 1 1 0], 'LineWidth', 2 , 'Color', [0 0 0] );
            end
        end
    end

    % overprint the p-value
    for jj = ii+1:areas2plot
        aux_idx = find(pvalues(ii,jj) < significance_levels, 1, 'last');
        if( ~isempty(aux_idx) )
            y_loc = max(areas(3,ii), areas(3,jj)) + (0.05*areas_range);

            if( bPrint )
                aux_hdl = text( box_loc(ii)+(box_loc(jj) - box_loc(ii))/2, y_loc + (0.07*areas_range), [ 'p < ' significance_levels_str{aux_idx} ], 'HorizontalAlignment', 'center', 'FontName', strFontName, 'FontSize', FontSizeTick, 'Visible', 'off');
                aux_extent = get(aux_hdl, 'Extent');
                delete(aux_hdl)
                aux_extent(1) = aux_extent(1) + 0.1*aux_extent(3);
                aux_extent(3) = 0.8*aux_extent(3);
                aux_extent(2) = aux_extent(2) + 0.25*aux_extent(4);
                aux_extent(4) = 0.7*aux_extent(4);
                fill( aux_extent(1)+ [ 0 0 aux_extent(3) aux_extent(3) ], aux_extent(2)+ [ 0 aux_extent(4) aux_extent(4) 0 ], [1 1 1], 'EdgeColor', [1 1 1]  );
                text( box_loc(ii)+(box_loc(jj) - box_loc(ii))/2, y_loc + (0.07*areas_range), [ 'p < ' significance_levels_str{aux_idx} ], 'HorizontalAlignment', 'center', 'FontName', strFontName, 'FontSize', FontSizeTick);
            else
                text( box_loc(ii)+(box_loc(jj) - box_loc(ii))/2, y_loc + (0.07*areas_range), [ 'p < ' significance_levels_str{aux_idx} ], 'HorizontalAlignment', 'center', 'FontName', strFontName, 'FontSize', FontSizeTick, 'BackgroundColor', [1 1 1]);
            end
        end
    end

end

hold off

set(axes_hdl, 'Box', 'off' );
set(axes_hdl, 'Xtick', box_loc );
set(axes_hdl, 'XtickLabel', strLegend );
rotateticklabel(axes_hdl, 20);
set(axes_hdl, 'Ytick', linspace(areas_min, areas_max, 5) );
set(axes_hdl, 'YtickLabel', num2str(colvec(linspace(areas_min, areas_max, 5)), '%3.2f') );

set(axes_hdl, 'FontName', strFontName );
set(axes_hdl, 'FontSize', FontSizeTick );

title(strTitle, 'FontName', strFontName, 'FontSize', FontSizeTitle)

ylabel('AUC', 'FontName', strFontName, 'FontSize', FontSizeLabel)


%kkpoisson 'Introduce Poisson Noise in Input Object'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kpoisson.pane file
%
% Parameters:
% InputFile: i 'Input File', required: 'input file'
% OutputFile: o 'Output File', required: 'output file'
% Toggle: replace 'Replace Data with Noise', default: 0: 'Replace existing values with noise'
% Toggle: add 'Add Noise to Data', default: 0: 'Add noise to the specified segment'
%
% Example: o = kkpoisson(i, {'i','';'o','';'replace',0;'add',0})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kpoisson - Introduce Poisson Noise in Input Object
%
%  DESCRIPTION
% "kpoisson" introduces Poisson noise of the specified parameters in the
% input data object (-i).  The noise can either replace the existing value
% data or it can be added to the existing value data by specifying
% the appropriate flag (-replace or -add).
% The time (-ptime) and the variance (-pvar) of the Poisson distribution
% must be specified.
%
%  "Data Type" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_1input
%
%  "Map Data" 5
% .cI $DATAMANIP/repos/shared/man/sections/map_1input
%
%  "Validity Mask" 5
% .cI $DATAMANIP/repos/shared/man/sections/mask_1input
%
%  "Explicit Location and Time Data" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_1input
%
%  "Failure Modes"
% .cI $DATAMANIP/repos/shared/man/sections/fail_1input
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
% DATAMANIP::knoise, DATAMANIP::kexpon, DATAMANIP::kgauss,
% DATAMANIP::krayleigh, DATAMANIP::kuniform
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkpoisson(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kkpoisson(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'o', '__output';'replace', 0;'add', 0};
maxval={0,0,0,0};
minval={0,0,0,0};
istoggle=[0,0,1,1];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile','Toggle','Toggle'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'knoise"  -poiss'],Inputs,narglist);


function paramlist = mtrFilenames2Paramlist(filenames,paramnames)
%% Assume each name is *kSmooth_#smooth_kLength_#len_kMidSD_#mid* and stored in
%% paramData.  Grid will be returned in the following format:
%%
%% row 1: #smooth, #len, #mid
%% row 2: #smooth, #len, #mid
%%
%% ex: paramnames = {'kLength' 'kSmooth' 'kMidSD'};

paramlist = zeros(length(filenames),length(paramnames));
for nn = 1:length(filenames)
    for pp = 1:length(paramnames)
        paramlist(nn,pp) = mtrFilename2Param(filenames{nn},paramnames{pp});
    end
end


%% Display Start message
disp('Running Convolutional Codes BER Simulation set')

disp('By default, this script does not run the Monte Carlo simulations.')
disp('It simply loads results from a previous run.')
sim_mode = input('Do you want to (R)un simulations or (L)oad results from disk? [R/L]','s');
if isempty(sim_mode)
    sim_mode = 'l';
end
sim_mode = lower(sim_mode);

%% Plot theoretical curves
[h_fig, h_lines] = ConvCode_BER_Curves;
%% Run Monte Carlo simulations
disp('By default, this script does not run the Monte Carlo simulations.')
disp('It simply loads results from a previous run.  If you are interested in')
disp('running the simulations, edit run_me.m and uncomment the following')
disp('line:  CC_BER = ConvCode_Simulate;')

SNRs = 0:0.5:7;
total_time = tic;
% Pre-allocate
CC_BER = zeros(6,length(SNRs));
figure(h_fig)
drawnow
if strcmp(sim_mode,'r')
    hold on
    % Create place-holder plots
    simLines = semilogy(SNRs, CC_BER,'*-');
    CC_BER = ConvCode_Simulate(SNRs, simLines);
else
    % Load from Disk (NO SIMULATIONS ARE RUN)
    load CC_BER  % Loads simulation results from disk instead of running them
    hold on
    simLines = semilogy(SNRs, CC_BER,'*-');
end
toc(total_time)

%% Plot simulation results
% hold on
% simLines = semilogy(0:0.5:7, CC_BER);

%% Add Legend
% Do MATLAB graphics magic to create concise legend
% See "Controling Legends" in MATLAB doc

% group lines together
simGrp = hggroup('DisplayName','Simulation');
theoGrp = hggroup('DisplayName','Theoretical Bound');
set(simLines,'Parent',simGrp)
set(h_lines,'Parent',theoGrp)
set(get(get(simGrp,'Annotation'),'LegendInformation'),...
    'IconDisplayStyle','on'); % Include this hggroup in the legend
set(get(get(theoGrp,'Annotation'),'LegendInformation'),...
    'IconDisplayStyle','on'); % Include this hggroup in the legend
legend show

figure1 = h_fig;
annotation(figure1,'textarrow',[0.3489 0.4267],[0.3911 0.4381],...
    'TextEdgeColor','none',...
    'TextBackgroundColor',[1 1 1],...
    'String',{'Soft-decision','Decoding'});

% Create textarrow
annotation(figure1,'textarrow',[0.3911 0.4956],[0.2974 0.3603],...
    'TextEdgeColor','none',...
    'TextBackgroundColor',[1 1 1],...
    'String',{'3-bit quantization'});

% Create textbox
annotation(figure1,'textbox',[0.5985 0.5804 0.1164 0.04873],...
    'String',{'Hard-decision','Decoding'},...
    'HorizontalAlignment','center',...
    'LineStyle','none',...
    'BackgroundColor',[1 1 1]);


%ASSEMBLECONSTR Assemble integral constraints.
%
%   [ C, D ] = ASSEMBLECONSTR( PROB, ICUB ) Assemble integral constraints.
%
%   Assemble subdomain/boundary integral constraints specified in the
%   PROB.CONSTR field. Each constr entry have TYPE (intsubd/intbdr),
%   DVAR, INDEX (indices to subdomains/boundaries), and EXPR
%   (resulting integrand expression, must evaluate to a numeric
%   scalar) entries, for example
%
%       const(1).type = 'intsubd';   % Subdomain integral constraint.
%       const(1).dvar = 'u';         % Applied to dependent variable u.
%       const(1).index = [1,2];      % Applied to domains 1 and 2.
%       const(1).expr  = 2.3;        % Resulting integrand.

% Copyright 2013-2022 Precise Simulation, Ltd.


function test_bug1902

% WALLTIME 02:00:00
% MEM 2gb
% DEPENDENCY ft_volumesegment ft_prepare_sourcemodel volumesmooth

mri = ft_read_mri(dccnpath('/home/common/matlab/fieldtrip/data/test/latest/mri/nifti/single_subj_T1.nii'));
mri.coordsys = 'spm';

cfg = [];
tpm = ft_volumesegment(cfg,mri);  % gray, white, csf tissue prob. map

% there are some spm functions which change their own input

cfg = [];
cfg.mri = tpm;
grid01 = ft_prepare_sourcemodel(cfg);

cfg = [];
cfg.mri = tpm;
grid02 = ft_prepare_sourcemodel(cfg);

cfg = [];
cfg.mri = tpm;
grid03 = ft_prepare_sourcemodel(cfg);

grid01 = rmfield(grid01, 'cfg');
grid02 = rmfield(grid02, 'cfg');
grid03 = rmfield(grid03, 'cfg');

% make sure that they are the same, and not super-smoohted
isequal(grid01,grid02);
isequal(grid01,grid03);


function t_opf_dc_cplex(quiet)
%T_OPF_DC_CPLEX  Tests for DC optimal power flow using CPLEX solver.

%   MATPOWER
%   Copyright (c) 2004-2021, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

if nargin < 1
    quiet = 0;
end

algs = [1; 2; 3; 4; 5; 6];
alg_names = {
    'primal simplex',
    'dual simplex',
    'network simplex',
    'barrier',
    'sifting',
    'concurrent'
};
num_tests = 43 * length(algs);

t_begin(num_tests, quiet);

[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
    VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
    MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
    QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
[F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
    TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
    ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;

casefile = 't_case9_opf';
if quiet
    verbose = 0;
else
    verbose = 0;
end

mpopt = mpoption('out.all', 0, 'verbose', verbose);
mpopt = mpoption(mpopt, 'opf.dc.solver', 'CPLEX');

%% run DC OPF
if have_feature('cplex')
  for k = 1:length(algs)
    mpopt = mpoption(mpopt, 'cplex.lpmethod', algs(k), 'cplex.qpmethod', algs(k));
    t0 = sprintf('DC OPF (CPLEX %s): ', alg_names{k});

    %% set up indices
    ib_data     = [1:BUS_AREA BASE_KV:VMIN];
    ib_voltage  = [VM VA];
    ib_lam      = [LAM_P LAM_Q];
    ib_mu       = [MU_VMAX MU_VMIN];
    ig_data     = [GEN_BUS QMAX QMIN MBASE:APF];
    ig_disp     = [PG QG VG];
    ig_mu       = (MU_PMAX:MU_QMIN);
    ibr_data    = (1:ANGMAX);
    ibr_flow    = (PF:QT);
    ibr_mu      = [MU_SF MU_ST];
    ibr_angmu   = [MU_ANGMIN MU_ANGMAX];

    %% get solved DC power flow case from MAT-file
    load soln9_dcopf;       %% defines bus_soln, gen_soln, branch_soln, f_soln

    %% run OPF
    t = t0;
    [baseMVA, bus, gen, gencost, branch, f, success, et] = rundcopf(casefile, mpopt);
    t_ok(success, [t 'success']);
    t_is(f, f_soln, 3, [t 'f']);
    t_is(   bus(:,ib_data   ),    bus_soln(:,ib_data   ), 10, [t 'bus data']);
    t_is(   bus(:,ib_voltage),    bus_soln(:,ib_voltage),  3, [t 'bus voltage']);
    t_is(   bus(:,ib_lam    ),    bus_soln(:,ib_lam    ),  3, [t 'bus lambda']);
    t_is(   bus(:,ib_mu     ),    bus_soln(:,ib_mu     ),  2, [t 'bus mu']);
    t_is(   gen(:,ig_data   ),    gen_soln(:,ig_data   ), 10, [t 'gen data']);
    t_is(   gen(:,ig_disp   ),    gen_soln(:,ig_disp   ),  3, [t 'gen dispatch']);
    t_is(   gen(:,ig_mu     ),    gen_soln(:,ig_mu     ),  3, [t 'gen mu']);
    t_is(branch(:,ibr_data  ), branch_soln(:,ibr_data  ), 10, [t 'branch data']);
    t_is(branch(:,ibr_flow  ), branch_soln(:,ibr_flow  ),  3, [t 'branch flow']);
    t_is(branch(:,ibr_mu    ), branch_soln(:,ibr_mu    ),  2, [t 'branch mu']);

    %%-----  test OPF with angle difference limits  -----
    t = [t0 'w/angle diff lims : '];
    mpc = loadcase(casefile);
    mpc.branch(4, ANGMAX) = 3;
    mpc.branch(7, ANGMIN) = -4.5;
    r = rundcopf(mpc, mpopt);
    [bus, gen, branch, f, success] = deal(r.bus, r.gen, r.branch, r.f, r.success);
    t_ok(success, [t 'success']);
    t_is(   f, 6456.7213, 3, [t 'f']);
    t_is(   bus(:,ib_data   ),    bus_soln(:,ib_data   ), 10, [t 'bus data']);
    t_is(   gen(:,ig_data   ),    gen_soln(:,ig_data   ), 10, [t 'gen data']);
    t_is(   gen(:,PG        ),    [99.98497;89.35133;125.66371], 4, [t 'gen dispatch']);
    t_is(branch(:,ibr_data  ), mpc.branch(:,ibr_data   ), 10, [t 'branch data']);
    e = zeros(size(branch, 1), 1);
    e(4) = 297.83776;
    e(7) = -26.94788;
    t_is(branch(:,MU_ANGMAX )-branch(:,MU_ANGMIN ), e, 4, [t 'branch ang diff mu']);

    t = [t0 'w/ignored angle diff lims : '];
    mpopt1 = mpoption(mpopt, 'opf.ignore_angle_lim', 1);
    r = rundcopf(mpc, mpopt1);
    [bus, gen, branch, f, success] = deal(r.bus, r.gen, r.branch, r.f, r.success);
    t_ok(success, [t 'success']);
    t_is(f, f_soln, 3, [t 'f']);
    t_is(   bus(:,ib_data   ),    bus_soln(:,ib_data   ), 10, [t 'bus data']);
    t_is(   bus(:,ib_voltage),    bus_soln(:,ib_voltage),  3, [t 'bus voltage']);
    t_is(   bus(:,ib_lam    ),    bus_soln(:,ib_lam    ),  3, [t 'bus lambda']);
    t_is(   bus(:,ib_mu     ),    bus_soln(:,ib_mu     ),  2, [t 'bus mu']);
    t_is(   gen(:,ig_data   ),    gen_soln(:,ig_data   ), 10, [t 'gen data']);
    t_is(   gen(:,ig_disp   ),    gen_soln(:,ig_disp   ),  3, [t 'gen dispatch']);
    t_is(   gen(:,ig_mu     ),    gen_soln(:,ig_mu     ),  3, [t 'gen mu']);
    t_is(branch(:,ibr_data  ), mpc.branch(:,ibr_data   ), 10, [t 'branch data']);
    t_is(branch(:,ibr_flow  ), branch_soln(:,ibr_flow  ),  3, [t 'branch flow']);
    t_is(branch(:,ibr_mu    ), branch_soln(:,ibr_mu    ),  2, [t 'branch mu']);

    %%-----  run OPF with extra linear user constraints & costs  -----
    %% two new z variables
    %%      0 <= z1, P3 - P1 <= z1
    %%      0 <= z2, P3 - P2 <= z2
    %% with A and N sized for DC opf
    mpc = loadcase(casefile);
    mpc.A = sparse([1;1;1;2;2;2],[10;12;13;12;11;14],[-1;1;-1;1;-1;-1],2,14);
    mpc.u = [0; 0];
    mpc.l = [-Inf; -Inf];
    mpc.zl = [0; 0];

    mpc.N = sparse([1;2], [13;14], [1;1], 2, 14);   %% new z variables only
    mpc.fparm = ones(2,1) * [1 0 0 1];              %% w = r = z
    mpc.H = sparse(2,2);                            %% no quadratic term
    mpc.Cw = [1000;1];

    t = [t0 'w/extra constraints & costs 1 : '];
    [r, success] = rundcopf(mpc, mpopt);
    t_ok(success, [t 'success']);
    t_is(r.gen(1, PG), 116.15974, 5, [t 'Pg1 = 116.15974']);
    t_is(r.gen(3, PG), 116.15974, 5, [t 'Pg3 = 116.15974']);
    t_is(r.var.val.z, [0; 0.3348], 4, [t 'user vars']);
    t_is(r.cost.usr, 0.3348, 4, [t 'user costs']);

    %% with A and N sized for AC opf
    mpc = loadcase(casefile);
    mpc.A = sparse([1;1;1;2;2;2],[19;21;25;21;20;26],[-1;1;-1;1;-1;-1],2,26);
    mpc.u = [0; 0];
    mpc.l = [-Inf; -Inf];
    mpc.zl = [0; 0];

    mpc.N = sparse([1;2], [25;26], [1;1], 2, 26);   %% new z variables only
    mpc.fparm = ones(2,1) * [1 0 0 1];              %% w = r = z
    mpc.H = sparse(2,2);                            %% no quadratic term
    mpc.Cw = [1000;1];

    t = [t0 'w/extra constraints & costs 2 : '];
    [r, success] = rundcopf(mpc, mpopt);
    t_ok(success, [t 'success']);
    t_is(r.gen(1, PG), 116.15974, 5, [t 'Pg1 = 116.15974']);
    t_is(r.gen(3, PG), 116.15974, 5, [t 'Pg3 = 116.15974']);
    t_is(r.var.val.z, [0; 0.3348], 4, [t 'user vars']);
    t_is(r.cost.usr, 0.3348, 4, [t 'user costs']);

    t = [t0 'infeasible : '];
    %% with A and N sized for DC opf
    mpc = loadcase(casefile);
    mpc.A = sparse([1;1], [10;11], [1;1], 1, 14);   %% Pg1 + Pg2
    mpc.u = Inf;
    mpc.l = 600;
    [r, success] = rundcopf(mpc, mpopt);
    t_ok(~success, [t 'no success']);

    %% OPF with all buses isolated
    t = [t0 'all buses isolated : '];
    mpc = loadcase(casefile);
    mpc.bus(:, BUS_TYPE) = NONE;
    try
        r = rundcopf(mpc, mpopt);
        t_is(r.success, 0, 12, [t 'success = 0']);
    catch
        t_ok(0, [t 'unexpected fatal error']);
    end
  end
else
    t_skip(num_tests, 'CPLEX not available');
end

t_end;


function Lden = symbcholden(L,dense,DAt)
% Lden = symbcholden(L,dense,DAt)
%
% SYMBCHOLDEN  Creates Lden.{LAD, perm,dz, sign, first}
%
% ******************** INTERNAL FUNCTION OF SEDUMI ********************
%
% See also sedumi, dpr1fact

% This file is part of SeDuMi 1.1 by Imre Polik and Oleksandr Romanko
% Copyright (C) 2005 McMaster University, Hamilton, CANADA  (since 1.1)
%
% Copyright (C) 2001 Jos F. Sturm (up to 1.05R5)
%   Dept. Econometrics & O.R., Tilburg University, the Netherlands.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% Affiliation SeDuMi 1.03 and 1.04Beta (2000):
%   Dept. Quantitative Economics, Maastricht University, the Netherlands.
%
% Affiliations up to SeDuMi 1.02 (AUG1998):
%   CRL, McMaster University, Canada.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% 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 Street, Fifth Floor, Boston, MA
% 02110-1301, USA

% ------------------------------------------------------------
% Symbolic forward Cholesky of dense columns, in order
% [LP, Q-blk, Q-norm, Q-tr]
% ------------------------------------------------------------
i1 = dense.l + 1;
i2 = i1 + length(dense.q);
LAD = [symbfwblk(L,dense.A(:,1:i1-1)), symbfwblk(L,DAt.denq),...
    symbfwblk(L,dense.A(:,i2:end)),symbfwblk(L,dense.A(:,i1:i2-1))];
% ------------------------------------------------------------
% Incremental ordering heuristic, excluding the Lorentz-trace cols
% ------------------------------------------------------------
[perm, dz] = incorder(LAD(:,1:length(dense.cols)));
% ------------------------------------------------------------
% Insert the trace cols with a "-1"-factor just after corresponding
% Lorentz-block columns
% ------------------------------------------------------------
Lden = finsymbden(LAD,perm,dz,i1);


%% This code allows complete manual reselection of every corner in the
%% images.
%% This tool is specifically useful in the case of highly distorted images.
%%
%% Use it when in standard mode.
%% In memory efficient mode, use manual_corner_extraction_no_read.m

if ~exist('n_ima'),
   fprintf(1,'No image data available\n');
   return;
end;

check_active_images;

if n_ima == 0,

    fprintf(1,'No image data available\n');

else

if ~exist(['I_' num2str(ind_active(1))]),
   n_ima_save = n_ima;
   active_images_save = active_images;
   ima_read_calib;
   n_ima = n_ima_save;
   active_images = active_images_save;
   check_active_images;
   if no_image_file,
      disp('Cannot extract corners without images');
      return;
   end;
end;

fprintf(1,'\nManual re-extraction of the grid corners on the images\n');

q_converge = input('Do you want to try to automatically find the closest corner? - only works with ckecker board corners  ([]=yes, other = no) ','s');

if isempty(q_converge),
    q_converge = 1;
    fprintf(1,'Automatic refinement of the corner location after manual mouse click\n');
    disp('Window size for corner finder (wintx and winty):');
    wintx = input('wintx ([] = 5) = ');
    if isempty(wintx), wintx = 5; end;
    wintx = round(wintx);
    winty = input('winty ([] = 5) = ');
    if isempty(winty), winty = 5; end;
    winty = round(winty);

    fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
else
    q_converge = 0;
    fprintf(1,'No attempt to refine the corner location after manual mouse click\n');
end;

ima_numbers = input('Number(s) of image(s) to process ([] = all images) = ');

if isempty(ima_numbers),
   ima_proc = 1:n_ima;
else
   ima_proc = ima_numbers;
end;

fprintf(1,'Processing image ');

for kk = ima_proc;

    if active_images(kk),

        fprintf(1,'%d...',kk);

        eval(['I = I_' num2str(kk) ';']);

        eval(['x = x_' num2str(kk) ';']);

        Np = size(x,2);

        figure(2);
        image(I);
        colormap(map);
        hold on;
        hx = plot(x(1,:)+1,x(2,:)+1,'r+');
        hcp = plot(x(1,1)+1,x(2,1)+1,'co');
        hold off;

        for np = 1:Np,

            set(hcp,'Xdata',x(1,np)+1,'Ydata',x(2,np)+1);

            title(['Click on corner #' num2str(np) ' out of ' num2str(Np) ' (right button: keep point unchanged)']);

            [xi,yi,b] = ginput4(1);

            if b==1,
                xxi = [xi;yi];
                if q_converge,
                    [xxi] = cornerfinder(xxi,I,winty,wintx);
                end;
                x(1,np) = xxi(1) - 1;
                x(2,np) = xxi(2) - 1;
                set(hx,'Xdata',x(1,:)+1,'Ydata',x(2,:)+1);
            end;

        end;

        eval(['wintx_' num2str(kk) ' = wintx;']);
        eval(['winty_' num2str(kk) ' = winty;']);

        eval(['x_' num2str(kk) '= x;']);

    else

        if ~exist(['omc_' num2str(kk)]),

            eval(['dX_' num2str(kk) ' = NaN;']);
            eval(['dY_' num2str(kk) ' = NaN;']);

            eval(['wintx_' num2str(kk) ' = NaN;']);
            eval(['winty_' num2str(kk) ' = NaN;']);

            eval(['x_' num2str(kk) ' = NaN*ones(2,1);']);
            eval(['X_' num2str(kk) ' = NaN*ones(3,1);']);

            eval(['n_sq_x_' num2str(kk) ' = NaN;']);
            eval(['n_sq_y_' num2str(kk) ' = NaN;']);

        end;

    end;

end;

fprintf(1,'\ndone\n');

end;


function sum = cfg_example_sum
% Example script that creates an cfg_exbranch to sum two numbers. The
% inputs are entered as vector, the output is just a single
% number. This function differs from cfg_example_add2 (except from names)
% only in the specification of input1.num.
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: cfg_example_sum.m 1716 2008-05-23 08:18:45Z volkmar $

rev = '$Rev: 1716 $'; %#ok

%% Input Item
input1         = cfg_entry; % This is the generic data entry item
input1.name    = 'Input a'; % The displayed name
input1.tag     = 'a';       % The name appearing in the harvested job structure. This name must be unique among all items in the val field of the superior node
input1.strtype = 'e';       % No restriction on what type of data is entered. This could be used to restrict input to real numbers, integers ...
input1.num     = [1 Inf];   % Number of inputs required (2D-array with exactly one row and two column)
input1.help    = {'This is the input vector.','The elements will be added together.'}; % help text displayed

%% Executable Branch
sum      = cfg_exbranch;       % This is the branch that has information about how to run this module
sum.name = 'sum';             % The display name
sum.tag  = 'cfg_example_sum'; % The name appearing in the harvested job structure. This name must be unique among all items in the val field of the superior node
sum.val  = {input1};    % The items that belong to this branch. All items must be filled before this branch can run or produce virtual outputs
sum.prog = @cfg_example_run_sum;  % A function handle that will be called with the harvested job to run the computation
sum.vout = @cfg_example_vout_sum; % A function handle that will be called with the harvested job to determine virtual outputs
sum.help = {'Add two numbers.'};

%% Local Functions
% The cfg_example_vout_sum function can go here, it is not useful outside
% the batch environment.
function vout = cfg_example_vout_sum(job)
% Determine what outputs will be present if this job is run. In this case,
% the structure of the inputs is fixed, and the output is always a single
% number. Note that input items may not be numbers, they can also be
% dependencies.

vout = cfg_dep;                        % The dependency object
vout.sname      = 'sum(a)';       % Displayed dependency name
vout.src_output = substruct('()',{1}); % The output subscript reference. This could be any reference into the output variable created during computation


% Codes for CVPR-15 work `Face Alignment by Coarse-to-Fine Shape Searching'
% Any question please contact Shizhan Zhu: zhshzhutah2@gmail.com
% Released on July 25, 2015

function ind = selectPosesIdx(len,sub,d)

if nargin<3
    d = 2;
end
assert(mod(len,d)==0);
gap = len/d;
ind = [];
sub = sub(:)';
for i = 1:d
    ind = [ind sub + (i-1)*gap];
end

end


function drawLine(p1, p2, varargin)
%DRAWLINE Draws a line from point p1 to point p2
%   DRAWLINE(p1, p2) Draws a line from point p1 to point p2 and holds the
%   current figure

plot([p1(1) p2(1)], [p1(2) p2(2)], varargin{:});

end


function data = rle(x)
% data = rle(x) (de)compresses the data with the RLE-Algorithm
%   Compression:
%      if x is a numbervector data{1} contains the values
%      and data{2} contains the run lenths
%
%   Decompression:
%      if x is a cell array, data contains the uncompressed values
%
%      Version 1.0 by Stefan Eireiner (stefan-e@web.de)
%      based on Code by Peter J. Acklam
%      last change 14.05.2004

if iscell(x) % decoding
	i = cumsum([ 1 x{2} ]);
	j = zeros(1, i(end)-1);
	j(i(1:end-1)) = 1;
	data = x{1}(cumsum(j));
else % encoding
	if size(x,1) > size(x,2), x = x'; end % if x is a column vector, tronspose
    i = [ find(x(1:end-1) ~= x(2:end)) length(x) ];
	data{2} = diff([ 0 i ]);
	data{1} = x(i);
end


%% Load Model
data_path = '../';

%% Load Sample
sample_name = 'image00002';
img = imread([data_path sample_name '.jpg']);
load([data_path sample_name '.mat']);
[height, width, nChannels] = size(img);

imshow(img);
hold on;
plot(pt3d_68(1,:), pt3d_68(2,:), 'b.');
hold off;


function board = designboard(file)

%
% This program allows you to draw a board, based on some image (file). Each
% territory is drawn by clicking the coordinates of its vertices. On
% clicking the first vertex again, the patch is closed. To finish the
% territory, click again somewhere in the middle. This determines the
% position where the number of troops will be shown. You can ofcourse draw
% any kind of board, having arbitrary names and continents. However, to be
% fully compatible with the playrisk-program, the board should have the
% same continents as the original game: Asia, North-America, Europe,
% Africa, Australia and South-America. Moreover, the map should be fully
% interconnected. This means that it should be possible to travel from any
% territory to any other territory: no isolated patches. This program keeps
% track of the neighbouring patches, but oversea connections should be
% specified manually using the 'connect()' function. If you downloaded this
% file from the Mathworks Central File Exchange, there should be a
% predesigned board included meeting these requirements. An optional
% feature is the display of lines between two patches. This should also
% be done outside this program using the lines() function.
%

sz = [800, 600];
close(findobj('Name', 'Board'))
board = struct('Name',[],'Continent',[],'Neighbors',[],'xy',[],'TextPos',[], 'lines', []);
res = get(0, 'ScreenSize');
fig = figure('Name', 'Board', 'Position', res);
ax  = axes('Parent', fig, 'XLim', [0, sz(1)], 'YLim', [0, sz(2)]);

if nargin == 1 && exist(file, 'file')
    pic = imread(file);
    imshow(pic, 'Parent', ax, 'InitialMagnification', 'fit');
end

eps = 5;    % Welding treshold

%% MAKE BOARD
count = 1;
while true
    prompt = {'Name','Continent'};
    data = inputdlg(prompt, 'Name', 1, {'',''});
    if isempty(data)
        break
    end
    [x, y, nblist, tp] = getxy(board, eps);
    poly = patch(x, y, [0 0 0]);
    set(poly, 'EdgeColor', [1 0 0], 'Marker', '.', 'MarkerEdgeColor', [0 0 1]);
    ok = questdlg('OK?', 'Verify', 'Yes', 'No', 'Yes');
    if strcmp(ok, 'Yes')
        board(count) = struct('Name', data{1},          ...
                              'Continent', data{2},     ...
                              'Neighbors', nblist,      ...
                              'xy', [x,y],              ...
                              'TextPos', tp, ...
                              'lines', []);
        count = count + 1;
        set(poly, 'FaceColor', [.5 .5 .5])
    else
        delete(poly);
    end
end

%% SYNCHRONIZE NEIGHBORS
for i = 1:numel(board)
    for j = board(i).Neighbors
        if isempty(find(board(j).Neighbors == i, 1))
            board(j).Neighbors = [board(j).Neighbors, i];
        end
    end
end

%% FINALIZE
if isempty(board(1).Name)
    close(fig);
    return
end

for i = 1:numel(board)
    board(i).xy(:,2) =  sz(2) - board(i).xy(:,2);
    board(i).TextPos(2) = sz(2) - board(i).TextPos(2);
end
close(fig);


% Test file for @chebfun/realsqrt.m.

function pass = test_realsqrt(pref)

if ( nargin == 0 )
    pref = chebfunpref();
end

%% These should fail:

x = chebfun('x', pref);
try
    realsqrt(x);
    pass(1) = false;
catch ME
    pass(1) = strcmp(ME.identifier, 'CHEBFUN:CHEBFUN:realsqrt:complexRes');
end

try
    realsqrt(1i*abs(x));
    pass(2) = false;
catch ME
    pass(2) = strcmp(ME.identifier, 'CHEBFUN:CHEBFUN:realsqrt:complexRes');
end

%% These should pass:

realsqrt(x.^2);
pass(3) = true;

realsqrt(abs(x));
pass(4) = true;

%% Test array-valued:

X = [x x];
try
    realsqrt(1i*X);
    pass(5) = false;
catch ME
    pass(5) = strcmp(ME.identifier, 'CHEBFUN:CHEBFUN:realsqrt:complexRes');
end

try
    realsqrt(X);
    pass(6) = false;
catch ME
    pass(6) = strcmp(ME.identifier, 'CHEBFUN:CHEBFUN:realsqrt:complexRes');
end

realsqrt(X.^2);
pass(7) = true;

realsqrt(abs(X));
pass(8) = true;

end


function [refBody, scName] = orbitPanelGetOrbitFromKSPTOTConnectActiveVesselCallBack(hSMA, hECC, hINC, hRAAN, hARG, varargin)

    refBody = [];
    [orbit] = getSingularOrbitFromKSPTOTConnect([]);
    if(not(isempty(orbit)))
        if(not(isempty(hSMA)))
            set(hSMA, 'String', fullAccNum2Str(orbit{3}));
        end

        if(not(isempty(hECC)))
            set(hECC, 'String', fullAccNum2Str(orbit{4}));
        end

        if(not(isempty(hINC)))
            set(hINC, 'String', fullAccNum2Str(orbit{5}));
        end

        if(not(isempty(hRAAN)))
            set(hRAAN, 'String', fullAccNum2Str(orbit{6}));
        end

        if(not(isempty(hARG)))
            set(hARG, 'String', fullAccNum2Str(orbit{7}));
        end

        refBody = orbit{10};
        scName = orbit{1};

        if(nargin == 7)
            hMA = varargin{1};
            hEpoch = varargin{2};
            set(hMA, 'String', fullAccNum2Str(rad2deg(orbit{8})));
            set(hEpoch, 'String', fullAccNum2Str(orbit{9}));
        end
    end
end


%%**********************************************************
%% SDPT3data_SEDUMIdata: convert SQLP data in SDPT3 format to
%%                       SeDuMi format
%%
%% [At,b,c,K] = SDPT3data_SEDUMIdata(blk,AAt,CC,bb);
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%**********************************************************

function [At,b,c,K] = SDPT3data_SEDUMIdata(blk,AAt,CC,bb)

c = []; At = [];
b = bb;
mm = length(bb);
%%
if (~iscell(CC))
    Ctmp = CC; clear CC; CC{1} = Ctmp;
end
%%
%% extract unrestricted blk
%%
for p = 1:size(blk,1)
    pblk = blk(p,:);
    if (p==1); K.f = []; end
    if strcmp(pblk{1},'u')
        K.f = [K.f, pblk{2}];
        At  = [At; AAt{p}]; %#ok
        c   = [c; CC{p}]; %#ok
    end
end
K.f = sum(K.f);
%%
%% extract linear blk
%%
for p = 1:size(blk,1)
    pblk = blk(p,:);
    if (p==1); K.l = []; end
    if strcmp(pblk{1},'l')
        K.l = [K.l, pblk{2}];
        At  = [At; AAt{p,1}]; %#ok
        c   = [c; CC{p,1}]; %#ok
    end
end
K.l = sum(K.l);
%%
%% extract second order cone blk
%%
for p = 1:size(blk,1)
    pblk = blk(p,:);
    if (p==1); K.q = []; end
    if strcmp(pblk{1},'q')
        K.q = [K.q, pblk{2}];
        At  = [At; AAt{p,1}]; %#ok
        c   = [c; CC{p,1}]; %#ok
    end
end
%%
%% extract rotated cone blk
%%
for p = 1:size(blk,1)
    pblk = blk(p,:);
    if (p==1); K.r = []; end
    if strcmp(pblk{1},'r')
        K.r = [K.r, pblk{2}];
        At  = [At; AAt{p,1}]; %#ok
        c   = [c; CC{p,1}]; %#ok
    end
end
%%
%% extract semidefinite cone blk
%%
for p = 1:size(blk,1)
    if (p==1); K.s = []; end
    pblk = blk(p,:);
    if strcmp(pblk{1},'s')
        K.s = [K.s, pblk{2}];
        ss = [0,cumsum(pblk{2})];
        idxstart = [0,cumsum(pblk{2}.*pblk{2})];
        numblk = length(pblk{2});
        nnzA = nnz(AAt{p,1});
        II = zeros(2*nnzA,1);
        JJ = zeros(2*nnzA,1);
        VV = zeros(2*nnzA,1);
        m2 = size(AAt{p,1},2);
        if (length(pblk) > 2)
            rr = [0, cumsum(pblk{3})];
            dd = AAt{p,3};
            idxD = [0; find(diff(dd(:,1))); size(dd,1)];
        end
        count = 0;
        for k = 1:mm
            if (k<= m2);
                Ak = smat(pblk,AAt{p,1}(:,k),1);
            else
                idx = rr(k)+1 : rr(k+1);
                Vk  = AAt{p,2}(:,idx);
                len = pblk{3}(k);
                if (size(dd,2) == 4)
                    idx2 = idxD(k)+1:idxD(k+1);
                    Dk = spconvert([dd(idx2,2:4); len,len,0]);
                elseif (size(dd,2) == 1);
                    Dk = spdiags(dd(idx),0,len,len);
                end
                Ak = Vk*Dk*Vk';
            end
            for tt = 1:numblk
                if (numblk > 1)
                    idx = ss(tt)+1: ss(tt+1);
                    Aksub = full(Ak(idx,idx));
                else
                    Aksub = Ak;
                end
                tmp = Aksub(:);
                nzidx = find(tmp);
                len = length(nzidx);
                II(count+1:count+len,1) = idxstart(tt)+nzidx;
                JJ(count+1:count+len,1) = k*ones(length(nzidx),1);
                VV(count+1:count+len,1) = tmp(nzidx);
                count = count + len;
            end
        end
        II = II(1:count);
        JJ = JJ(1:count);
        VV = VV(1:count);
        At = [At; spconvert([II,JJ,VV; sum(pblk{2}.*pblk{2}), mm, 0])]; %#ok
        Cp = CC{p};
        ctmp = [];
        for tt = 1:numblk
            if (numblk > 1)
                idx = ss(tt)+1: ss(tt+1);
                Csub = full(Cp(idx,idx));
            else
                Csub = Cp;
            end
            ctmp = [ctmp; Csub(:)]; %#ok
        end
        c = [c; ctmp]; %#ok
    end
end
%%**********************************************************


function vw = zoomInplane(vw, resetFlag);
% view = zoomInplane(view, <resetFlag=0>);
%
% Zooms the 3-view. Allows the subject to click once (rect or center of
% zooming) on one of the views of the brain, gets the new extent of view,
% and sets the other axes to be consistent with the new zoom extent.
%
% resetFlag: if 1, will reset the zoom to be the whole view size and
% update the axis bounds of the image. If 0 <default>, will get the zoom
% from the user input.
%
% 05/04 ras, from zoom3view.
% 06/02 ras: now just updates zoom w/ AXIS command, rather than
% going through a full refresh. Also added resetFlag, so both
% zoom buttons have callbacks to this function (for Inplane/Flat views).
montageFlag = isequal(vw.viewType, 'Inplane'); % 1 for inplanes, 0 for other

% this should only work on Inplane or Flat views
if ~ismember(vw.viewType,{'Inplane' 'Flat'}),    return;      end

if exist('resetFlag', 'var') && resetFlag==1
    % reset the zoom
    dims = viewGet(vw,'Size');
    zoom = [1 dims(2) 1 dims(1)];
else
    %%%%%%%%%%%%%%%%%%%%
    % Get data from UI %
    %%%%%%%%%%%%%%%%%%%%
    [X, Y] = ginput(2);

    zoom = [X(1) X(2) Y(1) Y(2)];

    % montage views will need some fiddling:
    if isfield(vw.ui,'montageSize') || isfield(vw.ui,'numLevelEdit')
        montageFlag = 1;
        [zoom, rows, cols] = montage2Coords(vw, [Y X]', 1);

        % set to zoom format [xmin xmax ymin ymax], or [cols rows]
        zoom = [zoom(2,1) zoom(2,2) zoom(1,1) zoom(1,2)];

        % get current zoom size
        dims =viewGet(vw,'Size');

        % ensure the zoom values are increasing (if the pts were clipped,
        % this may not be the case)
        if zoom(1) > zoom(2), zoom(1:2) = zoom([2 1]); end
        if zoom(3) > zoom(4), zoom(3:4) = zoom([4 3]); end

    else
        montageFlag = 0;
    end
end

vw.ui.zoom = zoom;

axes(vw.ui.mainAxisHandle);
if montageFlag==1
    % we need to refresh the screen
    vw = refreshScreen(vw);
else
    % we can just use the zoom directly
    axis(zoom);
end

return

% zoom on
%
% waitForClick = ginput(1);
%
% zoom = round(axis);


function T = ful(T)
%FUL Convert formatted data set to an array.
%   T = ful(T) converts the formatted data set T into a MATLAB array. If T
%   is incomplete, unknown entries are represented by the value NaN.

%   Authors: Laurent Sorber (Laurent.Sorber@cs.kuleuven.be)
%            Marc Van Barel (Marc.VanBarel@cs.kuleuven.be)
%            Lieven De Lathauwer (Lieven.DeLathauwer@kuleuven-kulak.be)
%
%   References:
%   [1] L. Sorber, M. Van Barel, L. De Lathauwer, "Structured data fusion,"
%       ESAT-SISTA Internal Report 13-177, KU Leuven, 2013.

if isnumeric(T), return; end
if ~isstruct(T)
    error('ful:T','T must be a data set formatted by fmt.');
end

val = T.val;
size_tens = T.size;
if 8*prod(size_tens) > 8e9
    error('ful:size','T is too large to be stored as an array.');
end
if ~isfield(T,'ind')
    ind = sub2ind(size_tens,T.sub{:});
else
    ind = T.ind;
end

if isfield(T,'sparse') && T.sparse
    T = zeros(size_tens);
elseif isfield(T,'incomplete') && T.incomplete
    T = nan(size_tens);
else
    error('ful')
end
T(ind) = val;


%% This function will generate the ODE function based on calculation result of the sybolic expression
% Last Update: 2019/04/22
% Coded By: K

function Generate_ODE_RHS(Sindy_ODEs,var_num_state,var_num_control)
z=sym('z',[var_num_state,1]);
u=sym('u',[var_num_control,1]);
syms t
f= matlabFunction(Sindy_ODEs,'File','Sindy_ODE_RHS','Optimize',true,'Vars',{t,z,u});


% DEMSHAREDVARGPLVM1 Run the shared variational GPLVM on various kinds of data.
% DESC
%
% COPYRIGHT: Andreas C. Damianou, Carl Henrik Ek,  2011
% SEEALSO : svargplvmPrepareData
%
% VARGPLVM

%{
%---- How to run this demo:
% Vargplvm created data
close all; initLatent='ppca'; dataSetNames = {}; toyDataCreate ='vargplvm';initVardistIters = 400; itNo = [100 200 1500 500 500 400];  demSharedVargplvm1

% Fols data (make sure to use a linard2 kernel)
close all; initLatent='pca'; dataSetNames = {}; toyDataCreate ='fols';initVardistIters = 170; itNo = 300; dataToKeep=50;  demSharedVargplvm1

% Human pose data with features extracted from silhouettes
clear ;close all; initLatent='pca3'; dataSetNames = {}; toyDataCreate='humanPose';initVardistIters = 160; itNo = [200 200 200 200 200 200 200 200]; dataToKeep=418;  demSharedVargplvm1
clear ;close all; experimentNo=1;initLatent='pca3'; dataSetNames = {};toyDataCreate='humanPose';initVardistIters = 180; itNo = [500 200 200 200 200 200 200 200 200];  demSharedVargplvm1

% Human pose data with the whole silhouette (TEMPdemSharedVargplvm is like
% demSharedVargplvm but just uses more latent dimensions)
clear ;close all; experimentNo=6; imageSilhouette=1;initLatent='ppca'; latentDimPerModel=7;dataSetNames = {};toyDataCreate='humanPose';initVardistIters = 380; itNo = [500 200 200 200 200 200 200 200 200 200];  indPoints=100;TEMPdemSharedVargplvm

% TODO: ___
clear ;close all; experimentNo=5;initLatent='ppca'; mappingKern = 'rbfardjit';dataSetNames = {};toyDataCreate='humanPose';initVardistIters = 180; itNo = [500 200 200 200 200 200 200 200 200];  demSharedVargplvm1
%}

%___

% Fix seeds
randn('seed', 1e5);
rand('seed', 1e5);

% Define constants (in a manner that allows other scripts to parametrize
% this one).
if ~exist('experimentNo') ,  experimentNo = 404;      end
if ~exist('itNo')         ,  itNo = [500 500];              end     % Default: 2000
if ~exist('indPoints')    ,  indPoints = 80;          end     % Default: 49
if ~exist('latentDimPerModel')    ,  latentDimPerModel = 3;          end
if ~exist('latentDim'), latentDim = 5; end
if ~exist('numSharedDims'), numSharedDims = 2; end
% Set to 1 to use dynamics or to 0 to use the standard var-GPLVM
if ~exist('dynUsed')      ,  dynUsed = 0;             end
if ~exist('initVardistIters'), initVardistIters = 100;      end
if ~exist('dynamicKern')   ,     dynamicKern = {'rbf', 'white', 'bias'}; end
if ~exist('mappingKern')   ,  mappingKern = {'rbfard2', 'white'}; end
% if ~exist('mappingKern'),  mappingKern = {'rbfard2', 'bias', 'white'}; end
% Set to 1 to tie the inducing points with the latent vars. X
if ~exist('fixInd')        ,     fixInd = 0;    end
% 0.1 gives around 0.5 init.covars. 1.3 biases towards 0.
if ~exist('vardistCovarsMult'),  vardistCovarsMult=1.3;                  end
% Set to empty value {} to work with toy data
if ~exist('dataSetNames')    ,    dataSetNames = {};    end
if ~exist('invWidthMultDyn'),    invWidthMultDyn = 100;                     end
if ~exist('invWidthMult'),       invWidthMult = 5;                     end
if ~exist('initX'),     initX ='ppca';   end % That's for the dynamics initialisation
if ~exist('initLatent'),     initLatent ='ppca';   end % That's for the whole latent space init.
if ~exist('dataToKeep'), dataToKeep = -1; end
if ~exist('toyDataCreate'), toyDataCreate = 'fols'; end
if ~exist('doPredictions'), doPredictions = 0; end
if ~exist('dataType'), dataType = 'default'; end
if ~exist('enableParallelism'), enableParallelism = 1; end

if ~exist('Yall')
    svargplvmPrepareData;
end

%%

%-- Load datasets
for i=1:numberOfDatasets
    Y = Yall{i};
    if dataToKeep ~= -1 && dataToKeep <= size(Y,1)
        Y = Y(1:dataToKeep,:);
    end
    dims{i} = size(Y,2);
    N{i} = size(Y,1);
    indTr = 1:N{i};
    indTs = setdiff(size(Y,1), indTr);
    Ytr{i} = Y(indTr,:); %Yts = Y(indTs,:);
    t{i} = linspace(0, 2*pi, size(Y, 1)+1)'; t{i} = t{i}(1:end-1, 1);
    timeStampsTraining{i} = t{i}(indTr,1); %timeStampsTest = t(indTs,1);
    d{i} = size(Ytr{i}, 2);
end

for i=2:numberOfDatasets
    if N{i} ~= N{i-1}
        error('The number of observations in each dataset must be the same!');
    end
end

%-- Options for the models
for i=1:numberOfDatasets
    % Set up models
    options{i} = vargplvmOptions('dtcvar');
    options{i}.kern = mappingKern; %{'rbfard2', 'bias', 'white'};
    %indPoints = 80; %%%%%
    options{i}.numActive = indPoints;
    options{i}.optimiser = 'scg2';

    % !!!!! Be careful to use the same type of scaling and bias for all
    % models!!!

    % scale = std(Ytr);
    % scale(find(scale==0)) = 1;
    %options.scaleVal = mean(std(Ytr));
    options{i}.scaleVal = sqrt(var(Ytr{i}(:)));
    if fixInd
        options{i}.fixInducing=1;
        options{i}.fixIndices=1:size(Ytr{i},1);
    end
end

X_init = svargplvmInitLatentSpace(Ytr, d, options, initLatent, latentDim, latentDimPerModel, numSharedDims);

latentDim = size(X_init,2);

% Free up some memory
clear('Y')

%-- Create the sub-models: Assume that for each dataset we have one model.
% This can be changed later, as long as we find a reasonable way to
% initialise the latent spaces.
for i=1:numberOfDatasets
    %---- Here put some code to assign X to the global common X which must
    % be created by doing pca in the concatenation of Y's...After this
    % point, model{i}.X will be the same for all i's. TODO...
    fprintf(1,'# Creating the model...\n');
    options{i}.initX = X_init;
    model{i} = vargplvmCreate(latentDim, d{i}, Ytr{i}, options{i});
    model{i}.X = X_init; %%%%%%%
    model{i} = vargplvmParamInit(model{i}, model{i}.m, model{i}.X);
    model{i}.X = X_init; %%%%%%%

    inpScales = invWidthMult./(((max(model{i}.X)-min(model{i}.X))).^2); % Default 5
    %inpScales(:) = max(inpScales); % Optional!!!!!
    model{i}.kern.comp{1}.inputScales = inpScales;

    if strcmp(model{i}.kern.type, 'rbfardjit')
        model{i}.kern.inputScales = model{i}.kern.comp{1}.inputScales;
    end
    params = vargplvmExtractParam(model{i});
    model{i} = vargplvmExpandParam(model{i}, params);
    model{i}.vardist.covars = 0.5*ones(size(model{i}.vardist.covars)) + 0.001*randn(size(model{i}.vardist.covars));

    %-------- Add dynamics to the model -----
    if dynUsed
        fprintf(1,'# Adding dynamics to the model...\n');
        optionsDyn{i}.type = 'vargpTime';
        optionsDyn{i}.t=timeStampsTraining{i};
        optionsDyn{i}.inverseWidth=invWidthMultDyn; % Default: 100
        optionsDyn{i}.initX = X_init; % initX; % That's for the dynamics

        kern = kernCreate(t{i}, dynamicKern); % Default: {'rbf','white','bias'}

        %-- Initialize each element of the compound kernel
        svargplvmInitDynKern

        optionsDyn{i}.kern = kern;
        optionsDyn{i}.vardistCovars = vardistCovarsMult; % 0.23 gives true vardist.covars around 0.5 (DEFAULT: 0.23) for the ocean dataset

        % Fill in with default values whatever is not already set
        optionsDyn{i} = vargplvmOptionsDyn(optionsDyn{i});
        model{i} = vargplvmAddDynamics(model{i}, 'vargpTime', optionsDyn{i}, optionsDyn{i}.t, 0, 0,optionsDyn{i}.seq);

        fprintf(1,'# Further calibration of the initial values...\n');
        model{i} = vargplvmInitDynamics(model{i},optionsDyn{i});

        %  to also not learn the last kernel's variance
        if numel(kern.comp) > 1 && exist('learnSecondVariance') && ~learnSecondVariance
            fprintf(1,'# The variance for %s in the dynamics is not learned!\n',kern.comp{end}.type)
            model{i}.dynamics.learnSecondVariance = 0;
            model{i}.dynamics.kern.comp{end}.inverseWidth = model{i}.dynamics.kern.comp{1}.inverseWidth/10; %%% TEMP
        end
    end

    model{i}.beta=1/(0.01*var(model{i}.m(:)));
    prunedModelInit{i} = vargplvmPruneModel(model{i});
    %disp(model{i}.vardist.covars)
end

if experimentNo == -1
    experimentNo = globalExperimentNumber('sharedVargplvm', 'dataType');
end

%modelInit = model;%%%TEMP

%--  Unify models into a structure
model = svargplvmModelCreate(model);
model.dataSetNames = dataSetNames;
model.initLatent = initLatent;
model.experimentNo = experimentNo;
model.dataType = dataType;
%%---
capName = dataType;
capName(1) = upper(capName(1));
modelType = model.type;
modelType(1) = upper(modelType(1));
fileToSave = ['dem' capName modelType num2str(experimentNo) '.mat'];
%%---

%-- Define what level of parallelism to use (w.r.t submodels or/and w.r.t
% datapoints).
if enableParallelism
    if model.numModels > 8
        fprintf('# Parallel computations w.r.t the submodels!\n');
        model.parallel = 1;
        model = svargplvmPropagateField(model,'parallel', 1);
    elseif model.N > 15
        fprintf('# Parallel computations w.r.t the datapoints!\n');
        model.vardist.parallel = 1;
        for i=1:model.numModels
            model.comp{i}.vardist.parallel = 1;
        end
    end
end

% Force kernel computations
params = svargplvmExtractParam(model);
model = svargplvmExpandParam(model, params);

%%

display = 1;
%%%% Optimisation
% do not learn beta and sigma_f for few iterations for intitialization
if initVardistIters ~=0
    model.initVardist = 1;
    model = svargplvmPropagateField(model,'initVardist', model.initVardist);
    fprintf(1,'# Intitiliazing the variational distribution...\n');
    model = svargplvmOptimise(model, display, initVardistIters); % Default: 20
    %fprintf(1,'1/b = %.4d\n',1/model.beta);

    modelInitVardist = model;
    model.initVardistIters=initVardistIters;
end

model.initVardist = 0;
model = svargplvmPropagateField(model,'initVardist', model.initVardist);

% Optimise the model.
model.iters = 0;
for i=1:length(itNo)
    iters = itNo(i); % default: 2000
    fprintf(1,'\n# Optimising the model for %d iterations (session %d)...\n',iters,i);
    model = svargplvmOptimise(model, display, iters);
    model.iters = model.iters + iters;
    % Save model
    fprintf(1,'# Saving %s\n',fileToSave);
    save(fileToSave, 'model', 'prunedModelInit');
end

for i=1:numberOfDatasets
    figure, bar(model.comp{i}.kern.comp{1}.inputScales);
    title(['Final scales for dataset ' num2str(i)]);
end

if toyData && strcmp(toyDataCreate,'fols')
    figure,plot(model.X(:,1)), hold on, plot(model.X(:,2),'r')
    hold on, plot(model.X(:,3),'g')
end

%%
%--------------------- PREDICTIONS --------------%
if ~doPredictions
    return
end
if model.numModels ~=2
    error('Predictions cannot be made (currently) with sharedVargplvm unless the number of submodels used is 2.');
end
%%

obsMod = 1; % one of the involved sub-models (the one for which we have the data)
infMod = setdiff(1:2, obsMod);

% Find the dimensions that are shared for obsMod and infMod
if ~exist('sharedDims')
    thresh = max(model.comp{obsMod}.kern.comp{1}.inputScales) * 0.001;
    retainedScales{obsMod} = find(model.comp{obsMod}.kern.comp{1}.inputScales > thresh);
    thresh = max(model.comp{infMod}.kern.comp{1}.inputScales) * 0.001;
    retainedScales{infMod} = find(model.comp{infMod}.kern.comp{1}.inputScales > thresh);
    sharedDims = intersect(retainedScales{obsMod}, retainedScales{infMod});
end

% Find X_* only for the shared dimensions (Xs*):
if ~exist('privateDims')
    privateDims{infMod} = setdiff(1:model.comp{obsMod}.q, sharedDims);
end

testOnTraining=0;

if testOnTraining
    i = size(model.comp{obsMod}.y,1); % last observation
    % Find p(X_* | Y_*): If Y* is not taken from the tr. data, then this step
    % must be an optimisation step of q(x*). X_* and Y_* here refer to the
    % spaces of the submodel obsMod.
    y_star = model.comp{obsMod}.y(i);
    x_star = model.comp{obsMod}.vardist.means(i,:);
    varx_star = model.comp{obsMod}.vardist.covars(i,:);
    [ind, distInd] = nn_class(model.X(:,sharedDims), x_star(:,sharedDims), 10, 'euclidean');

    ZpredMu = zeros(length(ind), size(Ytoy{infMod},2));
    ZpredSigma = zeros(length(ind), size(Ytoy{infMod},2));
    for k=1:length(ind)
        [ZpredMu(k,:), ZpredSigma(k,:)] = vargplvmPosteriorMeanVar(model.comp{infMod}, model.X(ind(k),:));
    end
else
    testInd = 25;
    Yts = Y_test(testInd,:); % Now this is a matrix
    for i=1:size(Yts,1)
        % initialize the latent points using the nearest neighbour
        % from the training data
        dst = dist2(Yts(i,:), model.comp{obsMod}.y);
        [mind, mini] = min(dst);

        Init(i,:) = model.vardist.means(mini,:);
        vardistx = vardistCreate(model.comp{obsMod}.vardist.means(mini,:), model.q, 'gaussian');
        vardistx.covars = model.comp{obsMod}.vardist.covars(mini,:);
        model.comp{obsMod}.vardistx = vardistx;
        display=1;
        iters = 100;
        % Find p(X_* | Y_*) which is approximated by q(X_*)
        [x_star, varx_star, modelUpdated] = vargplvmOptimisePoint(model.comp{obsMod}, vardistx, Yts(i,:), display, iters);%%%
        numberOfNN = 10;
        % Now we selected a datapoint X_* by taking into account only the
        % private dimensions for Y. Now, based on the shared dimensions of
        % that, we select the closest (in a NN manner) X from the training data.
        [ind, distInd] = nn_class(model.X(:,sharedDims), x_star(:,sharedDims), numberOfNN, 'euclidean');

        x = model.X(ind,:);
        % Careful:  Since x is coming from the training set, it is somewhat
        % natural that the predicted y's will also closely match the ones
        % from the training set. What makes it interesting, is to show that
        % the shared dimensions are the ones controlling the common
        % ambiguities, so, actually it really matters what indices of
        % training X's we find with the NN based on sharedDims.
        mu = vargplvmPosteriorMeanVar(model.comp{infMod}, x);

        ZpredK{i} = mu;

        ZpredMu(i,:) = mu(1);

        %ZpredSigma(i,:) = sigma;
    end

    errsumFull = sum((ZpredMu - Z_test(testInd,:)).^2);
    errorFull = mean(errsumFull);

    if toyData && strcmp(toyDataCreate,'humanPose')
        for j = 1:1:length(testInd)
            handle = xyzankurVisualise(ZpredK{j}(1,:),1);
            for k = 2:length(ind)
                %  xyzankurModify(handle,ZpredK{j}(k,:));            handle = xyzankurVisualise(ZpredK{j}(1,:),1);
                handle = xyzankurVisualise(ZpredK{j}(k,:),k);
                title(['Pose'])
                pause;
            end
        end
    end
end


% POP_CROSSF - Return estimates and plots of event-related spectral coherence
%
% Usage:
%       >> pop_crossf(EEG, typeproc, num1, num2, tlimits,cycles,
%                                 'key1',value1,'key2',value2, ... );
% Inputs:
%   INEEG    - Input EEG dataset
%   typeproc - Type of processing:
%                  1 = process two raw-data channels,
%                  0 = process two ICA components
%   num1     - First component or channel number
%   num2     - Second component or channel number
%   tlimits  - [mintime maxtime] Sub-epoch time limits in ms
%   cycles   -   >0 -> Number of cycles in each analysis wavelet
%                 0 -> Use FFTs (with constant window length)
%
% Optional inputs: As for CROSSF.  See >> help crossf
%
% Outputs: Same as CROSSF. No outputs are returned when a
%          window pops-up to ask for additional arguments
%
% Author: Arnaud Delorme, CNL / Salk Institute, 11 March 2002
%
% See also: TIMEF, EEGLAB

% Copyright (C) 11 March 2002 arno@salk.edu, Arnaud Delorme, CNL / Salk Institute
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

% 03-18-02 added title -ad & sm
% 04-04-02 added outputs -ad & sm

function varargout = pop_crossf(EEG, typeproc, num1, num2, tlimits, cycles, varargin );

varargout{1} = '';
% display help if not enough arguments
% ------------------------------------
if nargin < 2
	help pop_crossf;
	return;
end;
lastcom = [];
if nargin < 3
	popup = 1;
else
	popup = ischar(num1) | isempty(num1);
	if ischar(num1)
		lastcom = num1;
	end
end

% pop up window
% -------------
if popup
	[txt vars] = gethelpvar('timef.m');

	geometry = { [1 0.5 0.5] [1 0.5 0.5] [1 0.5 0.5] [1 0.5 0.5] [0.92 0.1 0.78] [1 0.5 0.5] [1 0.8 0.2] [1] [1 1]};
    uilist = { { 'Style', 'text', 'string', fastif(typeproc, 'First channel number', 'First component number'), 'fontweight', 'bold'  } ...
			   { 'Style', 'edit', 'string', getkeyval(lastcom,3,[],'1') } {} ...
			   { 'Style', 'text', 'string', fastif(typeproc, 'Second channel number', 'Second component number'), 'fontweight', 'bold'  } ...
			   { 'Style', 'edit', 'string', getkeyval(lastcom,4,[],'2') } {} ...
			   { 'Style', 'text', 'string', 'Epoch time range [min max] (msec)', 'fontweight', 'bold', ...
				 'tooltipstring', 'Sub epoch time limits' } ...
			   { 'Style', 'edit', 'string', getkeyval(lastcom,5,[],[ int2str(EEG.xmin*1000) ' ' int2str(EEG.xmax*1000) ]) } {} ...
			   { 'Style', 'text', 'string', 'Wavelet cycles (0->FFT, see >> help timef)', 'fontweight', 'bold', ...
				 'tooltipstring', context('cycles',vars,txt) } ...
			   { 'Style', 'edit', 'string', getkeyval(lastcom,6,[],'3 0.5') } {} ...
			   { 'Style', 'text', 'string',  '[set]->Linear coher / [unset]->Phase coher', 'fontweight', 'bold', ...
				 'tooltipstring', ['Compute linear inter-trial coherence (coher)' 10 ...
					'OR Amplitude-normalized inter-trial phase coherence (phasecoher)'] } ...
			   { 'Style', 'checkbox', 'value', ~getkeyval(lastcom,'phasecoher','present',1) } { } ...
			   { 'Style', 'text', 'string', 'Bootstrap significance level (Ex: 0.01 -> 1%)', 'fontweight', 'bold', ...
				 'tooltipstring', context('alpha',vars,txt) } ...
			   { 'Style', 'edit', 'string', getkeyval(lastcom,'alpha') } {} ...
			   { 'Style', 'text', 'string', 'Optional timef() arguments (see Help)', 'fontweight', 'bold', ...
				 'tooltipstring', 'See crossf() help via the Help button on the right...' } ...
			   { 'Style', 'edit', 'string', '''padratio'', 4' } ...
			   { 'Style', 'pushbutton', 'string', 'Help', 'callback',  'pophelp(''crossf'');' } ...
			   {} ...
			   { 'Style', 'checkbox', 'value', ~getkeyval(lastcom,'plotersp','present',0), 'string', ...
				 'Plot coherence amplitude', 'tooltipstring', ...
				 'Plot coherence ampltitude image in the upper panel' } ...
			   { 'Style', 'checkbox', 'value', ~getkeyval(lastcom,'plotphase','present',0), 'string', ...
				 'Plot coherence phase', 'tooltipstring', ...
				 'Plot coherence phase image in the lower panel' } ...
			 };

	result = inputgui( geometry, uilist, 'pophelp(''pop_crossf'');', ...
					   fastif(typeproc, 'Plot channel cross-coherence -- pop_crossf()', ...
							  'Plot component cross-coherence -- pop_crossf()'));
	if length( result ) == 0 return; end

	num1     = eval( [ '[' result{1} ']' ] );
	num2     = eval( [ '[' result{2} ']' ] );
	tlimits	 = eval( [ '[' result{3} ']' ] );
	cycles	 = eval( [ '[' result{4} ']' ] );
    if result{5}
    	options = [',''type'', ''coher''' ];
    else
		options = [',''type'', ''phasecoher''' ];
    end;

    % add topoplot
    % ------------
	if isfield(EEG.chanlocs, 'theta')
        if ~isfield(EEG, 'chaninfo'), EEG.chaninfo = []; end
		if typeproc == 1
			options = [options ', ''topovec'', [' int2str([num1 num2]) ...
                       '], ''elocs'', EEG.chanlocs, ''chaninfo'', EEG.chaninfo' ];
		else % typeproc == 0
			options = [options ', ''topovec'', EEG.icawinv(:, [' int2str([num1 num2]) ...
                       '])'', ''elocs'', EEG.chanlocs, ''chaninfo'', EEG.chaninfo' ];
		end
	end

    % add title
    % ---------
	if isempty( findstr(  'title', result{7}))
        if ~isempty(EEG.chanlocs) && typeproc
            chanlabel1 = EEG.chanlocs(num1).labels;
            chanlabel2 = EEG.chanlocs(num2).labels;
        else
            chanlabel1 = int2str(num1);
            chanlabel2 = int2str(num2);
        end
		if result{5}
            options = [options ', ''title'',' fastif(typeproc, '''Channel ', '''Component ') chanlabel1 '-' chanlabel2 ...
					' Coherence'''];
        else
            options = [options ', ''title'',' fastif(typeproc, '''Channel ', '''Component ') chanlabel1 '-' chanlabel2 ...
					' Phase Coherence''' ];
		end
	end
	if ~isempty( result{6} )
		options      = [ options ', ''alpha'',' result{6} ];
	end
	if ~isempty( result{7} )
		  options = [ options ',' result{7} ];
	end
	if ~result{8}
		options = [ options ', ''plotersp'', ''off''' ];
	end
	if ~result{9}
		options = [ options ', ''plotphase'', ''off''' ];
	end
    figure; try, icadefs; set(gcf, 'color', BACKCOLOR); catch, end;
else
	options = [ ',' vararg2str(varargin) ];
end

% compute epoch limits
% --------------------
if isempty(tlimits)
	tlimits = [EEG.xmin, EEG.xmax]*1000;
end;
pointrange1 = round(max((tlimits(1)/1000-EEG.xmin)*EEG.srate, 1));
pointrange2 = round(min((tlimits(2)/1000-EEG.xmin)*EEG.srate, EEG.pnts));
pointrange = [pointrange1:pointrange2];

% call function sample either on raw data or ICA data
% ---------------------------------------------------
if typeproc == 1
	tmpsig1 = EEG.data(num1,pointrange,:);
	tmpsig2 = EEG.data(num2,pointrange,:);
else
	if ~isempty( EEG.icasphere )
        tmpsig1 = eeg_getdatact(EEG, 'component', num1, 'samples', pointrange);
        tmpsig2 = eeg_getdatact(EEG, 'component', num2, 'samples', pointrange);
	else
		error('You must run ICA first');
	end;
end;
tmpsig1 = reshape( tmpsig1, 1, size(tmpsig1,2)*size(tmpsig1,3));
tmpsig2 = reshape( tmpsig2, 1, size(tmpsig2,2)*size(tmpsig2,3));

% outputs
% -------
outstr = '';
if ~popup
    for io = 1:nargout, outstr = [outstr 'varargout{' int2str(io) '},' ]; end
    if ~isempty(outstr), outstr = [ '[' outstr(1:end-1) '] =' ]; end
end

% plot the datas and generate output command
% --------------------------------------------
if length( options ) < 2
    options = '';
end
varargout{1} = sprintf('figure; pop_crossf( EEG, %d, %d, %d, [%s], [%s] %s);', ...
          typeproc, num1, num2, int2str(tlimits), num2str(cycles), options);

%options = [ options ', ''ydir'', ''norm''' ];
com = sprintf( '%s crossf( tmpsig1, tmpsig2, length(pointrange), [tlimits(1) tlimits(2)], EEG.srate, cycles %s);', outstr, options);
eval(com)

return;

% get contextual help
% -------------------
function txt = context(var, allvars, alltext);
	loc = strmatch( var, allvars);
	if ~isempty(loc)
		txt= alltext{loc(1)};
	else
		disp([ 'warning: variable ''' var ''' not found']);
		txt = '';
	end


function f = abs(f, varargin)
%ABS   Absolute value of a CHEBTECH object.
%   ABS(F) returns the absolute value of F, where F is a CHEBTECH object with no
%   roots in [-1 1]. If ~isempty(roots(F)), then ABS(F) will return garbage
%   with no warning. F may be complex.

%  Copyright 2017 by The University of Oxford and The Chebfun Developers.
%  See http://www.chebfun.org/ for Chebfun information.

if ( isreal(f) || isreal(1i*f) )
    % Convert to values and then compute ABS().
    values = f.coeffs2vals(f.coeffs);
    values = abs(values);
    f.coeffs = f.vals2coeffs(values);
else
    f = compose(f, @abs, [], [], varargin{:});
end

end


function varargout = pm_ff_unwrap(varargin)
% Performs phase-unwrapping along the shore of a flood-fill
% progressing from some seed in a low-variance area towards
% higher variance areas.
% FORMAT [pm,wm] = pm_ff_unwrap(pm,vm,wm,mask,thres)
%
% Input:
% pm     : 2 or 3D phasemap where some voxels have been unwrapped
%          and some not.
% vm     : Variance map, indicating the variance of the phase estimate.
% wm     : Wrap-map, where a non-zero value indicates corresponding
%          phase-value in pm has been unwrapped.
% mask   : Mask that indicates which voxels are worth
%          bothering with and which are not.
% thres  : Array of thresholds such that unwrapping proceeds by
%          serial dilates from some seed point in wm until all
%          connected voxels with vm<thres(1) have been unwrapped,
%          after which the same happens with vm<thres(2) etc etc
%
% Output:
% pm     : Same as pm but with unwrapping now completed as far as
%          indicated by wm on output.
% wm     : Indicates how far unwrapping has progressed.
%
% Note that the following are equivalent in terms of the final
% result
%
% [pm,wm] = pm_ff_unwrap(pm,vm,wm,mask,thres);
%
% for i=1:length(thres)
%   [pm,vm] = pm_ff_unwrap(pm,vm,wm,maskm,thres(i));
% end
%
% where the later would be slightly slower but would allow
% reporting of progress to some GUI.
%_________________________________________________________________
% Jesper Andersson 30/9-03
%_______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Jesper Andersson
% $Id: pm_ff_unwrap.m 1317 2008-04-08 16:16:38Z chloe $

error('mex-function pm_ff_unwrap.c not compiled');