function [Ep,Cp] = spm_dcm_sparse(DCM,field)
% Bayesian model reduction of all permutations of model parameters
% FORMAT [RCM,BMR] = spm_dcm_sparse(DCM,field
%
% DCM      - A single estimated DCM (or PEB) structure:
%
%  DCM.M.pE  - prior expectation
%  DCM.M.pC  - prior covariance
%  DCM.Ep    - posterior expectation
%  DCM.Cp    - posterior covariances
%  DCM.gamma - prior variance    of reduced parameters (default: 0)
%
% field      - parameter fields in DCM{i}.Ep to optimise [default: {'A','B'}]
%             'All' will invoke all fields (i.e. random effects)
%             If Ep is not a structure, all parameters will be considered
%
% Returns:
%  Ep    - (BMA) posterior expectation
%  Cp    - (BMA) posterior covariance
%
%--------------------------------------------------------------------------
% This routine searches over reduced (nested) models of a full model (DCM)
% using Bayesian model reduction and performs Bayesian Model Averaging.
% 'Reduced' means some free parameters (parameters with a non-
% zero prior covariance) are switched off by fixing their prior variance
% to zero.This version incorporates a sparsity  prior over models (with a
% Gaussian hyperprior). In other words, the free energy is taken to be the
% likelihood of some data under a given model. The prior on that model
% corresponds to a softmax function of the prior entropy. Finally, the
% softmax (Gibbs) parameter is equipped with a Gaussian prior. Using
% Bayesian model reduction, this routine evaluates the joint probability
% over model and softmax sparsity parameter. The marginals over model space
% are then used to form Bayesian model averaging.
%
% The greedy search in this version simply evaluates the log evidence of
% models with and without each parameter and then successively removes the
% parameters with the least evidence.
%
% See also: spm_dcm_bmr and spm_dcm_bmr_all
%__________________________________________________________________________
% Copyright (C) 2010-2014 Wellcome Trust Centre for Neuroimaging

% Karl Friston, Peter Zeidman
% $Id: spm_dcm_sparse.m 7082 2017-05-27 19:36:36Z karl $

%-Number of parameters to consider before invoking greedy search
%--------------------------------------------------------------------------
nmax  = 8;

%-specification of null prior covariance
%--------------------------------------------------------------------------
if isfield(DCM,'beta'),  beta  = DCM.beta;  else, beta  = 0; end
if isfield(DCM,'gamma'), gamma = DCM.gamma; else, gamma = 0; end

%-Check fields of parameter stucture
%--------------------------------------------------------------------------
if nargin < 2 || isempty(field)
    field = {'A','B'};
end
if ischar(field)
    field = {field};
end

%-dela with filenames stucture
%--------------------------------------------------------------------------
if ischar(DCM)
    DCM = load(DCM,'DCM');
    DCM = DCM.DCM;
end

% Get prior covariances
%--------------------------------------------------------------------------
if isstruct(DCM.M.pC), DCM.M.pC = diag(spm_vec(DCM.M.pC)); end
if spm_length(DCM.M.pE) ~= size(DCM.M.pC,1)
    DCM.M.pC = diag(spm_vec(DCM.M.pC));
end

% Get priors and posteriors
%--------------------------------------------------------------------------
qE  = DCM.Ep;
qC  = DCM.Cp;
pE  = DCM.M.pE;
pC  = DCM.M.pC;

% Remove (a priori) null space
%--------------------------------------------------------------------------
U   = spm_svd(pC);
qE  = U'*spm_vec(qE);
pE  = U'*spm_vec(pE);
qC  = U'*qC*U;
pC  = U'*pC*U;

%-Greedy search (GS) - eliminating parameters in a top down fashion
%==========================================================================

% Accumulated reduction vector (C)
%--------------------------------------------------------------------------
q   = diag(DCM.M.pC);
if sum(q < 1024)
    C   = double(q > mean(q(q < 1024))/1024);
else
    C   = double(q > 0);
end

%-Find free coupling parameters
%----------------------------------------------------------------------
if isstruct(DCM.Ep)
    k = spm_fieldindices(DCM.Ep,field{:});
else
    k = 1:spm_length(DCM.Ep);
end
k     = k(find(C(k))); %#ok<FNDSB>

% Model search over new prior without the i-th parameter
%------------------------------------------------------------------
nparam = length(k);
for i  = 1:nparam

    % Identify parameters to retain r and to remove s
    %--------------------------------------------------------------
    r    = C; r(k(i)) = 0; s = 1 - r;

    % Create reduced priors
    %--------------------------------------------------------------
    R    = U'*diag(r + s*gamma)*U;
    rC   = R*pC*R;
    F(i) = spm_log_evidence(qE,qC,pE,pC,pE,rC);

end

% Find parameters with the least evidence
%--------------------------------------------------------------------------
[F,i] = sort(-F);
k     = k(i);
M     = cell(0);
for i = 1:nparam

    % parameters to retain (r) and to remove (s)
    %----------------------------------------------------------------------
    r    = C; r(k(1:i)) = 0; s = 1 - r;

    % Create reduced prior covariance matrix
    %----------------------------------------------------------------------
    R    = U'*diag(r + s*gamma)*U;
    rC   = R*pC*R;

    % record
    %----------------------------------------------------------------------
    M(i).F  = spm_log_evidence(qE,qC,pE,pC,pE,rC)
    M(i).H  = spm_logdet(rC);
    M(i).rC = rC;

end

% Sparsity hyperpriors
%--------------------------------------------------------------------------
s     = (1:64)/64;
Ps    = exp(-((1:64) - 32).^2/(2*16));
Ps    = Ps/sum(Ps);

%  model likelihood, model prior and  sparsity hyperprior
%--------------------------------------------------------------------------
Lm    = spm_softmax(spm_vec(M.F));
for i = 1:numel(s)
    Pm      = spm_softmax(-s(i)*spm_vec(M.H));
    Qm(:,i) = Lm.*Pm*Ps(i);
end

% evidence and log evidence
%--------------------------------------------------------------------------
Qm    = Qm/sum(sum(Qm));
G     = log(sum(Qm,2));

%-Bayesian model average
%==========================================================================
qE    = DCM.Ep;
qC    = DCM.Cp;
pE    = DCM.M.pE;
pC    = DCM.M.pC;
pE    = spm_vec(pE);
Gmax  = max(G);
BMA   = {};
for i = 1:length(G)
    if G(i) > (Gmax - 4)
        [F,Ep,Cp]    = spm_log_evidence_reduce(qE,qC,pE,pC,pE,M(i).rC);
        BMA{end + 1} = struct('Ep',Ep,'Cp',Cp,'F',F);
    end
end

BMA   = spm_dcm_bma(BMA);
Ep    = BMA.Ep;
Cp    = BMA.Cp;
if isstruct(Cp) || (spm_length(Cp) == spm_length(Ep))
    Cp = diag(spm_vec(Cp));
end

% Show results
% -------------------------------------------------------------------------
GRAPHICS = 1;

if ~GRAPHICS, return, end

spm_figure('Getwin','BMR - all'); clf
subplot(3,2,1)
imagesc(log(Qm)')
title('Joint density','FontSize',16)
xlabel('model','FontSize',12)
ylabel('sparsity','FontSize',12)
axis square

subplot(3,2,2)
plot(DCM.Ep,Ep,'.',DCM.Ep,DCM.Ep,':')
title('Full and reduced expectations','FontSize',16)
xlabel('Full expectations','FontSize',12)
ylabel('Reduced expectations','FontSize',12)
axis square

subplot(3,2,3)
plot(s,sum(Qm,1))
title('Marginal over sparsity','FontSize',16)
xlabel('sparsity parameter','FontSize',12)
ylabel('probability','FontSize',12)
axis square

subplot(3,2,4)
plot(sum(Qm,2))
title('Marginal over  model','FontSize',16)
xlabel(' model','FontSize',12)
ylabel('probability','FontSize',12)
axis square
drawnow


function [pesq_mos]= pesq(ref_wav, deg_wav)

% ----------------------------------------------------------------------
%            PESQ objective speech quality measure
%
%   This function implements the PESQ measure based on the ITU standard
%   P.862 [1].
%
%
%   Usage:  pval=pesq(cleanFile.wav, enhancedFile.wav)
%
%         cleanFile.wav - clean input file in .wav format
%         enhancedFile  - enhanced output file in .wav format
%         pval          - PESQ value
%
%    Note that the PESQ routine only supports sampling rates of 8 kHz and
%    16 kHz [1]
%
%  Example call:  pval = pesq ('sp04.wav','enhanced.wav')
%
%
%  References:
%   [1] ITU (2000). Perceptual evaluation of speech quality (PESQ), and
%       objective method for end-to-end speech quality assessment of
%       narrowband telephone networks and speech codecs. ITU-T
%       Recommendation P. 862
%
%   Authors: Yi Hu and Philipos C. Loizou
%
%
% Copyright (c) 2006 by Philipos C. Loizou
% $Revision: 0.0 $  $Date: 10/09/2006 $
% ----------------------------------------------------------------------

if nargin<2
    fprintf('Usage: [pesq_mos]=pesq(cleanfile.wav,enhanced.wav) \n');
    return;
end;

global Downsample DATAPADDING_MSECS SEARCHBUFFER Fs WHOLE_SIGNAL
global Align_Nfft Window

[ref_data,sampling_rate]= audioread( ref_wav);
% if sampling_rate~=8000 & sampling_rate~=16000
%     error('Sampling frequency needs to be either 8000 or 16000 Hz');
% end

setup_global( sampling_rate);

% Window= hann( Align_Nfft, 'periodic'); %Hanning window
% Window= Window';
TWOPI= 6.28318530717959;
%for count = 0: Align_Nfft- 1
%    Window(1+ count) = 0.5 * (1.0 - cos((TWOPI * count) / Align_Nfft));
%end

count=0:Align_Nfft- 1;
Window= 0.5 * (1.0 - cos((TWOPI * count) / Align_Nfft));

ref_data= ref_data';
ref_data= ref_data* 32768;
ref_Nsamples= length( ref_data)+ 2* SEARCHBUFFER* Downsample;
ref_data= [zeros( 1, SEARCHBUFFER* Downsample), ref_data, ...
    zeros( 1, DATAPADDING_MSECS* (Fs/ 1000)+ SEARCHBUFFER* Downsample)];

deg_data= audioread( deg_wav);
deg_data= deg_data';
deg_data= deg_data* 32768;
deg_Nsamples= length( deg_data)+ 2* SEARCHBUFFER* Downsample;
deg_data= [zeros( 1, SEARCHBUFFER* Downsample), deg_data, ...
    zeros( 1, DATAPADDING_MSECS* (Fs/ 1000)+ SEARCHBUFFER* Downsample)];

maxNsamples= max( ref_Nsamples, deg_Nsamples);

ref_data= fix_power_level( ref_data, ref_Nsamples, maxNsamples);
deg_data= fix_power_level( deg_data, deg_Nsamples, maxNsamples);

standard_IRS_filter_dB= [0, -200; 50, -40; 100, -20; 125, -12; 160, -6; 200, 0;...
    250, 4; 300, 6; 350, 8; 400, 10; 500, 11; 600, 12; 700, 12; 800, 12;...
    1000, 12; 1300, 12; 1600, 12; 2000, 12; 2500, 12; 3000, 12; 3250, 12;...
    3500, 4; 4000, -200; 5000, -200; 6300, -200; 8000, -200];

ref_data= apply_filter( ref_data, ref_Nsamples, standard_IRS_filter_dB);
deg_data= apply_filter( deg_data, deg_Nsamples, standard_IRS_filter_dB);
%

% for later use in psychoacoustical model
model_ref= ref_data;
model_deg= deg_data;

[ref_data, deg_data]= input_filter( ref_data, ref_Nsamples, deg_data, ...
    deg_Nsamples);

[ref_VAD, ref_logVAD]= apply_VAD( ref_data, ref_Nsamples);
[deg_VAD, deg_logVAD]= apply_VAD( deg_data, deg_Nsamples);

crude_align (ref_logVAD, ref_Nsamples, deg_logVAD, deg_Nsamples,...
    WHOLE_SIGNAL);

utterance_locate (ref_data, ref_Nsamples, ref_VAD, ref_logVAD,...
    deg_data, deg_Nsamples, deg_VAD, deg_logVAD);

ref_data= model_ref;
deg_data= model_deg;

% make ref_data and deg_data equal length
if (ref_Nsamples< deg_Nsamples)
    newlen= deg_Nsamples+ DATAPADDING_MSECS* (Fs/ 1000);
    ref_data( newlen)= 0;
elseif (ref_Nsamples> deg_Nsamples)
    newlen= ref_Nsamples+ DATAPADDING_MSECS* (Fs/ 1000);
    deg_data( newlen)= 0;
end

pesq_mos= pesq_psychoacoustic_model (ref_data, ref_Nsamples, deg_data, ...
    deg_Nsamples );


function [data, wAxis, dAxis, xAxis, yAxis, misc] = lscload(filename)
% Reads in IR image data from PerkinElmer block structured files.
% This version is compatible with '1994' standard LSC files.
%
% [data, wAxis, dAxis, xAxis, yAxis, misc] = lscload(filename):
%   data:  2D array, [W, D]     wavelength x distance
%   wAxis: vector of e.g. wavenumbers
%   dAxis: vector of distance along line
%   xAxis: vector for stage x positions (e.g. micrometers)
%   yAxis: vector for stage y positions (e.g. micrometers)
%   misc: miscellanous information in name,value pairs

% Copyright (C)2007 PerkinElmer Life and Analytical Sciences
% Stephen Westlake, Seer Green
%
% History
% 2007-05-01 SW     Initial version

% Block IDs
DS4C3IData            = 5100;   % 4D DS: header info
DS4C3IPts             = 5101;   % 4D DS: point coordinates (CvCoOrdArray)
DS4C3IPtsCont         = 5102;   % 4D DS: point coordinates (continuator for large CvCoOrdArray)
DS4C3ITemp2DData      = 5103;   % 4D DS: temp block for storing part of component 2d dataset
DS4C3I2DData          = 5104;   % 4D DS: release sw block for storing ALL of component 2d data
DS4C3IFloatPts        = 5105;   % 4D DS: point coordinates (FloatArray)
DS4C3IFloatPtsCont    = 5106;   % 4D DS: point coordinates (continuator for large FloatArray)
DS4C3IHistory         = 5107;   % 4D DS: history record

fid = fopen(filename,'r');
if fid == -1
    error('Cannot open the file.');
    return
end

% Fixed file header of signature and description
signature = setstr(fread(fid, 4, 'uchar')');
if ~strcmp(signature, 'PEPE')
    error('This is not a PerkinElmer block structured file.');
    return
end
description = setstr(fread(fid, 40, 'uchar')');

% Initialize a variable so we can tell if we have read it.
dLen = int32(0);
qLen = int32(0);

% The rest of the file is a list of blocks
while ~feof(fid)
    blockID = fread(fid,1,'int16');
    blockSize = fread(fid,1,'int32');

    % feof does not go true until after the read has failed.
    if feof(fid)
        break
    end

    switch blockID
        case DS4C3IData
            len = fread(fid,1,'int16');
            alias = setstr(fread(fid, len, 'uchar')');

            dDelta = fread(fid, 1, 'double');       % distance delta
            angle = fread(fid, 1, 'double');        % angle (radians)
            wDelta = fread(fid, 1, 'double');       % wavenumber delta
            fread(fid, 1, 'double');      % zstart
            fread(fid, 1, 'double');      % zend
            fread(fid, 1, 'double');      % min data value
            fread(fid, 1, 'double');      % max data value
            x0 = fread(fid, 1, 'double');           % stage x0
            y0 = fread(fid, 1, 'double');           % stage y0
            w0 = fread(fid, 1, 'double');           % wavenumber start
            dLen = fread(fid, 1, 'int32');          % distance points
            qLen = fread(fid, 1, 'int32');          % should be 1
            wLen = fread(fid, 1, 'int32');          % wavelength points

            len = fread(fid, 1, 'int16');
            dLabel = setstr(fread(fid, len, 'uchar')');
            len = fread(fid, 1, 'int16');
            setstr(fread(fid, len, 'uchar')');
            len = fread(fid, 1, 'int16');
            wLabel = setstr(fread(fid, len, 'uchar')');
            len = fread(fid, 1, 'int16');
            zLabel = setstr(fread(fid, len, 'uchar')');

            % imshow row 1 is the top, i.e. fsm row N.
            d = dLen;

        case DS4C3IFloatPts         % the next spectrum
            data(d, :) = fread(fid, wLen, 'float');
            if d == 0
                error('There are too many data points.');
                return
            end
            % set up the index for the next point
            d = d - 1;

        otherwise               % unknown block, just seek past it
            fseek(fid, blockSize, 'cof');
    end
end
fclose(fid);

if dLen == 0
    error('The file does not contain spectral image data.');
    return
end
if qLen ~= 1
    error('The file does not contain line scan data.');
    return
end

% d0 is implicitly 0
dEnd = (dLen - 1) * dDelta;
wEnd = w0 + (wLen - 1) * wDelta;

% Calculate end stage positions from angle and hypoteneuse
xEnd = x0 + dEnd * cos(angle);
yEnd = y0 + dEnd * sin(angle);
xDelta = dDelta * cos(angle);
yDelta = dDelta * sin(angle);

% Expand the axes specifications into vectors
% D axis is reversed to match the image data
xAxis = x0 : xDelta : xEnd;
yAxis = y0 : yDelta : yEnd;
dAxis = dEnd : -dDelta : 0;
wAxis = w0 : wDelta : wEnd;

% Return the other details as name,value pairs
misc(1,:) = {'dLabel', dLabel};
misc(2,:) = {'wLabel', wLabel};
misc(3,:) = {'zLabel', zLabel};
misc(4,:) = {'alias', alias};
misc(5,:) = {'angle', angle};


function [data_train, labels_train, data_devel, labels_devel, raw_devel, PC, means_norm, stds_norm, devel_ids, devel_success] = ...
    Prepare_HOG_AU_data(train_users, devel_users, au_train, rest_aus, Bosphorus_dir, params_data_dir)

%%
addpath(genpath('../data extraction/'));

% First extracting the labels
[ labels_train, valid_ids_train, filenames ] = extract_Bosphorus_labels(Bosphorus_dir, train_users, au_train);

[ labels_other, ~, ~ ] = extract_Bosphorus_labels(Bosphorus_dir, train_users, rest_aus);

% Reading in the HOG data (of only relevant frames)
[train_appearance_data, valid_ids_train_hog, vid_ids_train_string] = Read_HOG_files(filenames, params_data_dir);

[train_geom_data] = Read_geom_files(filenames,  params_data_dir);

% Subsample the data to rebalance it
if(numel(train_users) > 0)
    reduced_inds = false(size(labels_train,1),1);
    reduced_inds(labels_train > 0) = true;

    % make sure the same number of positive and negative samples is taken
    pos_count = sum(labels_train > 0);
    neg_count = sum(labels_train == 0);

    num_other = floor( pos_count / (size(labels_other, 2)));

    inds_all = 1:size(labels_train,1);

    for i=1:size(labels_other, 2)+1

        if(i > size(labels_other, 2))
            % fill the rest with a proportion of neutral
            inds_other = inds_all(sum(labels_other,2)==0 & ~labels_train );
                num_other_i = min(numel(inds_other), pos_count - sum(labels_train(reduced_inds,:)==0));
        else
                % take a proportion of each other AU
            inds_other = inds_all(labels_other(:, i) & ~labels_train );
            num_other_i = min(numel(inds_other), num_other);
        end
        inds_other_to_keep = inds_other(round(linspace(1, numel(inds_other), num_other_i)));
        reduced_inds(inds_other_to_keep) = true;

    end

    % Remove invalid ids based on CLM failing or AU not being labelled
    reduced_inds(~valid_ids_train) = false;
    reduced_inds(~valid_ids_train_hog) = false;

    labels_other = labels_other(reduced_inds, :);
    labels_train = labels_train(reduced_inds,:);
    train_appearance_data = train_appearance_data(reduced_inds,:);
    train_geom_data = train_geom_data(reduced_inds,:);
    vid_ids_train_string = vid_ids_train_string(reduced_inds,:);
end
%% Extract devel data

% First extracting the labels
[ labels_devel, valid_ids_devel, filenames_devel ] = extract_Bosphorus_labels(Bosphorus_dir, devel_users, au_train);

% Reading in the HOG data (of only relevant frames)
[devel_appearance_data, valid_ids_devel_hog, vid_ids_devel_string] = Read_HOG_files(filenames_devel, params_data_dir);
devel_success = valid_ids_devel_hog;
devel_ids = vid_ids_devel_string;

[devel_geom_data] = Read_geom_files(filenames_devel, params_data_dir);

% Peforming zone specific masking
if(au_train < 8 || au_train == 43 || au_train == 45) % upper face AUs ignore bottom face
    % normalise the data
    pca_file = '../../pca_generation/generic_face_upper.mat';
    load(pca_file);
elseif(au_train > 9) % lower face AUs ignore upper face and the sides
    % normalise the data
    pca_file = '../../pca_generation/generic_face_lower.mat';
    load(pca_file);
elseif(au_train == 9) % Central face model
    % normalise the data
    pca_file = '../../pca_generation/generic_face_rigid.mat';
    load(pca_file);
end

% Grab all data for validation as want good params for all the data
raw_devel = cat(2, devel_appearance_data, devel_geom_data);

devel_appearance_data = bsxfun(@times, bsxfun(@plus, devel_appearance_data, -means_norm), 1./stds_norm);

data_devel = devel_appearance_data * PC;

data_devel = cat(2, data_devel, devel_geom_data);

valid_ids_devel = valid_ids_devel & devel_success;
data_devel = data_devel(valid_ids_devel,:);
labels_devel = labels_devel(valid_ids_devel,:);
raw_devel = raw_devel(valid_ids_devel,:);
devel_success = devel_success(valid_ids_devel,:);
devel_ids = devel_ids(valid_ids_devel);

if(numel(train_users) > 0)
    train_appearance_data = bsxfun(@times, bsxfun(@plus, train_appearance_data, -means_norm), 1./stds_norm);

    data_train = train_appearance_data * PC;
    data_train = cat(2, data_train, train_geom_data);
else
    data_train = [];
end

geom_size = max(size(train_geom_data, 2), size(devel_geom_data, 2));

PC_n = zeros(size(PC)+geom_size);
PC_n(1:size(PC,1), 1:size(PC,2)) = PC;
PC_n(size(PC,1)+1:end, size(PC,2)+1:end) = eye(geom_size);
PC = PC_n;

means_norm = cat(2, means_norm, zeros(1, geom_size));
stds_norm = cat(2, stds_norm, ones(1, geom_size));

end


function [sumD] = mesh_fit_elec_optim(SUMD,scalp,elec)

% mesh_fit_elec_optim - optimise the fitting of electrodes to scalp vertices
%
% This function is in development.  It needs rotations and
% translations of elec vertices to fit those of the scalp
% vertices and a minimisation function for the difference
% between the vertex locations of the nearest scalp vertices
% and those of the electrodes.

% $Revision: 1.1 $ $Date: 2009-04-28 22:13:57 $

% Licence:  GNU GPL, no implied or express warranties
% History:  09/2002, Darren.Weber_at_radiology.ucsf.edu
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fprintf('Still in development\n'); return

% Rotations/translations/scaling here???

[k,d] = dsearchn(scalp,elec);

sumD = sum(d) - SUMD;

return


function [gb_thin_CSG, gb_thin_CS, gb_fat_CS, texton] = simpleGPb(I)

% place the current directory on the top of paths (so rgb2lab in this
% directory will get called when needed)
curr_dir = fileparts(which(mfilename));
rmpath(curr_dir);
addpath(curr_dir);

[gb_thin_CSG, gb_thin_CS, gb_fat_CS] = Gb_CSG(I);
texton = genTexton(I);
gb_thin_CSG = uint8(round(255*gb_thin_CSG));
gb_thin_CS = uint8(round(255*gb_thin_CS));
gb_fat_CS = 255*gb_fat_CS;
texton = uint8(texton);

end


clear

Extract_table_results_49
%%
scrsz = get(0,'ScreenSize');
figure1 = figure('Position',[20 50 3*scrsz(3)/4 0.9*scrsz(4)]);

set(figure1,'Units','Inches');
pos = get(figure1,'Position');
set(figure1,'PaperPositionMode','Auto','PaperUnits','Inches','PaperSize',[pos(3), pos(4)])

% Create axes
axes1 = axes('Parent',figure1,'FontSize',40,'FontName','Helvetica');

line_width = 6;
hold on;

[error_x, error_y] = cummErrorCurve(ceclm_error);
plot(error_x, error_y, 'r','DisplayName', 'OpenFace 2.0', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(clnf_error);
plot(error_x, error_y, 'DisplayName', 'OpenFace', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(cfss_error);
plot(error_x, error_y, 'DisplayName', 'CFSS', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(sdm_error);
plot(error_x, error_y, 'DisplayName', 'SDM', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(pocr_error);
plot(error_x, error_y,'DisplayName', 'PO-CR', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(cfan_error);
plot(error_x, error_y,'DisplayName', 'CFAN', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(tcdcn_error);
plot(error_x, error_y,'DisplayName', 'TCDCN', 'LineWidth',line_width);

[error_x, error_y] = cummErrorCurve(error_3ddfa);
plot(error_x, error_y,'DisplayName', '3DDFA', 'LineWidth',line_width);

set(gca,'xtick',[0:0.02:0.10])
xlim([0.02,0.10]);
xlabel('Size normalised MSE','FontName','Helvetica');
ylabel('Proportion of images','FontName','Helvetica');
grid on
% title('Fitting in the wild without outline','FontSize',60,'FontName','Helvetica');

leg = legend('show', 'Location', 'SouthEast');
set(leg,'FontSize',40)

print -dpdf results/Janus-no-outline.pdf
print -dpng results/Janus-no-outline.png


% example8_10.m
net1=competlayer(40);
load simpleclass_dataset
net2=newsom(simpleclassInputs,[5 8]);
view(net1)
view(net2)

web -broswer http://www.ilovematlab.cn/forum-222-1.html


function [Oq,Oqval,DEOPA,goodperiods] = OP(simppeak,SIG,dSIG,valid,doublepeaks,COEF,resampC,Ts,method)
% OP: Opening Peaks detection.
% Input files:
% - <simppeak>: contains a list of closing-peak times in ms, and amplitudes
% (<simppeak> is a 2-column matrix)
% - <dSIG>: Derivative of EGG signal
% - <valid> : vector containing information on peaks that have several summits
% - <doublepeaks>: vector containing information on peaks that cluster together
% - <COEF>: contains, among other coefficients, the smoothing step chosen by the
% user. It is not used in analyzing the positive part of the signal, only in the
% negative part, for the calculation of Oq.
% - <resampC>: coefficient for reinterpolation
% - <Ts>: the inverse of the sampling rate
% - <method>: indication on the method which is to be used in the handling of
% double / multiple peaks: selecting either the first or the highest.
% (The fact that there is not one single peak will also be passed on
% to the following functions, so this choice is not of much consequence.)
%
% Output files:
% <Oq>: vector containing open quotient values detected using the maxima
% <Oqval>: open quotient values computed by peak detection (single peaks only)
% <DEOPA>: vector containing DEOPA values
% <SM>, for Success of Method: variable indicating the number of Oq values that
% could be calculated using peak detection.
% <goodperiods>: beginning and end of cycles for which closing peaks are unique.
% <validGOI>: ratio of highest to second highest peak.
%
% No use of autocorrelation or comparison across cycles, otherwise the method
% would not give results up to the end of voicing: border phenomena.
% Passages where voice quality changes quickly are not found only at the offset
% of voicing: they can be word-internal, as in the case of consonantal glottal
% stops, ejectives, implosives, or glottalized tones, e.g. in Vietnamese tone
% C2, which has medial glottal constriction.
%
% Method: detecting maxima; checking the plausibility of results; if results are
% implausible, detecting maxima anew with increased smoothing step

% Setting the output vector Oqval at []; otherwise, in case no single period has
% single closing and opening peaks, this output argument is not assigned during
% call to OP.
Oqval = [];

% creating a matrix containing the beginning and end of periods for which Oq
% will be calculated. Values are converted to indices.
goodperiods = [];

if ~isempty(simppeak)
    if length(simppeak(:,1)) > 1
        for i = 1: length(simppeak(:,1)) - 1
            goodperiods(i,1) = round(simppeak(i,1) * (1 / Ts));
            goodperiods(i,2) = round(simppeak(i + 1,1) * (1 / Ts));
        end

        % Previous calculation method: eliminating periods for which closing peaks are
        % not unique:
        % %%%%%%%%%%%%%%%%%%%%%% Determining periods for which closings are unique
        % % Open quotient measurements are attempted only when closings are unique. For
        % % each glottal cycle, there are two condition:
        % % 1) that the values associated to the peak in <valid> be
        % % above 0.6, i.e. within the peak there is no other summit that is higher than
        % % 60% of the highest summit
        % % 2) that none of the neighbouring peaks be higher than 60% of the candidate peak.
        %
        % goodperiods = [];
        % for i = 1:length(valid) - 1
        %     if (doublepeaks(i) == 0) & (valid(i) < 0.6) & (doublepeaks(i + 1) == 0) & (valid(i) < 0.6)
        %         goodperiodsnb = goodperiodsnb + 1;
        %         goodperiods(goodperiodsnb,1) = Tgci(i,1);
        %         goodperiods(goodperiodsnb,2) = Tgci(i + 1,1);
        %     end
        % end

        %%%%%%%%%%%%%%%%%%%%%% First measurement of openings: done by detecting
        %%%%%%%%%%%%%%%%%%%%%% local minima, without any condition on the values obtained.
        texis = exist('goodperiods');
        if texis == 1
            if length(goodperiods(:,1)) > 0
                for i = 1:length(goodperiods(:,1))
                    % A rounding of the indices is necessary: as there has been
                    % reinterpolation, the values are not integers.
                    [DEOPA(i),GOI(i)] = min(    dSIG( round(goodperiods(i,1)):round(goodperiods(i,2) ))   );
                    % correction: adding the index corresponding to the first point of the
                    % excerpt
                    GOI(i) = GOI(i) + goodperiods(i,1);
                    %% Calculation of Oq, in %
                    Oq(i) = 100 * ((  goodperiods(i,2) - GOI(i)  ) / (  goodperiods(i,2) - goodperiods(i,1)  ));
                end
        %     else
        %         DEOPA = 0;
        %         GOI = 0;
        %         Oq = 0;
            end
        end

        %%%%%%%%%%%%%%%%%%%%%%%% Measurement by peak detection and barycentre calculation
        texis = exist('goodperiods');
        if texis == 1
            if length(goodperiods(:,1)) > 0
                for i = 1:length(goodperiods(:,1))
                    % if you want to see information displayed as analysis is being
                    % conducted, uncomment the two lines below:
                    %% disp(['Treating period number ',num2str(i)])
                    %% disp(goodperiods(i,:))
                    % placing the indices of beginning and end of the relevant portion of
                    % the signal in variables
                    % A rounding of the indices is necessary: as there has been
                    % reinterpolation, the values are not integers. In the present state of
                    % the programme, this rounding is performed earlier, when the
                    % <goodperiods> matrix is built up.
                    BE = goodperiods(i,1);           % BEginning of period
                    EN = goodperiods(i,2);           % ENd of period
                    % placing the extract in a vector, inverting it because CRO operates on
                    % a positive signal. An extra precaution must be taken: excluding the
                    % first and last eight points of the signal (by setting them at zero):
                    % it is physically impossible that a clear opening will take place
                    % at these points, so close to the closing; technically, a small part of
                    % the signal immediately before the closing peak that marks the
                    % beginning of the period (res. after the closing peak that marks its
                    % end) may be included and result in program crash.
                    dSIGextr = - dSIG(BE:EN);
                    L = length(dSIGextr);
                    if L > 16
                        dSIGextr(1:8) = 0;
                        dSIGextr(L-7:L) = 0;
                    end
                    % Also creating an extract for the EGG signal, which is used later on,
                    % by AMPOS
                    SIGextr = - SIG(BE:EN);

                    %%%%%%%%%%%%%%%%%% Calling the function CRO to detect crossings.
                    % The <method> toggle (3rd value in <COEF>) must be set at 0, and the
                    % amplitude threshold (4th value in <COEF>) passed on to the function.
                    COEFOPEN = COEF;
                    COEFOPEN(3) = 0;

                    % setting the threshold for peak detection (empirically). Choice in
                    % Henrich 2001:123 : setting it at 70% of the highest point.
                    COEFOPEN(4) = 0.70 * max(dSIGextr);

                    % finding out the crossings with the DEGG signal. In the best cases, it is
                    % expected that there will be only two crossings, one up and one down.
                    % But this is not frequent: the signal is often dented.
                    [rimsOPEN] = CRO(dSIGextr,COEFOPEN);

                    if isempty(rimsOPEN)
                        % If there is no single detected threshold crossing: the user should
                        % changed the maximum F0 value and ask for the results to be
                        % calculated anew. The user is advised to do so inside the <rim>
                        % function.
                        Oqval(i) = 0;
                        DEOPA(i) = 0;
                    else
                        % finding out the amplitude and position of the peaks. No
                        % reinterpolation of the signal is useful, as the signal-to-noise ratio in
                        % the negative part of the DEGG signal is poor. Quite the opposite: the
                        % signal is smoothed (over 3 samples, i.e. 0.07 ms).

                        % The threshold for exclusion of small peaks is set at 0.7 in the case of
                        % opening peaks, following Henrich 2001:123. This has in fact already
                        % been applied before, in detection of peak rims by RIM; but the
                        % function PEAKSHAPE called by AMPOS needs this input.
                        propthresh = 0.7;
                       % figure(1)
                       % clf
                       % plot(SIGextr)
                        [TGOI,TGOIFo,validGOI,validtimeGOI] = AMPOS(SIGextr,rimsOPEN,1,Ts,method,propthresh);

                        % detection of double / multiple closing peaks ("peak clusters"). The
                        % threshold passed to this function is: (the inverse of) one-fifth of
                        % the period, under the assumption that peaks separated by more than
                        % one-fifth of the period should not be considered as a bundle. In these
                        % cases, no Oq is calculated.
                        maxF = 1 / ( (goodperiods(i,2) - goodperiods(i,1)) / 5);
                        doublepeaks = detectmult(TGOI,maxF);

                        % choice of opening peak, leaving only one, following the method
                        % specified by the user. If there are 2 peaks that are too far apart for
                        % averaging to make sense, there will be 2 lines in simppeak: two "real
                        % peaks" according to the criteria used in the SIMP function.
                        [simppeak,BUND] = simp(TGOI,doublepeaks,method);

                        % calculating the open quotient when possible. The condition is: if
                        % there is one single value in <simppeak>, the matrix where detected
                        % peaks are stored. If there are two (or more) values, this indicates
                        % that there were two (or more) peaks that were too far apart for
                        % averaging to make sense, and it seems best not to give an Fo value;
                        % the Oq value is then set at zero. This is also what happens if it
                        % remains unaffected: it comes out as a zero inside the vector; but if
                        % the last values are zero, then the length of the vector is less than
                        % the size of the Fo vector, resulting in assignment problems. So the
                        % value is set at zero in this programme.
                        % inside the vector).
                        if length(simppeak(:,1)) == 1
                            % transforming the time of peak to an index
                            indexsimppeak = simppeak(1,1) * (1 / Ts);
                            Oqval(i) = 100 * (       ((goodperiods(i,2) - goodperiods(i,1)) - indexsimppeak ) / ...
                                  (goodperiods(i,2) - goodperiods(i,1))       );
                        else
                              Oqval(i) = 0;
                        end
                    % end of "if" loop: condition on existence of rimsOPEN values.
                    end
                end
            end
        end
    else
        goodperiods = []; Oq = []; Oqval = []; DEOPA = [];
    end
else
    goodperiods = []; Oq = []; Oqval = []; DEOPA = [];
end
        %%%%%%%%%%% The method for detecting opening peaks is fairly similar to
        %%%%%%%%%%% that for detecting closing peaks. Concerning the detection
        %%%%%%%%%%% of multiple peaks, however, in the case of closing peaks
        %%%%%%%%%%% the threshold for detection was set rather low, and the
        %%%%%%%%%%% peaks were later sorted according to size and closeness to
        %%%%%%%%%%% one another. In the case of opening peaks, the period is
        %%%%%%%%%%% known already, so the threshold is fixed straight away,
        %%%%%%%%%%% on the basis of the highest point in this part of the
        %%%%%%%%%%% signal: if the second highest peak is 70% as high as the
        %%%%%%%%%%% highest peak, it is decided that the peak is not unique
        %%%%%%%%%%% (following Henrich 2001:123).

        %%%%%%%%%%% It is an issue whether this threshold must apply
        %%%%%%%%%%% within the peak region as well as in the comparison of
        %%%%%%%%%%% neighbouring peaks. The fine detail of the peak is often
        %%%%%%%%%%% slightly dented (see figures); this will result in
        %%%%%%%%%%% "secondary peaks" being detected very close to the maximum
        %%%%%%%%%%% (about 0.1 ms to its left and right). A time condition could
        %%%%%%%%%%% be added: if the secondary peak is very close
        %%%%%%%%%%% (threshold empirically set at a time value, e.g. 0.5 ms, or
        %%%%%%%%%%% as a proportion of the period), it would not count as
        %%%%%%%%%%% a doubled peak. In the present programme, the solution
        %%%%%%%%%%% chosen instead is to use smoothing of the signal.

%         % In an earlier version, the algorithm was:
%         % 1) retrieve highest peak in TGOI; 2) check that it is unique
%         % internally; 3) check that the neighbouring peaks are less than 70% of its
%         % height. GOIC stands for Glottis-Opening-Instant Candidate.
%         % First step:
%         [GOICvalue,GOICindex] = max (TGOI(:,2));
%         % Second step: finding out whether the peak is unique internally. For
%         % this: look up the corresponding slot in vector <validtimeGOI>.
%         if validtimeGOI(GOICindex) < threshtime
%             % retrieving the index of maximum value in TGOI relative to the
%             % beginning of the <dSIGextr> extract: it is the value
%             % in the first column of <TGOI> at the line indicated in
%             % <GOICindex>
%             GOICindex = TGOI(GOICindex,1);
%             % changing the relative index <GOICindex> into an index relative
%             % to the <SIG> signal as a
%             % whole, for computation of the open quotient
%             GOICindex = GOICindex + goodperiods(i,1);
%             % calculation of open quotient
%             Oqval(i) = 100 * (       (goodperiods(i,2) - GOICindex ) / ...
%                 (goodperiods(i,2) - goodperiods(i,1))       );
%         end

            %%%%%%%%%%% Note:
            %% In the first version of the programme, the threshold for detection
            %% of peak regions was first set at 40% of the signal, and the
            %% condition on peak amplitude was added later, by recovering the
            % second highest peak in TGOI and
            % comparing its amplitude to that of the highest peak.
            %% In the present version of the function, only the peaks above 70% of the maximum
            %% within the dSIG extract <dSIGextr> are detected, so that
            %% this part of the function is not necessary anymore.
            %% The calculations were as follows:

%             COEFOPEN(4) = 0.7 * max(dSIGextr);
%             % Setting value for TGOI(GOICindex,2) at zero and re-calculating the
%             % maximum:
%             TGOI(GOICindex,2) = 0;
%             [GOICvalue2,GOICindex2] = max (TGOI(:,2));
%             % condition on whether the proportion of the two peaks is below
%             % threshold
%             if GOICvalue2 / GOICvalue < threshGOI
%                 % retrieving the index of maximum value in TGOI: it is the value
%                 % in the first column of <TGOI> at the line indicated in
%                 % <GOICindex>
%                 GOICindex = TGOI(GOICindex,1);
%                 % changing the relative index <GOICindex> into an index relative
%                 % to the <SIG> signal as a
%                 % whole, for computation of the open quotient
%                 GOICindex = GOICindex + goodperiods(i,1);
%                 % calculation of open quotient
%                 Oqval(i) = 100 * (       (goodperiods(i,2) - GOICindex ) / ...
%                     (goodperiods(i,2) - goodperiods(i,1))       );
%             end


function evalPCK_multi(expidxs,bUseHeadSize,bHeadSizeFromRect,bTrain)

fprintf('evalPCK()\n');

if (nargin < 2)
    bUseHeadSize = true;
end

if (nargin < 3)
    bHeadSizeFromRect = false;
end

if (nargin < 4)
    bTrain = false;
end

if (bUseHeadSize)
    prefix = 'pck-head-';
    range = 0:0.01:0.5;
else
    prefix = 'pck-torso-';
    range = 0:0.01:0.2;
end

if (bTrain)
    prefix = [prefix 'train-'];
end

if bTrain
    image_set = 'train';
else
    image_set = 'test';
end

legendName = cell(0);

[~,parts] = util_get_parts24();
jidxsUpperBody = 7:12;
nJoints = 14;
% nJoints = length(p.cidxs);
for expidx = expidxs
    fprintf('**********************************************************************************\n');
    % load experiment parameters
    p = exp_params(expidx);

    % load ground truth
    if (~bTrain)
        load(p.testGT);
    else
        load(p.trainGT);
        annolist = annolist(1:17000);
    end

    if (~exist('annolist','var'))
        annolist = single_person_annolist;
    end
    annolist_gt = annolist;%(1:100)

    if (~exist(p.outputDir,'dir')), mkdir(p.outputDir); end
    fnameEvalRes = [fileparts(p.outputDir) '/evalAll'];

    clear boxes boxes_nonms image_ids keypointsAll;

    if (~exist(p.latexDir,'dir')), mkdir(p.latexDir); end
    if (~exist(p.plotsDir,'dir')), mkdir(p.plotsDir); end

%     assert(length(p.pidxs) == nJoints);
%     assert(length(p.cidxs) == nJoints);

    if (~isfield(p,'bidxs'))
        bidxs = 1:length(p.pidxs)+1;
    else
        bidxs = p.bidxs;
    end

    % Load keypoints
    fn = fullfile(p.exp_dir, image_set, 'keypointsAll.mat');
    if exist(fn, 'file') ~= 2
        scoremaps2keypoints(expidx, image_set);
    end
    fprintf('loading %s\n', fn);
    load(fn, 'keypointsAll');

%     visBoxes(annolist_gt,keypointsAll,p.pidxs,parts);
    nrects = 0;
    for imgidx = 1:length(annolist_gt)
        nrects = nrects + length(annolist_gt(imgidx).annorect);
    end

    distAll = nan(nrects,nJoints);
    accAll = zeros(length(range),nJoints+2);

    for i = 1:length(p.pidxs)
      pidx = p.pidxs(i);
      % part is a joint
      assert(parts(pidx+1).pos(1) == parts(pidx+1).pos(2));
      jidx = parts(pidx+1).pos(1);

      % compute distance to the ground truth jidx
      distAll(:,i) = getNormGTJointDistMulti(keypointsAll,annolist_gt,jidx,bUseHeadSize,bHeadSizeFromRect,jidx,nrects);
    end
    matchPCK = double(distAll <= range(end));

    totalPCK = zeros(size(matchPCK,1),1);
    nCorrect = zeros(size(matchPCK,1),1);
    for imgidx = 1:length(totalPCK)
      idxs = ~isnan(distAll(imgidx,:));
%       idxs = ~isnan(matchPCK(imgidx,:));
      totalPCK(imgidx) = sum(matchPCK(imgidx,idxs))/sum(idxs);
%       totalPCK(imgidx) = sum(matchPCK(imgidx,idxs))/length(idxs);
      nCorrect(imgidx) = sum(matchPCK(imgidx,idxs));
    end

    for i = 1:length(p.pidxs)
      dist = distAll(:,i);
      % remove the cases without the ground truth
      dist(isnan(dist)) = [];
      % compute accuracy for each threshold
      for k = 1:numel(range)
        accAll(k,i) = 100*mean(dist<=range(k));
      end
    end

    % compute avg PCKh upper body
    dist = reshape(distAll(:,jidxsUpperBody),size(distAll,1)*length(jidxsUpperBody),1);
    dist(isnan(dist)) = [];
    for k = 1:numel(range)
      accAll(k,end-1) = 100*mean(dist<=range(k));
    end

    % compute avg PCKh full body
    dist = reshape(distAll,size(distAll,1)*size(distAll,2),1);
    dist(isnan(dist)) = [];
    for k = 1:numel(range)
      accAll(k,end) = 100*mean(dist<=range(k));
    end

    pidxs = p.pidxs;
%     save(fnameEvalRes,'distAll','accAll','pidxs','keypointsAll','matchPCK');

    auc = area_under_curve(scale01(range),accAll(:,end));
    legendName{end+1} = sprintf('%s, AUC: %1.1f%%', p.name, auc);

    tableFilename = [p.latexDir '/' prefix 'expidx' num2str(expidx) '.tex'];
    [row, header] = genTableNew(accAll(end,:),auc,p.name);
    row = strrep(row,'NaN','-');
    fid = fopen(tableFilename,'wt');assert(fid ~= -1);
    fprintf(fid,'%s\n',row{1});fclose(fid);
    fid = fopen([p.latexDir '/' prefix 'header.tex'],'wt');assert(fid ~= -1);
    fprintf(fid,'%s\n',header);fclose(fid);

%     fprintf('%s\n',legendName{end});
end

end


% STD_DIPPLOT - Commandline function to plot cluster component dipoles. Dipoles for each
%                 named cluster is displayed in a separate figure. To view all the clustered
%                 components in the STUDY on the same figure (in a separate subplot), all
%                 STUDY clusters must be requested.
%                 To visualize dipoles, they first must be stored in the EEG dataset structures
%                 using DIPFIT. Only components that have dipole locations will be displayed,
%                 along with the cluster mean dipole (in red).
% Usage:
%                 >> [STUDY] = std_dipplot(STUDY, ALLEEG, clusters);
% Inputs:
%   STUDY      - EEGLAB STUDY set comprising some or all of the EEG datasets in ALLEEG.
%   ALLEEG     - global EEGLAB vector of EEG structures for the dataset(s) included in
%                the STUDY. ALLEEG for a STUDY set is typically created using LOAD_ALLEEG.
%
% Optional inputs:
%   'clusters' - [numeric vector | 'all']  -> specific cluster numbers to plot.
%                'all'  -> plot all clusters in STUDY.
%                {default: 'all'}.
%   'comps'    - [numeric vector]  -> indices of the cluster components to plot.
%                'all'  -> plot all the components in the cluster
%                {default: 'all'}.
%   'mode'     - ['together'|'apart'|'multicolor'] Display all requested cluster on one
%                figure ('together') or separate figures ('apart').
%                'together'-> plot all 'clusters' individually in one multi-pane figure (without the gui).
%                'apart'   -> plot each cluster in a separate figure.
%                'multicolor' -> plot all clusters in one figure,
%                Note that this parameter has no effect if the 'comps' option (above) is used.
%                {default: 'together'}
%   'figure'   - ['on'|'off'] plots on a new figure ('on')  or plots on current
%                figure ('off'). If 'figure','off' does not display gui controls,
%                Useful for incomporating a cluster dipplot into a complex figure.
%                {default: 'on'}.
%   'groups'   - ['on'|'off'] use different colors for different groups.
%                {default: 'off'}.
%   'dipcolor' - [cell vector] color for dipoles in each cluster. (multicolor mode)
%   'dipsize'  - [numeric vector] size for each cluster. (multicolor mode)
%                {default if unspecified: will automatically color/size each
%                cluster}
% Outputs:
%   STUDY      - the input STUDY set structure modified with plotted cluster
%                mean dipole, to allow quick replotting (unless cluster means
%                already exists in the STUDY).
%   Example:
%   >> [STUDY] = std_dipplot(STUDY,ALLEEG, 'clusters', 5, 'mode', 'apart', 'figure', 'off');
%                % Plot cluster-5 component dipoles (in blue), plus their mean dipole (in red),
%                % on an existing (gui-less) figure.
%
%  See also  POP_CLUSTEDIT, DIPPLOT
%
% Authors:  Hilit Serby, Arnaud Delorme, Scott Makeig, SCCN, INC, UCSD, June, 2005
%          'groups' added by Makoto Miyakoshi on June 2012.
%          'multicolor' mode added by John Iversen to draw all clusters on
%           a single panel, with each cluster indicated by different color/size dipoles.

% Copyright (C) Hilit Serby, SCCN, INC, UCSD, June 08, 2005, hilit@sccn.ucsd.edu
%
% 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.

function STUDY = std_dipplot(STUDY, ALLEEG, varargin)

% Set default values
cls = []; % plot all clusters in STUDY
figureon = 1; % plot on a new figure
mode = 'apart';

STUDY = pop_dipparams(STUDY, 'default');

opt_dipplot = {'projlines',STUDY.etc.dipparams.projlines, 'axistight', STUDY.etc.dipparams.axistight, 'projimg', STUDY.etc.dipparams.projimg, 'dipolelength', 0, 'density', STUDY.etc.dipparams.density};

dipcolor = [];
dipsize = [];
%, 'spheres', 'on'
groupval = 'off';
nosphere = true;
for k = 3:2:nargin
    switch varargin{k-2}
        case 'clusters'
            if isnumeric(varargin{k-1})
                cls = varargin{k-1};
                if isempty(cls)
                    cls = 2:length(STUDY.cluster);
                end
            else
                if ischar(varargin{k-1}) && strcmpi(varargin{k-1}, 'all')
                    cls = 2:length(STUDY.cluster);
                else
                    error('std_dipplot: ''clusters'' input takes either specific clusters (numeric vector) or keyword ''all''.');
                end
            end
            if length(cls) == 1, mode = 'apart'; else mode = 'together'; end
        case 'comps'
            if strcmpi(STUDY.etc.dipparams.density, 'on')
                disp('Single dipole should not be plotted using dipole density, reverting to dipole plotting');
                opt_dipplot{end} = 'off';
            end
            STUDY = std_plotcompdip(STUDY, ALLEEG,  cls, varargin{k-1}, opt_dipplot{:});
            return;
        case 'plotsubjects', % do nothing
        case 'mode', mode = varargin{k-1};
        case 'groups', groupval = varargin{k-1};
        case 'figure'
            if strcmpi(varargin{k-1},'off')
                if strcmpi(STUDY.etc.dipparams.density, 'on')
                    disp('Cannot plot dipole density within figure, reverting to dipole plotting');
                    opt_dipplot{end} = 'off';
                end
                opt_dipplot{end + 1} = 'gui';
                opt_dipplot{end + 1} = 'off';
                figureon = 0;
            end
      case 'dipcolor'
        dipcolor = varargin{k-1};
      case 'dipsize'
        dipsize = varargin{k-1};
      case 'spheres'
        opt_dipplot = { opt_dipplot{:}, 'spheres',  varargin{k-1} };
        nosphere = false;
    end
end
if nosphere
    opt_dipplot = { opt_dipplot{:}, 'spheres', 'on' };
end

if strcmpi(mode, 'together')
    if strcmpi(STUDY.etc.dipparams.density, 'on')
        disp('Cannot plot dipole density within figure, reverting to dipole plotting');
        opt_dipplot{end} = 'off';
    end
end

% select clusters to plot
% -----------------------
if isempty(cls)
    tmp =[];
    cls = 2:length(STUDY.cluster); % plot all clusters in STUDY
    for k = 1: length(cls)
        % don't include 'Notclust' clusters
        if ~strncmpi('Notclust',STUDY.cluster(cls(k)).name,8) && ~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13)
            tmp = [tmp cls(k)];
        end
    end
    cls = tmp;
end

if strcmpi(mode, 'apart')  % case each cluster on a separate figure
    for clus = 1: length(cls) % For each cluster requested
        if length(STUDY.cluster(cls(clus)).comps) > 0  % check there are comps in cluster
            max_r = 0;
            clear cluster_dip_models;
            len = length(STUDY.cluster(cls(clus)).comps);
            ndip = 0;
            dip_ind = [];
            if ~isfield(STUDY.cluster(cls(clus)),'dipole')
                STUDY = std_centroid(STUDY,ALLEEG, cls(clus) , 'dipole');
            elseif isempty(STUDY.cluster(cls(clus)).dipole)
                STUDY = std_centroid(STUDY,ALLEEG, cls(clus) , 'dipole');
            end
            for k = 1:len
                abset   = STUDY.datasetinfo(STUDY.cluster(cls(clus)).sets(1,k)).index;
                subject = STUDY.datasetinfo(STUDY.cluster(cls(clus)).sets(1,k)).subject;
               if ~isfield(ALLEEG(abset), 'dipfit')
                   warndlg2(['No dipole information available in dataset ' ALLEEG(abset).filename ' , abort plotting'], 'Aborting plot dipoles');
                   return;
               end
               comp = STUDY.cluster(cls(clus)).comps(k);
               cluster_dip_models(k).posxyz = ALLEEG(abset).dipfit.model(comp).posxyz;
               cluster_dip_models(k).momxyz = ALLEEG(abset).dipfit.model(comp).momxyz;
               cluster_dip_models(k).rv = ALLEEG(abset).dipfit.model(comp).rv;
               if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
                   if isfield(ALLEEG(abset).dipfit, 'hdmfile') %dipfit 2 spherical model
                       load('-mat', ALLEEG(abset).dipfit.hdmfile);
                       max_r = max(max_r, max(vol.r));
                   else % old version of dipfit
                       max_r = max(max_r,max(ALLEEG(abset).dipfit.vol.r));
                   end
               end
               comp_to_disp{k} = [subject  ', ' 'IC' num2str(comp) ];
               if ~isempty(cluster_dip_models(k).posxyz)
                   ndip = ndip +1;
                   dip_ind = [dip_ind k];
               end
            end % finished going over cluster comps

            STUDY.cluster(cls(clus)).dipole = computecentroid(cluster_dip_models);
            cluster_dip_models(end + 1) = STUDY.cluster(cls(clus)).dipole;

           % additional options
           % ------------------
           dip_color = cell(1,ndip+1);
           dip_color(1:ndip) = {'b'};
           dip_color(end) = {'r'};
           options = opt_dipplot;
           options{end+1} =  'mri';
           options{end+1} =  ALLEEG(abset).dipfit.mrifile;
           options{end+1} =  'coordformat';
           options{end+1} =  ALLEEG(abset).dipfit.coordformat;
           options{end+1} =  'dipnames';
           options{end+1} = {comp_to_disp{dip_ind } [STUDY.cluster(cls(clus)).name ' mean']};
           options{end+1} = 'color';
           options{end+1} = dip_color;

           % if 'groups'==1, overwrite cluster_dip_models, dip_color and dipnames in option -makoto
           if strcmpi(groupval, 'on')
               [cluster_dip_models, options] = dipgroups(ALLEEG, STUDY, cls, comp_to_disp, cluster_dip_models, options);
               break
           end

           if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
               options{end+1} = 'sphere';
               options{end+1} = max_r;
           else
               options{end+1} = 'meshdata';
               options{end+1} = ALLEEG(abset).dipfit.hdmfile;
           end
           %enable both lines and images to be projected; increase #dipole limits
           if ndip < 20 && strcmpi(options{1}, 'projlines') && length(cls) == 1
               options{2} = 'on';
           end
           if ndip < 20 && strcmpi(options{5}, 'projimg') && length(cls) == 1
             options{6} = 'on';
           end

           % Dealing with projection lines
           if strcmpi(options{2},'on')
               projlinesvect = ones(1,length(cluster_dip_models));
           elseif strcmpi(options{2},'off') && strcmp(STUDY.etc.dipparams.centrline,'on')
               projlinesvect = zeros(1,length(cluster_dip_models));
               projlinesvect(end) = 1;
           elseif strcmpi(options{2},'off')
               projlinesvect = zeros(1,length(cluster_dip_models));
           end
           options{2} = projlinesvect;

           if figureon
               dipplot(cluster_dip_models, options{:});
               fig_h = gcf;
               set(fig_h,'Name', [STUDY.cluster(cls(clus)).name ' - ' num2str(length(unique(STUDY.cluster(cls(clus)).sets(1,:)))) ...
                       ' sets - ' num2str(length(STUDY.cluster(cls(clus)).comps)) ' components (' num2str(ndip) ' dipoles)' ],'NumberTitle','off');
           else
               dipplot(cluster_dip_models, options{:},'view', [0.5 -0.5 0.5]);
               for gind = 1:length(options) % remove the 'gui' 'off' option
                   if ischar(options{gind})
                       if strfind(options{gind}, 'gui')
                           break;
                       end
                   end
               end
               options(gind:gind+1) = [];
               dipinfo.dipmod =  cluster_dip_models;
               dipinfo.op = options;
               diptitle = [STUDY.cluster(cls(clus)).name ', ' num2str(length(unique(STUDY.cluster(cls(clus)).sets(1,:)))) ' sets -' ...
                   num2str(length(STUDY.cluster(cls(clus)).comps)) ' components (' num2str(ndip) ' dipoles)' ];
               dipinfo.title = diptitle;
               set(gcf, 'UserData', dipinfo);
               set(gca,'UserData', dipinfo);
               rotate3d off;
               axcopy(gca, ['dipinfo = get(gca, ''''UserData''''); dipplot(dipinfo.dipmod, dipinfo.op{:}); set(gcf, ''''Name'''', dipinfo.title,''''NumberTitle'''',''''off''''); ']);
           end
        end % finished the if condition that cluster isn't empty
    end % finished going over requested clusters
end

if strcmpi(mode, 'together')  % case all clusters are plotted in the same figure (must be a new figure)
    N = length(cls);
    rowcols(2) = ceil(sqrt(N)); % Number of rows in the subplot figure.
    rowcols(1) = ceil(N/rowcols(2));
    fig_h = figure;
    orient tall
    set(fig_h,'Color', 'black');
    set(fig_h,'Name', 'All clusters dipoles','NumberTitle','off');
    set(fig_h, 'resize','off');
    for l = 1:N
        len = length(STUDY.cluster(cls(l)).comps);
        max_r = 0;
        clear cluster_dip_models;
        if ~isfield(STUDY.cluster(cls(l)),'dipole')
            STUDY = std_centroid(STUDY,ALLEEG, cls(l), 'dipole');
        elseif isempty(STUDY.cluster(cls(l)).dipole)
            STUDY = std_centroid(STUDY,ALLEEG, cls(l), 'dipole');
        end
        for k = 1: len
            abset = STUDY.datasetinfo(STUDY.cluster(cls(l)).sets(1,k)).index;
           if ~isfield(ALLEEG(abset), 'dipfit')
               warndlg2(['No dipole information available in dataset ' num2str(abset) ' , abort plotting'], 'Aborting plot dipoles');
               return;
           end
           comp = STUDY.cluster(cls(l)).comps(k);
           cluster_dip_models(k).posxyz = ALLEEG(abset).dipfit.model(comp).posxyz;
           cluster_dip_models(k).momxyz = ALLEEG(abset).dipfit.model(comp).momxyz;
           cluster_dip_models(k).rv = ALLEEG(abset).dipfit.model(comp).rv;
           if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
                if isfield(ALLEEG(abset).dipfit, 'hdmfile') %dipfit 2 spherical model
                   load('-mat', ALLEEG(abset).dipfit.hdmfile);
                   max_r = max(max_r, max(vol.r));
               else % old version of dipfit
                   max_r = max(max_r,max(ALLEEG(abset).dipfit.vol.r));
               end
           end
        end % finished going over cluster comps
        STUDY.cluster(cls(l)).dipole = computecentroid(cluster_dip_models);
        cluster_dip_models(end + 1) = STUDY.cluster(cls(l)).dipole;
        dip_color = cell(1,length(cluster_dip_models));
        dip_color(1:end-1) = {'b'};
        dip_color(end) = {'r'};
        options = opt_dipplot;
        options{end + 1} =  'gui';
        options{end + 1} =  'off';
        options{end+1} =  'mri';
        options{end+1} =  ALLEEG(abset).dipfit.mrifile;
        options{end+1} =  'coordformat';
        options{end+1} =  ALLEEG(abset).dipfit.coordformat;
        options{end+1} = 'color';
        options{end+1} = dip_color;
        if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
            options{end+1} = 'sphere';
            options{end+1} = max_r;
        else
            options{end+1} = 'meshdata';
            options{end+1} = ALLEEG(abset).dipfit.hdmfile;
        end

        % Dealing with projection lines
        if strcmpi(options{2},'on')
            projlinesvect = ones(1,length(cluster_dip_models));
        elseif strcmpi(options{2},'off') && strcmp(STUDY.etc.dipparams.centrline,'on')
            projlinesvect = zeros(1,length(cluster_dip_models));
            projlinesvect(end) = 1;
        elseif strcmpi(options{2},'off')
            projlinesvect = zeros(1,length(cluster_dip_models));
        end
           options{2} = projlinesvect;

        hsbplot = subplot(rowcols(1),rowcols(2),l);
        % Creating new axis for title only
        set(hsbplot,'visible','off');
        htitle = title([ STUDY.cluster(cls(l)).name ' (' num2str(length(unique(STUDY.cluster(cls(l)).sets(1,:)))) ' Ss, ' num2str(length(STUDY.cluster(cls(l)).comps)),' ICs)'],'color','white','Visible', 'on');
        if rowcols(1)> 1, set(htitle,'Position', get(htitle,'Position')+ [0 0.05 0].*get(htitle,'Position') ); end
        axes('Position', get(hsbplot,'Position'),'Color', 'black');
        dipplot(cluster_dip_models, options{:});

        %diptitle = [STUDY.cluster(cls(l)).name ', ' num2str(length(unique(STUDY.cluster(cls(l)).sets(1,:)))) 'Ss'];
        %title(diptitle, 'Color', 'white');
        % Complex axcopy
        %if l == 1
        %    for gind = 1:length(options) % remove the 'gui' 'off' option
        %        if ischar(options{gind})
        %            if strfind(options{gind}, 'gui')
        %                break;
        %            end
        %        end
        %    end
        %    options(gind:gind+1) = [];
        %end
        %dipinfo.dipmod =  cluster_dip_models;
        %dipinfo.op = options;
        %dipinfo.title = diptitle;
        %set(gcf, 'UserData', dipinfo);
        %set(gca,'UserData', dipinfo);
        %axcopy(gcf, ['dipinfo = get(gca, ''''UserData''''); dipplot(dipinfo.dipmod, dipinfo.op{:}); set(gcf, ''''Name'''', dipinfo.title,''''NumberTitle'''',''''off'''');']);
   end %finished going over all clusters
   set(fig_h, 'resize','on');
end % finished case of 'all' clusters

% ========================================================================================
% multicolor mode
%   all clusters are plotted in the same axis, with each cluster indicated by color/size
%   also enable 'data cursor' so that in data tip mode, clicking on a dipole
%    will display its name
if strcmpi(mode, 'multicolor')
  N = length(cls);
  %%%%%%%%%%%%%%%%%%%%% color list %%%%%%%%%%%%%%%%%%%%%
  % This color list was developed for std_envtopo
  % modified from dipgroups below
  colors{1}  = [1 1 1];            % White
  colors{2}  = [1 1 0];            % Yellow
  colors{3}  = [1 0 1];            % Fuchsia
  colors{4}  = [1 0 0];            % Red
  colors{5}  = [0.875 0.875 0.875]; % Silver
  colors{6}  = [0.5 0.5 0.5];      % Gray
  colors{7}  = [0.5 0.5 0];        % Olive
  colors{8}  = [0.5 0 0.5];        % Purple
  colors{9}  = [0.5 0 0];          % Maroon
  colors{10} = [0 1 1];            % Aqua
  colors{11} = [0 1 0];            % Lime
  colors{12} = [0 0.5 0.5];        % Teal
  colors{13} = [0 0.5 0];          % Green
  colors{14} = [0 0 1];            % Blue
  colors{15} = [0 0 0.5];          % Navy
  colors{16} = [0 0 0];            % Black
  % Choosing and sorting 13 colors for clusters: Red, Green, Blue,
  % Fuchsia, Lime, Aqua, Maroon, Olive, Purple, Teal, Navy, Gray, and White
  colors = colors([4 13 14 3 11 10 9 7 8 12 15 6 1 ]);
  fig_h = figure;
  orient tall
  set(fig_h,'Color', 'black');
  set(fig_h,'Name', 'All clusters dipoles','NumberTitle','off');
  set(fig_h, 'resize','off');

  idx = 0; %cumulative dipole index
  centroidIdx = [];
  clear cluster_dip_models;
  for l = 1:N %loop over clusters
    len = length(STUDY.cluster(cls(l)).comps);
    max_r = 0;

    %color, size for every cluster can be passed as arguments, or
    %automatically iterate through a set of colors/sizes
    if ~isempty(dipcolor)
      clusterColors{l} = dipcolor{idx};
    else
      colorIndex = mod(l-1, length(colors))+1;
      clusterColors{l} = colors{colorIndex};
    end

    if ~isempty(dipsize)
      clusterSizes(l) = dipsize(idx);
    else
      %after rotating through color list once, change size of dipole
      if l <= length(colors)
        clusterSizes(l) = 30;
      elseif l <= 2*length(colors)
        clusterSizes(l) = 20;
      else
        clusterSizes(l) = 15;
      end
    end

    if ~isfield(STUDY.cluster(cls(l)),'dipole')
      STUDY = std_centroid(STUDY,ALLEEG, cls(l), 'dipole');
    elseif isempty(STUDY.cluster(cls(l)).dipole)
      STUDY = std_centroid(STUDY,ALLEEG, cls(l), 'dipole');
    end
    clustStartIdx = idx + 1;

    for k = 1:len %loop over components within a cluster
      idx = idx + 1;
      abset = STUDY.datasetinfo(STUDY.cluster(cls(l)).sets(1,k)).index;
      subjname = STUDY.datasetinfo(STUDY.cluster(cls(l)).sets(1,k)).subject;
      if ~isfield(ALLEEG(abset), 'dipfit')
        warndlg2(['No dipole information available in dataset ' num2str(abset) ' , abort plotting'], 'Aborting plot dipoles');
        return;
      end
      comp = STUDY.cluster(cls(l)).comps(k);
      cluster_dip_models(idx).posxyz = ALLEEG(abset).dipfit.model(comp).posxyz;
      cluster_dip_models(idx).momxyz = ALLEEG(abset).dipfit.model(comp).momxyz;
      cluster_dip_models(idx).rv = ALLEEG(abset).dipfit.model(comp).rv;
      if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
        if isfield(ALLEEG(abset).dipfit, 'hdmfile') %dipfit 2 spherical model
          load('-mat', ALLEEG(abset).dipfit.hdmfile);
          max_r = max(max_r, max(vol.r));
        else % old version of dipfit
          max_r = max(max_r,max(ALLEEG(abset).dipfit.vol.r));
        end
      end

      dip_color{idx} = clusterColors{l};
      dip_size(idx) = clusterSizes(l);
      dip_label{idx} = sprintf('Cls %d (%s IC%d)',cls(l), subjname, comp);
    end % finished going over cluster comps

    %add the cluster centroid
    clustEndIdx = idx;
    STUDY.cluster(cls(l)).dipole = computecentroid(cluster_dip_models(clustStartIdx:clustEndIdx));
    idx = idx + 1;
    centroidIdx(end+1) = idx;
    cluster_dip_models(idx) = STUDY.cluster(cls(l)).dipole;
    dip_color(idx) = {'k'};
    dip_size(idx) = 10;
    dip_label{idx} = sprintf('Cls %d centroid',cls(l));
    clusterLabels{l} = sprintf('Cls %d',cls(l));

  end %loop over clusters

  options = opt_dipplot;
  options{end + 1} =  'gui';
  options{end + 1} =  'off';
  options{end+1} =  'mri';
  options{end+1} =  ALLEEG(abset).dipfit.mrifile;
  options{end+1} =  'coordformat';
  options{end+1} =  ALLEEG(abset).dipfit.coordformat;
  options{end+1} = 'color';
  options{end+1} = dip_color;
  options{end+1} = 'dipolesize';
  options{end+1} = dip_size;
  options{end+1} = 'dipnames';
  options{end+1} = dip_label;
  if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
    options{end+1} = 'sphere';
    options{end+1} = max_r;
  else
    options{end+1} = 'meshdata';
    options{end+1} = ALLEEG(abset).dipfit.hdmfile;
  end

  % Dealing with projection lines
  if strcmpi(options{2},'on')
      projlinesvect = ones(1,length(cluster_dip_models));
  elseif strcmpi(options{2},'off') && strcmp(STUDY.etc.dipparams.centrline,'on')
      projlinesvect = zeros(1,length(cluster_dip_models));
      projlinesvect(centroidIdx) = 1;
  elseif strcmpi(options{2},'off')
      projlinesvect = zeros(1,length(cluster_dip_models));
  end
  options{2} = projlinesvect;

  dipplot(cluster_dip_models, options{:});
  set(fig_h, 'resize','on');

  %data cursor will show component label
  datacursormode on
  dcm = datacursormode(gcf);
  set(dcm,'Enable','on', 'UpdateFcn', @componentText)

end % multicolor. Supporting functions at end of file

% ========================================================================================

% STD_PLOTCOMPDIP - Commandline function, to visualizing cluster components dipoles.
%                   Displays the dipoles of specified cluster components with the cluster mean
%                   dipole on separate figures.
%                   To visualize dipoles they first must be stored in the EEG dataset structures
%                   using DIPFIT. Only components that have a dipole locations will be displayed,
%                   along with the cluster mean dipole in red.
% Usage:
%                   >> [STUDY] = std_plotcompdip(STUDY, ALLEEG, cluster, comps);
% Inputs:
%   STUDY      - EEGLAB STUDY set comprising some or all of the EEG datasets in ALLEEG.
%   ALLEEG     - global EEGLAB vector of EEG structures for the dataset(s) included in the STUDY.
%                     ALLEEG for a STUDY set is typically created using LOAD_ALLEEG.
%   cluster     - single cluster number.
%
% Optional inputs:
%   comps      - [numeric vector]  -> indices of the cluster components to plot.
%                       'all'                       -> plot all the components in the cluster {default: 'all'}.
%
% Outputs:
%   STUDY    - the input STUDY set structure modified with plotted cluster
%                     dipole mean, to allow quick replotting (unless cluster mean
%                     already existed in the STUDY).
%
%   Example:
%                         >> cluster = 4; comps= 1;
%                         >> [STUDY] = std_plotcompdip(STUDY,ALLEEG, cluster, comps);
%                    Plots component 1 dipole in blue with the cluster 4 mean dipole in red.
%
%  See also  pop_clustedit, dipfit, std_dipplot
%
% Authors:  Hilit Serby, Arnaud Delorme, Scott Makeig, SCCN, INC, UCSD, June, 2005

% Copyright (C) Hilit Serby, SCCN, INC, UCSD, June 08, 2005, hilit@sccn.ucsd.edu
%
% 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.

function STUDY = std_plotcompdip(STUDY, ALLEEG, cls, comp_ind, varargin)
if ~exist('cls')
    error('std_plotcompdip: you must provide a cluster number as an input.');
end
if isempty(cls)
   error('std_plotcompdip: you must provide a cluster number as an input.');
end
if nargin == 3 % no components indices were given
    % Default plot all components of the cluster
    [STUDY] = std_dipplot(STUDY, ALLEEG, 'clusters', cls);
    return
end

for ci = 1:length(comp_ind)
    abset = STUDY.datasetinfo(STUDY.cluster(cls).sets(1,comp_ind(ci))).index;
    comp = STUDY.cluster(cls).comps(comp_ind(ci));
    subject = STUDY.datasetinfo(STUDY.cluster(cls).sets(1,comp_ind(ci))).subject;
    if ~isfield(ALLEEG(abset), 'dipfit')
        warndlg2(['No dipole information available in dataset ' num2str(abset) ' , abort plotting'], 'Aborting plot dipoles');
        return;
    end
    if length(comp_ind) == 1 && isempty(ALLEEG(abset).dipfit.model(comp).posxyz)
        warndlg2(strvcat('There is no dipole information available in', ...
                       [ 'dataset ' num2str(abset) ' for this component, abort plotting']), 'Aborting plot dipoles');
        return;
    end
    if ~isfield(STUDY.cluster(cls),'dipole')
        STUDY = std_centroid(STUDY,ALLEEG, cls , 'dipole');
    elseif isempty(STUDY.cluster(cls).dipole)
        STUDY = std_centroid(STUDY,ALLEEG, cls , 'dipole');
    end
    comp_to_disp = [subject  ' / ' 'IC' num2str(comp) ];
    cluster_dip_models.posxyz = ALLEEG(abset).dipfit.model(comp).posxyz;
    cluster_dip_models.momxyz = ALLEEG(abset).dipfit.model(comp).momxyz;
    cluster_dip_models.rv = ALLEEG(abset).dipfit.model(comp).rv;
    cluster_dip_models(2) = STUDY.cluster(cls).dipole;
    if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
        if isfield(ALLEEG(abset).dipfit, 'hdmfile') %dipfit 2 spherical model
            load('-mat', ALLEEG(abset).dipfit.hdmfile);
            max_r = max(vol.r);
        else
            max_r = max(ALLEEG(abset).dipfit.vol.r);
        end
        dipplot(cluster_dip_models, 'sphere', max_r, 'mri', ALLEEG(abset).dipfit.mrifile,'coordformat', ALLEEG(abset).dipfit.coordformat , ...
           'normlen' ,'on', 'pointout' ,'on','color', {'b', 'r'}, 'dipnames', {comp_to_disp [ STUDY.cluster(cls).name ' mean' ] },...
            'spheres', 'on', 'verbose', 'off', varargin{:});
    else
       dipplot(cluster_dip_models, 'meshdata', ALLEEG(abset).dipfit.hdmfile, 'mri', ALLEEG(abset).dipfit.mrifile,'coordformat', ALLEEG(abset).dipfit.coordformat , ...
          'normlen' ,'on', 'pointout' ,'on','color', {'b', 'r'}, 'dipnames', {comp_to_disp [STUDY.cluster(cls).name ' mean']}, ...
          'spheres', 'off', 'verbose', 'off', varargin{:});
    end
    fig_h = gcf;
    set(fig_h,'Name', [subject ' / ' 'IC' num2str(comp) ', ' STUDY.cluster(cls).name],'NumberTitle','off');
end

% -----------------------
% load all dipoles and
% compute dipole centroid
% DEVELOPMENT: this function
% should be the only one to
% access dipole information
% -----------------------
function STUDY = std_centroid(STUDY,ALLEEG, clsind, tmp);

    for clust = 1:length(clsind)
        max_r = 0;
        len = length(STUDY.cluster(clsind(clust)).comps);
        tmppos = [ 0 0 0 ];
        tmpmom = [ 0 0 0 ];
        tmprv = 0;
        ndip = 0;
        for k = 1:len
            fprintf('.');
            comp  = STUDY.cluster(clsind(clust)).comps(k);
            abset = STUDY.cluster(clsind(clust)).sets(1,k);
            if ~isfield(ALLEEG(abset), 'dipfit')
               warndlg2(['No dipole information available in dataset ' num2str(abset) ], 'Aborting compute centroid dipole');
               return;
            end
            if ~isempty(ALLEEG(abset).dipfit.model(comp).posxyz)
                ndip   = ndip +1;
                posxyz = ALLEEG(abset).dipfit.model(comp).posxyz;
                momxyz = ALLEEG(abset).dipfit.model(comp).momxyz;
                if size(posxyz,1) == 2
                    if all(posxyz(2,:) == [ 0 0 0 ])
                        posxyz(2,:) = [];
                        momxyz(2,:) = [];
                    end
                end
                tmppos = tmppos + mean(posxyz,1);
                tmpmom = tmpmom + mean(momxyz,1);
                tmprv = tmprv + ALLEEG(abset).dipfit.model(comp).rv;
                if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical')
                   if isfield(ALLEEG(abset).dipfit, 'hdmfile') %dipfit 2 spherical model
                       load('-mat', ALLEEG(abset).dipfit.hdmfile);
                       max_r = max(max_r, max(vol.r));
                   else % old version of dipfit
                       max_r = max(max_r,max(ALLEEG(abset).dipfit.vol.r));
                   end
               end
            end
        end
        centroid{clust}.dipole.posxyz =  tmppos/ndip;
        centroid{clust}.dipole.momxyz =  tmpmom/ndip;
        centroid{clust}.dipole.rv =  tmprv/ndip;
        if strcmpi(ALLEEG(abset).dipfit.coordformat, 'spherical') && (~isfield(ALLEEG(abset).dipfit, 'hdmfile')) %old dipfit
            centroid{clust}.dipole.maxr = max_r;
        end
        STUDY.cluster(clsind(clust)).dipole = centroid{clust}.dipole;
    end
    fprintf('\n');

% --------------------------------
% new function to compute centroid
% was programmed to debug the function
% above but is now used in the code
% --------------------------------
function dipole = computecentroid(alldipoles)

        max_r = 0;
        len = length(alldipoles);
        dipole.posxyz = [ 0 0 0 ];
        dipole.momxyz = [ 0 0 0 ];
        dipole.rv = 0;
        ndip = 0;
        count = 0;
        warningon = 1;
        for k = 1:len
            if size(alldipoles(k).posxyz,1) == 2
                if all(alldipoles(k).posxyz(2,:) == [ 0 0 0 ])
                    alldipoles(k).posxyz(2,:) = [];
                    alldipoles(k).momxyz(2,:) = [];
                end
            end
            if ~isempty(alldipoles(k).posxyz)
                dipole.posxyz = dipole.posxyz + mean(alldipoles(k).posxyz,1);
                dipole.momxyz = dipole.momxyz + mean(alldipoles(k).momxyz,1);
                dipole.rv     = dipole.rv     + alldipoles(k).rv;
                count = count+1;
            elseif warningon
                disp('Some components do not have dipole information');
                warningon = 0;
            end
        end
        dipole.posxyz = dipole.posxyz/count;
        dipole.momxyz = dipole.momxyz/count;
        dipole.rv     = dipole.rv/count;
        if isfield(alldipoles, 'maxr')
            dipole.maxr = alldipoles(1).max_r;
        end

function [cluster_dip_models, options] = dipgroups(ALLEEG, STUDY, cls, comp_to_disp, cluster_dip_models, options);

    % first, extract the subject number
    for n = 1:length(comp_to_disp)
        subjectnum(n,1) = str2num(comp_to_disp{n}(1:3));
    end

    % second, extract group info
    for n = 1:length(subjectnum)
        subj_group{n,1} = ALLEEG(1,subjectnum(n)).group;
    end

    % third, replace the group names with numbers
    for n = 1:length(subj_group)
        for m = 1:length(STUDY.group)
            if strcmp(subj_group{n,1}, STUDY.group{1,m})
                subj_groupnum(n,1) = m;
                break
            end
        end
    end

    % fourth, compute centroid for each group
    for n = 1:length(STUDY.group)
        samegroupIC = find(subj_groupnum==n);
        cluster_dip_models(1,length(subj_groupnum)+n) = computecentroid(cluster_dip_models(1, samegroupIC));
    end

    % fifth, use subj_groupnum as a type of dipole color

        %%%%%%%%%%%%%%%%%%%%% color list %%%%%%%%%%%%%%%%%%%%%
        % This color list was developed for std_envtopo
        % 16 colors names officially supported by W3C specification for HTML
        colors{1,1}  = [1 1 1];            % White
        colors{2,1}  = [1 1 0];            % Yellow
        colors{3,1}  = [1 0 1];            % Fuchsia
        colors{4,1}  = [1 0 0];            % Red
        colors{5,1}  = [0.75  0.75  0.75]; % Silver
        colors{6,1}  = [0.5 0.5 0.5];      % Gray
        colors{7,1}  = [0.5 0.5 0];        % Olive
        colors{8,1}  = [0.5 0 0.5];        % Purple
        colors{9,1}  = [0.5 0 0];          % Maroon
        colors{10,1} = [0 1 1];            % Aqua
        colors{11,1} = [0 1 0];            % Lime
        colors{12,1} = [0 0.5 0.5];        % Teal
        colors{13,1} = [0 0.5 0];          % Green
        colors{14,1} = [0 0 1];            % Blue
        colors{15,1} = [0 0 0.5];          % Navy
        colors{16,1} = [0 0 0];            % Black
        % Silver is twice brighter because silver is used for a background color
        colors{5,1} = [0.875 0.875 0.875];
        % Choosing and sorting 12 colors for line plot, namely Red, Blue, Green, Fuchsia, Lime, Aqua, Maroon, Olive, Purple, Teal, Navy, and Gray
        selectedcolors = colors([4 13 14 3 11 10 9 7 8 12 15 6]);

    % determine the new dip colors
    for n = 1:length(subj_groupnum)
        dip_color{1,n}=selectedcolors{subj_groupnum(n,1)+1};
    end
    for n = 1:length(STUDY.group)
        dip_color{1,end+1}= selectedcolors{n+1};
    end

    for n = 1:length(options)
        if      strcmp(options{1,n}, 'color')
            options{1,n+1} = dip_color;
        elseif  strcmp(options{1,n}, 'dipnames')
            dipnames = options{1,n+1};
            for m = 1:length(STUDY.group)
                dipnames{1,length(subj_groupnum)+m}= [STUDY.group{1,m} ' mean'];
            end
            options{1,n+1} = dipnames;
        end
    end

% ========================================================================================
% multicolor mode support functions
function str = componentText(~,obj)
% look up component name--used in data cursor callback in 'multicolor' mode
try
  str = obj.Target.UserData.name;
  h=findall(gcf,'type','hggroup');
  h(1).FontSize = 14;
catch
  str = '';
end


function destination = BV_CombineWithMask(sourceFile, destinationFile, maskFile, outFile, normalizeImages)
%
%   destination = BV_CombineWithMask(sourceFile, destinationFile, maskFile, outFile)
%
% Combines Analyze images using a mask
%
% Like this:
%    destination(mask) = source(mask);
%
% EXAMPLE:
%       BV_CombineWithMask(homog_brain, orig, brain_mask);
%
% $Author: bob $
% $Date: 2003/12/20 00:01:50 $

if (~exist('normalizeImages','var'))
    normalizeImages=0;
end
if ~exist('outFile','var')
    outFile = [destinationFile,'_Combined']
end

% Load in the images:
[source,mmPerVox]      = loadAnalyze(sourceFile,'',1);
[destination,mmPerVox] = loadAnalyze(destinationFile,'',1);

% Assume that mask is 0s and 1s
mask = loadAnalyze(maskFile,'',1);
mask = mask~=0;

% Do some normalization if required
if (normalizeImages);
    disp('Normalizing...');
    source = double(source);
    source = source-min(source(:));
    source = source/max(source(:))*65000;
    source = uint16(source);
    destination = double(destination);
    destination = destination-min(destination(:));
    destination = destination/max(destination(:))*65000;
    destination = uint16(destination);
end

% Take the locations in the Source that are in the mask positions
% and copy them into the Destination file.
destination(mask) = source(mask);

if nargout == 0
    saveAnalyze(double(destination),outFile, mmPerVox);
    fprintf('Saving combined file:  %s\n',outFile);
end

return;


function RecreateTspFile(fbasename)

tspdata=load([fbasename '.tsp']);
tspdata = tspdata(:,1);

if size(tspdata,2)>1
  warning('tsp has data in it! Are You sure you want to continue?')
%   keyboard
end

nFramesTsp = size(tspdata,1);
tspnew = [tspdata -1*ones(size(tspdata,1),6)];

%readerobj  = VideoReader([fbasename '.mpg']);

if ~exist([fbasename '.ogg'],'file') && exist([fbasename '.mpg'],'file')
    %eval(['!ffmpeg -i ' fbasename '.mpg -f ogg ' fbasename '.ogg'])
    eval(['!avconv -i ' fbasename '.mpg -f ogg ' fbasename '.ogg'])
elseif ~exist([fbasename '.ogg'],'file') && ~exist([fbasename '.mpg'],'file')
    error('No video file!!')
end

whl = ApproxMedianFilter_RB_LED([fbasename '.ogg']);
figure(1),clf
plot(whl(:,1),whl(:,2))
hold on
plot(whl(:,3),whl(:,4),'r')

nDiff = nFramesTsp - size(whl,1);
if nDiff ~=0 %in case of frame drop, interpolate the output

    twhl = (1:size(whl,1));
    ttsp = (1:size(tspdata,1));
    whl(whl==-1) = NaN;
    interpData = interp1(twhl,whl,ttsp);
    interpData(isnan(interpData)) = -1;
    tspnew(:,[2 3 6 7]) = interpData;
else
    tspnew(:,[2 3 6 7]) = whl;
end

fid = fopen([fbasename '.tsp'],'w');
fprintf(fid,'%i\t %f\t %f\t %f\t %f\t %f\t %f\t \n',tspnew');
fclose(fid);
%eval(['!rm ' fbasename '.ogg'])


function [w, s, h] = gp_pak(gp, param)
%GP_PAK  Combine GP parameters into one vector
%
%  Description
%    W = GP_PAK(GP, PARAM) takes a Gaussian Process structure
%    GP and string PARAM defining, which parameters are packed and
%    combines the parameters into a single row vector W. If PARAM
%    is not given the function packs all parameters.
%
%    Each of the following strings in PARAM defines one group of
%    parameters to pack:
%      covariance  - pack parameters of covariance function
%      likelihood  - pack parameters of likelihood
%      inducing    - pack inducing inputs (in sparse approximations):
%                    W = gp.X_u(:)
%
%    By combining the strings one can pack more than one group of
%    parameters. For example:
%      covariance+inducing  - pack covariance function parameters
%                             and inducing inputs
%      covariance+likelih   - pack covariance function parameters
%                             and likelihood parameters
%
%    Inside each group (such as covariance functions) the
%    parameters to be packed is defined by the existence of a prior
%    structure. For example, if GP has two covariance functions but
%    only the first one has prior for its parameters then only the
%    parameters of the first one are packed. Thus, also inducing
%    inputs require prior if they are to be optimized.
%
%    GP_PAK and GP_UNPAK functions are used, e.g., when GP
%    parameters are optimized with GP_OPTIM or sampled with GP_MC.
%    See GP_SET and option 'infer_params'.
%
%    [W, WS] = GP_PAK(GP, PARAM) returns also cell array of string
%    labels for the weight vector elements, which makes diagnostics
%    easier.
%
%    [W, WS, H] = GP_PAK(GP, PARAM) returns also hierarchy level H of
%    different parameters (0 for likelihood parameters and 1 for covariance
%    function parameters)
%
%  See also
%    GP_UNPAK, GP_SET
%
% Copyright (c) 2007-2010 Jarno Vanhatalo

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

  w = []; s = {}; h = [];

  if isfield(gp,'etr') && length(gp.etr) > 1
    if strcmp(gp.type, 'PIC_BLOCK') || strcmp(gp.type, 'PIC')
      ind = gp.tr_index;           % block indeces for training points
      gp = rmfield(gp,'tr_index');
    end
    ns = length(gp.etr);
    for i1 = 1:ns
      Gp = take_nth(gp,i1);
      [w(i1,:), s, h] = gp_pak(Gp);
    end
  else

    if nargin < 2
      param = gp.infer_params;
    end

    % Pack SVI variational parameters
    if isfield(gp, 'latent_method') && isequal(gp.latent_method,'SVI') ...
        && isfield(gp, 't1')
      w=[gp.t1; gp.t2(:)]';
      if length(gp.t1)>1
        s = [s; sprintf('E[u] x %d', gp.nind); ...
          sprintf('Cov[u] x %d', gp.nind^2)];
      else
        s = [s; 'E[u]'; 'Cov[u]'];
      end
    end

    % Pack the parameters of covariance functions
    if ~isempty(strfind(param, 'covariance'))
      ncf = length(gp.cf);

      for i=1:ncf
        gpcf = gp.cf{i};
        [wi, si, hi] = gpcf.fh.pak(gpcf);
        w = [w wi];
        s = [s; si];
        h = [h hi];
      end
    end

    % Pack the parameters of likelihood function
    if ~isempty(strfind(param, 'likelihood'))
      [wi, si, hi] = gp.lik.fh.pak(gp.lik);
      if isfield(gp, 'latent_method') && isequal(gp.latent_method, 'SVI') ...
          && ~isequal(gp.lik.type, 'Gaussian') && isfield(gp, 't1') ...
          && ~isempty(gp.lik.p.sigma2)
        wi=log(gp.lik.sigma2);
        si='log(sigma2)';
        hi=0;
      end
      w = [w wi];
      s = [s; si];
      h = [h hi];
    end

    % Pack the parameters of the second likelihood function (monotonic)
    if ~isempty(strfind(param, 'likelihood')) && isfield(gp, 'lik_mono')
      [wi, si, hi] = gp.lik_mono.fh.pak(gp.lik_mono);
      if isfield(gp, 'latent_method') && isequal(gp.latent_method, 'SVI') ...
           && isfield(gp, 't1') && ~isempty(gp.lik_mono.p.sigma2)
        wi=log(gp.lik_mono.sigma2);
        si='log(sigma2_mono)';
        hi=0;
      end
      w = [w wi];
      s = [s; si];
      h = [h hi];
    end

    % Pack the inducing inputs
    if ~isempty(strfind(param, 'inducing'))
      if isfield(gp,'p') && isfield(gp.p, 'X_u') && ~isempty(gp.p.X_u)
        if ~iscell(gp.p.X_u)
          % One prior for all inducing inputs
          w = [w reshape(gp.X_u', numel(gp.X_u),1)'];
%           w = [w gp.X_u'];
          s = [s; sprintf('inducing x %d',numel(gp.X_u))];
          h = [h ones(1,numel(gp.X_u))];
          [wi,si,hi]=gp.p.X_u.fh.pak(gp.p.X_u);
          w = [w wi];
          s = [s; si];
          h = [h 1+hi];
        else
          % Own prior for each inducing input
          for i=1:size(gp.X_u,1)
            w = [w gp.X_u(i,:)];
            s = [s; sprintf('inducing x %d',numel(gp.X_u(i,:)))];
            h = [h ones(1,size(gp.X_u(i,:),2))];
            [wi,si,hi]=gp.p.X_u{i}.fh.pak(gp.p.X_u{i});
            si=strcat(repmat('prior-', size(si,1),1),si);
            w = [w wi];
            s = [s; si];
            h = [h 1+hi];
          end
        end
      end
    end

    % Pack the prior weights and variances of mean functions
    if ~isempty(strfind(param, 'mean'))
      mf = length(gp.meanf);

      for i=1:mf
        gpmf = gp.meanf{i};
        [wi, si, hi] = gpmf.fh.pak(gpmf);
        w = [w wi];
        s = [s; si];
        h = [h, hi];
      end
    end

  end

end


%  This scriptfile ask for several input parameters that can be setup
%  at the beginning of each session. The default values are the
%  extrema in the catalog
%
%a = org;        % resets the main catalogue "a" to initial state

% TODO remove this file, it has been replaced by catalog_overview.m
report_this_filefun(mfilename('fullpath'));

%  default values
t0b = min(ZG.primeCatalog.Date);
teb = max(ZG.primeCatalog.Date);
tdiff = (teb - t0b)*365;

if ~exist('par1', 'var')
    %  if tdiff>10                 %select bin length respective to time in catalog
    %     par1 = ceil(tdiff/100);
    %  elseif tdiff<=10 & tdiff>1
    %     par1 = 0.1;
    %  elseif tdiff<=1
    %     par1 = 0.01;
    %  end
    par1 = 30;
end

ZG.big_eq_minmag = max(ZG.primeCatalog.Magnitude) -0.2;
dep1 = 0.3*max(ZG.primeCatalog.Depth);
dep2 = 0.6*max(ZG.primeCatalog.Depth);
dep3 = max(ZG.primeCatalog.Depth);
minti = min(ZG.primeCatalog.Date);
maxti  = max(ZG.primeCatalog.Date);
minma = min(ZG.primeCatalog.Magnitude);
maxma = max(ZG.primeCatalog.Magnitude);
mindep = min(ZG.primeCatalog.Depth);
maxdep = max(ZG.primeCatalog.Depth);

%
% make the interface
%
figure_w_normalized_uicontrolunits(...
    'Units','pixel','pos',[300 100 300 400 ],...
    'Name','General Parameters!',...
    'visible','off',...
    'NumberTitle','off',...
    'MenuBar','none',...
    'NextPlot','new');
axis off

inp1B=uicontrol('Style','edit','Position',[.70 .90 .22 .05],...
    'Units','normalized','String',num2str(ZG.primeCatalog.Count),...
    'Callback','nueq=str2double(inp1B.String); inp1B.String=num2str(ZG.primeCatalog.Count);');

inp1=uicontrol('Style','edit','Position',[.70 .80 .22 .05],...
    'Units','normalized','String',num2str(ZG.big_eq_minmag),...
    'Callback','ZG.big_eq_minmag=str2double(inp1.String); inp1.String=num2str(ZG.big_eq_minmag))');

inp2=uicontrol('Style','edit','Position',[.70 .70 .22 .05],...
    'Units','normalized','String',num2str(par1),...
    'Callback','par1=str2double(inp2.String); inp2.String=num2str(par1);');

inp3=uicontrol('Style','edit','Position',[.70 .60 .22 .05],...
    'Units','normalized','String',num2str(minti),...
    'Callback','minti=str2double(inp3.String); inp3.String=num2str(minti);');

inp4=uicontrol('Style','edit','Position',[.70 .50 .22 .05],...
    'Units','normalized','String',num2str(maxti),...
    'Callback','maxti=str2double(inp4.String); inp4.String=num2str(maxti);');

inp5=uicontrol('Style','edit','Position',[.70 .40 .22 .05],...
    'Units','normalized','String',num2str(minma),...
    'Callback','minma=str2double(inp5.String); inp5.String=num2str(minma);');

inp6=uicontrol('Style','edit','Position',[.70 .30 .22 .05],...
    'Units','normalized','String',num2str(maxma),...
    'Callback','maxma=str2double(inp6.String); inp6.String=num2str(maxma);');

inp7=uicontrol('Style','edit','Position',[.30 .15 .15 .05],...
    'Units','normalized','String',num2str(mindep),...
    'Callback','mindep=str2double(inp7.String); inp7.String=num2str(mindep);');

inp8=uicontrol('Style','edit','Position',[.50 .15 .15 .05],...
    'Units','normalized','String',num2str(maxdep),...
    'Callback','maxdep=str2double(inp8.String); inp8.String=num2str(maxdep);');

close_button=uicontrol('Style','Pushbutton',...
    'Position',[.65 .02 .20 .10 ],...
    'Units','normalized','Callback','close;zmap_message_center.set_info('' '','' '');done','String','cancel');

go_button=uicontrol('Style','Pushbutton',...
    'Position',[.35 .02 .20 .10 ],...
    'Units','normalized',...
    'Callback','close,think, sele_sub',...
    'String','Go');

info_button=uicontrol('Style','Pushbutton',...
    'Position',[.05 .02 .20 .10 ],...
    'Units','normalized',...
    'Callback','zmaphelp(titstr,hlpStr)',...
    'String','Info');
titstr = 'General Parameters';
hlpStr = ...
    ['This window allows you to select earthquakes '
    'from a catalog. You can select a subset in   '
    'time, magnitude and depth.                   '
    '                                             '
    'The top frame displays the number of         '
    'earthquakes in the catalog - no selection is '
    'possible.                                    '
    '                                             '
    'Two more parameters can be adjusted: The Bin '
    'length in days that is used to sample the    '
    'seismicity and the minimum magnitude of      '
    'quakes displayed with a larger symbol in the '
    'map.                                         '];

txt3 = text(...
    'Color',[1 0 0 ],...
    'Position',[0.02 1.00 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String',' EQs in catalog: ');

txt1 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.75 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','Bin Length in days :');

txt2 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.87 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','Plot Big Events with M > ');

txt4 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.63 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','Beginning year: ');

txt5 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.51 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','Ending year: ');

txt6 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.38 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','Minimum Magnitude: ');

txt6 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.25 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','Maximum Magnitude: ');

txt7 = text(...
    'Color',[0 0 0 ],...
    'Position',[0.02 0.15 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'FontWeight','bold' ,...
    'String','       Min Depth     Max Depth  ');

%clear txt1 txt2 txt3 txt4 txt5 txt6 txt7 inp1 inp1B inp3 inp3 inp4 inp5 inp6 inp7
set(gcf,'visible','on')
watchoff
str = [ 'Please Select a subset of earthquakes'
    ' and press Go                        '];
zmap_message_center.set_message('Message',str);