function []=panel3plot(endo,Units,Xi,Yi,N,n,m,p,k,T,beta_median,beta_gibbs,It,Bu,decimaldates1,stringdates1,pref,cband,favar)

% actual vs. fitted

% initiate predictions
Ytilde=[];
% loop over units
for ii=1:N
% obtain a point estimate betatilde of the VAR coefficients
% use the point estimate, which is simply the median
betatilde=beta_median(:,:,ii);
Btilde=reshape(betatilde,k,n);
% compute fitted values for the unit
Ytilde(:,:,ii)=Xi(:,:,ii)*Btilde;
end
% then plot the figure
if pref.plot
actualfitted=figure('Tag','BEARresults');
set(actualfitted,'Color',[0.9 0.9 0.9]);
set(actualfitted,'name','actual vs fitted')
% initiate the count
count=0;
% loop over units
for ii=1:N
   % loop over endogenous variables
   for jj=1:n
   % increment count
   count=count+1;
   % then plot
   subplot(N,n,count)
   hold on
   plot(decimaldates1,Yi(:,jj,ii),'Color',[0 0 0],'LineWidth',2);
   plot(decimaldates1,Ytilde(:,jj,ii),'Color',[1 0 0],'LineWidth',2);
   hold off
   set(gca,'XLim',[decimaldates1(1,1) decimaldates1(end,1)],'FontName','Times New Roman');
      % top labels
      if count<=n
      title(endo{count,1},'FontWeight','normal');
      end
      % side labels
      if jj==1
      ylabel(Units{ii,1},'FontWeight','normal');
      end
      % legend
      if ii==1 && jj==1
      plotlegend=legend('actual','fitted');
      set(plotlegend,'FontName','Times New Roman');
      end
   end
end
end
% save on Excel
% create the cell that will be saved on excel
afcell={};
% build preliminary elements: space between the tables
vertspace=repmat({''},T+3,1);
horzspace=repmat({''},3,4*n);
% loop over units
for ii=1:N
% initiate the cell of results
unitcell={};
   % loop over endogenous variables (horizontal dimension)
   for jj=1:n
   % create a header
   header=[{[Units{ii,1} ': ' endo{jj,1}]} {''} {''};{''} {''} {''};{''} {'sample'} {'fitted'}];
   % complete the cell
   endocell=[[header;stringdates1 num2cell(Yi(:,jj,ii)) num2cell(Ytilde(:,jj,ii))] vertspace];
   % concatenate to the previous parts of unitcell
   unitcell=[unitcell endocell];
   end
% concatenate to the previous parts of afcell
afcell=[afcell;horzspace;unitcell];
end
% trim
afcell=afcell(4:end,1:end-1);
% write in excel
if pref.results==1
    bear.xlswritegeneral(fullfile(pref.results_path, [pref.results_sub '.xlsx']),afcell,'actual fitted','B2');
end

% residuals

% inititate the matrix of residuals
EPStilde=[];
% loop over units
for ii=1:N
% estimate the residuals for this unit
EPStilde(:,:,ii)=Yi(:,:,ii)-Ytilde(:,:,ii);
end
if pref.plot
% using these values, plot
residuals=figure('Tag','BEARresults');
set(residuals,'Color',[0.9 0.9 0.9]);
set(residuals,'name','residuals')
% initiate the count
count=0;
% loop over units
for ii=1:N
   % loop over endogenous variables
   for jj=1:n
   % increment count
   count=count+1;
   % then plot
   subplot(N,n,count)
   plot(decimaldates1,EPStilde(:,jj,ii),'Color',[0 0 0],'LineWidth',2);
   set(gca,'XLim',[decimaldates1(1,1) decimaldates1(end,1)],'FontName','Times New Roman');
      % top labels
      if count<=n
      title(endo{count,1},'FontWeight','normal');
      end
      % side labels
      if jj==1
      ylabel(Units{ii,1},'FontWeight','normal');
      end
   end
end
end
% save on Excel
% create the cell that will be saved on excel
residcell={};
% build preliminary elements: space between the tables
vertspace=repmat({''},T+3,1);
horzspace=repmat({''},3,3*n);
% loop over units
for ii=1:N
% initiate the cell of results
unitcell={};
   % loop over endogenous variables (horizontal dimension)
   for jj=1:n
   % create a header
   header=[{[Units{ii,1} ': ' endo{jj,1}]} {''};{''} {''};{''} {'median'}];
   % complete the cell
   endocell=[[header;stringdates1 num2cell(EPStilde(:,jj,ii))] vertspace];
   % concatenate to the previous parts of unitcell
   unitcell=[unitcell endocell];
   end
% concatenate to the previous parts of afcell
residcell=[residcell;horzspace;unitcell];
end
% trim
residcell=residcell(4:end,1:end-1);
% write in excel
if pref.results==1
    bear.xlswritegeneral(fullfile(pref.results_path, [pref.results_sub '.xlsx']),residcell,'resids','B2');
end

% steady-state

% initiate the cell storing the steady-state draws
ss_record={};
ss_estimates={};
% run the Gibbs sampler for the steady-state (common to all units)
ss_record=bear.ssgibbs(n,m,p,k,Xi(:,:,1),beta_gibbs,It,Bu,favar);
% obtain point estimates and credibility interval
ss_estimates=bear.ssestimates(ss_record,n,T,cband);
if pref.plot
% then plot the figure
sstate=figure('Tag','BEARresults');
set(sstate,'Color',[0.9 0.9 0.9]);
set(sstate,'name','steady-state')
% initiate the count
count=0;
% loop over units
for ii=1:N
   % loop over endogenous variables
   for jj=1:n
   % increment count
   count=count+1;
   % then plot
   subplot(N,n,count)
   hold on
   Xpatch=[decimaldates1' fliplr(decimaldates1')];
   Ypatch=[ss_estimates{jj,1}(1,:) fliplr(ss_estimates{jj,1}(3,:))];
   Fpatch=patch(Xpatch,Ypatch,[0.7 0.78 1]);
   set(Fpatch,'facealpha',0.6);
   set(Fpatch,'edgecolor','none');
   ss=plot(decimaldates1,ss_estimates{jj,1}(2,:),'Color',[0.4 0.4 1],'LineWidth',2);
   actual=plot(decimaldates1,Yi(:,jj,ii),'Color',[0 0 0],'LineWidth',2);
   plot([decimaldates1(1,1),decimaldates1(end,1)],[0 0],'k--');
   hold off
   minband=min(min(ss_estimates{jj,1}(1,:)),min(Yi(:,jj,ii)));
   maxband=max(max(ss_estimates{jj,1}(3,:)),max(Yi(:,jj,ii)));
   space=maxband-minband;
   Ymin=minband-0.2*space;
   Ymax=maxband+0.2*space;
   set(gca,'XLim',[decimaldates1(1,1) decimaldates1(end,1)],'YLim',[Ymin,Ymax],'FontName','Times New Roman');
      % top labels
      if count<=n
      title(endo{count,1},'FontWeight','normal');
      end
      % side labels
      if jj==1
      ylabel(Units{ii,1},'FontWeight','normal');
      end
      % legend
      if ii==1 && jj==1
      plotlegend=legend([ss,actual],'steady-state','actual');
      set(plotlegend,'FontName','Times New Roman');
      end
   end
end
end
% save on Excel
% create the cell that will be saved on excel
sscell={};
% build preliminary elements: space between the tables
vertspace=repmat({''},T+3,1);
horzspace=repmat({''},3,6*n);
% loop over units
for ii=1:N
% initiate the cell of results
unitcell={};
   % loop over endogenous variables (horizontal dimension)
   for jj=1:n
   % create a header
   header=[{[Units{ii,1} ': ' endo{jj,1}]} {''} {''} {''} {''};{''} {''} {''} {''} {''};{''} {'actual'} {'lower bound'} {'median'} {'upper bound'}];
   % complete the cell
   endocell=[[header;stringdates1 num2cell(Yi(:,jj,ii)) num2cell(ss_estimates{jj,1}(1,:)') num2cell(ss_estimates{jj,1}(2,:)') num2cell(ss_estimates{jj,1}(3,:)')] vertspace];
   % concatenate to the previous parts of unitcell
   unitcell=[unitcell endocell];
   end
% concatenate to the previous parts of afcell
sscell=[sscell;horzspace;unitcell];
end
% trim
sscell=sscell(4:end,1:end-1);
% write in excel
if pref.results==1
    bear.xlswritegeneral(fullfile(pref.results_path, [pref.results_sub '.xlsx']),sscell,'steady state','B2');
end


function relm_PaintCumPlot(rRelmTest, sXLabel, hAxes)
    % Creates the result plots of one of the RELM tests
    %
    % relm_PaintCumPlot(rRelmTest, sXLabel, hAxes)
    %
    %
    % Input parameters:
    %   rRelmTest		Record of results from one of the RELM tests
    %   sXLabel		Label of X-axis (optional)
    %   hAxes		Handle of existing axes. If not specified, a figure is created
    %
    % Copyright (C) 2002-2006 by Danijel Schorlemmer
    %
    % 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.

    if ~exist('sXLabel')
        sXLabel = '';
    end
    if ~exist('hAxes')
        figure_w_normalized_uicontrolunits('Name', 'Result plot', 'NumberTitle', 'off');
        hAxes = newplot;
    end

    % Activate the given or newly created axes
    axes(hAxes);

    % Plot the CDF and the line of observed data
    vIndex = [1:rRelmTest.nNumberSimulation]/rRelmTest.nNumberSimulation;
    vObservedX = [rRelmTest.fObservedData, rRelmTest.fObservedData];
    vObservedY = [0,1];
    plot(rRelmTest.vSimValues_H, vIndex, 'g', rRelmTest.vSimValues_N, vIndex, 'r', vObservedX, vObservedY, 'k', 'LineWidth', 1);

    % Add the patches
    set(hAxes, 'NextPlot', 'add');
    vPatch1Y = [1 1 0.975 0.975];
    vPatch2Y = [0.025 0.025 0 0];
    vXLim = xlim;
    vPatch1X = [vXLim(1) rRelmTest.fObservedData rRelmTest.fObservedData vXLim(1)];
    vPatch2X = [rRelmTest.fObservedData vXLim(2) vXLim(2) rRelmTest.fObservedData];
    patch(vPatch1X, vPatch1Y, [0.8 0.8 0.8], 'facealpha', 0.7);
    patch(vPatch2X, vPatch2Y, [0.8 0.8 0.8], 'facealpha', 0.7);

    % Add information
    title(['\alpha = ' num2str(rRelmTest.fAlpha) ', \beta = ' num2str(rRelmTest.fBeta)]);
    ylabel('Fraction of cases');
    xlabel(sXLabel);
end


% RECOMBIN.M       (RECOMBINation high-level function)
%
% This function performs recombination between pairs of individuals
% and returns the new individuals after mating. The function handles
% multiple populations and calls the low-level recombination function
% for the actual recombination process.
%
% Syntax:  NewChrom = recombin(REC_F, OldChrom, RecOpt, SUBPOP)
%
% Input parameters:
%    REC_F     - String containing the name of the recombination or
%                crossover function
%    Chrom     - Matrix containing the chromosomes of the old
%                population. Each line corresponds to one individual
%    RecOpt    - (optional) Scalar containing the probability of
%                recombination/crossover occurring between pairs
%                of individuals.
%                if omitted or NaN, 1 is assumed
%    SUBPOP    - (optional) Number of subpopulations
%                if omitted or NaN, 1 subpopulation is assumed
%
% Output parameter:
%    NewChrom  - Matrix containing the chromosomes of the population
%                after recombination in the same format as OldChrom.

%  Author:    Hartmut Pohlheim
%  History:   18.03.94     file created

function NewChrom = recombin(REC_F, Chrom, RecOpt, SUBPOP);

% Check parameter consistency
   if nargin < 2, error('Not enough input parameter'); end

   % Identify the population size (Nind)
   [Nind,Nvar] = size(Chrom);

   if nargin < 4, SUBPOP = 1; end
   if nargin > 3,
      if isempty(SUBPOP), SUBPOP = 1;
      elseif isnan(SUBPOP), SUBPOP = 1;
      elseif length(SUBPOP) ~= 1, error('SUBPOP must be a scalar'); end
   end

   if (Nind/SUBPOP) ~= fix(Nind/SUBPOP), error('Chrom and SUBPOP disagree'); end
   Nind = Nind/SUBPOP;  % Compute number of individuals per subpopulation

   if nargin < 3, RecOpt = 0.7; end
   if nargin > 2,
      if isempty(RecOpt), RecOpt = 0.7;
      elseif isnan(RecOpt), RecOpt = 0.7;
      elseif length(RecOpt) ~= 1, error('RecOpt must be a scalar');
      elseif (RecOpt < 0 | RecOpt > 1), error('RecOpt must be a scalar in [0, 1]'); end
   end

% Select individuals of one subpopulation and call low level function
   NewChrom = [];
   for irun = 1:SUBPOP,
      ChromSub = Chrom((irun-1)*Nind+1:irun*Nind,:);
      NewChromSub = feval(REC_F, ChromSub, RecOpt);
      NewChrom=[NewChrom; NewChromSub];
   end

% End of function


classdef(Abstract) ZmapFunction < matlab.mixin.Copyable
    %ZmapFunction base class for functions in Zmap, providing a common interface
    %   expects that functions can be called from command prompt or menus
    %
    %  To use, first create a class that inherits from ZmapFunction and provides
    %  the following:
    %
    %
    %     define variables here that would be used in calculation
    %
    %   ZmapFunction Properties(Constant):
    %      PlotTag - string name used to access all items from the plot this creates.
    %
    %
    %   ZmapFunction Methods:
    %
    %       The following methods are RECOMMENDED, but do not need to be defined in your derrived
    %       class:
    %
    %       ModifyGlobals - change ZmapGlobal.Data items here. If possible: ONLY here.
    %
    %       The following methods MUST BE DEFINED.  They provide a
    %       coherent framework for this function's behaviors and to make it easy to
    %       control when this routine does things (IO, for example)
    %
    %       function obj=<name of this class/function>(varargin)
    %           % this is your function constructor that should behave so:
    %           % if varargin is empty, then do the interactive setup.
    %           % otherwise, check pronditions, calculate values, plot, and then modify globals.
    %
    %       InteractiveSetup - create a ZmapDialog that provides the user a way to manipulate parameters used by the Calculate() method.
    %
    %       Calculate - do the calculations, and put all important results into fields of the obj.Results variable.
    %         optionally return the Results so that the caller can directly manipulate them
    %
    %       plot - plot the results of this function
    %
    %  METHODS(Static)
    %       AddMenuItem - create a menu item that calls the constructor
    %
    %
    % TROUBLESHOOTING HELP.
    %    If not all methods have been created, then MATLAB will fail to create
    %    your function with a message "Abstract classes cannot be instantiated."
    %    that includes a clickable link.  Click it go get a list of methodes/properties
    %    that still need to be created.
    %
    %
    % see also ZmapDialog, sample_ZmapFunction, blank_ZmapFunction, ZmapQuickResultPcolor

    properties
        % THESE ARE ACCESSIBLE BY ALL DERRIVED CLASSES

         % holds complete catalog to be analyzed. defaults to the primary catalog
        RawCatalog      {mustBeZmapCatalog}  = ZmapGlobal.Data.primeCatalog
        Result          struct            % results of the calculation, stored in a struct

        ZG                           = ZmapGlobal.Data; % provides access to the ZMAP global variables.
        hPlot                               % tracks the plot(s) for each function
        ax                           = [];       % axis where plotting will go

        AutoShowPlots   logical      = true; % will plots be generated upon calculation?
        InteractiveMode logical      = true;
        DelayProcessing logical      = false;
        CalcFinishedFcn function_handle = @do_nothing ; %call this once calculation ("do it") has finished.
    end

    properties(Constant,Abstract)
        PlotTag % string used for tracking the plot for each function (assign in your function)
        ParameterableProperties % properties from each class that can be used as constructor parameters
        References % paper references for calculations contained within this fn
    end

    properties(Transient)
        ResultDisplayer ResultsDisplay.ZmapResultsPlugin = ResultsDisplay.Hdisplay% chosen from +ResultsDisplay
    end

    properties(Dependent)
        FunctionCall    char; % text representation of the function call.
    end

    methods
        function obj=ZmapFunction(catalog)
            if exist('catalog','var')
                obj.RawCatalog=catalog;
                obj.verify_catalog(catalog);
            end
            obj.ResultDisplayer.Parent = obj;
        end

        function fcall = get.FunctionCall(obj)
            % FUNCTIONCALL provides probable function call for CURRENT STATE of object
            % obj.SETFUNCTIONCALL(varargin)

            fcall = class(obj) + "(ZAP";
            for j=1:numel(obj.ParameterableProperties)
                fld = obj.ParameterableProperties(j);
                val=obj.(fld);
                switch class(val)
                    case 'char'
                        fcall = fcall + sprintf(", '%s', '%s'", fld, val);
                    case 'string'
                        fcall = fcall + sprintf(', ''%s'', "%s"', fld, val);
                    case 'datetime'
                        fcall = fcall + sprintf(", '%s', datetime('%s')", fld, string(val));
                    case 'duration'
                        val.Format = 'dd:hh:mm:ss.SSS';
                        fcall = fcall + sprintf(", '%s', duration('%s')", fld,string(val));
                    case 'McMethods'
                        fcall = fcall + sprintf(", '%s', McMethods.%s", fld,string(val));

                    otherwise
                        if isnumeric(val) && isempty(val)
                            val = '[]';
                        elseif (isnumeric(val) || islogical(val)) && numel(val)>1
                            v="";
                            for r=1:size(val,1)
                                v(r)=strjoin(string(val(r,:)),',');
                            end
                            val="[" + strjoin(v,';') + "]";
                        else
                            try
                            val=string(val);
                            if ismissing(val)
                                val = "<missing>";
                            end
                            catch
                                val = "<some " + class(val) + ">";
                            end
                        end
                        fcall = fcall + sprintf(", '%s', %s", fld, val);
                end
            end
            fcall = fcall + ", 'AutoShowPlots', " + string(obj.AutoShowPlots);
            fcall = fcall + ", 'InteractiveMode', " + string(obj.InteractiveMode);
            % fcall = fcall + ", 'DelayProcessing', " + string(obj.DelayProcessing);
            fcall = fcall + ")";
        end

        function p = parseParameters(obj, varginstuff)

            % property list is a list of this objects properties that
            % can be set via the parameter list.
            p=inputParser();
            for i=1:numel(obj.ParameterableProperties)
                % use this object's default properties as the... uh. default.
                p.addParameter(obj.ParameterableProperties(i), obj.(obj.ParameterableProperties(i)));
            end

            % add parameters inheritable by all functions
            p.addParameter('AutoShowPlots',   obj.AutoShowPlots)
            p.addParameter('InteractiveMode', obj.InteractiveMode);
            p.addParameter('DelayProcessing', obj.DelayProcessing);
            p.addParameter('CalcFinishedFcn', obj.CalcFinishedFcn);
            p.parse(varginstuff{:});

            % assign values from parameter to this object
            for i=1:numel(obj.ParameterableProperties)
                obj.(obj.ParameterableProperties(i)) = p.Results.(obj.ParameterableProperties(i));
            end
            obj.AutoShowPlots = p.Results.AutoShowPlots;
            obj.InteractiveMode = p.Results.InteractiveMode;
            obj.DelayProcessing = p.Results.DelayProcessing;
            obj.CalcFinishedFcn = p.Results.CalcFinishedFcn;
        end

        function StartProcess(obj)
            if obj.DelayProcessing
                msg.dbdisp('Delaying processing',class(obj))
                return
            end

            if obj.InteractiveMode
                obj.InteractiveSetup();
            else
                obj.doIt();
            end
        end

        function clearPlot(obj)
            % CLEARPLOT remove all plot items added by this function
            delete(obj.hPlot);
            obj.hPlot=[];
        end

        function doIt(obj)
            % DOIT called by the interactive dialog box once OK is pressed.
            % Calls, in turn: Calculate, plot, ModifyGlobals, saveToDesktop
            %
            % each of these functions is defined in the subclass.
            % change DOIT behavior by redefining DOIT in the sublcass.
            obj.Calculate();
            if obj.AutoShowPlots
                obj.plot();
            end
            obj.ModifyGlobals();
            obj.saveToDesktop();
        end

        function  ModifyGlobals(obj)
            % MODIFYGLOBALS modify zmapglobals (define in subclass)
            % do any changing of zmap globals here
            do_nothing(obj)
        end

        function saveToDesktop(obj)
            % SAVETODESKTOP saves results to desktop
            vname = matlab.lang.makeValidName([class(obj),'_result']);
            %assert(~isfield(obj.Result,'FunctionCall'), 'FunctionCall is a reserved field in the results');
            obj.Result.FunctionCall = obj.FunctionCall;

            obj.Result.InCatalogName = obj.RawCatalog.Name; %was OperatingCatalog
            assignin('base', vname, obj.Result);
            fprintf('%s  %% called by Zmap : %s\n',obj.FunctionCall, char(datetime));
            fprintf('%% results in: %s\n',vname);
        end

        function plot(obj, varargin)
            obj.ResultDisplayer.plot(varargin{:})
        end
    end % PUBLIC METHODS

    methods(Abstract)  % these functions MUST be defined in every class derived from ZmapFunction

        % INTERACTIVESETUP ask the user for additional parameters necessary for the calculation
        InteractiveSetup(obj);

        % CALCULATE perform calculations
        % obj.CALCULATE() stores results in obj.Result  (obj.Result.values = results)
        % RESULTS = OBJ.CALCULATE() also, return results
        Results=Calculate(obj);

        % PLOT visually communicate results to the user
        %
        % obj.PLOT(varargin) plot results, passing along all parameters

    end %ABSTRACT METHODS

    methods % will be protected
        function t = helptext(obj, subject)
            % provides help text, based on the subject.
            % -all lists everything
            % -choice gives list of topics one can ask about
            switch subject
                case 'PlotTag'
                    t = "Title for this plot will be '" + obj.PlotTag+"'";
                case 'ParameterableProperties'
                    m=metaclass(obj);
                    t = "Name-Value pairs that can be specified when creating this function:"+newline+...
                        "";
                    plist = [string(obj.ParameterableProperties),"AutoShowPlots","InteractiveMode","DelayProcessing"];
                    for j=1:numel(plist)
                        pidx=string({m.PropertyList.Name})==plist(j);
                        p = m.PropertyList(pidx);
                        t=t+newline+"   "+ pad(plist(j),20,'right') + " : " + class(obj.(plist(j)));
                        if p.HasDefault
                            if numel(p.DefaultValue)>0 && (isnumeric(p.DefaultValue) || islogical(p.DefaultValue))
                                dv=string(mat2str(p.DefaultValue));
                            else
                                dv = string(p.DefaultValue);
                            end
                            if ismissing(dv)
                                if isnumeric(p.DefaultValue)
                                    dv="nan";
                                else
                                    dv="<missing>";
                                end
                            end

                        if dv.strlength > 33
                            dv=dv.extractBefore(15) + "..."+dv.extractAfter(dv.strlength-14);
                        end
                            t=t+" [default: "+dv+"]";
                        end
                        try
                        if ~isempty(p.Validation) && ~isempty(p.Validation.ValidatorFunctions)
                            fn = cellfun(@func2str,p.Validation.ValidatorFunctions,'UniformOutput',false);
                            t=t+ " that " + strjoin(fn,',');
                        end
                        catch ME
                            disp("error wile parsing validator functions:"+ ME.identifier)
                        end
                    end

                    if ~isempty(plist)
                        pv = obj.(obj.ParameterableProperties(1));
                        if ischar(pv)
                            pp = sprintf("'%s'",pv);
                        elseif isstring(pv)
                            pp = sprintf('"%s"',pv);
                        elseif isa(pv,'function_handle')
                            pp = sprintf('@%s', func2str(pv)');
                        elseif (isnumeric(pv) || islogical(pv)) && length(pv)>1
                            pp=string(mat2str(pv));
                        else
                            try
                                pp = string(pv);
                            catch
                                pp="some_"+ class(pv);
                            end
                        end

                        t = t+ newline+newline+ "For example:"+newline+...
                            "    obj = "+class(obj) +"(... , '" + ...
                            obj.ParameterableProperties(1) + "', " + ...
                            pp + ")";
                    end

                    assert(numel(t)==1)

                case "ReturnDetails"
                    t = "This function calculates :" + newline + ...
                        strjoin("  "+pad(obj.ReturnDetails.Names,20,'right') + " "+ obj.ReturnDetails.Descriptions,newline);

                case "References"
                    t = "References for this function:"+newline;
                    padValue = "  ";
                    r = strjoin(padValue + string(obj.References),newline);
                    if r~=padValue
                        t = t + r;
                    else
                        t = t + "   <missing>";
                    end

                case "-choices"
                    t = ["PlotTag","ParameterableProperties","ReturnDetails", "References"];
                    t = [t,  obj.ResultDisplayer.helptext(subject)];
                    t = t(~ismissing(t)) ;
                case "-all"
                    ch = obj.helptext("-choices");
                    t="";
                    for i=1:numel(ch)
                        t = t+ newline + newline + obj.helptext(ch(i));
                    end

                otherwise
                    placesToLook = "ResultDisplayer"; %comma separated string list
                    for i = placesToLook
                        t = obj.ResultDisplayer.helptext(subject);
                        if ~ismissing(t)
                            return
                        end
                    end
                    error('help for item %s not found', subject)
             end
        end
    end

    methods(Static, Abstract)

        % create a menu item that will be used to call this function/class (Define this as a static member of your class)
        %    sample implementation here:
        %
        %    function h = AddMenuItem(parent, zapFcn, varargin)
        %        % ADDMENUITEM create a menu item that will be used to call this function/class
        %        % h = AddMenuItem(parent, zapFcn) creates a menu item under the container PARENT
        %        %     that will call this class/fuction.  ZAPFCN is a function_handle that, when
        %        %     called returns a ZmapAnalysisPkg containing all the state details used to
        %        %     process the data.
        %
        %       label = 'testmenuitem';                        % CHANGE THIS TO YOUR MENUNAME
        %       cb = @(~,~)sample_ZmapFunction(zapFcn());      % CHANGE THIS TO YOUR CALLBACK
        %       h = uimenu(parent, 'Label', label, 'MenuSelectedFcn', cb, varargin{:});
        %    end
        %
        % you can copy/paste the above into your Static methods section
        AddMenuItem(parent, zapFcn, varargin)

    end % STATIC ABSTRACT METHODS

    methods(Static, Access=protected)
        function verify_catalog(c)
            % VERIFY_CATALOG makes sure the catalog is valid and has events
            % verify_catalog( CATALOG )
            assert(~isempty(c),'Catalog is empty');
            assert(isa(c,'ZmapCatalog'),'Please provide a Zmap catalog, not a ',class(c));
        end
    end
end


function [MetsAndRxns, pVal_up, pVal_down, Dir_1, Dir_2] = compareConditions(MetConnectivity1, ConnectedMet1, MetConnectivity2, ConnectedMet2)
% This function compare reaction score of both sampling condition
% and identify metabolites that change significantly
%
% USAGE:
%
%    [MetsAndRxns, pVal_up, pVal_down, Dir_1, Dir_2] = compareConditions(MetConnectivity1, ConnectedMet1, MetConnectivity2, ConnectedMet2)
%
% INPUTS:
%    MetConnectivity1:    A structure that present, for each
%                         metabolite present in the model sampled under first
%                         condition the following sets of fields:
%
%                           * ConnRxns - the reactions that are connected
%                             to the metabolite
%                           * Sij - The stoichiometric coefficient for the
%                             metabolite in each reaction in `ConnRxns`
%                           * RxnScore - Score for each reaction in `ConnRxns`
%                           * Direction - The direction of reaction flux
%                             for each sample point
%                           * MetNotUsed - Whether or not the metabolite is
%                             used in the condition
%    ConnectedMet1:       List of metabolites described in `MetConnectivity1`
%    MetConnectivity2:    Same as `MetConnectivity1` but for `model`
%                         sampled under the second condition
%    ConnectedMet2:       List of metabolites described in `MetConnectivity2`
%
% OUTPUTS:
%    MetsAndRxns:         Cell arrays containing in the first column
%                         the list of metabolites that significantly change
%                         under both sampling conditions and in the second
%                         column the reactions that are connected to
%                         these metabolites
%    pVal_up:             p-value associated to upregulated
%                         `MetsAndRxns`
%    pVal_down:           p-value associated to downregulated
%                         `MetsAndRxns`
%    Dir_1:               reaction directionality for model sampled under first
%                         condition (1 producing metabolite, -1
%                         consuming the metabolite)
%    Dir_2:               Same as `Dir_1` but for model
%                         sampled under the second condition
%
% .. Authors:
%       - Nathan E. Lewis, May 2010-May 2011
%       - Anne Richelle, May 2017

Met1=MetConnectivity1.(ConnectedMet1{1});
Met2=MetConnectivity2.(ConnectedMet2{1});
% Get the minimum number of points used to score reactions in the two
% conditions
MinNumPts = min([length(Met1.RxnScore(1,:)) length(Met2.RxnScore(1,:))]);

% only look at nodes shared between the sampled models
ConnectedMet = intersect(ConnectedMet1,ConnectedMet2);
MetsAndRxns={};
pVal_up=[];
pVal_down=[];
Dir_1 = [];
Dir_2 = [];

for i = 1:length(ConnectedMet)

    Met1=MetConnectivity1.(ConnectedMet{i});
    Met2=MetConnectivity2.(ConnectedMet{i});

    FracNotUsed1 = sum(Met1.MetNotUsed(1:MinNumPts))/(MinNumPts); % fraction of the sample points not using this node in model1
    FracNotUsed2 = sum(Met2.MetNotUsed(1:MinNumPts))/(MinNumPts); % fraction of the sample points not using this node in model2

    % ignore nodes that are used in less than 10% of the sample points in one
    % condition
    if and(FracNotUsed1<.9,FracNotUsed2<.9)

        % subtract scores of 2nd condition from the 1st condition
        tmp = Met1.RxnScore(:,1:MinNumPts) - Met2.RxnScore(:,1:MinNumPts);

        % p of increasing flux is obtained by subtracting 2nd from 1st and
        % finding how many are > or < 0 for the pvalue for up and down,
        % respectively. (many >= 0 means 2nd condition was lower, so high
        % p-value for up and low for down, suggesting that the flux dropped
        % in the 2nd condition
        p_up = sum(tmp>=0,2)/length(tmp(1,:));
        p_down = sum(tmp<=0,2)/length(tmp(1,:));

        % This computes the median direction, just to give an idea which
        % direction the reaction tends to go in the conditions
        tmp_Dir1 = median(Met1.Direction(:,1:MinNumPts),2);
        tmp_Dir2 = median(Met2.Direction(:,1:MinNumPts),2);

        % Go through each reaction and build arrays with the reactions, the
        % branch-point metabolites, and p-values, and reaction directionality
        % (i.e., in or out of the central metabolite)
        for j = 1:length(tmp(:,1))
            if ~all(tmp(j,:)==0) % skip reactions that carry no flux or don't change at all
                MetsAndRxns{end+1,1} =ConnectedMet{i};
                MetsAndRxns{end,2}=Met1.ConnRxns{j};
                pVal_up(end+1,1)=p_up(j);
                pVal_down(end+1,1)=p_down(j);
                Dir_1(end+1,1)= tmp_Dir1(j);
                Dir_2(end+1,1)= tmp_Dir2(j);
            end
        end

    end
end

end


function [nu] = tapas_ti_init_u(u, ptheta, pars)
%%
%
% aponteeduardo@gmail.com
% copyright (C) 2016
%

nu = cell(1, numel(pars.T));
nu(:) = {u};

end


%SETRNGSEED  Sets state of default random number generator
%
%     cv.setRNGSeed(seed)
%
% ## Input
% * __seed__ integer, new state for default random number generator.
%
% The function cv.setRNGSeed sets state of default random number generator to
% custom value.
%
% See also: rng, rand, randn
%


function v = tfocs_size( x )

% SIZE   TFOCS-friendly size operator.

v = { @zeros, m, n };

% TFOCS v1.3 by Stephen Becker, Emmanuel Candes, and Michael Grant.
% Copyright 2013 California Institute of Technology and CVX Research.
% See the file LICENSE for full license information.


function [M]=unpadeven(M_pad,L_even_dim)

num_dims=ndims(M_pad);
siz=size(M_pad)-L_even_dim;
switch num_dims
    case 2
        M=M_pad(1:1:siz(1),1:1:siz(2));
    case 3
        M=M_pad(1:1:siz(1),1:1:siz(2),1:1:siz(3));
end

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


function seedRNG(s)
%SEEDRNG   Seed the MATLAB random number generator.
%   SEEDRNG(S) seeds the MATLAB random number generator with the integer value
%   S.  This function is meant to provide an interface for seeding the RNG that
%   is independent of the currently installed version of MATLAB.  It is used
%   solely for seeding the RNG in tests which use random numbers to ensure
%   deterministic behavior between runs.
%
%   Users should NOT call this function from their own code, as it may be
%   removed without warning in a future release.

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

if ( verLessThan('matlab', '7.12') )
    % Before R2011a.
    rand('seed', s);
    randn('seed', s);
else
    % R2011a and later
    rng('default');
    rng(s);
end

end


classdef TestPlotting < testUnfitted

    properties (Access = protected)
        testName;
        meshType;
        meshIncludeBoxContour;
    end

    properties (Access = private)
        varAdim
    end

    methods (Access = public)

        function obj = TestPlotting(cParams)
            obj.init(cParams);
            obj.createTopOpt();
            obj.createMesh();
            obj.plot();
        end

        function plot(obj)
            figure();
            if isequal(obj.meshType,'BOUNDARY')
                obj.unfittedMesh.plotBoundary();
                obj.unfittedMesh.plotNormals();
            elseif isequal(obj.meshType,'INTERIOR')
                obj.unfittedMesh.plot();
            end
            view(obj.getViewAngle());
        end

        function passed = computePassed(obj)
            d = load(obj.testName);
            unfittedMesh = obj.unfittedMesh;
            loaded = d.unfittedMesh;
            passed = isequaln(unfittedMesh,loaded);
            if ~passed
                save(obj.testName, 'unfittedMesh', '-append')
            end
        end

        function overwriteResults(obj)
            save(obj.testName, 'unfittedMesh', '-append')
        end

    end

    methods (Access = private)

        function init(obj, cParams)
            obj.testName        = cParams.testName;
            obj.meshType        = cParams.meshType;
            obj.meshIncludeBoxContour = cParams.meshIncludeBoxContour;
        end

        function angle = getViewAngle(obj)
            if isprop(obj,'viewAngle')
                angle = obj.viewAngle;
            else
                angle = [0 0 1];
            end
        end

    end

    %% Heredat de testUnfitted, s'ha de declarar buit
    methods (Access = protected)
        function printTestNotPassed()
        end
        function printTestPassed()
        end
        function hasPassed()
        end
    end
end


function amplitudes = LoadSpikeAmplitudes(filename,nChannels,nSamples,peak,rate)

%LoadSpikeAmplitudes - Read spike times, cluster IDs and amplitudes from disk.
%
%  USAGE
%
%    amplitudes = LoadSpikeAmplitudes(filename,nChannels,nSamples)
%
%    filename            spike waveform file name
%    nChannels           number of channels in electrode group
%    nSamples            number of samples per waveform
%    peak                peak sample (1..N)
%    rate                sampling rate
%
%  SEE
%
%    See also GetSpikeAmplitudes, LoadSpikeWaveforms.

% Copyright (C) 2004-2012 by Michaël Zugaro
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 3 of the License, or
% (at your option) any later version.

if nargin < 3,
  error('Incorrect number of parameters (type ''help LoadSpikeAmplitudes'' for details).');
end

[path,basename,extension] = fileparts(filename);
if isempty(path), path = '.'; end

electrodeGroupStr = extension(2:end);
electrodeGroup = str2num(electrodeGroupStr);
[~,basename] = fileparts(basename);

% Times and cluster IDs
times = LoadSpikeTimes(filename,rate);

% Load .spk file
filename = [path '/' basename '.spk.' electrodeGroupStr];
if ~exist(filename),
	error(['File ''' filename ''' not found.']);
end
amp = LoadBinary(filename,'offset',peak-1,'skip',nSamples-1,'nChannels',nChannels);

amplitudes = [times amp];


function status = GE_convertADW(inDir,outStem,starttime,nvols)
%
% status = GE_convertADW(inDir,outStem,starttime,nvols)
%
%GE_convertADW
%
% Version 3.1
%
% Converts a series of GE slices acquired on the Advanced
% Development Workstation into Analyze format for SPM.
% inDir is the name of the first directory containing the
%      series, e.g. 003
% outStem is the stem used for naming the Analyze files
% starttime is the time point number to start
% nvols is the number of volumes (time points) to convert
%
% status = 1, error
% status = 0, all is well
%
% eg GE_convert('DATA/00023/003','converted',5,27)
% Will convert 27 time points starting at the 5th time point
% named converted_i0001.img, converted_i0002.img, ...,
% converted_i0027.img and their associated header and mat files.
%
% Assumes the data is stored as 003/I.001 through 003/I.999 and
% then 023/I.001 through 023/I.999, etc.
% Remember to skip the template images ie 1 time point for the
% first run.  You don't need to do this for subsequent runs.
%
% Modified to use spm write functions
% Modified to use spm_write_plane instead of spm_write_vol
%
% Souheil J. Inati
% Dartmouth College
% September 2001
% souheil.inati@dartmouth.edu
%

if (nargin < 4)
        error('Not enough input arguments.')
        return
end

% Create the name of the first file in inDir
firstfile = fullfile(inDir,'I.001');

% Read the Header from the first file
[su_hdr,ex_hdr,se_hdr,im_hdr,pix_hdr,im_offset] = GE_readHeader(firstfile);

% The image Dimensions
Nx =  im_hdr.imatrix_X; % X Voxels
Ny =  im_hdr.imatrix_Y; % Y Voxels
Nz =  im_hdr.slquant;   % Z Voxels
volSize = [Nx Ny Nz];

% Is the first image the first or the last?
if (se_hdr.end_loc - se_hdr.start_loc) > 0
  scandir = 1;
else
  scandir = -1;
end

% Compute the M matrix
M = GE_createSPMmat(im_hdr,scandir);

% Create the template SPM volume structure
V.fname = '';
V.dim = [volSize spm_type('int16')]; % short ints
V.mat = M;
V.pinfo = [1 0 0]';

% Loop over the volumes until there is no more looping to be done.
for i = 1:nvols
  passnum = starttime + i - 1;

  % Read in the volume
  [imageVol, lastfile] = GE_readVolume(inDir, passnum, volSize, ...
				       pix_hdr.img_depth, im_offset);

  % Create analyze file
  vol_str = sprintf('000%d',i);
  vol_str = vol_str(length(vol_str)-3:length(vol_str));
  outName = [outStem sprintf('_i%s.img',vol_str)];
  V.fname = outName;
  V = spm_create_image(V);

  % Write out the SPM Volume
  % Don't use spm_write_vol because that sets a scale factor.
  for i = 1:Nz
    V = spm_write_plane(V,squeeze(imageVol(:,:,i)),i);
  end

  % Update to the screen
  fprintf('Wrote %s\n',outName);

end

% Done
fprintf('\nConversion Finished. \n');

return


function [varargout] = isrow(varargin)

% ISROW is a drop-in replacement for the same function that was
% introduced in MATLAB R2010b.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% try to automatically remove incorrect compat folders from the path, see https://github.com/fieldtrip/fieldtrip/issues/899

if isempty(strfind(mfilename('fullpath'), matlabroot))
  % automatic cleanup does not work when FieldTrip is installed inside the MATLAB path, see https://github.com/fieldtrip/fieldtrip/issues/1527

  alternatives = which(mfilename, '-all');
  if ~iscell(alternatives)
    % this is needed for octave, see https://github.com/fieldtrip/fieldtrip/pull/1171
    alternatives = {alternatives};
  end

  keep = true(size(alternatives));
  for i=1:numel(alternatives)
    keep(i) = keep(i) && ~any(alternatives{i}=='@');  % exclude methods from classes
    keep(i) = keep(i) && alternatives{i}(end)~='p';   % exclude precompiled files
  end
  alternatives = alternatives(keep);

  if exist(mfilename, 'builtin') || any(strncmp(alternatives, matlabroot, length(matlabroot)) & cellfun(@isempty, strfind(alternatives, fullfile('private', mfilename))))
    % remove this directory from the path
    p = fileparts(mfilename('fullpath'));
    warning('removing "%s" from your path, see http://bit.ly/2SPPjUS', p);
    rmpath(p);
    % call the original MATLAB function
    if exist(mfilename, 'builtin')
      [varargout{1:nargout}] = builtin(mfilename, varargin{:});
    else
      [varargout{1:nargout}] = feval(mfilename, varargin{:});
    end
    return
  end

end % automatic cleanup of compat directories

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% this is where the actual replacement code starts
% function tf = isrow(x)

% deal with the input arguments
if nargin==1
  [x] = deal(varargin{1:1});
else
  error('incorrect number of input arguments')
end

tf = length(size(x))==2 && size(x,1)==1;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% deal with the output arguments

varargout = {tf};


% std_renameclust()  - Commandline function, to rename clusters using specified (mnemonic) names.
% Usage:
%                   >> [STUDY] = std_renameclust(STUDY, ALLEEG, cluster, new_name);
% 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.
%   new_name  - [string] mnemonic cluster name.
%
% Outputs:
%   STUDY    - the input STUDY set structure modified according to specified new cluster name.
%
%   Example:
%                         >> cluster = 7; new_name = 'artifacts';
%                         >> [STUDY] = std_renameclust(STUDY,ALLEEG, cluster, new_name);
%                    Cluster 7 name (i.e.: STUDY.cluster(7).name) will change to 'artifacts 7'.
%
%  See also  pop_clustedit
%
% Authors:  Hilit Serby, Arnaud Delorme, Scott Makeig, SCCN, INC, UCSD, June, 2005

% Copyright (C) Hilit Serby, SCCN, INC, UCSD, June 07, 2005, hilit@sccn.ucsd.edu
%
% 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 STUDY = std_renameclust(STUDY, ALLEEG, cls, new_name)

if ~exist('cls')
    error('std_renameclust: you must provide a cluster number to rename.');
end
if isempty(cls)
   error('std_renameclust: you must provide a cluster number to rename.');
end
if ~exist('new_name')
    error('std_renameclust: you must provide a new cluster name.');
end
if strncmpi('Notclust',STUDY.cluster(cls).name,8)  % Don't rename Notclust 'clusters'
    warndlg2('std_renameclust: Notclust cannot be renamed');
    return;
end

ti = strfind(STUDY.cluster(cls).name, ' ');
clus_id = STUDY.cluster(cls).name(ti(end) + 1:end);
new_name = sprintf('%s %s', new_name, clus_id);
% If the cluster have children cluster update their parent cluster name to the
% new cluster.
if ~isempty(STUDY.cluster(cls).child)
    for k = 1:length(STUDY.cluster(cls).child)
        child_cls = STUDY.cluster(cls).child{k};
        child_id = find(strcmp({STUDY.cluster.name},child_cls));
        parent_id = find(strcmp(STUDY.cluster(child_id).parent,STUDY.cluster(cls).name));
        STUDY.cluster(child_id).parent{parent_id} = new_name;
    end
end
% If the cluster has parent clusters, update the parent clusters with the
% new cluster name of child cluster.
if ~isempty(STUDY.cluster(cls).parent)
    for k = 1:length(STUDY.cluster(cls).parent)
        parent_cls = STUDY.cluster(cls).parent{k};
        parent_id = find(strcmp({STUDY.cluster.name},parent_cls));
        STUDY.cluster(parent_id).child{find(strcmp(STUDY.cluster(parent_id).child,STUDY.cluster(cls).name))} = new_name;
    end
end
% If the cluster have an Outlier cluster, update the Outlier cluster name.
outlier_clust = std_findoutlierclust(STUDY,cls); %find the outlier cluster for this cluster
if outlier_clust ~= 0
    ti = strfind(STUDY.cluster(outlier_clust).name, ' ');
    clus_id = STUDY.cluster(outlier_clust).name(ti(end) + 1:end);
    STUDY.cluster(outlier_clust).name = sprintf('Outliers %s %s', new_name, clus_id);
end

% Rename cluster
STUDY.cluster(cls).name = new_name;


function x = vec(X)
x = X(:);


function cont=progress(status,rate)
%PROGRESS   Text progress bar
%   Similar to waitbar but without the figure display.
%
%   Start:
%      C = PROGRESS('init',TITLE), where the default TITLE is 'please wait'
%
%   On progress:
%      C = PROGRESS(C,RATE);
%
%   Examples:
%      n=20;
%      for i=1:n
%        if i==1, c=progress('init');
%        else     c=progress(c,i/n); end
%
%        % computing something ...
%        pause(.1)
%      end
%
%      % inside a script you may use:
%       c=progress('init','wait for ... whatever');
%       for i=1:n
%         c=progress(c,i/n);
%         ...
%       end
%

lmax=50;
if isequal(status,'init')
  if nargin > 1
    title = rate;
    fprintf(1,'\n   %s\n',title);
    str = repmat(' ',1,lmax-4);
  else
    str = '                please wait                   ';
    fprintf(1,'\n');
  end
  fprintf(1,'  |-%s-|\n',str);
  fprintf(1,'%s','  ');
  cont=0;
else
  cont = status;
  n=ceil(rate*lmax);
  dif = n - cont;
  if dif > 0 & n <=lmax
    N=dif;
  else
    N=0;
  end
  cont=cont+N;
  str = repmat('*',1,N);
  fprintf(1,'%s',str);
  if rate==1
   fprintf(1,'%s\n',' done');
  end
end


function yn = has_mex_jmh
% for advanced features of this toolbox.

yn = which('jmh_sse_mex'); % seems to force a path check ??

yn =	...
	exist('jmh_sse_mex') == 3;

persistent Mexwarned
if isempty(Mexwarned)
	Mexwarned = 0;
end

if ~yn & ~Mexwarned
  warning('mex files not found: are your paths correct?')
  Mexwarned = 1;
end


2     % problem
4     % grid parameter
2     % discretisation
0.25  % Stokes stabilization parameter

%% Data file for test problem S2


function nleqopt = mpopt2nleqopt(mpopt, model, alg)
%MPOPT2NLEQOPT   Create/modify NLEQS_MASTER options struct from MPOPT.
%
%   NLEQOPT = MPOPT2NLEQOPT(MPOPT, MODEL)
%   NLEQOPT = MPOPT2NLEQOPT(MPOPT, MODEL, ALG)
%
%   Uses a MATPOWER options struct, MPOPT, to create or modify an
%   NLEQS_MASTER options struct.
%
%   Inputs (default values in parentheses):
%       MPOPT : MATPOWER options struct
%       MODEL ('NLEQ') : (optional) one of the following model types, required
%               for selection of solver in case ALG is 'DEFAULT' (solver
%               precedence for each model type list in parentheses):
%           'NLEQ' - nonlinear equation with all continuous variables
%                   (NEWTON, FSOLVE)
%       ALG ('pf.alg') : (optional) 'pf.alg' or any valid value of
%               OPT.alg for NLEQS_MASTER. The first option indicates that
%               it should be taken from MPOPT.pf.alg.
%
%   Output:
%       NLEQOPT : an options struct for use by NLEQS_MASTER and friends
%
%   See NLEQS_MASTER, MPOPTION.

%   MP-Opt-Model
%   Copyright (c) 2015-2020, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MP-Opt-Model.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://github.com/MATPOWER/mp-opt-model for more info.

%% set default args
if nargin < 3
    alg = '';
    if nargin < 2
        model = '';
    end
end
if isempty(model)
    model = 'NLEQ';
else
    model = upper(model);
end

%% get ALG, MAX_IT from mpopt, if necessary
switch alg
    case {'pf.alg', ''}
        alg = upper(mpopt.pf.alg);
    otherwise
        alg = upper(alg);
end

%% create NLEQS_MASTER options struct
nleqopt = struct(   'verbose',  mpopt.verbose, ...
                    'alg',      alg, ...
                    'tol',      mpopt.pf.tol  );
switch alg
    case {'DEFAULT', 'NEWTON'}
        %% set up options
        nleqopt.newton_opt.lin_solver = mpopt.pf.nr.lin_solver;
        nleqopt.max_it = mpopt.pf.nr.max_it;
    case 'FD'
        nleqopt.max_it = mpopt.pf.fd.max_it;
    case 'GS'
        nleqopt.max_it = mpopt.pf.gs.max_it;
    case 'ZG'
        nleqopt.max_it = mpopt.pf.zg.max_it;
        nleqopt.alg = 'CORE';
    case 'FSOLVE'
        %% basic optimset options needed for fmincon
%         nleqopt.fsolve_opt.Algorithm = '';
%         nleqopt.fsolve_opt.Algorithm = 'trust-region-dogleg';
%         nleqopt.fsolve_opt.Algorithm = 'trust-region';              %% for optimoptions
%         nleqopt.fsolve_opt.Algorithm = 'trust-region-reflective';   %% for optimset
%         nleqopt.fsolve_opt.Algorithm = 'levenberg-marquardt';
        nleqopt.max_it = 0;      %% use fsolve default
end


function ConvertPhyKilo2Neurosuite(basepath,basename)

% Converts Phy kilosort output files into klusters-compatible
% fet,res,clu,spk files.  Works on a single shank of a recording, assumes a
% 16bit .dat, .xml file is present in "basepath" (home folder) and
% that they are named basename.dat and basename.xml.
% It assumes that your directory contains:
% spike_clusters.npy, spikes_times.npy, cluster_group.tsv, pcfeatures.npy,
% templates.npy, cluster_ids.npy and shanks.npy (these last two are
% generated by a phy plugin -Export Shanks- found in the lab wiki)
%
% Inputs:
%   basepath -  directory path to the main recording folder with .dat and .xml
%               as well as shank folders made by makeProbeMapKlusta2.m (default is
%               current directory matlab is pointed to)
%   basename -  shared file name of .dat and .xml (default is last part of
%               current directory path, ie most immediate folder name)
%
% Eliezyer de Oliveira, 2018

if ~exist('basepath','var')
    [~,basename] = fileparts(cd);
    basepath = cd;
end
savepath = basepath;

if ~exist('rez','var');
    load(fullfile(basepath,'rez.mat'))
end

Nchan = rez.ops.Nchan;
connected    = rez.connected;
xcoords      = rez.xc;
ycoords      = rez.yc;
% Nchan = rez.ops.Nchan;
% connected    = ones(Nchan, 1);
% xcoords      = ones(Nchan, 1);
% ycoords      = (1:Nchan)';

par = LoadParameters(fullfile([basepath],[basename '.xml']));

totalch = par.nChannels;
sbefore = 16;%samples before/after for spike extraction
safter = 16;%... could read from SpkGroups in xml
if isfield(par,'SpkGrps')
    if isfield(par.SpkGrps,'nSamples')
        if ~isempty(par.SpkGrps(1).nSamples);
            if isfield(par.SpkGrps,'PeakSample')
                if ~isempty(par.SpkGrps(1).PeakSample);
                    sbefore = par.SpkGrps(1).PeakSample;
                    safter = par.SpkGrps(1).nSamples - par.SpkGrps(1).PeakSample;
                end
            end
        end
    end
end

if exist(rez.ops.fbinary,'file')
    datpath = rez.ops.fbinary;
else
    datpath = fullfile(basepath,[basename '.dat']);
end

%% identify timestamps that are from good clusters
spikeTimes = readNPY('spike_times.npy');
clusters = readNPY('spike_clusters.npy');
S = tdfread('cluster_group.tsv');
group = S.group;
cluster_id = S.cluster_id;
c = 0;
for idx = 1:size(group,1)
    if group(idx,1:4) == 'good'
        c  = c+1;
        GClusters(c) = idx;
    end
end
ExtClus = cluster_id(GClusters);

% Separating idx by cluster
auxiliarC = [];
for idx = 1:length(ExtClus)
    auxC = find(clusters == ExtClus(idx));
    auxiliarC = cat(1,auxiliarC,auxC);
end
[~,I] = sort(auxiliarC);
auxiliarC = auxiliarC(I);
%% getting spike information

spktimes = uint64(readNPY('spike_times.npy'));
spktimes = spktimes(auxiliarC);
clu = uint32(readNPY('spike_clusters.npy'));
clu = clu(auxiliarC);
pcFeatures = readNPY('pc_features.npy');
pcFeatures = pcFeatures(auxiliarC,:,:);
% pcFeatureInds = uint32(readNPY('pc_feature_ind.npy'))';
templates = readNPY('templates.npy');

mkdir(fullfile(savepath,'PhyClus'))
%% assigning cluster ids to shanks
shanks = readNPY('shanks.npy');
cluShank = readNPY('cluster_ids.npy');

auxC = unique(clu);
templateshankassignments = zeros(size(auxC));
for idx = 1:length(auxC)
    temp = find(cluShank == auxC(idx));
    templateshankassignments(idx) = shanks(temp);
end
grouplookup = rez.ops.kcoords;
allgroups = unique(grouplookup);
allgroups(allgroups==0) = [];

for groupidx = 1:length(allgroups)

    %if isfield(par.SpkGrps(groupidx),'Channels')
    %if ~isempty(par.SpkGrps(groupidx).Channels)
    % for each group loop through, find all templates clus
    tgroup          = allgroups(groupidx);%shank number
    ttemplateidxs   = find(templateshankassignments==tgroup);%which templates/clusters are in that shank
    %     ttemplates      = templates(:,:,ttemplateidxs);
    %     tPCFeatureInds  = pcFeatureInds(:,ttemplateidxs);

    tidx            = ismember(clu,auxC(ttemplateidxs));%find spikes indices in this shank
    tclu            = clu(tidx);%extract template/cluster assignments of spikes on this shank
    tspktimes       = spktimes(tidx);

    gidx            = find(rez.ops.kcoords == tgroup);%find all channels in this group
    channellist     = [];

    for ch = 1:length(par.spikeGroups.groups{groupidx})
        if sum(ismember(gidx,par.spikeGroups.groups{groupidx}(:)+1))
            channellist = par.spikeGroups.groups{groupidx}(:)+1;
            break
        end
    end
    if isempty(channellist)
        disp(['Cannot find spkgroup for group ' num2str(groupidx) ])
        continue
    end

    %% spike extraction from dat
    if groupidx == 1;
        dat             = memmapfile(datpath,'Format','int16');
    end
    tsampsperwave   = (sbefore+safter);
    ngroupchans     = length(channellist);
    valsperwave     = tsampsperwave * ngroupchans;
    wvforms_all     = zeros(length(tspktimes)*tsampsperwave*ngroupchans,1,'int16');
    wvranges        = zeros(length(tspktimes),ngroupchans);
    wvpowers        = zeros(1,length(tspktimes));

    for j=1:length(tspktimes)
        try
            w = dat.data((double(tspktimes(j))-sbefore).*totalch+1:(double(tspktimes(j))+safter).*totalch);
            wvforms=reshape(w,totalch,[]);
            %select needed channels
            wvforms = wvforms(channellist,:);
            %         % detrend
            %         wvforms = floor(detrend(double(wvforms)));
            % median subtract
            wvforms = wvforms - repmat(median(wvforms')',1,sbefore+safter);
            wvforms = wvforms(:);

        catch
            disp(['Error extracting spike at sample ' int2str(double(tspktimes(j))) '. Saving as zeros']);
            disp(['Time range of that spike was: ' num2str(double(tspktimes(j))-sbefore) ' to ' num2str(double(tspktimes(j))+safter) ' samples'])
            wvforms = zeros(valsperwave,1);
        end

        %some processing for fet file
        wvaswv = reshape(wvforms,tsampsperwave,ngroupchans);
        wvranges(j,:) = range(wvaswv);
        wvpowers(j) = sum(sum(wvaswv.^2));

        lastpoint = tsampsperwave*ngroupchans*(j-1);
        wvforms_all(lastpoint+1 : lastpoint+valsperwave) = wvforms;
        %     wvforms_all(j,:,:)=int16(floor(detrend(double(wvforms)')));
        if rem(j,100000) == 0
            disp([num2str(j) ' out of ' num2str(length(tspktimes)) ' done'])
        end
    end
    wvranges = wvranges';

    %% Spike features
    %     for each template, rearrange the channels to reflect the shank order
    tdx = [];
    for tn = 1:size(pcFeatures,3)
%         %         tTempPCOrder = tPCFeatureInds(:,tn);%channel sequence used for pc storage for this template
        for k = 1:length(channellist);
%             %             i = find(tTempPCOrder==channellist(k));
            if ~isempty(k)
                tdx(tn,k) = k;
            else
                tdx(tn,k) = nan;
            end
%
        end
    end

    featuresperspike = 3; % kilosort default

    % initialize fet file
    fets    = zeros(sum(tidx),size(pcFeatures,2),size(pcFeatures,3));
    pct     = pcFeatures(tidx,:,:);

    %for each cluster/template id, grab at once all spikes in that group
    %and rearrange their features to match the shank order
    allshankclu = unique(tclu);

    for tc = 1:length(allshankclu)
        tsc     = allshankclu(tc);
        i       = find(tclu==tsc);
        tforig  = pct(i,:,:);%the subset of spikes with this clu ide
        tfnew   = tforig; %will overwrite

        ii      = tdx(:,16);%handling nan cases where the template channel used was not in the shank
        gixs    = ~isnan(ii);%good vs bad channels... those shank channels that were vs were not found in template pc channels
        bixs    = isnan(ii);
        g       = ii(gixs);

        tfnew(:,:,gixs) = tforig(:,:,gixs);%replace ok elements
        tfnew(:,:,bixs) = 0;%zero out channels that are not on this shank
        try
            fets(i,:,:) = tfnew(:,:,1:size(pcFeatures,3));
        catch
            keyboard
        end
    end
    %extract for relevant spikes only...
    % and heurstically on d3 only take fets for one channel for each original channel in shank... even though kilosort pulls 12 channels of fet data regardless
    tfet1 = squeeze(fets(:,1,1:size(pct,3)));%lazy reshaping
    tfet2 = squeeze(fets(:,2,1:size(pct,3)));
    tfet3 = squeeze(fets(:,3,1:size(pct,3)));
    fets = cat(2,tfet1,tfet2,tfet3)';%     fets = h5read(tkwx,['/channel_groups/' num2str(shank) '/features_masks']);
    %     fets = double(squeeze(fets(1,:,:)));
    %mean activity per spike
    %     fetmeans = mean(fets,1);%this is pretty redundant with wvpowers
    %     %find first pcs, make means of those...
    %     featuresperspike = 4;
    %     firstpcslist = 1:featuresperspike:size(fets,1);
    %     firstpcmeans = mean(fets(firstpcslist,:),1);
    %
    %     nfets = size(fets,1)+1;
    %     fets = cat(1,fets,fetmeans,firstpcmeans,wvpowers,wvranges,double(tspktimes'));
    fets = cat(1,double(fets),double(wvpowers),double(wvranges),double(tspktimes'));
    fets = fets';
    % fets = cat(1,nfets,fets);

    %% writing to clu, res, fet, spk

    cluname = fullfile(savepath, [basename '.clu.' num2str(tgroup)]);
    resname = fullfile(savepath, [basename '.res.' num2str(tgroup)]);
    fetname = fullfile(savepath, [basename '.fet.' num2str(tgroup)]);
    spkname = fullfile(savepath, [basename '.spk.' num2str(tgroup)]);
    %fet
    SaveFetIn(fetname,fets);

    %clu
    % if ~exist(cluname,'file')
    tclu = cat(1,length(unique(tclu)),double(tclu));
    fid=fopen(cluname,'w');
    %     fprintf(fid,'%d\n',clu);
    fprintf(fid,'%.0f\n',tclu);
    fclose(fid);
    clear fid
    % end

    %res
    fid=fopen(resname,'w');
    fprintf(fid,'%.0f\n',tspktimes);
    fclose(fid);
    clear fid

    %spk
    fid=fopen(spkname,'w');
    fwrite(fid,wvforms_all,'int16');
    fclose(fid);
    clear fid

    disp(['Shank ' num2str(tgroup) ' done'])
    %end
    %end
end
clear dat
copyfile(fullfile(savepath, [basename,'.clu.*']),fullfile(savepath, 'PhyClus'))

function SaveFetIn(FileName, Fet, BufSize);

if nargin<3 | isempty(BufSize)
    BufSize = inf;
end

nFeatures = size(Fet, 2);
formatstring = '%d';
for ii=2:nFeatures
    formatstring = [formatstring,'\t%d'];
end
formatstring = [formatstring,'\n'];

outputfile = fopen(FileName,'w');
fprintf(outputfile, '%d\n', nFeatures);

if isinf(BufSize)

    temp = [round(100* Fet(:,1:end-1)) round(Fet(:,end))];
    fprintf(outputfile,formatstring,temp');
else
    nBuf = floor(size(Fet,1)/BufSize)+1;

    for i=1:nBuf
        BufInd = [(i-1)*nBuf+1:min(i*nBuf,size(Fet,1))];
        temp = [round(100* Fet(BufInd,1:end-1)) round(Fet(BufInd,end))];
        fprintf(outputfile,formatstring,temp');
    end
end
fclose(outputfile);


%{
    Copyright (C) Cambridge Electronic Design Limited 2014
    Author: James Thompson
    Web: www.ced.co.uk email: james@ced.co.uk, softhelp@ced.co.uk

    This file is part of CEDS64ML, a MATLAB interface to the SON64 library.

    CEDS64ML is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CEDS64ML 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 CEDS64ML.  If not, see <http://www.gnu.org/licenses/>.
%}

function [ iOk, TimeDateOut ] = CEDS64TimeDate( fhand, TimeDateIn )
%CEDS64TIMEDATE Gets and sets the time and date saved in a file (usually the time that sampling began)
% Note this is not the same format as MATLAB's clock function
%   [ iOk, TimeDateOut ] = CEDS64TimeDate( fhand, TimeDateIn )
%   Inputs
%   fhand - Integer file handle
%   TimeDateIn - (Optional) The new time date as a 7-by-1 vector
%   Outputs
%   iOk = 0 if the operation completed without error, otherwise a negative
%   error code.
%   TimeDateOut - The old time date as a 7-by-1 vector
%   The structure of the time-date vector is:
%   element 1 - hundredths of seconds (0-99)
%   element 2 - seconds (0-59)
%   element 3 - minutes (0-59)
%   element 4 - hours (0-23)
%   element 5 - day of the month (1-31)
%   element 6 - month of the year (1-12)
%   element 7 - year (1980-2200)

%TimeDateOut = zeros(7, 1, 'int32');

if (nargin == 1 || nargin == 2) % get the old TimeDate
    dBufferIn = int64(0);
    dBufferOut = int64(0);
    [ iOk, A ] = calllib('ceds64int', 'S64TimeDate', fhand, dBufferOut, dBufferIn, -1);
    TimeDateOut(1) = bitand(bitshift(A, 0), 255);     % Hundredth of a second
    TimeDateOut(2) = bitand(bitshift(A, -8), 255);    % Second
    TimeDateOut(3) = bitand(bitshift(A, -16), 255);   % Minute
    TimeDateOut(4) = bitand(bitshift(A, -24), 255);   % Hour
    TimeDateOut(5) = bitand(bitshift(A, -32), 255);   % day
    TimeDateOut(6) = bitand(bitshift(A, -40), 255);   % month
    TimeDateOut(7) = bitand(bitshift(A, -48), 65535); % year
else
   iOk = -22;
   return;
end

% set the new TimeDate if we're given one
if (nargin == 2)
    if (length(TimeDateIn) ~= 7)
        iOk = -22;
        return;
    end
	dBufferIn = int64(0);
    dBufferOut = int64(0);
    dBufferIn = dBufferIn + TimeDateIn(1);
    dBufferIn = dBufferIn + bitshift(TimeDateIn(2), 8);
    dBufferIn = dBufferIn + bitshift(TimeDateIn(3), 16);
    dBufferIn = dBufferIn + bitshift(TimeDateIn(4), 24);
    dBufferIn = dBufferIn + bitshift(TimeDateIn(5), 32);
    dBufferIn = dBufferIn + bitshift(TimeDateIn(6), 40);
    dBufferIn = dBufferIn + bitshift(TimeDateIn(7), 48);
    [ iOk, A ] = calllib('ceds64int', 'S64TimeDate', fhand, dBufferOut, dBufferIn, 0);
end
end


% eegplot2event() - convert EEGPLOT rejections into events
%                   compatible with the eeg_eegrej function for rejecting
%                   continuous portions of datasets.
%
% Usage:
%   >> [events] = eegplot2event( eegplotrej, type, colorin, colorout );
%
% Inputs:
%   eegplotrej - EEGPLOT output (TMPREJ; see eegplot for more details)
%   type       - type of the event. Default -1.
%   colorin    - only extract rejection of specific colors (here a n x 3
%                array must be given). Default: extract all rejections.
%   colorout   - do not extract rejection of specified colors.
%
% Outputs:
%   events     - array of events compatible with the eeg_eegrej function
%                for rejecting continuous portions of datasets.
%
% Example:
% NEWEEG = eeg_eegrej(EEG,eegplot2event(TMPREJ, -1));
%
% Author: Arnaud Delorme, CNL / Salk Institute, 2001
%
% See also: eegplot(), eeg_multieegplot(), eegplot2trial(), eeglab()

% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% 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 events = eegplot2event( TMPREJ, type, color, colorout )

if nargin < 1
   help eegplot2event;
   return;
end;

if nargin < 2
   type = -1;
end;

% only take into account specific colors
% --------------------------------------
if exist('color') == 1
	for index = 1:size(color,1)
   		tmpcol1 = TMPREJ(:,3) + 255*TMPREJ(:,4) + 255*255*TMPREJ(:,5);
   		tmpcol2 = color(index,1)+255*color(index,2)+255*255*color(index,3);
   		I = find( tmpcol1 == tmpcol2);
   		if isempty(I)
      		fprintf('Warning: color [%d %d %d] not found\n', ...
      			color(index,1), color(index,2), color(index,3));
   		end;
   		TMPREJ = TMPREJ(I,:);
   	end;
end;

% remove other specific colors
% ----------------------------
if exist('colorout') == 1
	for index = 1:size(colorout,1)
   		tmpcol1 = TMPREJ(:,3) + 255*TMPREJ(:,4) + 255*255*TMPREJ(:,5);
   		tmpcol2 = colorout(index,1)+255*colorout(index,2)+255*255*colorout(index,3);
   		I = find( tmpcol1 ~= tmpcol2);
   		TMPREJ = TMPREJ(I,:);
   	end;
end;

events = [];
if ~isempty(TMPREJ)
   events = TMPREJ(:,1:5);
   events = [ type*ones(size(events,1), 1) ones(size(events,1), 1) round(events(:,1:2)) events(:,3:5)];
end;

return;


function f = minus(f, g)
%-	Subtraction of two CLASSICFUN objects.
%   F - G subtracts G from F, where F and G may be CLASSICFUN objects or scalars.
%
%   If F and G are both CLASSICFUN objects, they are assumed to have the same domain.
%   The method gives no warning if their domains don't agree, but the output of
%   the method will be meaningless.
%
% See also PLUS, UMINUS.

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

% To avoid duplication, we note that (f - g) = f + (-g):
f = plus(f, uminus(g));

end


% pop_rejmenu() - Main menu for rejecting trials in an EEG dataset
%
% Usage: >> pop_rejmenu(INEEG, typerej);
%
% Inputs:
%   INEEG      - input dataset
%   typerej    - data to reject on (0 = component activations;
%                1 = raw electrode data). {Default: 1 = reject on raw data}
%
% Author: Arnaud Delorme, CNL / Salk Institute, 2001
%
% See also: eeglab(), pop_eegplot(), pop_eegthresh, pop_rejtrend()
% pop_rejkurt(), pop_jointprob(), pop_rejspec()

% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% 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 pop_rejmenu( EEG, icacomp );

if icacomp == 0
	if isempty( EEG.icasphere )
		disp('Error: you must first run ICA on the data'); return;
	end;
end;

if icacomp == 1 	rejtitle = 'Reject trials using data statistics - pop_rejmenu()'; tagmenu = 'rejtrialraw';
else            	rejtitle = 'Reject trials using component activity statistics - pop_rejmenu()'; tagmenu = 'rejtrialica';
end;

if ~isempty( findobj('tag', tagmenu))
	error('cannot open two identical windows; close the first one first');
end;

figure('visible', 'off', 'numbertitle', 'off', 'name', rejtitle, 'tag', tagmenu);

% definition of callbacks
% -----------------------
checkstatus = [ 'rejstatus = get( findobj(''parent'', gcbf, ''tag'', ''rejstatus''), ''value'');' ...
                'if rejstatus == 3,' ...
                '    EEG.reject.disprej = {};' ...
				'    if get( findobj(''parent'', gcbf, ''tag'', ''IManual''), ''value''), EEG.reject.disprej{1} = ''manual''; end;' ...
                '    if get( findobj(''parent'', gcbf, ''tag'', ''IThresh''), ''value''), EEG.reject.disprej{2} = ''thresh''; end;' ...
                '    if get( findobj(''parent'', gcbf, ''tag'', ''IConst''), ''value''), EEG.reject.disprej{3} = ''const''; end;' ...
                '    if get( findobj(''parent'', gcbf, ''tag'', ''IEnt''), ''value''), EEG.reject.disprej{4} = ''jp''; end;' ...
                '    if get( findobj(''parent'', gcbf, ''tag'', ''IKurt''), ''value''), EEG.reject.disprej{5} = ''kurt''; end;' ...
                '    if get( findobj(''parent'', gcbf, ''tag'', ''IFreq''), ''value''), EEG.reject.disprej{6} = ''freq''; end;' ...
                'end;' ...
                'rejstatus = rejstatus-1;' ]; % from 1-3 range, go to 0-2 range

if icacomp, ICAPREFIX = '';
else        ICAPREFIX = 'ica';
end;
% tmp_comall is used when returning from eegplot
tmp_comall =      [ 'set(findobj(''''parent'''', findobj(''''tag'''', ''''' tagmenu ...
					'''''), ''''tag'''', ''''mantrial''''), ''''string'''', num2str(sum(EEG.reject.' ICAPREFIX 'rejmanual)));' ...
                    'set(findobj(''''parent'''', findobj(''''tag'''', ''''' tagmenu ...
					'''''), ''''tag'''', ''''threshtrial''''), ''''string'''', num2str(sum(EEG.reject.' ICAPREFIX 'rejthresh)));' ...
                    'set(findobj(''''parent'''', findobj(''''tag'''', ''''' tagmenu ...
					'''''), ''''tag'''', ''''freqtrial''''), ''''string'''', num2str(sum(EEG.reject.' ICAPREFIX 'rejfreq)));' ...
                    'set(findobj(''''parent'''', findobj(''''tag'''', ''''' tagmenu ...
					'''''), ''''tag'''', ''''consttrial''''), ''''string'''', num2str(sum(EEG.reject.' ICAPREFIX 'rejconst)));' ...
                    'set(findobj(''''parent'''', findobj(''''tag'''', ''''' tagmenu ...
					'''''), ''''tag'''', ''''enttrial''''), ''''string'''', num2str(sum(EEG.reject.' ICAPREFIX 'rejjp)));' ...
                    'set(findobj(''''parent'''', findobj(''''tag'''', ''''' tagmenu ...
					'''''), ''''tag'''', ''''kurttrial''''), ''''string'''', num2str(sum(EEG.reject.' ICAPREFIX 'rejkurt)));' ];

cb_manual = [ 	checkstatus ...
				'pop_eegplot( EEG, ' int2str( icacomp ) ', rejstatus, 0,''' tmp_comall ''');' ...
				'clear rejstatus;' ];

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

cb_compthresh = [ '  posthresh = get( findobj(''parent'', gcbf, ''tag'', ''threshpos''), ''string'' );' ...
                  '  negthresh = get( findobj(''parent'', gcbf, ''tag'', ''threshneg''), ''string'' );' ...
                  '  startime  = get( findobj(''parent'', gcbf, ''tag'', ''threshstart''), ''string'' );' ...
                  '  endtime   = get( findobj(''parent'', gcbf, ''tag'', ''threshend''), ''string'' );' ...
                  '  elecrange = get( findobj(''parent'', gcbf, ''tag'', ''threshelec''), ''string'' );' ...
                  checkstatus ...
				  '[EEG Itmp LASTCOM] = pop_eegthresh( EEG,' int2str(icacomp) ...
				  ', elecrange, negthresh, posthresh, str2num(startime)/1000, str2num(endtime)/1000, rejstatus, 0,''' tmp_comall ''');' ...
				  'EEG = eegh(LASTCOM, EEG);' ...
				  'clear com Itmp elecrange posthresh negthresh startime endtime rejstatus;' ];

%                  '  set(findobj(''parent'', gcbf, ''tag'', ''threshtrial''), ''string'', num2str(EEG.trials - length(Itmp)));' ...
%				  'eegh(LASTCOM);' ...
%				  'clear Itmp elecrange posthresh negthresh startime endtime rejstatus;' ];

% -----------------------------------------------------
cb_compfreq   = [ '  posthresh = get( findobj(''parent'', gcbf, ''tag'', ''freqpos''), ''string'' );' ...
                  '  negthresh = get( findobj(''parent'', gcbf, ''tag'', ''freqneg''), ''string'' );' ...
                  '  startfreq = get( findobj(''parent'', gcbf, ''tag'', ''freqstart''), ''string'' );' ...
                  '  endfreq   = get( findobj(''parent'', gcbf, ''tag'', ''freqend''), ''string'' );' ...
                  '  elecrange = get( findobj(''parent'', gcbf, ''tag'', ''freqelec''), ''string'' );' ...
                  checkstatus ...
				  '[EEG Itmp LASTCOM] = pop_rejspec( EEG,' int2str(icacomp) ...
				  ', elecrange, negthresh, posthresh, startfreq, endfreq, rejstatus, 0,''' tmp_comall ''');' ...
				  'EEG = eegh(LASTCOM, EEG);' ...
				  'clear Itmp elecrange posthresh negthresh startfreq endfreq rejstatus;' ];

% -----------------------------------------------------
cb_compconstrej = [ '  minslope   = get( findobj(''parent'', gcbf, ''tag'', ''constpnts''), ''string'' );' ...
					'  minstd    = get( findobj(''parent'', gcbf, ''tag'', ''conststd''), ''string'' );' ...
					'  elecrange = get( findobj(''parent'', gcbf, ''tag'', ''constelec''), ''string'' );' ...
                    checkstatus ...
				    '[rej LASTCOM] = pop_rejtrend(EEG,' int2str(icacomp) ', elecrange, ''' ...
					int2str(EEG.pnts) ''', minslope, minstd, rejstatus, 0,''' tmp_comall ''');' ...
				    'EEG = eegh(LASTCOM, EEG);' ...
				    'clear rej elecrange minslope minstd rejstatus;' ];

% -----------------------------------------------------
cb_compenthead = [ '  locthresh  = get( findobj(''parent'', gcbf, ''tag'', ''entloc''), ''string'' );', ...
				   '  globthresh = get( findobj(''parent'', gcbf, ''tag'', ''entglob''), ''string'' );', ...
				   '  elecrange  = get( findobj(''parent'', gcbf, ''tag'', ''entelec''), ''string'' );' ];
cb_compenttail = [ '  set( findobj(''parent'', gcbf, ''tag'', ''entloc''), ''string'', num2str(locthresh) );', ...
				   '  set( findobj(''parent'', gcbf, ''tag'', ''entglob''), ''string'', num2str(globthresh) );', ...
				   '  set( findobj(''parent'', gcbf, ''tag'', ''enttrial''), ''string'', num2str(nrej) );' ...
				   'EEG = eegh(LASTCOM, EEG);' ...
				   'clear nrej elecrange locthresh globthresh rejstatus;' ];
cb_compentplot =  [ cb_compenthead ...
				    '[EEG locthresh globthresh nrej LASTCOM] = pop_jointprob( EEG, ' int2str(icacomp) ...
					', elecrange, locthresh, globthresh, 0, 0,''' tmp_comall ''');', ...
				    cb_compenttail ];
cb_compentcalc =  [ cb_compenthead ...
				    '[EEG locthresh globthresh nrej LASTCOM] = pop_jointprob( EEG, ' int2str(icacomp) ...
					', [ str2num(elecrange) ], str2num(locthresh), str2num(globthresh), 0, 0);', ...
 				    cb_compenttail ];
cb_compenteeg  =  [ cb_compenthead ...
                    checkstatus ...
				    '[EEG locthresh globthresh nrej LASTCOM] = pop_jointprob( EEG, ' int2str(icacomp) ...
					', elecrange, locthresh, globthresh, rejstatus, 0, 1,''' tmp_comall ''');', ...
 				    cb_compenttail ];

% -----------------------------------------------------
cb_compkurthead =[ '  locthresh  = get( findobj(''parent'', gcbf, ''tag'', ''kurtloc''), ''string'' );', ...
				   '  globthresh = get( findobj(''parent'', gcbf, ''tag'', ''kurtglob''), ''string'' );', ...
				   '  elecrange  = get( findobj(''parent'', gcbf, ''tag'', ''kurtelec''), ''string'' );' ];
cb_compkurttail =[ '  set( findobj(''parent'', gcbf, ''tag'', ''kurtloc''), ''string'', num2str(locthresh) );', ...
				   '  set( findobj(''parent'', gcbf, ''tag'', ''kurtglob''), ''string'', num2str(globthresh) );', ...
				   '  set( findobj(''parent'', gcbf, ''tag'', ''kurttrial''), ''string'', num2str(nrej) );' ...
				   'EEG = eegh(LASTCOM, EEG);' ...
				   'clear nrej elecrange locthresh globthresh rejstatus;' ];
cb_compkurtplot = [ cb_compkurthead ...
				    '[EEG locthresh globthresh nrej LASTCOM] = pop_rejkurt( EEG, ' int2str(icacomp) ...
					', elecrange, locthresh, globthresh, 0, 0,''' tmp_comall ''');', ...
				    cb_compkurttail ];
cb_compkurtcalc = [ cb_compkurthead ...
				    '[EEG locthresh globthresh nrej LASTCOM] = pop_rejkurt( EEG, ' int2str(icacomp) ...
					', [ str2num(elecrange) ], str2num(locthresh), str2num(globthresh), 0, 0);', ...
 				    cb_compkurttail ];
cb_compkurteeg  = [ cb_compkurthead ...
                    checkstatus ...
				    '[EEG locthresh globthresh nrej LASTCOM] = pop_rejkurt( EEG, ' int2str(icacomp) ...
					', elecrange, locthresh, globthresh, rejstatus, 0, 1,''' tmp_comall ''');', ...
 				    cb_compkurttail ];

% -----------------------------------------------------
cb_reject =      [ 'set( findobj(''parent'', gcbf, ''tag'', ''rejstatus''), ''value'', 3);' ... % force status to 3
				    checkstatus ...
				   '[EEG LASTCOM] = eeg_rejsuperpose(EEG,' int2str(icacomp) ',1,1,1,1,1,1,1); EEG = eegh(LASTCOM, EEG);' ...
                   'if isempty(find(EEG.reject.rejglobal)),' ...
                   '   warndlg2(strvcat(''No epoch selected...'', ''When using thresholding, click update'',''marks in the EEG plotting window''));' ...
				   'else,' ...
                   '   [EEG LASTCOM] = pop_rejepoch( EEG, EEG.reject.rejglobal, 1);' ...
				   '   if ~isempty(LASTCOM), ' ...
				   '      EEG = eegh(LASTCOM, EEG); [ALLEEG EEG CURRENTSET LASTCOM] = pop_newset(ALLEEG, EEG, CURRENTSET); eegh(LASTCOM);' ...
				   '   end; eeglab redraw; close(gcbf);' ...
                   'end;' ];

cb_clear =       [ 'close gcbf; EEG = rmfield( EEG, ''reject''); EEG.reject.rejmanual = [];' ...
				   'EEG=eeg_checkset(EEG); pop_rejmenu(' inputname(1) ',' int2str(icacomp) ');' ];

cb_close =       [ 'close gcbf;' ...
				   'disp(''Marks stored in dataset'');' ...
				   '[ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);' ...
				   'eegh(''[ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);'');'];

lisboxoptions = { 'string', [ 'Show only the new trials marked for rejection by the measure selected above|' ...
                  'Show previous and new trials marked for rejection by the measure selected above|' ...
                  'Show all trials marked for rejection by the measure selected above or checked below'], 'tag', 'rejstatus', 'value', 1, 'callback', ...
                  [ 'if get(gcbo, ''value'') == 3,' ...
                    '   set(findobj(''parent'', gcbf, ''style'', ''checkbox''), ''enable'', ''on'');' ...
                    'else' ...
                    '   set(findobj(''parent'', gcbf, ''style'', ''checkbox''), ''enable'', ''off'');' ...
                    'end;' ] };

	chanliststr = [fastif(icacomp,'Electrode(s)','Component(s)') ];
	chanlistval = fastif(icacomp, [ '1:' int2str(EEG.nbchan) ], [ '1:' int2str(size(EEG.icaweights,1)) ]);

	% assess previous rejections
	% --------------------------
	sizeman = 0;
	sizethresh = 0;
	sizetrend = 0;
	sizejp = 0;
	sizekurt = 0;
	sizespec = 0;
	if icacomp == 1
		if ~isempty(EEG.reject.rejmanual), sizeman   = length(find(EEG.reject.rejmanual)); end;
		if ~isempty(EEG.reject.rejconst),  sizetrend = length(find(EEG.reject.rejconst)); end;
		if ~isempty(EEG.reject.rejjp),     sizejp    = length(find(EEG.reject.rejjp)); end;
		if ~isempty(EEG.reject.rejkurt),   sizekurt  = length(find(EEG.reject.rejkurt)); end;
		if ~isempty(EEG.reject.rejfreq),   sizespec  = length(find(EEG.reject.rejfreq)); end;
	else
		if ~isempty(EEG.reject.icarejmanual), sizeman   = length(find(EEG.reject.icarejmanual)); end;
		if ~isempty(EEG.reject.icarejconst),  sizetrend = length(find(EEG.reject.icarejconst)); end;
		if ~isempty(EEG.reject.icarejjp),     sizejp    = length(find(EEG.reject.icarejjp)); end;
		if ~isempty(EEG.reject.icarejkurt),   sizekurt  = length(find(EEG.reject.icarejkurt)); end;
		if ~isempty(EEG.reject.icarejfreq),   sizespec  = length(find(EEG.reject.icarejfreq)); end;
	end;

    stdl = [0.25 1.2 0.8 1.2 0.8]; % standard line
	titl = [0.9 0.18 1.55]; % title line
    geometry = { 	[0.883 0.195 .2 .45 .4 .4] ...
					[1] titl stdl stdl stdl stdl ...
					[1] titl stdl stdl stdl  ...
					[1] titl stdl stdl stdl  ...
					[1] titl stdl stdl stdl  ...
					[1] titl stdl stdl stdl stdl ...
					[1] [1] [1] [1 1 1] [1 1 1]  ...
					[1] [1 1 1]};

	listui = {{'Style', 'text', 'string', 'Mark trials by appearance', 'fontweight', 'bold' }, ...
    {  'Style', 'pushbutton', 'string', '', 'tag', 'butmanual', ...
	   'callback', [ 'tmpcolor = uisetcolor(EEG.reject.rejmanualcol); if length(tmpcolor) ~= 1,' ...
	   'EEG.reject.rejmanualcol=tmpcolor; set(gcbo, ''backgroundcolor'', tmpcolor); end; clear tmpcolor;'] },...
	{ } { 'Style', 'pushbutton', 'string', fastif(icacomp,'Scroll Data','Scroll Acts.'), 'callback', cb_manual }, ...
	{ 'Style', 'text', 'string', 'Marked trials' }, ...
	{ 'Style', 'text', 'string', int2str(sizeman), 'tag', 'mantrial' }, ...
	{ }, ...
	... % ---------------------------------------------------------------------------
	{ 'Style', 'text', 'string', 'Find abnormal values', 'fontweight', 'bold' }, ...
    {  'Style', 'pushbutton', 'string', '', 'tag', 'butthresh',  ...
	   'callback', [ 'tmpcolor = uisetcolor(EEG.reject.rejthreshcol); if length(tmpcolor) ~= 1,' ...
	   'EEG.reject.rejthreshcol=tmpcolor; set(gcbo, ''backgroundcolor'', tmpcolor); end; clear tmpcolor;'] }, { },...
	...
	{ }, { 'Style', 'text', 'string', ['Upper limit(s) ' fastif(icacomp,'(uV)', '(std. dev.)')] }, ...
	{ 'Style', 'edit', 'string', '25', 'tag', 'threshpos' }, ...
	{ 'Style', 'text', 'string', ['Lower limit(s) ' fastif(icacomp,'(uV)', '(std. dev.)')] }, ...
	{ 'Style', 'edit', 'string', '-25', 'tag', 'threshneg' }, ...
	...
	{ }, { 'Style', 'text', 'string', 'Start time(s) (ms)' }, ...
	{ 'Style', 'edit', 'string', int2str(EEG.xmin*1000), 'tag', 'threshstart' }, ...
	{ 'Style', 'text', 'string', 'Ending time(s) (ms)' }, ...
	{ 'Style', 'edit', 'string', int2str(EEG.xmax*1000), 'tag', 'threshend' }, ...
	...
	{ }, { 'Style', 'text', 'string', chanliststr }, ...
	{ 'Style', 'edit', 'string', chanlistval, 'tag', 'threshelec' }, ...
	{ 'Style', 'text', 'string', 'Currently marked trials' }, ...
	{ 'Style', 'text', 'string', int2str(sizethresh), 'tag', 'threshtrial' }, ...
	...
	{ }, { 'Style', 'pushbutton', 'string', 'Calc / Plot', 'callback', cb_compthresh }, ...
	{ }, { },{ 'Style', 'pushbutton', 'string', 'HELP', 'callback', 'pophelp(''pop_eegthresh'');' }, ...
	... % ---------------------------------------------------------------------------
	{ }, { 'Style', 'text', 'string', 'Find abnormal trends', 'fontweight', 'bold' }, ...
    {  'Style', 'pushbutton', 'string', '', 'tag', 'buttrend', ...
	   'callback', [ 'tmpcolor = uisetcolor(EEG.reject.rejconstcol); if length(tmpcolor) ~= 1,' ...
	   'EEG.reject.rejconstcol=tmpcolor; set(gcbo, ''backgroundcolor'', tmpcolor); end; clear tmpcolor;'] }, { },...
	...
	{ }, { 'Style', 'text', 'string', ['Max slope ' fastif(icacomp, ...
           '(uV/epoch)', ...
           '(std. dev./epoch)') ] }, ...
	{ 'Style', 'edit', 'string', '50', 'tag', 'constpnts' }, ...
	{ 'Style', 'text', 'string', 'R-squared limit (0 to 1)' }, ...
	{ 'Style', 'edit', 'string', '0.3', 'tag', 'conststd'  }, ...
    ...
	{ }, { 'Style', 'text', 'string', chanliststr }, ...
	{ 'Style', 'edit', 'string', chanlistval, 'tag', 'constelec'  }, ...
	{ 'Style', 'text', 'string', 'Currently marked trials' }, ...
	{ 'Style', 'text', 'string', int2str(sizetrend), 'tag', 'consttrial'  }, ...
	...
	{ }, { 'Style', 'pushbutton', 'string', 'Calc / Plot', 'callback', cb_compconstrej }, ...
	{ }, { }, { 'Style', 'pushbutton', 'string', 'HELP', 'callback', 'pophelp(''pop_rejtrend'');' }, ...
	...  % ---------------------------------------------------------------------------
	{ }, { 'Style', 'text', 'string', 'Find improbable data', 'fontweight', 'bold' }, ...
    {  'Style', 'pushbutton', 'string', '',  'tag', 'butjp', ...
	   'callback', [ 'tmpcolor = uisetcolor(EEG.reject.rejjpcol); if length(tmpcolor) ~= 1,' ...
	   'EEG.reject.rejjpcol=tmpcolor; set(gcbo, ''backgroundcolor'', tmpcolor); end; clear tmpcolor;'] }, { },...
	...
	{ }, { 'Style', 'text', 'string', fastif(icacomp, 'Single-channel limit (std. dev.)', 'Single-comp. limit (std. dev.)') }, ...
	{ 'Style', 'edit', 'string', fastif(icacomp, '5', '20'), 'tag', 'entloc' }, ...
	{ 'Style', 'text', 'string', fastif(icacomp, 'All channels limit (std. dev.)', 'All comp. limit (std. dev.)') }, ...
	{ 'Style', 'edit', 'string', '5', 'tag', 'entglob' }, ...
    ...
	{ }, { 'Style', 'text', 'string', chanliststr }, ...
	{ 'Style', 'edit', 'string', chanlistval, 'tag', 'entelec' }, ...
	{ 'Style', 'text', 'string', 'Currently marked trials' }, ...
	{ 'Style', 'text', 'string', int2str(sizejp), 'tag', 'enttrial' }, ...
	...
	{ }, { 'Style', 'pushbutton', 'string', 'Calculate', 'callback', cb_compentcalc }, ...
	{ 'Style', 'pushbutton', 'string', 'Scroll Data', 'callback', cb_compenteeg }, ...
	{ 'Style', 'pushbutton', 'string', 'PLOT', 'callback', cb_compentplot }, ...
	{ 'Style', 'pushbutton', 'string', 'HELP', 'callback', 'pophelp(''pop_jointprob'');' }, ...
	...  % ---------------------------------------------------------------------------
	{ }, { 'Style', 'text', 'string', 'Find abnormal distributions', 'fontweight', 'bold' }, ...
    {  'Style', 'pushbutton', 'string', '', 'tag', 'butkurt', ...
	   'callback', [ 'tmpcolor = uisetcolor(EEG.reject.rejkurtcol); if length(tmpcolor) ~= 1,' ...
	   'EEG.reject.rejkurtcol=tmpcolor; set(gcbo, ''backgroundcolor'', tmpcolor); end; clear tmpcolor;'] }, { },...
	...
	{ }, { 'Style', 'text', 'string', fastif(icacomp, 'Single-channel limit (std. dev.)', 'Single-comp. limit (std. dev.)') }, ...
	{ 'Style', 'edit', 'string', fastif(icacomp, '5', '20'), 'tag', 'kurtloc' }, ...
	{ 'Style', 'text', 'string', fastif(icacomp, 'All channels limit (std. dev.)', 'All comp. limit (std. dev.)') }, ...
	{ 'Style', 'edit', 'string', '5', 'tag', 'kurtglob' }, ...
    ...
	{ }, { 'Style', 'text', 'string', chanliststr }, ...
	{ 'Style', 'edit', 'string', chanlistval, 'tag', 'kurtelec' }, ...
	{ 'Style', 'text', 'string', 'Currently marked trials' }, ...
	{ 'Style', 'text', 'string', int2str(sizekurt), 'tag', 'kurttrial' }, ...
	...
	{ }, { 'Style', 'pushbutton', 'string', 'Calculate', 'callback', cb_compkurtcalc }, ...
	{ 'Style', 'pushbutton', 'string', 'Scroll Data', 'callback', cb_compkurteeg }, ...
	{ 'Style', 'pushbutton', 'string', 'PLOT', 'callback', cb_compkurtplot }, ...
	{ 'Style', 'pushbutton', 'string', 'HELP', 'callback', 'pophelp(''pop_rejkurt'');' }, ...
	... % ---------------------------------------------------------------------------
	{ }, { 'Style', 'text', 'string', 'Find abnormal spectra (slow)', 'fontweight', 'bold' }, ...
    {  'Style', 'pushbutton', 'string', '', 'tag', 'butspec', ...
	   'callback', [ 'tmpcolor = uisetcolor(EEG.reject.rejfreqcol); if length(tmpcolor) ~= 1,' ...
	   'EEG.reject.rejfreqcol=tmpcolor; set(gcbo, ''backgroundcolor'', tmpcolor); end; clear tmpcolor;'] }, { },...
	...
	{ }, { 'Style', 'text', 'string', 'Upper limit(s) (dB)' }, ...
	{ 'Style', 'edit', 'string', '25', 'tag', 'freqpos' }, ...
	{ 'Style', 'text', 'string', 'Lower limit(s) (dB)' }, ...
	{ 'Style', 'edit', 'string', '-25', 'tag', 'freqneg' }, ...
	...
	{ }, { 'Style', 'text', 'string', 'Low frequency(s) (Hz)' }, ...
	{ 'Style', 'edit', 'string', '0', 'tag', 'freqstart' }, ...
	{ 'Style', 'text', 'string', 'High frequency(s) (Hz)' }, ...
	{ 'Style', 'edit', 'string', '50', 'tag', 'freqend' }, ...
	...
	{ }, { 'Style', 'text', 'string', chanliststr }, ...
	{ 'Style', 'edit', 'string', chanlistval, 'tag', 'freqelec' }, ...
	{ 'Style', 'text', 'string', 'Currently marked trials' }, ...
	{ 'Style', 'text', 'string', int2str(sizespec), 'tag', 'freqtrial' }, ...
	...
	{ }, { 'Style', 'pushbutton', 'string', 'Calc / Plot', 'callback', cb_compfreq }, ...
	{ }, { },{ 'Style', 'pushbutton', 'string', 'HELP', 'callback', 'pophelp(''pop_rejspec'');' }, ...
    ...
    {}, ...  % ---------------------------------------------------------------------------
	...
	{ 'Style', 'text', 'string', 'Plotting options', 'fontweight', 'bold' }, ...
	{ 'style', 'listbox', lisboxoptions{:}, 'value', 3 }, ...
	{ 'style', 'checkbox', 'String', 'Abnormal appearance', 'tag', 'IManual', 'value', 1, ...
      'callback', 'set(gcbo, ''value'', 1); disp(''This checkbox must be set so that you may mark/unmark data epochs'');'}, ...
	{ 'style', 'checkbox', 'String', 'Abnormal values', 'tag', 'IThresh', 'value', 1}, ...
	{ 'style', 'checkbox', 'String', 'Abnormal trends', 'tag', 'IConst', 'value', 1}, ...
	{ 'style', 'checkbox', 'String', 'Improbable epochs', 'tag', 'IEnt', 'value', 1}, ...
	{ 'style', 'checkbox', 'String', 'Abnormal distributions', 'tag', 'IKurt', 'value', 1}, ...
	{ 'style', 'checkbox', 'String', 'Abnormal spectra', 'tag', 'IFreq', 'value', 1}, ...
	...
	{ }, ...
 	{ 'Style', 'pushbutton', 'string', 'CLOSE (KEEP MARKS)', 'callback', cb_close }, ...
 	{ 'Style', 'pushbutton', 'string', 'CLEAR ALL MARKS', 'callback', cb_clear  }, ...
	{ 'Style', 'pushbutton', 'string', 'REJECT MARKED TRIALS', 'callback', cb_reject }};

	allh = supergui( gcf, geometry, [], listui{:});

%	{ 'style', 'checkbox', 'String', ['Include ' fastif(icacomp, 'ica data', 'raw data')], 'tag', 'IOthertype', 'value', 1}, { }, ...
set(gcf, 'userdata', { allh });
set(findobj('parent', gcf', 'tag', 'butmanual'), 'backgroundcolor', EEG.reject.rejmanualcol);
set(findobj('parent', gcf', 'tag', 'butthresh'), 'backgroundcolor', EEG.reject.rejthreshcol);
set(findobj('parent', gcf', 'tag', 'buttrend'),  'backgroundcolor', EEG.reject.rejconstcol);
set(findobj('parent', gcf', 'tag', 'butjp'),     'backgroundcolor', EEG.reject.rejjpcol);
set(findobj('parent', gcf', 'tag', 'butkurt'),   'backgroundcolor', EEG.reject.rejkurtcol);
set(findobj('parent', gcf', 'tag', 'butspec'),   'backgroundcolor', EEG.reject.rejfreqcol);
set( findobj('parent', gcf, 'tag', 'rejstatus'), 'style', 'popup');


% draw the frame id (1 based ) and GPS TOW timestamp onto the image
function drawTimeOntoVideo()
close all;
resdir='..\20130808\';
sequencePath =[resdir, 'casio2_3430.MOV'];
imgtimefile=[resdir, 'casio2timestamps.txt'];
initIm =12464; % 415530 GTOW
endIm=12986;
[fimgtime, imgepoch, initIm]=readimgtimeheader(imgtimefile,0, initIm);
hstream=sprintf('%d,%.5f', initIm, imgepoch);
myVid= VideoReader(sequencePath);
figure(1);
tic;
for x = initIm : endIm
    imRGB=read(myVid,x); %78612;
    imwrite(imRGB,strcat('F:\relaylatest\20130808\garage\casio2_',num2str(x),'.jpg'));
    %     if(isempty(imRGB)||imgepoch>416033.2)
    %         break;
    %     else
    %display frmId and timestamp on the image
    %         text(xlbl(:), ylbl(:), lbl(:),'color','w',...
    %     'HorizontalAlignment','center','VerticalAlignment','middle');
    imshow(imRGB);
    text(50, 50, hstream);
    pause(0.02);
    % read in next image epoch
    hstream= fgetl(fimgtime);
    %         if(hstream==-1)
    %             imgepoch=inf;
    %         end
end
toc;
end


function r = exprand(mu,m,n)
% EXPRAND Random matrices from exponential distribution.
%
%    R = EXPRAND(MU) returns a matrix of random numbers chosen
%    from the exponential distribution with parameter MU.
%    The size of R is the size of MU.
%    Alternatively, R = EXPRAND(MU,M,N) returns an M by N matrix.

% Copyright (c) 1998-2004 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.

error('No mex-file for this architecture. See Matlab help and convert.m in ./linuxCsource or ./winCsource for help.')


function value = p27_r8vec ( action, name, dim_num, value )

%*****************************************************************************80
%
%% P27_R8VEC sets or gets R8VEC parameters for problem 27.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 November 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string ACTION, the action.
%    'D' sets the internal value of the object to a default value.
%    If NAME = '*', then all variables are defaulted.
%    'G' means the current value of the object should be returned.
%    'R' means randomize the object and return it.
%    'S' means the input values of the object and its dimension should
%    be stored.
%
%    Input, string NAME, the name of the parameter.
%    'C' is the coefficient vector.
%
%    Input, integer DIM_NUM, the dimension of the object.
%
%    Input/output, real VALUE(DIM_NUM,1), the value of the object.
%
  persistent c
  persistent dim_num_save

  if ( size ( dim_num_save ) == 0 )
    dim_num_save = 0;
  end

  if ( dim_num_save ~= dim_num )
    dim_num_save = 0;
    c = [];
  end

  if ( dim_num_save == 0 )
    dim_num_save = dim_num;
  end

  if ( action == 'D' | action == 'd' )

    if ( name == 'C' | name == 'c' | name == '*' )
      c(1:dim_num,1) = 1.0 / dim_num;
    end

  elseif ( action == 'G' | action == 'g' )

    if ( name == 'C' | name == 'c' )
      value = zeros ( 1:dim_num, 1 );
      value(1:dim_num,1) = c(1:dim_num,1);
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P27_R8VEC - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized name = "%s".\n', name );
      error ( 'P27_R8VEC - Fatal error!' );
    end

  elseif ( action == 'R' | action == 'r' )

    if ( name == 'C' | name == 'c' )
      c = rand ( 1, dim_num );
      c(1:dim_num,1) = c(1:dim_num,1) * 25.0 / dim_num;
      value(1:dim_num,1) = c(1:dim_num,1);
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P27_R8VEC - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized name = "%s".\n', name );
      error ( 'P27_R8VEC - Fatal error!' );
    end

  elseif ( action == 'S' | action == 's' )

    if ( name == 'C' | name == 'c' )
      c(1:dim_num,1) = value(1:dim_num,1);
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P27_R8VEC - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized name = "%s".\n', name );
      error ( 'P27_R8VEC - Fatal error!' );
    end

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'P27_R8VEC - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized action = "%s".\n', action );
    error ( 'P27_R8VEC - Fatal error!' );

  end

  return
end


function [result, ok] = import_ndk(nFunction, sFilename)
    % import NDK formatted catalog Global Centroid-Moment-Tensor (CMT) catalog,
    % formarly the Harvard CMT catalog
    %
    % see also NDK

    ok=false;
    if nFunction == FilterOp.getDescription
        % respond with brief summary of function, used in selection box
        result = 'Centroid-Moment-Tensor (CMT) Catalog, NDK file (formerly Harvard CMT catalog)';
    elseif nFunction == FilterOp.getWebpage
        % respond with an html file that should help
        % website last accessed 18-July-2018
        result = 'https://www.ldeo.columbia.edu/~gcmt/projects/CMT/catalog/allorder.ndk_explained';
    else
        ndk = NDK.read(sFilename);
        result = ndk.toZmapCatalog();
        ok=true;
    end
end