function gpcf = gpcf_mask(varargin)
%GPCF_MASK  Create a mask covariance function
%
%  Description
%    GPCF = GPCF_MASK('PARAM1',VALUE1,'PARAM2,VALUE2,...)
%    creates a mask covariance function structure in
%    which the named parameters have the specified values. Any
%    unspecified parameters are set to default values.
%
%    GPCF = GPCF_MASK(GPCF,'PARAM1',VALUE1,'PARAM2,VALUE2,...)
%    modify a covariance function structure with the named
%    parameters altered with the specified values.
%
%    Mask covariance function returns correlation 1 if input
%    values X_i and X_j are both non zero and 0 otherwise.
%
%    Parameters for mask covariance function
%      selectedVariables - vector defining which inputs are used
%
%  See also
%    GP_SET, GPCF_*, PRIOR_*, MEAN_*
%
% Copyright (c) 2007-2010 Jarno Vanhatalo
% Copyright (c) 2008-2010 Jaakko Riihimäki
% Copyright (c) 2010 Aki Vehtari

% 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.

  ip=inputParser;
  ip.FunctionName = 'GPCF_MASK';
  ip.addOptional('gpcf', [], @isstruct);
  ip.addParamValue('selectedVariables',[], ...
                   @(x) isempty(x) || (isvector(x) && all(x>0)));
  ip.parse(varargin{:});
  gpcf=ip.Results.gpcf;

  if isempty(gpcf)
    % Initialize a covariance function structure
    init=true;
    gpcf.type = 'gpcf_mask';
  else
    % Modify a covariance function structure
    if ~isfield(gpcf,'type') && ~isequal(gpcf.type,'gpcf_mask')
      error('First argument does not seem to be a valid covariance function structure')
    end
    init=false;
  end

  if ~ismember('selectedVariables',ip.UsingDefaults)
    if ~isempty(ip.Results.selectedVariables)
      gpcf.selectedVariables = ip.Results.selectedVariables;
    elseif isfield(gpcf,'selectedVariables')
      gpcf=rmfield(gpcf,'selectedVariables');
    end
  end
  if init
    gpcf.fh.pak = @gpcf_mask_pak;
    gpcf.fh.unpak = @gpcf_mask_unpak;
    gpcf.fh.lp = @gpcf_mask_lp;
    gpcf.fh.lpg = @gpcf_mask_lpg;
    gpcf.fh.cfg = @gpcf_mask_cfg;
    gpcf.fh.ginput = @gpcf_mask_ginput;
    gpcf.fh.cov = @gpcf_mask_cov;
    gpcf.fh.trcov  = @gpcf_mask_trcov;
    gpcf.fh.trvar  = @gpcf_mask_trvar;
    gpcf.fh.recappend = @gpcf_mask_recappend;
  end

end

function [w,s,h] = gpcf_mask_pak(gpcf, w)
%GPCF_MASK_PAK  Combine GP covariance function parameters into
%              one vector.
%
%  Description
%    W = GPCF_MASK_PAK(GPCF) takes a covariance function
%    structure GPCF and combines the covariance function
%    parameters and their hyperparameters into a single row
%    vector W. This is a mandatory subfunction used for
%    example in energy and gradient computations.
%
%       w = []
%
%  See also
%    GPCF_MASK_UNPAK

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

function [gpcf, w] = gpcf_mask_unpak(gpcf, w)
%GPCF_MASK_UNPAK  Sets the covariance function parameters into
%                the structure
%
%  Description
%    [GPCF, W] = GPCF_MASK_UNPAK(GPCF, W) takes a covariance
%    function structure GPCF and a parameter vector W, and
%    returns a covariance function structure identical to the
%    input, except that the covariance parameters have been set
%    to the values in W. Deletes the values set to GPCF from W
%    and returns the modified W. This is a mandatory subfunction
%    used for example in energy and gradient computations.
%
%    Assignment is inverse of
%       w = []
%
%  See also
%   GPCF_MASK_PAK

end

function lp = gpcf_mask_lp(gpcf)
%GPCF_MASK_LP  Evaluate the energy of prior of covariance function parameters
%
%  Description
%    LP = GPCF_MASK_LP(GPCF) takes a covariance function
%    structure GPCF and returns log(p(th)), where th collects the
%    parameters. This is a mandatory subfunction used for example
%    in energy computations.
%
%  See also
%    GPCF_MASK_PAK, GPCF_MASK_UNPAK, GPCF_MASK_LPG, GP_E

  lp = 0;

end

function lpg = gpcf_mask_lpg(gpcf)
%GPCF_MASK_LPG  Evaluate gradient of the log prior with respect
%               to the parameters.
%
%  Description
%    LPG = GPCF_MASK_LPG(GPCF) takes a covariance function
%    structure GPCF and returns LPG = d log (p(th))/dth, where th
%    is the vector of parameters. This is a mandatory subfunction
%    used for example in gradient computations.
%
%  See also
%    GPCF_MASK_PAK, GPCF_MASK_UNPAK, GPCF_MASK_LP, GP_G

  lpg = [];

end

function DKff = gpcf_mask_cfg(gpcf, x, x2, mask,i1)
%GPCF_MASK_CFG  Evaluate gradient of covariance function
%               with respect to the parameters.
%
%  Description
%    DKff = GPCF_MASK_CFG(GPCF, X) takes a covariance function
%    structure GPCF, a matrix X of input vectors and returns
%    DKff, the gradients of covariance matrix Kff = k(X,X) with
%    respect to th (cell array with matrix elements). This is a
%    mandatory subfunction used in gradient computations.
%
%    DKff = GPCF_MASK_CFG(GPCF, X, X2) takes a covariance function
%    structure GPCF, a matrix X of input vectors and returns
%    DKff, the gradients of covariance matrix Kff = k(X,X2) with
%    respect to th (cell array with matrix elements). This subfunction
%    is needed when using sparse approximations (e.g. FIC).
%
%    DKff = GPCF_MASK_CFG(GPCF, X, [], MASK) takes a covariance
%    function structure GPCF, a matrix X of input vectors and
%    returns DKff, the diagonal of gradients of covariance matrix
%    Kff = k(X,X2) with respect to th (cell array with matrix
%    elements). This subfunction is needed when using sparse
%    approximations (e.g. FIC).
%
%    DKff = GPCF_MASK_CFG(GPCF, X, X2, [], i) takes a covariance function
%    structure GPCF, a matrix X of input vectors and returns
%    DKff, the gradients of covariance matrix Kff = k(X,X2), or k(X,X)
%    if X2 is empty, with respect to ith hyperparameter. This subfunction
%    is needed when using memory save option in gp_set.
%
%  See also
%    GPCF_MASK_PAK, GPCF_MASK_UNPAK, GPCF_MASK_LP, GP_G

  DKff = {};

end

function [DKff, lpg]  = gpcf_mask_ginput(gpcf, x, x2, i1)
%GPCF_MASK_GINPUT  Evaluate gradient of covariance function with
%                  respect to x.
%
%  Description
%    DKff = GPCF_MASK_GINPUT(GPCF, X) takes a covariance function
%    structure GPCF, a matrix X of input vectors and returns
%    DKff, the gradients of covariance matrix Kff = k(X,X) with
%    respect to X (cell array with matrix elements). This subfunction
%    is needed when computing gradients with respect to inducing
%    inputs in sparse approximations.
%
%    DKff = GPCF_MASK_GINPUT(GPCF, X, X2) takes a covariance
%    function structure GPCF, a matrix X of input vectors
%    and returns DKff, the gradients of covariance matrix Kff =
%    k(X,X2) with respect to X (cell array with matrix elements).
%    This subfunction is needed when computing gradients with
%    respect to inducing inputs in sparse approximations.
%
%    DKff = GPCF_MASK_GINPUT(GPCF, X, X2, i) takes a covariance
%    function structure GPCF, a matrix X of input vectors
%    and returns DKff, the gradients of covariance matrix Kff =
%    k(X,X2), or k(X,X) if X2 is empty, with respect to ith covariate
%    in X. This subfunction is needed when using memory saving option
%    in gp_set.
%
%  See also
%   GPCF_MASK_PAK, GPCF_MASK_UNPAK, GPCF_MASK_LP, GP_G

  [n, m] =size(x);

  if nargin == 2 || isempty(x2)
    ii1 = 0;
    for i=1:m
      for j = 1:n
        ii1 = ii1 + 1;
        DKff{ii1} = zeros(n);
        lpg(ii1) = 0;
      end
    end
  elseif nargin == 3 || nargin == 4
    ii1 = 0;
    for i=1:m
      for j = 1:n
        ii1 = ii1 + 1;
        DKff{ii1} = zeros(n, size(x2,1));
        lpg(ii1) = 0;
      end
    end
  end
  if nargin==4
    DKff=DKff{1};
  end
end

function C = gpcf_mask_cov(gpcf, x1, x2, varargin)
%GP_MASK_COV  Evaluate covariance matrix between two input vectors
%
%  Description
%    C = GP_MASK_COV(GP, TX, X) takes in covariance function of a
%    Gaussian process GP and two matrixes TX and X that contain
%    input vectors to GP. Returns covariance matrix C. Every
%    element ij of C contains covariance between inputs i in TX
%    and j in X. This is a mandatory subfunction used for example in
%    prediction and energy computations.
%
%  See also
%    GPCF_MASK_TRCOV, GPCF_MASK_TRVAR, GP_COV, GP_TRCOV

  if isempty(x2)
    x2=x1;
  end
  [n1,m1]=size(x1);
  [n2,m2]=size(x2);

  if m1~=m2
    error('the number of columns of X1 and X2 has to be same')
  end

  C=repmat(true,n1,n2);
  if isfield(gpcf, 'selectedVariables')
    for j = 1:length(gpcf.selectedVariables)
      jj=gpcf.selectedVariables(j);
      C = C & bsxfun(@and,x1(:,jj)~=0,x2(:,jj)'~=0);
    end
  else
    for j = 1:m1
      C = C & bsxfun(@and,x1(:,j)~=0,x2(:,j)'~=0);
    end
  end
  C=double(C);

end

function C = gpcf_mask_trcov(gpcf, x)
%GP_MASK_TRCOV  Evaluate training covariance matrix of inputs
%
%  Description
%    C = GP_MASK_TRCOV(GP, TX) takes in covariance function of a
%    Gaussian process GP and matrix TX that contains training
%    input vectors. Returns covariance matrix C. Every element ij
%    of C contains covariance between inputs i and j in TX. This
%    is a mandatory subfunction used for example in prediction
%    and energy computations.
%
%  See also
%    GPCF_MASK_COV, GPCF_MASK_TRVAR, GP_COV, GP_TRCOV

  [n,m]=size(x);

  C=repmat(true,n,n);
  if isfield(gpcf, 'selectedVariables')
    for j = 1:length(gpcf.selectedVariables)
      jj=gpcf.selectedVariables(j);
      C = C & bsxfun(@and,x(:,jj)~=0,x(:,jj)'~=0);
    end
  else
    for j = 1:m
      C = C & bsxfun(@and,x(:,j)~=0,x(:,j)'~=0);
    end
  end
  C=double(C);

end

function C = gpcf_mask_trvar(gpcf, x)
%GP_MASK_TRVAR  Evaluate training variance vector
%
%  Description
%    C = GP_MASK_TRVAR(GPCF, TX) takes in covariance function of a
%    Gaussian process GPCF and matrix TX that contains training
%    inputs. Returns variance vector C. Every element i of C
%    contains variance of input i in TX. This is a mandatory
%    subfunction used for example in prediction and energy
%    computations.
%
%  See also
%    GPCF_MASK_COV, GP_COV, GP_TRCOV

  [n,m]=size(x);
  C=true(n,1);
  if isfield(gpcf, 'selectedVariables')
    for j = 1:length(gpcf.selectedVariables)
      jj=gpcf.selectedVariables(j);
      C = C & x(:,jj)~=0;
    end
  else
    for j = 1:m
      C = C & x(:,j)~=0;
    end
  end
  C=double(C);

end

function reccf = gpcf_mask_recappend(reccf, ri, gpcf)
%RECAPPEND  Record append
%
%  Description
%    RECCF = GPCF_MASK_RECAPPEND(RECCF, RI, GPCF) takes a
%    covariance function record structure RECCF, record index RI
%    and covariance function structure GPCF with the current MCMC
%    samples of the parameters. Returns RECCF which contains
%    all the old samples and the current samples from GPCF.
%    This subfunction is needed when using MCMC sampling (gp_mc).
%
%  See also
%    GP_MC and GP_MC -> RECAPPEND

  if nargin == 2
    % Initialize the record
    reccf.type = 'gpcf_mask';

    % Initialize parameters
    reccf.coeffSigma2= [];

    % Set the function handles
    reccf.fh.pak = @gpcf_mask_pak;
    reccf.fh.unpak = @gpcf_mask_unpak;
    reccf.fh.lp = @gpcf_mask_lp;
    reccf.fh.lpg = @gpcf_mask_lpg;
    reccf.fh.cfg = @gpcf_mask_cfg;
    reccf.fh.cov = @gpcf_mask_cov;
    reccf.fh.trcov  = @gpcf_mask_trcov;
    reccf.fh.trvar  = @gpcf_mask_trvar;
    reccf.fh.recappend = @gpcf_mask_recappend;
  else
    % Append to the record
    if isfield(gpcf, 'selectedVariables')
      reccf.selectedVariables = gpcf.selectedVariables;
    end
  end
end


classdef TimeDepthAnalysisWindow < AnalysisWindow
    % CUMRATEANALYSISWINDOW shows the cumulative event rate
    properties
    end
    methods
        function obj=TimeDepthAnalysisWindow(ax)
            obj@AnalysisWindow(ax);
        end

        function prepare_axes(obj)
            % prepare the cumulative event rate axes
            if isempty(obj.ax.Tag)
                obj.ax.Tag = 'dvTimeDepth';
            end
            obj.ax.YDir = 'reverse';
            obj.ax.Title.String='Depth through Time';
            obj.ax.XLabel.String='Time';
            obj.ax.YLabel.String='Depth';
        end

        function [x,y]=calculate(obj,catalog)
            % calculate the cumulative number of events (y) over time (x)
            x=sort(catalog.Date);
            y=catalog.Depth;
        end

    end
end


% std_detachplots() -  Given a figure with subplots and several lines per axis, will add a callback to
% each axis specified in the 'figtitles' input. The callback consist in a figure with all the detached
% individuals lines.
%
% Usage:
%   >>   std_detachplots('','','data',data 'figtitles', alltitlestmp,'sbtitles',sbtitles,'handles', handles);
%
% Inputs:
%      data        - Cell array containing the data matrices for each plot in the same order showed in the figure
%      figtitles   - Cell array of the titles of each individual axes in
%                    the  figure. The titles must correspond. The function
%                    use this value to find the right hanlde of the axis
%      sbtitles    - Cell array of cell arrays with the titles for each
%                    detached line per axis. i.e. {{'Axis1 line1' 'Axis1 line2'} {'Axis2 line1' 'Axis2 line2'}}
%      handles     - Handles of the main figure who contain all the
%                    subplots
%      flagstd     - Flag to plot the Standar Deviation  {default: 1} means 'on'
%
% See also:
%
% Author: Ramon Martinez-Cancino, SCCN, 2014
%
% Copyright (C) 2014  Ramon Martinez-Cancino,INC, SCCN
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
function std_detachplots(hObject,eventdata,varargin)

% display help if not enough arguments
if nargin < 2
    help std_detachplots;
    return;
end
icadefs;
try
    options = varargin;
    if ~isempty( varargin ),
        for i = 1:2:numel(options)
            g.(options{i}) = options{i+1};
        end
    else g= []; end;
catch
    disp('std_detachplots() error: calling convention {''key'', value, ... } error'); return;
end;

try g.data;         catch, g.data          =   [];  end; % Name of plots
try g.figtitles;    catch, g.figtitles     =   [];  end; % Name of plots
try g.sbtitles;     catch, g.sbtitles      =   [];  end; % Name of plots
try g.handles;      catch, g.handles       =   [];  end; % Handles of figure
try g.flagstd;      catch, g.flagstd       =   1;   end; % Plot std band around mean
try g.xlabel;       catch, g.xlabel        =   '';  end; % xlabel
try g.ylabel;       catch, g.ylabel        =   '';  end; % ylabel
try g.timevec;      catch, g.timevec       =   '';  end; % Time or freq vector
try g.filter;       catch, g.filter        =   '';  end; % Low pass filter freq

% Checking data
if isempty(g.handles) && any([isempty(g.data) isempty(g.figtitles)])
    error('std_detachplots : Check entries. Options ''handles'', ''data'' and ''figtitles'' must be provided');
end

if iscell(g.data)
    nplots = numel(g.data(:));
else
    nplots = 1 ;
    g.data = {g.data};
end

%  Checking sbtitles
if isempty(g.sbtitles)
    for i = 1:numel(g.data)
        c = 1;
        if ~isempty(g.data{i})
            for j = 1:size(g.data{i},2)
                g.sbtitles{i}{j} = {['Line ' num2str(c)]};
                c = c+1;
            end
        end
    end
end

% Plot goes here
%--------------------------------------------------------------------------
if isempty(g.handles)
    for i_nplots = 1 : nplots
        idata = g.data{i_nplots};

        % Filtering data to be plotted
        if ~isempty(g.filter), idata = myfilt(idata, 1000/(g.timevec(2)-g.timevec(1)), 0, g.filter); end;

        len = size(idata,2);
        if len > 0 % A non-empty cluster
            % Getting the mean
            meandata = mean(idata,2);
            stddata  = std(idata,0,2);

            if license('checkout', 'statistics_toolbox')
                SEM = std(idata,0,2)/sqrt(size(idata,2));       % Standard Error
                ts = tinv([0.025  0.975],size(idata,2)-1);      % T-Score
                lower    = meandata + ts(1)*SEM;                % CI
                upper    = meandata + ts(2)*SEM;                % CI
            else
                lower    = meandata-2*stddata;
                upper    = meandata+2*stddata;
            end

            hplot = figure('name', g.figtitles, 'NumberTitle','off');
            rowcols(2) = ceil(sqrt(len + 4));
            rowcols(1) = ceil((len+4)/rowcols(2));

            for k = 1:len
                %--- first sbplot row ----
                if k <= rowcols(2) - 2
                    figure(hplot);
                    sbplot(rowcols(1),rowcols(2),k+2);
                    hold on;
                    plotlines(k,idata,meandata,lower, upper,g.sbtitles{k},g);
                else
                    figure(hplot)
                    sbplot(rowcols(1),rowcols(2),k+4);
                    hold on;
                    plotlines(k,idata,meandata,lower, upper,g.sbtitles{k},g);
                end
            end
            % Plot all figure
            figure(hplot)
            sbplot(rowcols(1),rowcols(2),[1 rowcols(2)+2 ]);
            hold on;
            plotlines(1:len,idata,meandata,lower,upper,g.figtitles,g);
            set(gcf,'Color', BACKCOLOR);
            orient tall;
        end
    end
else
    xlabelval = '';
    ylabelval = '';
    % Match Children handles based on titles provided
    c = 0;
    for i = 1: nplots
        htemp          = findall(g.handles,'String', g.figtitles{i});
        if all([~isempty(htemp) ~isempty(g.data(i))])
            handlestemp{i} = htemp(1);
            % Getting x label from handles
            if isempty(xlabelval)
                xlabelval = get(get(get(handlestemp{i},'Parent'),'Xlabel'),'String'); % xlabelval = handlestemp{i}.Parent.XLabel.String;
            end
            % Getting y label from handles
            if isempty(ylabelval)
                ylabelval = get(get(get(handlestemp{i},'Parent'),'Ylabel'),'String'); % ylabelval = handlestemp{i}.Parent.YLabel.String;
            end
            % Getting timevec from handles
            if isempty(g.timevec)
                tmp = get(get(get(handlestemp{i},'Parent'),'Children'));
                g.timevec = tmp(i).XData; % g.timevec = handlestemp{i}.Parent.Children(i).XData;
            end
        else
            handlestemp{i} = [];
        end

        % Callback setting
        if ~isempty(handlestemp{i})
            c = c + 1;
            % For Axis
            set( get( handlestemp{i}, 'Parent'), 'ButtonDownFcn',{@std_detachplots,...
                'data'     ,g.data{i},...
                'timevec'  ,g.timevec,...
                'handles'  ,'',...
                'figtitles',g.figtitles{i},...
                'sbtitles' ,g.sbtitles{c},...
                'xlabel'   ,xlabelval,...
                'ylabel'   ,ylabelval,...
                'filter'   , g.filter,...
                });
            % For lines
            set( get(get( handlestemp{i}, 'Parent'), 'Children'), 'ButtonDownFcn',{@std_detachplots,...
                'data'     ,g.data{i},...
                'timevec'  ,g.timevec,...
                'handles'  ,'',...
                'figtitles',g.figtitles{i},...
                'sbtitles' ,g.sbtitles{c},...
                'xlabel'   ,xlabelval,...
                'ylabel'   ,ylabelval,...
                'filter'   , g.filter,...
                });
        end
    end
end

function plotlines(kindx,idata,meandata,lower,upper,sbtitle,g)
for i = 1:length(kindx)
    plot(g.timevec,idata(:,kindx(i)),'b','LineWidth', 0.1); % plot g.data
end
plot(g.timevec,meandata,'r','LineWidth', 0.1);              % plot mean

if g.flagstd                                                % plot std band
    eeglabciplot(lower,upper,g.timevec, 'r', 0.2);
    axis tight;
end

if length(kindx)>1
    xlabel(g.xlabel);
    ylabel(g.ylabel);
end
box on;
grid on;
axis tight;
title(sbtitle, 'interpreter', 'none');

% rapid filtering for ERP (from std_plotcurve)
% -----------------------
function tmpdata2 = myfilt(tmpdata, srate, lowpass, highpass);
    bscorrect = 1;
    if bscorrect
        % Getting initial baseline
        bs_val1  =  mean(tmpdata,1);
        bs1      = repmat(bs_val1, size(tmpdata,1), 1);
    end

    % Filtering
    tmpdata2 = reshape(tmpdata, size(tmpdata,1), size(tmpdata,2)*size(tmpdata,3)*size(tmpdata,4));
    tmpdata2 = eegfiltfft(tmpdata2',srate, lowpass, highpass)';
    tmpdata2 = reshape(tmpdata2, size(tmpdata,1), size(tmpdata,2), size(tmpdata,3), size(tmpdata,4));

    if bscorrect
        % Getting after-filter baseline
        bs_val2  =  mean(tmpdata2,1);
        bs2      = repmat(bs_val2, size(tmpdata2,1), 1);

        % Correcting the baseline
        realbs = bs1-bs2;
        tmpdata2 = tmpdata2 + realbs;
    end