function hs = binaryTreeApply( X, tree, maxDepth, minWeight, nThreads )
% Apply learned binary decision tree classifier.
%
% USAGE
%  hs = binaryTreeApply( X, tree, [maxDepth], [minWeight], [nThreads] )
%
% INPUTS
%  X          - [NxF] N length F feature vectors
%  tree       - learned tree classification model
%  maxDepth   - [] maximum depth of tree
%  minWeight  - [] minimum sample weigth to allow split
%  nThreads   - [16] max number of computational threads to use
%
% OUTPUTS
%  hs         - [Nx1] predicted output log ratios
%
% EXAMPLE
%
% See also binaryTreeTrain
%
% Piotr's Computer Vision Matlab Toolbox      Version 3.40
% Copyright 2014 Piotr Dollar.  [pdollar-at-gmail.com]
% Licensed under the Simplified BSD License [see external/bsd.txt]

if(nargin<3 || isempty(maxDepth)), maxDepth=0; end
if(nargin<4 || isempty(minWeight)), minWeight=0; end
if(nargin<5 || isempty(nThreads)), nThreads=16; end
if(maxDepth>0), tree.child(tree.depth>=maxDepth) = 0; end
if(minWeight>0), tree.child(tree.weights<=minWeight) = 0; end
hs = tree.hs(forestInds(X,tree.thrs,tree.fids,tree.child,nThreads));

end


function [ samplingMask ] = readSamplingMaskFromFile(sFilename)
%This function reads out a sampling pattern from a .txt-file

if(nargin < 1)
    file = fopen('samplingPattern.txt','r');
else
    file = fopen(sFilename,'r');
end

endOfDoc = false;
i = 0;

while(~endOfDoc)
    actualLine = fgetl(file);

    if(actualLine == -1)
        endOfDoc = true;
        break;
    end
    i = i + 1;
    lines{i} = actualLine;

    for j=1:numel(lines{i})
        actualChar = lines{i}(j);

        if(actualChar == '-')
            samplingMask(i, j) = 0;
        elseif (actualChar == 'x' || actualChar == '*' || actualChar == 'O' || actualChar == '0')
            samplingMask(i, j) = 1;
        else
            error('not working, because there is an unknown charakter');
        end
    end
end

if(exist('drawMask','file'))
    drawMask(samplingMask);
end

fclose(file);

end


function [beta_gibbs, sigma_gibbs, theta_gibbs, ss_record,indH,beta_theta_gibbs]=TVEmagibbs(data_endo,It,Bu,beta0,omega0,psi0,lambda0,Y,X,n,T,k1,q1,p,regimeperiods,names,TVEH)

% function [beta_gibbs psi_gibbs sigma_gibbs ss_record delta_gibbs]=magibbs(data_endo,data_exo,It,Bu,beta0,omega0,psi0,lambda0,Y,X,Z,n,m,T,k1,k3,q1,q2,q3,p)
% performs the Gibbs algortihm 3.5.1 for a MABVAR model, and returns draws from posterior distribution
% inputs:  - matrix 'data_endo': the matrix storing the endogenous time series data used to estimate the model
%          - matrix 'data_exo': the matrix storing the exogenous time series data used to estimate the model
%          - integer 'It': the total number of iterations run by the Gibbs sampler
%          - integer 'Bu': the number of initial iterations discared as burn-in sample
%          - vector 'beta0': the vector containing the mean of the prior distribution for beta, defined in (3.5.17)
%          - matrix 'omega0': the variance-covariance matrix for the prior distribution of beta, defined in (3.5.17)
%          - vector 'psi0': the vector containing the mean of the prior distribution for psi, defined in (3.5.19)
%          - matrix 'lambda0': the variance-covariance matrix for the prior distribution of psi, defined in (3.5.19)
%          - matrix 'Y': the matrix of endogenous variables, defined in (3.5.10)
%          - matrix 'X': the matrix of endogenous regressors, defined in (3.5.10)
%          - matrix 'Z': the matrix of exogenous regressors, defined in (3.5.10)
%          - integer 'n': the number of endogenous variables in the model
%          - integer 'm': the number of exogenous variables in the model
%          - integer 'T': the sample size, i.e. the number of time periods used to estimate the model
%          - integer 'k1': the number of coefficients related to the endogenous variables for each equation in the model
%          - integer 'k3': the number of coefficients related to the exogenous variables for each equation, in the reformulated model (3.5.5)
%          - integer 'q1': the total number of VAR coefficients related to the endogenous variables
%          - integer 'q2': the total number of VAR coefficients related to the exogenous variables
%          - integer 'q3': the total number of VAR coefficients related to the exogenous variables, in the reformulated model (3.5.5)
%          - integer 'p': the number of lags in the model
% outputs: - matrix 'beta_gibbs': the matrix recording the post-burn draws of beta
%          - matrix 'psi_gibbs': the matrix recording the post-burn draws of psi
%          - matrix 'sigma_gibbs': the matrix recording the post-burn draws of sigma
%          - matrix 'delta_gibbs': the matrix recording the post-burn draws of delta
%          - cell 'ss_record': the cell storing the post-burn steady-state values

% this function implements algorithm...

% preliminary tasks

% take the alternative exogenous regime
if isempty(regimeperiods)
    data_exo=[ones(size(data_endo,1),1)];
else
data_exo=[ones(size(data_endo,1),1) zeros(size(data_endo,1),1)];
data_exo(find(strcmp(names(2:end,1),regimeperiods(1))):find(strcmp(names(2:end,1),regimeperiods(2))),2)=1;
data_exo(find(strcmp(names(2:end,1),regimeperiods(1))):find(strcmp(names(2:end,1),regimeperiods(2))),1)=0;
end

indH=zeros(T+p,1);
for iR=1:size(data_exo,2)
    indH(data_exo(:,iR)==1)=iR;
end

% create the cell that will store the records for the steady-state
ss_record=cell(n,1); %change

% invert omega0
invomega0=diag(1./diag(omega0));

% invert lambda0
invlambda0=lambda0\eye(length(lambda0));

% step 2: set initial values
% set initial values for B, beta and sigma; as no OLS estimates are available, simply set the value as zeros for B and beta, and identity for sigma
B=zeros(k1,n);

% define the initial value for the inverse of sigma: beacause sigma is identity, this is also identity
invsigma=eye(n);

% preallocate space for the matrix with the equilibrium values
eq=zeros(T+p,n);

q2=length(psi0);

hbar = bear.parfor_progressbar(It,'Progress of the Gibbs sampler');  %create the progress bar

% start iterations
for ii=1:It

hbar.iterate(1);   % update progress by one iteration

% step 3: at iteration ii, draw psi from N, conditional on beta and sigma
% obtain the lambdabar matrix
Ybar=Y-X*B;
Ypsi=bear.vec(Ybar');

t=1;
Fsimple=TVEH(:,:,indH(t+p),t+p);
for k=2:p+1
    Fsimple=Fsimple-B((k-2)*n+1:(k-1)*n,:)'*TVEH(:,:,indH(t+p-(k-1)),t+p-(k-1));
end

for t=2:T
    Ftemp=TVEH(:,:,indH(t+p),t+p);
    for k=2:p+1
        Ftemp=Ftemp-B((k-2)*n+1:(k-1)*n,:)'*TVEH(:,:,indH(t+p-(k-1)),t+p-(k-1));
    end
    Fsimple=cat(1,Fsimple,Ftemp);
end

invOmega=kron(eye(T),invsigma);

CT=(invlambda0+Fsimple'*invOmega*Fsimple)\eye(length(lambda0));
mT=CT*(Fsimple'*invOmega*Ypsi++invlambda0*psi0);

% draw from N(psibar,lambdabar);
theta=mT+chol(bear.nspd(CT),'lower')*randn(q2,1);

% recover equilibrium values from psi
for it=1:T+p
    eq(it,:)=(squeeze(TVEH(:,:,indH(it),it))*theta)'; % compute the equilibrium values given theta
end

% step 4: now that psi/F has been drawn, it is possible to generate Yhat, Xhat and yhat
temp2=data_endo-eq;
temp3=bear.lagx(temp2,p);
Yhat=temp3(:,1:n);
yhat=Yhat(:);
Xhat=temp3(:,n+1:end);

% step 5: next, at iteration ii, draw sigma from IW, conditional on most recent draw for psi and beta
% obtain first Stilde
Stilde=(Yhat-Xhat*B)'*(Yhat-Xhat*B);
% next draw from IW(Stilde,T)
sigma=bear.iwdraw(Stilde,T);
% invert sigma
C=bear.trns(chol(bear.nspd(sigma),'Lower'));
invC=C\speye(n);
invsigma=invC*invC';

% step 6: finally, at iteration ii, draw beta from a N, conditional on most recent draw for psi and sigma
% first obtain the omegabar matrix
invomegabar=invomega0+kron(invsigma,Xhat'*Xhat);
C=bear.trns(chol(bear.nspd(invomegabar),'Lower'));
invC=C\speye(q1);
omegabar=invC*invC';
% following, obtain betabar
betabar=omegabar*(invomega0*beta0+kron(invsigma,Xhat')*yhat);
% draw from N(betabar,omegabar);
beta=betabar+chol(bear.nspd(omegabar),'lower')*randn(q1,1);
% reshape to obtain B
B=reshape(beta,k1,n);
% update U, using the draw obtained for B

   % record the values if the number of burn-in iterations is exceeded
   if ii>Bu
   % record the value of beta
   beta_gibbs(:,ii-Bu)=beta;
   % record the value of sigma (in vectorized form)
   sigma_gibbs(:,ii-Bu)=sigma(:);

   % compute and record the steady-state
   ss=eq;
   % trim p initial conditions to be consistent with the sample
   ss=ss(p+1:end,:);
      % then record in the corresponding cell
      for jj=1:n
      ss_record{jj,1}(ii-Bu,:)=ss(:,jj)';
      end
   % finally, record theta
   theta_gibbs(:,ii-Bu)=theta;

   beta_theta_gibbs(:,ii-Bu)=[beta;theta];
   % if current iteration is still a burn iteration, do not record the result
   else
   end

% step 7: go for next iteration
end

close(hbar);   %close progress bar


function [data,units] = compute_max_wing_area(trx,n)

flies = trx.exp2flies{n};
nflies = numel(flies);
data = cell(1,nflies);
for i = 1:nflies,
  fly = flies(i);

  data{i} = max(trx(fly).wing_areal_mm,trx(fly).wing_arear_mm);

end
units = parseunits('mm^2');


classdef OPBE < Algorithm
    %OPBE Ordinal Projection Based Ensemble (OPBE)[1]. This class derives
    %from the Algorithm Class and implements the OPBE method with the best
    %configuration found (product combiner, SVM base methodology, logit
    %function and equal distribution of probabilities). By default, this class uses
    %SVORIM implementation, but potentially any ORCA model can be used.
    %
    %   OPBE methods:
    %      fitpredict               - runs the corresponding algorithm,
    %                                   fitting the model and testing it in a dataset.
    %      fit                        - Fits a model from training data
    %      predict                    - Performs label prediction
    %
    %   References:
    %     [1] María Pérez-Ortiz, Pedro Antonio Gutiérrez and César
    %     Hervás-Martínez, Projection based ensemble learning for ordinal
    %     regression, IEEE Transactions on Cybernetics. Vol. 44 (5), 2014
    %     https://doi.org/10.1109/TCYB.2013.2266336

    %   This file is part of ORCA: https://github.com/ayrna/orca
    %   Original author: María Pérez Ortiz
    %   Contributors: Pedro A. Gutiérrez, Javier Sánchez-Monedero
    %   Citation: If you use this code, please cite the associated papers
    %      - http://www.uco.es/grupos/ayrna/elor2013
    %      - http://www.uco.es/grupos/ayrna/orreview
    %   Copyright:
    %       This software is released under the The GNU General Public License v3.0 licence
    %       available at http://www.gnu.org/licenses/gpl-3.0.html
    properties
        description = 'Ordinal Projection Based Ensemble';
        parameters = [];
        baseMethod = SVORIM;
        % Method name as str to allow loading from configuration file. The
        % constructor will instanciate it via feval()
        base_algorithm = 'SVORIM';
    end

    methods

        % TODO: Update and test parameter description
        function obj = OPBE(varargin)
            %OPBE constructs an object of the class OPBE and sets its
            %default properties.
            %   obj = OPBE('baseMethod', METHOD) sets METHOD as base
            %   algorithm.
            obj.parseArgs(varargin);
            % TODO: Pass varargin parameters to base algorithm?
            obj.baseMethod = feval(obj.base_algorithm);
            %obj.name_parameters = obj.baseMethod.getParameterNames();
            obj.parameters = obj.baseMethod.parameters;
        end

        function [projected, trainTargets] = privfit(obj, train, param)
            %PRIVFIT trains the model for the OPBE method with TRAIN data and
            %vector of parameters PARAMETERS.

            classes = unique(train.targets);
            nOfClasses = numel(classes);
            n = zeros(1,nOfClasses);
            for i=1:nOfClasses
                n(i) = sum(train.targets == i);
            end

            % Sort patterns
            orderedPatterns = train.patterns(train.targets==1,:);
            orderedTargets = train.targets(train.targets == 1);
            for i = 2:nOfClasses
                orderedPatterns = [orderedPatterns ; train.patterns(train.targets==i,:)];
                orderedTargets = [orderedTargets; train.targets(train.targets == i)];
            end

            train.patterns = orderedPatterns;
            train.targets = orderedTargets;
            classBelongingProbTrain = ones(nOfClasses, size(train.patterns,1));
            weights = zeros(nOfClasses,1);

            for i = 1:nOfClasses
                nLowerRankingClasses = sum(classes<i);
                nHigherRankingClasses = sum(classes>i);

                nPreviousClasses = numel(train.targets(train.targets < i));
                nFollowingClasses = numel(train.targets(train.targets > i));

                % Assign labels depending on the decomposition
                if nPreviousClasses == 0
                    currentTargets = [train.targets(train.targets==1); ones(size(train.targets(train.targets>1)))*2];
                elseif nFollowingClasses ==0
                    currentTargets = [ones(size(train.targets(train.targets<i)));  ones(size(train.targets(train.targets==i)))*2];
                else
                    currentTargets = [ones(size(train.targets(train.targets<i))); ones(size(train.targets(train.targets==i)))*2; ones(size(train.targets(train.targets>i)))*3];
                end

                auxtrain.patterns = train.patterns;
                auxtrain.targets = currentTargets;

                % Train each label decomposition
                [projectedTrain] = obj.baseMethod.fit(auxtrain, param);
                models(i) = obj.baseMethod.getModel();

                % Estimate probabilities
                probTrain = obj.calculateProbabilities(projectedTrain, models(i).thresholds');

                % Compute weights and fused probabilities
                for j = 1: nOfClasses
                    if nHigherRankingClasses~= 0 && nLowerRankingClasses ~=0
                        if(j<i)
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .* (probTrain(1,:)/nLowerRankingClasses);
                            weights(j) = weights(j) + 1/nLowerRankingClasses;
                        elseif (j>i)
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .* (probTrain(3,:)/nHigherRankingClasses);
                            weights(j) = weights(j) + 1/nHigherRankingClasses;
                        else
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .* probTrain(2,:);
                            weights(j) = weights(j) + 1;
                        end
                    elseif i==j
                        if nLowerRankingClasses == 0
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .*  probTrain(1,:);
                            weights(j) = weights(j) + 1;
                        else
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .* probTrain(2,:);
                            weights(j) = weights(j) + 1;
                        end
                    else
                        if nLowerRankingClasses == 0
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .* (probTrain(2,:)/nHigherRankingClasses);
                            weights(j) = weights(j) + 1/nHigherRankingClasses;
                        else
                            classBelongingProbTrain(j,:) = classBelongingProbTrain(j,:) .* (probTrain(1,:)/nLowerRankingClasses);
                            weights(j) = weights(j) + 1/nLowerRankingClasses;
                        end
                    end

                end
            end
            model.ensembleModels = models;
            model.parameters = param;
            obj.model = model;

            % Join weights and probabilities into a final
            % decision label
            classBelongingProbTrain = classBelongingProbTrain ./ (weights*ones(1,size(classBelongingProbTrain,2)));
            % There is not a single projection, so projected vector
            % should not be used (it is however needed in the framework)

            % Compute final prediction
            [projected, trainTargets] = max(classBelongingProbTrain);
            projected = projected';
            trainTargets = trainTargets';

        end

        function [projected, testTargets] = privpredict(obj, test)
            %PREDICT predicts labels of TEST patterns labels using model in MODEL.
            models = obj.model.ensembleModels;
            nOfClasses = size(models,2);
            classes = 1:nOfClasses;
            weights = zeros(nOfClasses,1);
            classBelongingProbTest = ones(nOfClasses, size(test,1));

            for i = 1:nOfClasses
                nLowerRankingClasses = sum(classes<i);
                nHigherRankingClasses = sum(classes>i);

                % Estimate probabilities
                obj.baseMethod.setModel(models(i));
                [projectedTest] = obj.baseMethod.predict(test);
                probTest = obj.calculateProbabilities(projectedTest, models(i).thresholds');

                % Compute weights and fused probabilities

                for j = 1: nOfClasses
                    if nHigherRankingClasses~= 0 && nLowerRankingClasses ~=0
                        if(j<i)
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .* (probTest(1,:)/nLowerRankingClasses);
                            weights(j) = weights(j) + 1/nLowerRankingClasses;
                        elseif (j>i)
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .* (probTest(3,:)/nHigherRankingClasses);
                            weights(j) = weights(j) + 1/nHigherRankingClasses;
                        else
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .* probTest(2,:);
                            weights(j) = weights(j) + 1;
                        end
                    elseif i==j
                        if nLowerRankingClasses == 0
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .*  probTest(1,:);
                            weights(j) = weights(j) + 1;
                        else
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .* probTest(2,:);
                            weights(j) = weights(j) + 1;
                        end
                    else
                        if nLowerRankingClasses == 0
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .* (probTest(2,:)/nHigherRankingClasses);
                            weights(j) = weights(j) + 1/nHigherRankingClasses;
                        else
                            classBelongingProbTest(j,:) = classBelongingProbTest(j,:) .* (probTest(1,:)/nLowerRankingClasses);
                            weights(j) = weights(j) + 1/nLowerRankingClasses;
                        end
                    end

                end
            end

            % Join weights and probabilities into a final
            % decision label
            classBelongingProbTest = classBelongingProbTest ./ (weights*ones(1,size(classBelongingProbTest,2)));
            % There is not a single projection, so projected vector
            % should not be used (it is however needed in the framework)

            % Compute final prediction
            [projected, testTargets] = max(classBelongingProbTest);
            projected = projected';
            testTargets = testTargets';

        end

        function [y] = cummulativeProb(obj, x, beta)
            %CUMMULATIVEPROB computes the cummulative probabilities for a
            %set of projected patterns and thresholds
            %
            %   [Y] = CUMMULATIVEPROB(X, BETA) compute cummulative
            %   probabilities Y of projected patterns X with thresholds
            %   BETA

            y =  1 ./ (1+exp((x-beta))); %Logit
            %    y =  1-exp(-exp(beta-x)); %complementary log log
            %    y = exp(-exp(x-beta)); %negative log log
            %    y = normcdf(beta-x); %probit
            %    y = atan(beta-x)/pi + 0.5; % cauchit
        end

        function [g] = calculateProbabilities(obj, z, theta)
            %CALCULATEPROBABILITIES computes the probabilities for a set of
            %projected patterns and thresholds
            %
            %   [G] = CALCULATEPROBABILITIES(OBJ, Z, THETA)
            %   compute probabilities G of projected patterns PROJECTED
            %   with thresholds THRESHOLDS

            % Numerical fix
            nOfClasses = numel(theta)+1;
            if (numel(theta)==2)
                desired=4.0;
                actual=abs(theta(2) - theta(1));
                if actual<4
                    z = z*(desired/actual);
                    theta = theta*(desired/actual);
                end
            end

            f = zeros(nOfClasses, numel(z));
            g = zeros(nOfClasses, numel(z));

            for i=1:(nOfClasses-1)
                f(i,:) = obj.cummulativeProb(z',theta(i));
            end
            f(nOfClasses,:) = ones(1, size(z',2));

            g(1,:) = f(1,:);
            for i=2:nOfClasses
                g(i,:)=f(i,:)-f(i-1,:);
            end

        end

    end

end


filename='CantileverBeam_Triangle_Linear_Fine';
ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = 1;
%cost = {'compliance'};
%weights = [1];
constraint = {'volumeConstraint'};
%optimizer = 'DualNestedInPrimal';
optimizer = 'AlternatingPrimalDual';

optimizerUnconstrained = 'PROJECTED GRADIENT';
incrementFactor = 1;
designVariable = 'Density';
filterType = 'P1';

nsteps = 1;
Vfrac_final = 0.4;
optimality_final =1e-3;
constr_final = 1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-2;
constr_initial = 1e-3;

TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;

plotting = false;
printing = false;
monitoring = false;

maxiter = 200;

monitoring_interval = 1;


function r = ldivide(a,b)
%LDIVIDE      Gradient elementwise left division a .\ b
%

% written  11/02/05     S.M. Rump
%

  r = b ./ a;


function [vname]=readcpx(fname,width,lines,endian,skipbytes,precision)
%READCPX Read complex interleaved files
%   A = READCPX(FILE_NAME, WIDTH, LINES, ENDIAN, SKIPBYTES, PRECISION)
%       FILE_NAME and WIDTH are compulsory
%
%   Andy Hooper, Nov 2003

if nargin < 2
  error('syntax is A = readcpx(FILE_NAME, WIDTH, LINES, ENDIAN, SKIPBYTES, PRECISION)')
end

if nargin < 3
    lines = inf;
end

if nargin < 4
    endian = 'n';
end

if nargin < 5
    skipbytes = 0;
end

if nargin < 6
    precision = 'float';
end

fid=fopen(fname,'r',endian);

fseek(fid,skipbytes,-1);

vname=fread(fid,[width*2,lines],[precision,'=>single']).';

vname=(complex(vname(:,1:2:end),vname(:,2:2:end)));


function PDt(option, up)
%PDT detects PPG pulse peaks in PPG signals.
%	            PDt(option, up)
%
%	Inputs:
%		option          the option which has led to this function being used
%       up              universal parameters structure
%
%	Outputs:
%       ...
%

fprintf('\n--- Detecting Pulse Peaks ');
log_int_respSig = 1;             % Has value 1 unless this is a final respiratory signal

for subj = up.paramSet.subj_list

    %% Skip if this processing has been done previously
    iden_resp_sig_file_ending
    savepath = [up.paths.data_save_folder, num2str(subj), ending];
    filecontents = whos('-file', savepath);
    var_names = extractfield(filecontents, 'name');
    temp = strfind(var_names, [option(1:3), up.paths.filenames.elim_vhf]); rel_els = find(~cellfun(@isempty,temp));
    rel_var_names = var_names(rel_els);
    for rel_var_name_no = 1 : length(rel_var_names)
        for current_opt_no = 1 : length(up.al.options.PDt)
            eval(['save_name = ''' option(1:3), up.paths.filenames.pulse_peaks, up.al.options.PDt{current_opt_no}, rel_var_names{rel_var_name_no}(4:end) ''';']);
            exist_log = check_exists(savepath, save_name);
            if exist_log
                continue
            end

            %% Load relevant data
            loadpath = [up.paths.data_save_folder, num2str(subj), up.paths.filenames.int_respSigs];
            rel_name = rel_var_names{rel_var_name_no};
            load(loadpath, rel_name);
            eval(['s = ' rel_name ';']);
            eval(['fs = ' rel_name '.fs;']);

            %% High-pass filter data for peak detection
            s_filt = elim_sub_cardiac(s, up);

            %% Detect Pulse Peaks in HPF'd version
            [peaks,onsets] = feval(up.al.options.PDt{current_opt_no}, s_filt, fs, up);

            eval([save_name '.fs = fs;']);
            % Identify Pulse Peaks in original version
            eval([save_name '.p.v = s.v(peaks);']);
            eval([save_name '.p.t = s.t(peaks);']);
            eval([save_name '.tr.v = s.v(onsets);']);
            eval([save_name '.tr.t = s.t(onsets);']);
            % Identify start and end times of raw data (for resampling)
            eval([save_name '.timings.t_start = s.t(1);']);
            eval([save_name '.timings.t_end = s.t(end);']);

            %% Save processed data
            save_or_append_data

            clear peaks onsets s_filt s fs temp

        end
    end

end

end

function [peaks,onsets] = IMS(s_filt,fs,up)

[peaks,onsets,artifs] = adaptPulseSegment(s_filt.v,fs);

end


 function lists = subset_lists(nsubset, nview, varargin)
%function lists = subset_lists(nsubset, nview [, options])
%
% in
%	nsubset		# of subsets (1 to nview)
%	nview		# of views
% option
%	(none now, hard-wired to "bit-reversal" ordering)
% out
%	lists {cell}	{nsubset} lists of view indices for each subset
%
% Copyright 2000-4-?, Jeff Fessler, The University of Michigan

if nargin < 2, ir_usage, end

starts = subset_start(nsubset);

for ii=1:nsubset
	lists{ii} = [starts(ii):nsubset:nview];
end


function Conn = stat_threshConn(Conn,Stat,ThreshMethod,ThreshValue,remNonStatMethods)
% threshold connectivity values according to Stats structure
% Author: Tim Mullen, 2011

if nargin<3
    error('You must supply at least 3 arguments');
end

if nargin<4 && strcmpi(ThreshMethod,'pval')
    error('You must supply a p-value threshold');
end

if nargin<5
    remNonStatMethods = false;
end

statconnmethods = hlp_getConnMethodNames(Stat);
connmethods     = hlp_getConnMethodNames(Conn);

methodsToSkip   = ~ismember_bc(connmethods,statconnmethods);

if remNonStatMethods
    % remove all methods that we don't have stats for
    Conn = rmfield(Conn,connmethods(methodsToSkip));
end

for m=1:length(connmethods)
    if methodsToSkip(m)
        % skip thresholding for methods
        % that don't have associated Stats
        continue;
    end

    switch ThreshMethod
        case 'pval'
            % zero out any connections with p-value greater than
            % threshold
            Conn.(connmethods{m})(Stat.(connmethods{m}).(ThreshMethod) > ThreshValue) = 0;
        case 'thresh'
            % zero out any connections with amplitude less than
            % stat threshold

            Conn.(connmethods{m})( Conn.(connmethods{m}) < (Stat.(connmethods{m}).(ThreshMethod)) ) = 0;

        otherwise
            error('ThreshMethod must be ''pval'' or ''thresh''');
    end

end


function coords = rmGetCoords(vw, model)
% Get the coordinates of the voxels associated with a retinotopy model.
%
% coords = rmGetCoords(view, [model=selected model]);
%
% This is almost the same as rmGet(model, 'coords'), except it allows
% the user to enter the view (instead of grabbing the current view), so
% it should be more robust.
%
% ras, 12/2006.
if notDefined('vw'),  vw = getCurView;  end
if notDefined('model'), model = viewGet(vw, 'rmCurModel'); end
if isnumeric(model)
    allModels = viewGet(vw, 'rmModel');
    model = allModels{model};
end

if isfield(model, 'roi_coordinates') && ~isempty(model.roi_coordinates)
    val  = model.roi_coordinates;
else
    if isfield(vw, 'coords') && ~isempty(vw.coords)
        coords = vw.coords;   % gray / volume
    else        % inplane / flat
        sz = viewGet(vw,'Size');
        [X, Y, Z] = meshgrid(1:sz(2), 1:sz(1), 1:sz(3));
        coords = [X(:) Y(:) Z(:)]';
    end
end

return


%% Misc Geometry Functions
%
% This section of geometry tools especially contains methods to convert
% directions and rotations from one parametrization into another.
% Additionally, some basic geometrical objects are predefined.
%%
%


function retVec=ICRS2J2000F(vec,TT1,TT2)
%%ICRS2J2000F Convert vectors from the International Celestial Reference
%             System (ICRS) to the J2000.0 dynamical frame. This involves
%             removing a frame bias rotation.
%
%INPUTS: vec The 3XN matrix of N vectors that are to be rotated rom the
%            ICRS to the J2000.0 dynamical frame.
%   TT1, TT2 Two parts of a Julian date given in terrestrial time (TT).
%            The units of the date are days. The full date is the sum of
%            both terms. The date is broken into two parts to provide more
%            bits of precision. It does not matter how the date is split.
%
%OUTPUTS: retVec The 3XN set of vectors rotated into the J2000.0 dynamical
%                frame.
%
%As described in [1], the ICRS is ofset from the J2000 dynamical frame by
%a bias rotation.
%
%This is a wrapper for the function iauBp06 and some matrix operations in
%the International Astronomical Union's (IAU) Standard's of Fundamental
%Astronomy library.
%
%The algorithm can be compiled for use in Matlab  using the
%CompileCLibraries function.
%
%The algorithm is run in Matlab using the command format
%retVec=ICRS2J2000F(vec,TT1,TT2);
%
%REFERENCES:
%[1] G. Petit and B. Luzum, IERS Conventions (2010), International Earth
%    Rotation and Reference Systems Service Std. 36, 2010.
%
%March 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

error('This function is only implemented as a mexed C or C++ function. Please run CompileCLibraries.m to compile the function for use.')

end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function plotThermoModelExtractStats(model, activeInactiveRxn, rxnWeights, presentAbsentMet, metWeights, thermoModelMetBool, thermoModelRxnBool)

nMet=length(thermoModelMetBool);
nRxn=length(thermoModelRxnBool);

if 0
    figure
    H1 = subplot(2,1,1);
    plot(abs(solution.v),g0orig,'.')
    xlim(H1,[-1/max(abs(solution.v)),max(abs(solution.v))])
    xlabel('Reaction flux magnitude')
    ylabel('Reaction weight')
    H2 = subplot(2,1,2);
    plot(abs(solution.d),model.h0,'.')
    xlim(H2,[-1/max(abs(solution.d)),max(abs(solution.d))])
    xlabel('Metabolite production rate')
    ylabel('Metabolite weight')
else

    if 0
        T = false(3,nRxn);
        T(1,:) = abs(solution.v)>=param.epsilon;
        T(2,:) = abs(solution.v)>=param.epsilon | abs(solution.v)<param.epsilon;
        T(2,:) = abs(solution.v)<param.epsilon;
        P = false(3,nRxn);
        P(1,:) = g0orig < 0;
        P(2,:) = g0orig == 0;
        P(3,:) = g0orig > 0;
        plotconfusion(T,P,'Reaction activity')
    else

        if 0
            T = cell(nRxn,1);
            T(abs(solution.v)>=param.epsilon & g0orig ~= 0)={'Active'};
            T(abs(solution.v)<param.epsilon & g0orig ~= 0)={'Inactive'};
            T(g0orig == 0)={'Unspecified'};
            P = cell(nRxn,1);
            P(g0orig < 0)={'Active'};
            P(g0orig == 0)={'Unspecified'};
            P(g0orig > 0)={'Inactive'};
            %             usage:
            %             % Find the confusionmat matrix first
            %             [C,order] = confusionmat(TestResults,PredictionResults)
            %             % Then, plot
            %             plotConfMat(C) plots the confmat with integers 1 to n as class labels
            %             plotConfMat(C, order) plots the confmat with the specified labels
            C = confusionmat(T,P,'order',{'Active';'Inactive';'Unspecified'});
            plotConfMat(C,{'Active';'Inactive';'Unspecified'});
        else

            if any(rxnWeights~=0)
                figure;
                hist(rxnWeights)
                title('Reaction weights')
                figure
                P = cell(nRxn,1);
                P(thermoModelRxnBool==1)={'Active'};
                P(thermoModelRxnBool==0)={'Inactive'};

                T = cell(nRxn,1);
                if 1
                    T(rxnWeights < 0)={'Active'};
                    T(rxnWeights > 0)={'Inactive'};
                    T=T(rxnWeights~=0);
                    P=P(rxnWeights~=0);
                else
                    T(activeInactiveRxn==1)={'Active'};
                    T(activeInactiveRxn==-1)={'Inactive'};
                    T=T(activeInactiveRxn~=0);
                    P=P(activeInactiveRxn~=0);
                end

                %             usage:
                %             % Find the confusionmat matrix first
                %             [C,order] = confusionmat(TestResults,PredictionResults)
                %             % Then, plot
                %             plotConfMat(C) plots the confmat with integers 1 to n as class labels
                %             plotConfMat(C, order) plots the confmat with the specified labels

                %    CM = CONFUSIONMAT(G,GHAT) returns the confusion matrix CM determined

                %    by the known group labels G and the predicted group labels GHAT.
                if any(rxnWeights == 0) && 0
                    labels = {'Active';'Inactive';'Unspecified'};
                else
                    labels = {'Active';'Inactive'};
                end
                C = confusionmat(P,T,'order',labels);
                plotConfMat(C,labels);
                accuracy = sum(diag(C),1)/sum(sum(C,1));
                title(['Reaction confusion matrix, accuracy = ' num2str(accuracy)])
            end

            if any(metWeights~=0)
                figure;
                hist(metWeights)
                title('Metabolite weights')

                figure;
                P = cell(nMet,1);
                P(thermoModelMetBool==1)={'Active'};
                P(thermoModelMetBool==0)={'Inactive'};

                T = cell(nMet,1);
                if 1
                    T(metWeights < 0)={'Active'};
                    T(metWeights >= 0)={'Inactive'};
                    T=T(metWeights~=0);
                    P=P(metWeights~=0);
                else
                    T(presentAbsentMet==1)={'Active'};
                    T(presentAbsentMet==-1)={'Inactive'};
                    T=T(presentAbsentMet~=0);
                    P=P(presentAbsentMet~=0);
                end
                %             usage:
                %             % Find the confusionmat matrix first
                %             [C,order] = confusionmat(TestResults,PredictionResults)
                %             % Then, plot
                %             plotConfMat(C) plots the confmat with integers 1 to n as class labels
                %             plotConfMat(C, order) plots the confmat with the specified labels

                %    CM = CONFUSIONMAT(G,GHAT) returns the confusion matrix CM determined

                %    by the known group labels G and the predicted group labels GHAT.
                if any(metWeights == 0) && 0
                    labels = {'Active';'Inactive';'Unspecified'};
                else
                    labels = {'Active';'Inactive'};
                end
                C = confusionmat(P,T,'order',labels);
                plotConfMat(C,labels);
                accuracy = sum(diag(C),1)/sum(sum(C,1));
                title(['Metabolite confusion matrix, accuracy = ' num2str(accuracy)])
            end
        end
    end
end


function p2 = resample(p,Np,ksType)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% resample(p,Np,KSType) -- construct a new estimate of the KDE p by sampling
%                      Np new points; determines a bandwidth by ksize(pNew,KSType)
%                      NOTE: KStype = 'discrete' resamples points by weight &
%                            preserves original kernel size
% see also: kde, ksize
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt

  if (nargin < 3) ksType = 'rot'; end;
  if (nargin < 2) Np = getNpts(p); end;
  if (strcmp(ksType,'discrete'))
    q = kde(getPoints(p),zeros(getDim(p),1),getWeights(p));
    [samplePts,ind] = sample(q,Np);
    if (size(p.bandwidth,2)>2*p.N), ks = getBW(p,ind);
    else ks = getBW(p,1); end;
    p2 = kde(samplePts,ks);
  else
    samplePts = sample(p,Np);
    p2 = kde(samplePts,ksType);
  end;


function r = atan(p)
%atan: this function calculates the atan of a x, y, and z values of
% the structures that I use in the FVtool.
%
% SYNOPSIS:
%
%
% PARAMETERS:
%
%
% RETURNS:
%
%
% EXAMPLE:
%
% SEE ALSO:
%

% Copyright (c) 2012-2016 Ali Akbar Eftekhari
% See the license file

r = p;
r.value = atan(p.value);


function M = feval(L, n, flag)
%FEVAL    Deprecated function, provided for limited backward compatibility.

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

warning('CHEBFUN:LINOP:feval:deprecated',...
    ['This function is provided only for limited backward compatibility.',...
    ' Use MATRIX instead.'] );
warning('off', 'CHEBFUN:LINOP:feval:deprecated')

if ( prod(size(L)) > 1 ) %#ok<PSIZE>
    error('CHEBFUN:LINOP:feval:multivariable', ...
        'This syntax is not available for multivariable systems.')
end

if ( nargin < 3 )
    flag = 'bc';
end
% TODO: Should we always use a chebcolloc2 representation here?
% if ( nargin < 4 )
%     pref = cheboppref();
%     discType = pref.discretization;
% elseif ( isa(discType, 'cheboppref') )
%     discType = discType.discretization;
% elseif ( ischar(discType) )
%     discType = str2func(discType);
% end
discType = @chebcolloc2;

if ( isa(n, 'chebfun') )
    M = L*n;   % application to a function

else

    disc = discType(L);
    disc.dimension = n;

    if ( strcmp(flag, 'oldschool') )
        disc.dimAdjust = 0;
    end

    [PA, ignored, B, A] = matrix(disc);

    % Depending on the flag, we will do different things about boundary
    % conditions.
    switch(flag)
        case 'nobc'
            M = A;
        case 'bc'
            M = [B; PA];
        otherwise  % oldschool

            k = size(B,1);     % number of rows to drop
            k2 = ceil(k/2);    % about half for top
            try
                A = cell2mat(A);
            catch
                error('CHEBFUN:LINOP:feval:oldschool', ...
                    'oldschool does not support this problem');
            end
            if ( k2 > 0 )
                A(1:k2,:) = B(1:k2,:);
                krem = k - k2;     % number remaining
                A(end-krem+1:end, :) = B(k2+1:end, :);
            end
            M = A;
    end
end

end


function T=findDartboardSubarrays(aperFracs,subarraysPerRing,angShifts,xyPoints)
%%FINDDARTBOARDSUBARRAYS When designing subarrays for a circular aperture,
%          it is noted in [1] that a dartboard pattern tends to work pretty
%          well. It is also suggested that a subarray pattern returned by
%          findBaylissSubarrays be used as a rule of thumb for choosing how
%          many rings and the number of subarrays per ring in the
%          dartboard. When given the positions of elements in a
%
%INPUTS: aperFracs A numRingsX1 or 1XnumRings vector sorted in increasing
%                  order where aperFrac(i) is the fraction of the aperture
%                  size where the ring specified ends. aperFrac(end) must
%                  equal 1 (100% of the aperture size). The aperture width
%                  is taken to be the maximum distance of a point in
%                  xyPoints from the origin.
% subarraysPerRing A numRingsX1 or 1XnumRings vector indicating the number
%                  of subarrays in each ring. These must be positive
%                  integers.
%        angShifts A numRingsX1 or 1XnumRings vector giving angular offsets
%                  in radians by which the first subarray in each ring
%                  begins. This is here to keep the rings from all lining
%                  up, which should improve how the grating lobes of the
%                  subarrays line up. If an empty matrix is passed, then
%                  angular shifts of zero are used.
%         xyPoints A 2XnumPoints set of numPoints points in the aperture
%                  plane corresponding to element positions. The points
%                  should be shifted such that the center of the aperture
%                  is the origin. The width of the aperture is the maximum
%                  distance of any point from the center.
%
%OUTPUTS: T A numSubarraysXnumPoints boolean matrix (a matrix such that
%           T(i,:) is a set of boolean values indicating which elements are
%           in each subarray). The subarrays do not overlap.
%
%EXAMPLE:
%Here, we lay out the elements for a circular array and then we break them
%into a dartboard configuration. We then display the elements with
%different symbols and colors for the subarrays.
% %First, we create a circular array. The element locations are given in
% %terms of the wavelength lambda, so lambda will not appear in the
% %equations for the sum beam.
% xyVals=getShaped2DLattice([49;49],'circular');
%
% aperFracs=[1/5;2/5;3/5;4/5;1];
% subarraysPerRing=[4;4;8;8;8];
% degShifts=[0;2*pi/(2*4);0;2*pi/(2*8);0];
% T=findDartboardSubarrays(aperFracs,subarraysPerRing,degShifts,xyVals);
%
% figure()
% clf
% hold on
% axis square
% numSubarrays=size(T,1);
% dispOpts={'.b','.g','.m','.c','.y','.k','.b','.r',...
%     'xm','xc','xy','xk','xb','xr','xb','xg',...
%     'ob','og','om','oc','oy','ok','ob','or'...
%     '+m','+c','+m','+y','+k','+r','+b','+g'...
%     'sb','sg','sm','sc','sm','sy','sk','sr'};
% for curSubarray=1:numSubarrays
%     points=xyVals(:,T(curSubarray,:)==1);
%     optVal=mod(curSubarray,length(dispOpts))+1;
%     scatter(points(1,:),points(2,:),dispOpts{optVal},'linewidth',2);
% end
% h1=xlabel('x');
% h2=ylabel('y');
% title('Coloring Represents Subarrays')
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%
%REFERENCES:
%[1] U. Nickel, "Subarray configurations for digital beamforming with
%    low sidelobes, adaptive interference suppression and superresolution,"
%    1995, FFM-Report (available from Fraunhofer FKIE, Wachtberg, Germany).
%
%September 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

numRings=length(aperFracs);
numSubarrays=sum(subarraysPerRing);
numEls=size(xyPoints,2);

if(aperFracs(numRings)~=1)
   error('The last element in  aperFracs must be one');
end

if(isempty(angShifts))
    angShifts=zeros(numRings,1);
end

%The maximum squared distance from the origin to a point is taken to be the
%radius of the aperture squared.
a=sqrt(max(sum(xyPoints.^2,1)));

temp=cumsum(subarraysPerRing(:));
numSubsInPriorRings=[0;temp(1:(numRings-1))];

T=false(numSubarrays,numEls);
for curEl=1:numEls
    %The fractional distance from the outer edge of the aperture where the
    %element is located.
    fracCur=norm(xyPoints(:,curEl))/a;

    %Determine which ring the element is in.
    [~, ringIdx]=binSearch(aperFracs,fracCur,2);

    %Each ring can have multiple subarrays. The subarrays are uniformly
    %spaced in angle, but the starting angle is not taken to be zero but
    %rather degShifts(ringIdx) radians.
    angle=atan2(xyPoints(2,curEl),xyPoints(1,curEl));

    subArrayWidth=2*pi/subarraysPerRing(ringIdx);

    subArrayInRing=fix(wrapRange(angle+angShifts(ringIdx),0,2*pi)/subArrayWidth)+1;
    subArrayIdx=numSubsInPriorRings(ringIdx)+subArrayInRing;
    T(subArrayIdx,curEl)=1;
end
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function [m,varargout] = min(varargin)

funname = 'min';

narginchk(1, 2)
if nargin == 1;
    nargoutchk(0, 2)
    [m,varargout{1}] = min(varargin{1}.Z(:));

elseif nargin == 2;
    nargoutchk(0, 1)

    % which one of the two input arguments is a GRIDobj
    isGRIDobj = cellfun(@(x) isa(x,'GRIDobj'),varargin);

    % if both
    if all(isGRIDobj)
        validatealignment(varargin{1},varargin{2});
        M = builtin(funname,varargin{1}.Z,varargin{2}.Z);
    else
        varargin = varargin(~isGRIDobj + 1);
        if ~isscalar(varargin{2});
            validatealignment(varargin{1},varargin{2});
        end
        M = builtin(funname,varargin{1}.Z,varargin{2});
    end

    m = varargin{1};
    m.name = funname;
    m.Z = M;
    m.zunit = '';
end


% Test file for ADCHEBFUN Bessel functions

function pass = test_bessel

% List of airy functions to test, with different number of inputs
besselj1 = @(f) besselj(1, f);
besselj25 = @(f) besselj(2.5, f);

funcList = {besselj1, besselj25};

% Call the ADCHEBFUN testUnary() method to do the tests.
pass = adchebfun.testUnary(funcList);

end


%DETECTCHARUCODIAMOND  Detect ChArUco Diamond markers
%
%     [diamondCorners, diamondIds] = cv.detectCharucoDiamond(img, markerCorners, markerIds, squareMarkerLengthRate)
%     [...] = cv.detectCharucoDiamond(..., 'OptionName',optionValue, ...)
%
% ## Input
% * __img__ input image necessary for corner subpixel (8-bit grayscale or
%   color).
% * __markerCorners__ cell array of detected marker corners from
%   cv.detectMarkers function `{{[x,y],..}, ..}`.
% * __markerIds__ vector of marker ids in `markerCorners` (0-based).
% * __squareMarkerLengthRate__ rate between square and marker length:
%   `squareMarkerLengthRate = squareLength/markerLength`. The real units are
%   not necessary.
%
% ## Output
% * __diamondCorners__ output list of detected diamond corners (4 corners per
%   diamond). The order is the same than in marker corners: top left, top
%   right, bottom right and bottom left. Similar format than the corners
%   returned by cv.detectMarkers (e.g `{{[x y],..}, ..}`).
% * __diamondIds__ ids of the diamonds in `diamondCorners` (0-based). The id
%   of each diamond is in fact a vector of four integers, so each diamond has
%   4 ids, which are the ids of the aruco markers composing the diamond.
%
% ## Options
% * __CameraMatrix__ Optional 3x3 camera calibration matrix
%   `A = [fx 0 cx; 0 fy cy; 0 0 1]`.
% * __DistCoeffs__ Optional vector of camera distortion coefficients
%   `[k1,k2,p1,p2,k3,k4,k5,k6,s1,s2,s3,s4]` of 4, 5, 8 or 12 elements.
%
% This function detects Diamond markers from the previous detected ArUco
% markers. The diamonds are returned in the `diamondCorners` and `diamondIds`
% parameters. If camera calibration parameters are provided, the diamond
% search is based on reprojection. If not, diamond search is based on
% homography. Homography is faster than reprojection but can slightly reduce
% the detection rate.
%
% See also: cv.detectMarkers, cv.interpolateCornersCharuco,
%  cv.drawDetectedDiamonds
%


function [result]=sv_NodeCalc(mCatalog, fSplitTime, bTimePeriod, fTimePeriod, nCalculateMC, vCluster, bDecluster, fMcOrg, fBValueOrg, bSeisModel)
% function [result]=sv_NodeCalc(mCatalog, fSplitTime, bTimeperiod, fTimePeriod, nCalculateMC, vCluster, bDecluster, fMcOrg, fBValueOrg, bSeisModel)
% -------------------------------------------------------------------------------------------------------------------------------------------------
% Function to calculate absolute difference of number of events between
% to time periods of an earthquake catalog normalized to a year
% Incoming variables:
% mCatalog     : current earthquake catalog
% fSplitTime   : Splitting time
% bTimePeriod  : Use specific time period to compare (1) or from beginning till end of catalog (0)
% fTimePeriod  : Time period in days to be compared before and after fSplitTime
% nCalculateMC : Number for Method of Mc determination
% vCluster     : Vector of cluster numbers
% bDecluster   : Decluster catalog or not
% fMcOrg       : Mc of entire catalog
% fBValueOrg   : b-value of entire catalog
% bSeisModel   : Method to model seismicity varation: 0 - b-value fittng, 1 - grid search
%
% Outgoing variable:
% result.dNdiffsum      : total difference of number of events in the two time periods
% result.fMc            : magnitude of completeness for entire catalog
% result.fMcFirstPeriod : magnitude of completeness for first period defined
% result.fMcSecondPeriod : magnitude of completeness for second period defined
% result.fdMc            : Difference in Mc: Mc(Per1)-Mc(Per2)
% result.fMshift         : Simple magnitude shift
% result.fMshiftFit      : Goodness of fit in percent to modeling second period with simple magnitude shift of first period
% result.fMshiftSig      : Simple magnitude shift at 99% significance level of z-statistic
% result.fFactorHi       : Mean rate factor for EQ >= Mc(Per1) between two periods
% result.fPerHi          : Percental seismicity change
% result.fFactorLow      : Mean rate factor for EQ < Mc(Per1) between two periods
% result.fPerLow         : Percental seismicity change
% result.fMRateFit       : Goodness of fit by modeling second period with rate factor multiplication of first period
% result.fMshiftCom      : Magnitude shift combined with stretch
% result.fStretch        : Magnitude stretch
% result.fMTransFit      : Goodness of fit by modeling second period manipulating the first period
% result.fdMag           : Magnitude shift for a M=1 EQ using result.fMshiftCom and result.fStretch
% result.mModelCat       : Magnitude alternation for a magnitude M=1 EQ
%
% Author: J. Woessner
% woessner@seismo.ifg.ethz.ch
% last update: 01.11.02
% Changes:
% 19.08.02: Replaced  fcumulsum.m with calc_cumulsum.m
% 08.10.02: Deleted return at the end.

% Changes:
% 19.08.02: Replaced  fcumulsum.m with calc_cumulsum.m
% 08.10.02: Deleted return at the end.

% Init variable
result=[];
fTimePeriod =fTimePeriod/365;

if bDecluster == 1
    % Determine degree of Poissonian distribution using Chi^2-Test
    [result.fChi2 result.fChi2_sig90 result.fChi2_sig95 result.Chi2_sig99 result.nPoissDeg]= calc_Chi2(mCatalog);
    vSel = (vCluster(:,1) > 0);
    mCatalogDecl = mCatalog(~vSel,:);
    [result.fChi2_Dec result.fChi2_sig90_Dec result.fChi2_sig95_Dec result.Chi2_sig99_Dec...
            result.nPoissDeg_Dec]= calc_Chi2(mCatalogDecl);
    % Determine degree of Clustering
    [result.fClusterDeg] = calc_ClusterDeg(mCatalog, vCluster);
elseif (bSeisModel == 1)
    % Create the catalogs for the two time peiods
    [result.mFirstCatalog, result.mSecondCatalog, result.fFirstPeriodExact, result.fSecondPeriodExact, result.fFirstPeriod,...
            result.fSecondPeriod] = ex_SplitCatalog(mCatalog, fSplitTime, bTimePeriod, fTimePeriod, bTimePeriod, fTimePeriod);

    %% Determination of difference between two time periods normalized to year
    [dEv_val dMags dEv_valsum dEv_valsum_rev,  dMags_rev] = calc_cumulsum(result.mFirstCatalog);
    [dEv_val2 dMags2 dEv_valsum2 dEv_valsum_rev2,  dMags_rev2] = calc_cumulsum(result.mSecondCatalog);
    result.dNdiff = max(dEv_val2)/result.fSecondPeriodExact-max(dEv_val)/result.fFirstPeriodExact; % Normalization
    result.dNdiffsum = cumsum(result.dNdiff');
    %result.dNdiffsumVal = result.dNdiffsum(length(result.dNdiffsum));

    % Determine Mc for entire catalog, two time periods and difference in Mc
    result.fMc = calc_Mc(mCatalog, nCalculateMC);
    if isempty(result.fMc)
        result.fMc = NaN;
    end
    result.fMcFirstPeriod = calc_Mc(result.mFirstCatalog, nCalculateMC);
    if isempty(result.fMcFirstPeriod)
        result.fMcFirstPeriod = NaN;
    end
    result.fMcSecondPeriod = calc_Mc(result.mSecondCatalog, nCalculateMC);
    if isempty(result.fMcSecondPeriod)
        result.fMcSecondPeriod = NaN;
    end
    result.fdMc = result.fMcSecondPeriod - result.fMcFirstPeriod;

    % Determine simple magnitude shift and Goodness of Fit
    [result.fMshift result.fMshiftFit] = calc_Magshift(mCatalog, fSplitTime, bTimePeriod, fTimePeriod, nCalculateMC);
    if isempty(result.fMshift)
        result.fMshift = NaN;
        result.fMshiftFit = NaN;
    end
    % Determine significant Mshift at 99% level
    [mLMagsig mHMagsig fLZmax fLZmean fLZmin fHZmax fHZmean,  fHZmin] =...
        calc_Magsig(result.mFirstCatalog, result.mSecondCatalog , result.fFirstPeriodExact, result.fSecondPeriodExact, 0.1);
    if ((fLZmax >= 2.57 & fHZmin <= -2.57) | fLZmin <= -2.57 & fHZmax >= 2.57)
        result.fMshiftSig = result.fMshift;
    else
        result.fMshiftSig = NaN;
    end
    % Determine rate factors and percentage change of EQ for M<Mc and M>=Mc
    [result.fFactorHi fStdHi fResHi result.fPerHi result.fFactorLow fStdLow fResLow result.fPerLow result.fMRateFit]...
        = calc_ratefac(result.mFirstCatalog, result.mSecondCatalog, fTimePeriod, fTimePeriod,...
        result.fMcFirstPeriod, result.fMcSecondPeriod);
    [result.fMshiftCom result.fStretch result.fMTransFit result.fARate] = calc_Shiftstretch(mCatalog, fSplitTime, bTimePeriod,...
        fTimePeriod, nCalculateMC, fMcOrg, fBValueOrg);
    %% Magnitude fit for a magnitude M=1 EQ
    result.fdMag = 1+((result.fStretch-1)+result.fMshiftCom); % Theoretical map
    result.mModelCat = result.mFirstCatalog;
    result.mModelCat(:,6) = result.fStretch.*result.mModelCat(:,6)+result.fMshiftCom;
else
    % Create the catalogs for the two time peiods
    [result.mFirstCatalog, result.mSecondCatalog, result.fFirstPeriodExact, result.fSecondPeriodExact, result.fFirstPeriod,...
            result.fSecondPeriod] = ex_SplitCatalog(mCatalog, fSplitTime, bTimePeriod, fTimePeriod, bTimePeriod, fTimePeriod);

    %% Determination of difference between two time periods normalized to year
    [dEv_val dMags dEv_valsum dEv_valsum_rev,  dMags_rev] = calc_cumulsum(result.mFirstCatalog);
    [dEv_val2 dMags2 dEv_valsum2 dEv_valsum_rev2,  dMags_rev2] = calc_cumulsum(result.mSecondCatalog);
%     result.dNdiff = max(dEv_val2)/result.fSecondPeriodExact-max(dEv_val)/result.fFirstPeriodExact; % Normalization
    result.dNdiff = max(dEv_valsum2)/result.fSecondPeriodExact-max(dEv_valsum)/result.fFirstPeriodExact;
    result.dNdiffsum = max(cumsum(result.dNdiff'));
    %result.dNdiffsumVal = result.dNdiffsum(length(result.dNdiffsum));
    if isempty(result.dNdiff)
        result.dNdiff = NaN;
    end
    if isempty(result.dNdiffsum)
        result.dNdiffsum = NaN;
    end
    % Determine Mc for entire catalog, two time periods and difference in Mc
    result.fMc = calc_Mc(mCatalog, nCalculateMC);
    if isempty(result.fMc)
        result.fMc = NaN;
    end
    result.fMcFirstPeriod = calc_Mc(result.mFirstCatalog, nCalculateMC);
    if isempty(result.fMcFirstPeriod)
        result.fMcFirstPeriod = NaN;
    end
    result.fMcSecondPeriod = calc_Mc(result.mSecondCatalog, nCalculateMC);
    if isempty(result.fMcSecondPeriod)
        result.fMcSecondPeriod = NaN;
    end
    result.fdMc = result.fMcSecondPeriod - result.fMcFirstPeriod;

    % Mc determination by grid search
    %[result.fProbMcGrid result.fMcGrid] = calc_McGridN(mCatalog,0.1);
    [result.fProbMcGrid result.fMcGrid] = calc_McCdf2(mCatalog,0.1)
    if (isempty(result.fProbMcGrid) | isempty(result.fMcGrid))
        result.fProbMcGrid = NaN;
        result.fMcGrid = NaN;
    end
    %% Use data only above completeness
    %fMinMc = min([result.fMcFirstPeriod result.fMcSecondPeriod]);
    %     vSel1 = (result.mFirstCatalog(:,6) >= result.fMcFirstPeriod);
    %     vSel2 = (result.mSecondCatalog(:,6) >= result.fMcFirstPeriod);
    %     result.mFirstCatalog = result.mFirstCatalog(vSel1,:);
    %     result.mSecondCatalog = result.mSecondCatalog(vSel2,:);

    %% Seismicity variation modelling
    %!!!!! NO MODELS WITH STRETCH ALLOWED !!!!!!!!!!!!!!!!!!!!!!!!!
    %%% Maximum likelihood scores and BICs
    [fProb_nochange, fBic_nochange] = calc_loglikelihood_nochange2(result.mFirstCatalog, result.mSecondCatalog);
    [fdM, fProb_dM, fBic_dM, mLikeli_dM] = calc_loglikelihood_dM2(result.mFirstCatalog, result.mSecondCatalog);
    %[fS, fProb_stretch, fBic_stretch, mLikeli_dS] = calc_loglikelihood_stretch(result.mFirstCatalog, result.mSecondCatalog);
    [fFac, fProb_Rate, fBic_Rate, mLikeli_Rate] = calc_loglikelihood_rate2(result.mFirstCatalog, result.mSecondCatalog);
    [fdM_rate, fdM_Fac, fProb_dMrate, fBic_dMrate, mLikeli_dMrate] = calc_loglikelihood_dM_rate2(result.mFirstCatalog, result.mSecondCatalog);
    %[fdS_rate, fdS_Fac, fProb_dSrate, fBic_dSrate mLikeli_dSrate] = calc_loglikelihood_stretch_rate(result.mFirstCatalog, result.mSecondCatalog);
    %[fdM_st, fStretch, fProb_Trans, fBic_Trans, mLikeli_Trans] = calc_loglikelihood_Trans(result.mFirstCatalog, result.mSecondCatalog);
    %[fdM_all, fdS_all, fFac_all, fProb_all, fBic_all, mLikeli_all] = calc_loglikelihood_dMdSrate(result.mFirstCatalog, result.mSecondCatalog);

    %vBic = [fBic_nochange; fBic_dM; fBic_stretch; fBic_Rate; fBic_dMrate; fBic_Trans; fBic_dSrate; fBic_all];
    vBic = [fBic_nochange; fBic_dM;  fBic_Rate; fBic_dMrate];
    [result.nType] = find(vBic == min(vBic));
    %% Initialize result
    result.fdM = nan; % Shift
    result.fdS = nan; % Stretch
    result.fRf = nan; % rate factor
    if length(result.nType) > 1
        vBic;
        result.nModelChoice = NaN;
    elseif length(result.nType) == 0
        result.nModelChoice = nan;
    else
        switch result.nType
        case 1
            result.nModelChoice = 1;
            %     result.fdM = 0; % Shift
            %     result.fdS = 1; % Stretch
            %     result.fRf = 1; % rate factor
        case 2
            result.nModelChoice = 2;
            result.fdM = fdM;
%         case 3
%             result.nModelChoice = 3;
%             result.fdS = fS;
        case 3
            result.nModelChoice = 3;
            result.fRf = fFac;
        case 4
            result.nModelChoice = 4;
            result.fdM = fdM_rate;
            result.fRf = fdM_Fac;
%         case 6
%             result.nModelChoice = 6;
%             result.fdM = fdM_st;
%             result.fdS = fStretch;
%         case 7
%             result.nModelChoice = 7;
%             result.fdS = fdS_rate;
%             result.fRf = fdS_Fac;
%         case 8
%             result.nModelChoice = 8;
%             result.fdM = fdM_all;
%             result.fdS = fdS_all;
%             result.fRf = fFac_all;
        otherwise
            disp('Something is equal');
        end; % END of Switch result.Type
    end;% END of IF result.Type
end; % END of IF bSeismodel
end % End of IF bDecluster


cleardataquestion   % clearing the data
savethis = 1;       % saves the results
params              % parameters for the computitation

delta_vec = [.1 .3 .5 .8 1]; %all...
ncomp_vec = [2];
for nc_ix = 1:length(ncomp_vec)
    peval.ncomp = ncomp_vec(nc_ix); %number of components without the background component....
    for delta = delta_vec
        % data location for each computaution:
        peval.data_path = [getenv('HOME') '/project/data/qdots/D2ptBMrandOblique' '/'];
        peval.data_dir= ['D_N2_delta' num2str(delta*100) '_NoNoise'];
        peval.data_name=peval.data_dir;

        % results name:
        peval.res_nameappendix = ['_nc' num2str(peval.ncomp)];
        peval.res_dir = [peval.data_dir peval.res_nameappendix];
        peval.res_name = peval.res_dir;

        %reads data:
        [dpixc, dpixc_ind, blinkmat, peval, p] = readSimulSimple(peval);
        peval.bg = peval.offset; %cheating here

        for iteration=1:10 % several evaluations of the same data
            for nn = 1 : peval.nrestartH
                % initialization:
                winit_pix = init_w_meandata1res;
                hinit = rand(peval.ncomp, size(dpixc,3));
                %nmf separation:
                [res, peval] = separcomp(dpixc, peval, winit_pix, hinit);

                %saving results
                if savethis
                    saveresultscompleteSimple
                end
            end

            % MAP fiting with nmf initialization
            peval.filenamebase = ['iter' num2str(iteration)];
            % peval.sigmaPSF = 1.3; %sigma of the PSF gauss approx (in pixels)
            if savethis; cd (peval.res_dir); end
            [ihs, x_mu, y_mu, sig] = plotreswh2(res, peval, dpixc, p, savethis, 1, 0, 1, 1,0);
            if savethis; cd ..; end
            % initialization form nmf ressults:
            x1in=reshape(res.h(1:peval.ncomp,:), 1,peval.ncomp*peval.nt);
            x2in=-1+[x_mu, y_mu];
            [x1in,x2in]=initx1x2(Hinit,Winit,x1,x2,x1rand,x2rand);
            Wres=x2in;
            Hres=x1in;
            pointlogWall=[]; flog=[]; pointlogHall=[];
            for kk=1:peval.nIterAlter %alternating optimization

                % W fixed, optimizing H (intensities)
                [Hres, optionsH, flogH, pointlogH] = conjgrad(peval.Hupdate, Hres, optionsH, ['grad' peval.Hupdate],reshape(dpixc, peval.nx*peval.ny, peval.nt), peval.sigmaPSF, peval.alpha, peval.beta, peval, Wres(1:peval.ncomp), Wres(peval.ncomp+1:end));
                flog=[flog; flogH];
                pointlogHall=[pointlogHall; pointlogH];
                % H fixed, optimizing W (positions)
                [Wres, optionsW, flogW, pointlogW] = conjgrad(peval.Wupdate, Wres, optionsW, ['grad' peval.Wupdate],reshape(dpixc, peval.nx*peval.ny, peval.nt), peval.sigmaPSF, peval.alpha, peval.beta, peval, Hres);
                flog=[flog; flogW];
                pointlogWall=[pointlogWall; pointlogW];

                peval.Wres=Wres;
                %% plotting & saves results
                if savethis; cd (peval.res_dir); end
                showimage=0;
                res.dpixc=dpixc;
                plotloglikGaP;
                if savethis; cd ..; end

            end
        end
    end
end


function VRes = spm_write_residuals(SPM,Ic)
% Write residual images
% FORMAT Vres = spm_write_residuals(SPM,Ic)
% SPM    - structure containing generic analysis details
% Ic     - contrast index used to adjust data (0:   no adjustment)
%                                             (NaN: adjust for everything)
%
% VRes   - struct array of residual image handles
%__________________________________________________________________________
% Copyright (C) 2012-2013 Wellcome Trust Centre for Neuroimaging

% Guillaume Flandin
% $Id: spm_write_residuals.m 6656 2015-12-24 16:49:52Z guillaume $

%-Get SPM.mat
%--------------------------------------------------------------------------
 if ~nargin || isempty(SPM)
     [SPM,sts] = spm_select(1,'^SPM\.mat$','Select SPM.mat');
     if ~sts, VRes = ''; return; end
 end

if ~isstruct(SPM)
    swd = spm_file(SPM,'fpath');
    try
        load(fullfile(swd,'SPM.mat'));
        SPM.swd = swd;
    catch
        error(['Cannot read ' fullfile(swd,'SPM.mat')]);
    end
end

try, SPM.swd; catch, SPM.swd = pwd; end
cwd = pwd; cd(SPM.swd);

%-Get contrast used to adjust data
%--------------------------------------------------------------------------
if nargin<2 || isempty(Ic)
    q(1)   = 0;
    Con    = {'<don''t adjust>'};
    q(2)   = NaN;
    Con{2} = '<adjust for everything>';
    for i = 1:length(SPM.xCon)
        if strcmp(SPM.xCon(i).STAT,'F')
            q(end + 1) = i;
            Con{end + 1} = SPM.xCon(i).name;
        end
    end
    i  = spm_input('adjust data for (select contrast)','!+1','m',Con);
    Ic = q(i);
end

%-Compute and write residuals
%==========================================================================
spm('Pointer','Watch')
M   = SPM.xY.VY(1).mat;
DIM = SPM.xY.VY(1).dim(1:min(numel(SPM.xY.VY(1).dim),3));
[nScan, nBeta] = size(SPM.xX.X);

if spm_mesh_detect(SPM.xY.VY)
    file_ext = '.gii';
else
    file_ext = spm_file_ext;
end

%-Initialise residual images
%--------------------------------------------------------------------------
VRes(1:nScan) = deal(struct(...
    'fname',    [],...
    'dim',      DIM,...
    'dt',       [spm_type('float64') spm_platform('bigend')],...
    'mat',      M,...
    'pinfo',    [1 0 0]',...
    'descrip',  'Residuals'));
for i = 1:nScan
    VRes(i).fname   = [sprintf('Res_%04d', i) file_ext];
    VRes(i).descrip = sprintf('Residuals (%04d)', i);
end
VRes = spm_data_hdr_write(VRes);

%-Loop over chunks
%--------------------------------------------------------------------------
chunksize = floor(spm_get_defaults('stats.maxmem') / 8 / nScan);
nbchunks  = ceil(prod(DIM) / chunksize);
chunks    = min(cumsum([1 repmat(chunksize,1,nbchunks)]),prod(DIM)+1);

spm_progress_bar('Init',nbchunks,'Writing residuals','Chunks');

for i=1:nbchunks
    chunk = chunks(i):chunks(i+1)-1;

    %-Get mask
    %----------------------------------------------------------------------
    m = spm_data_read(SPM.VM,chunk) > 0;
    m = m(:)';

    %-Get raw data, whiten and filter
    %----------------------------------------------------------------------
    y = zeros(nScan,numel(chunk));
    for j=1:nScan
        y(j,:) = spm_data_read(SPM.xY.VY(j),chunk);
    end
    y(:,~m) = [];

    y = spm_filter(SPM.xX.K,SPM.xX.W*y);

    if Ic ~= 0

        %-Parameter estimates: beta = xX.pKX*xX.K*y
        %------------------------------------------------------------------
        beta = zeros(nBeta,numel(chunk));
        for j=1:nBeta
            beta(j,:) = spm_data_read(SPM.Vbeta(j),chunk);
        end
        beta(:,~m) = [];

        %-Subtract Y0 = XO*beta,  Y = Yc + Y0 + e
        %------------------------------------------------------------------
        if ~isnan(Ic)
            y = y - spm_FcUtil('Y0',SPM.xCon(Ic),SPM.xX.xKXs,beta);
        else
            y = y - SPM.xX.xKXs.X * beta;
        end

    end

    %-Write residuals
    %----------------------------------------------------------------------
    yy = NaN(numel(chunk),1);
    for j=1:nScan
        yy(m)   = y(j,:);
        VRes(j) = spm_data_write(VRes(j), yy, chunk);
    end

    spm_progress_bar('Set',i)
end

cd(cwd);
spm_progress_bar('Clear')
spm('Pointer','Arrow')


%% inequality restrictions
% use the parameter restrictions block
% a >= b
% cos(tan(b))<=log(c)

%% equality restrictions
% One can use the parameter restrictions block as the interface
% to equality restrictions. Those restrictions can be nonlinear
% a = 3*b+4*c
% a = tan(cos(log(sin(b+c))))
% in the example above, if a is not estimated while b and c can be
%
% An alternative and more general solution is to use a steady state file or
% the steady_state_model block.

%% inequality restrictions as equality restrictions
% suppose we have the following inequality restriction
% a>=b
% this implies that there is a c>=0 such that a=b+c. One can exploit this
% insight to transform inequality restrictions into equality restrictions.
% We would need to define b and c as estimated while a will not appear in
% the parameterization block. The implied equality restriction will then be
% written either in the parameter_restrictions block (when this is formally
% implemented) or in a steady state file

%% fmincon and estimation with inequality restrictions
% lately, my experience with fmincon is that it does not always handle
% inequality restrictions well. Estimation may break down completely while
% fmincon tries to compute the derivatives of the inequality restrictions
% at a particular point. Unfortunately the function doing that step is
% p-coded and it is difficult to implement a workaround within fmincon
% itself (The Mathworks should be able to help on that...)
% in the models we estimate, this is sometimes the case for transition
% probabilities. Fmincon is known to work well when problems are smooth and
% differentiable. So in order to avoid the breakdown of fmincon, one has to
% be smart and RISE is:
% 1- use priors to smooth the shape of the objective function
% 2- use block_wise optimization
% 3- use a different optimization algorithm like bee_gate and its brothers,
% which I still need to push into the current version of RISE
%{
myblocks={
    {'beta_trans','kappa','rho_d','rho_s','rho_o','Lambda','Gamma',...
    'sig_d(vol,1)','sig_d(vol,2)','sig_s(vol,1)','sig_s(vol,2)',...
    'sig_r(vol,1)','sig_r(vol,2)','sig_o(oil,1)','sig_o(oil,2)','phi_pi',...
    'phi_y','rho_r'}
    {'vol_tp_1_2','vol_tp_2_1','oil_tp_1_2','oil_tp_2_1'}
};
m = estimate(m, 'optimizer', 'fmincon',...
    'estim_blocks',myblocks);
%}


% DEMBARENCORANK Do ranking experiments on data from Barenco et al in Genome Biology.

% SHEFFIELDML

colordef white
[y, yvar, gene, times, scale, rawExp, rawVar] = gpsimLoadBarencoData;

load demBarenco1.mat

% Get the default options structure.
options = gpsimOptions;
options.includeNoise = 1;
% Fix one decay (from the fourth gene --- p21) to 0.8 hr^-1, and
% the corresponding sensitivity (see just after eqn 2 in the
% mathematical methods of Barenco et al.)
options.fix(1).index = 8;
options.fix(1).value = expTransform(0.8, 'xtoa');
options.fix(2).index = 9;
options.fix(2).value = expTransform(1, 'xtoa');

% initialise the model.
model.type = 'cgpsim';  % This new model type is a hack to run
                        % the model in a hierarchical manner.
                        % need to do this more elegantly later.
for i =1:3
  model.comp{i} = gpsimCreate(5, 1, times, y{i}, yvar{i}, options);
end

% Learn the model.
model = modelOptimise(model, [], [], 1, 3000);

% Each component of the model gives us a prediction given one set
% of replicates. The replicates are from an independent cell line,
% so the probabilistic assumption here is that the samples of f(t)
% are independent for each prediction (but inverse width, decay,
% basal rate and sensitivity parameters are all shared).
for j = 1:length(model.comp)

  % Generate predictions of the functions.
  % to do this we need to compute the K_xf portions of the kernel
  % (simXrbfKernCompute does this for us).
  predt = [linspace(-2, 14, 100) 0:2:12]';
  proteinKern = kernCreate(model.comp{1}.t, 'rbf');
  proteinKern.inverseWidth = ...
      model.comp{j}.kern.comp{1}.inverseWidth;
  K = [];
  for i=1:model.comp{j}.kern.numBlocks
    K = [K; simXrbfKernCompute(model.comp{j}.kern.comp{i}, proteinKern, ...
                               model.comp{j}.t, predt)];

  end
  predF = K'*model.comp{j}.invK*model.comp{j}.y;
  varF = kernDiagCompute(proteinKern, predt) - sum(K.*(model.comp{j}.invK*K), 1)';

  % Take out predictions at data points.
  % Use them to get the scale for the other data.
  dataF = predF(end-6:end);
  dataVarF = varF(end-6:end);
  predF(end-6:end) = [];
  varF(end-6:end) = [];
  predt(end-6:end) = [];
  scalePred = sqrt(var(dataF));

  % Info from Martino Paper:
  % 'True f' from Figure 3.
  % Got these figures with a ruler ...
  % Don't actually plot these below, but they are stored for reference
  truef = [0 1.6 2.6 2.5 2.6 1.6 0.9];
  truef = truef/sqrt(var(truef))*scalePred;

  % Figure 2(a) histograms;
  B = [2.6 1.5 0.5 0.2 1.35]; % From Martino paper ... but don't know the scale
  B = B/mean(B)*mean(model.comp{1}.B); % do a rough rescaling so
                                       % that the scales match.
  S = [3 0.8 0.7 1.8 0.7]/1.8; % From Martino paper ... but here we
                               % know the scale, because p21 is
                               % fixed to 1.
  D = [1.2 1.6 1.75 3.2 2.3]*0.8/3.2; % From Martino paper, again
                                      % we know the scale because
                                      % p21 is fixed to 0.8.

  % Martino f from Figure 2(b), again measured with a ruler.
  barencof = [0 2.7 3.9 2.3 1.5 1.6 1.4]/(1.8*mean(S))*mean(model.comp{1}.S);
  barencof = barencof/sqrt(var(barencof))*scalePred;

  figure, lin = plot(predt, predF, '-');
  hold on,
  bh = plot(predt, predF + 2*sqrt(varF), '--');
  bh = [bh plot(predt, predF - 2*sqrt(varF), '--')];
  lin = [lin plot(0:2:12, barencof, 'rx')];
  set(bh, 'lineWidth', 3);
  set(lin, 'lineWidth', 4);
  set(lin, 'markersize', 20);
  set(gca, 'fontname', 'arial', 'fontsize', 24, 'xlim', xlim)
  fileName = ['demBarenco1_profile' num2str(j)];
  print('-deps', ['../tex/diagrams/' fileName]);
  pos = get(gcf, 'paperposition')
  origpos = pos;
  pos(3) = pos(3)/2;
  pos(4) = pos(4)/2;
  set(gcf, 'paperposition', pos);
  lineWidth = get(gca, 'lineWidth');
  set(gca, 'lineWidth', lineWidth*2);
  %print('-dpng', ['../html/' fileName])
  set(gca, 'lineWidth', lineWidth);
  set(gcf, 'paperposition', origpos)

end

order = [1 5 3 4 2];

counter = 0;

% Plot first basal transcription rates.
figure
bar([model.comp{1}.B(order); B]', 0.6); colormap([0 0 0; 1 1 1]);
set(gca, 'xticklabel', {'DDB2', 'hPA26', 'TNFRSF20b', 'p21', 'BIK'})
fileName = ['demBarenco1_basal'];
print('-deps', ['../tex/diagrams/' fileName]);
pos = get(gcf, 'paperposition')
origpos = pos;
pos(3) = pos(3)/2;
pos(4) = pos(4)/2;
set(gcf, 'paperposition', pos);
lineWidth = get(gca, 'lineWidth');
set(gca, 'lineWidth', lineWidth*2);
print('-dpng', ['../html/' fileName])
set(gcf, 'paperposition', origpos)
set(gca, 'lineWidth', lineWidth);

% Plot the sensitivities.
figure
bar([model.comp{1}.S(order); S]', 0.6); colormap([0 0 0; 1 1 1]);
set(gca, 'xticklabel', {'DDB2', 'hPA26', 'TNFRSF20b', 'p21', ...
                    'BIK'})
fileName = ['demBarenco1_sensitivity'];
print('-deps', ['../tex/diagrams/' fileName]);
pos = get(gcf, 'paperposition')
origpos = pos;
pos(3) = pos(3)/2;
pos(4) = pos(4)/2;
set(gcf, 'paperposition', pos);
lineWidth = get(gca, 'lineWidth');
set(gca, 'lineWidth', lineWidth*2);
print('-dpng', ['../html/' fileName])
set(gcf, 'paperposition', origpos)
set(gca, 'lineWidth', lineWidth);

% Finally plot degradation rates.
figure
bar([model.comp{1}.D(order); D]', 0.6); colormap([0 0 0; 1 1 1]);
set(gca, 'xticklabel', {'DDB2', 'hPA26', 'TNFRSF20b', 'p21', ...
                    'BIK'})
fileName = ['demBarenco1_decay'];
print('-deps', ['../tex/diagrams/' fileName]);
pos = get(gcf, 'paperposition')
origpos = pos;
pos(3) = pos(3)/2;
pos(4) = pos(4)/2;
set(gcf, 'paperposition', pos);
lineWidth = get(gca, 'lineWidth');
set(gca, 'lineWidth', lineWidth*2);
print('-dpng', ['../html/' fileName])
set(gcf, 'paperposition', origpos)
set(gca, 'lineWidth', lineWidth);


function p_data = p01_data ( dim_num, data_num )

%*****************************************************************************80
%
%% P01_DATA returns the data for problem p01.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 August 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension of the dependent
%    variables.
%
%    Input, integer DATA_NUM, the number of data points.
%
%    Output, real P_DATA(DIM_NUM,DATA_NUM), the data.
%
  p_data = [ ...
    0.0, 4.0; ...
    1.0, 5.0; ...
    2.0, 6.0; ...
    4.0, 6.0; ...
    5.0, 5.0; ...
    6.0, 3.0; ...
    7.0, 1.0; ...
    8.0, 1.0; ...
    9.0, 1.0; ...
   10.0, 3.0; ...
   11.0, 4.0; ...
   12.0, 4.0; ...
   13.0, 3.0; ...
   14.0, 3.0; ...
   15.0, 4.0; ...
   16.0, 4.0; ...
   17.0, 3.0; ...
   18.0, 0.0 ]';

 return
end


function crcCheck = checkCRC(response)
receivedMsg = response;
challengeMsg = append_crc(response(1:length(response)-2));
if all(challengeMsg==receivedMsg)
    crcCheck = 1;
else
    crcCheck = 0;
end


function plot(obj)
% Plot an fmri_model object
%
% :Usage:
% ::
%
%     plot(obj)

% ..
%    Setup
% ..

TR = obj.xY.RT;

bf = obj.xBF.bf;

% Define sessions and number of conditions
nsess = length(obj.Sess);

% ----------------------------------------------
% Image
% ----------------------------------------------
create_figure('design matrix image');
imagesc(obj.xX.X);
title('Design matrix (X)');
set(gca, 'YDir', 'reverse');
axis tight;
xlabel('Regressors');
ylabel('Images (TRs)');
colormap gray
drawnow

% ----------------------------------------------
% Basis sets
% ----------------------------------------------
nconds = length(obj.xBF);
create_figure('basis sets', 1, nconds);
for i = 1:nconds

    subplot(1, nconds, i);
    xx = linspace(0, obj.xBF(i).length - 1, size(obj.xBF(i).bf, 1));

    plot(xx, obj.xBF(i).bf, 'LineWidth', 2);
    title(sprintf('Basis set, Cond. %3.0f, %s', i, obj.xX.name{i}));
    axis tight
    xlabel('Time (sec)');

end

% ----------------------------------------------
% Plot
% ----------------------------------------------

switch obj.build_method
% ----------------------------------------------
    case 'Separate sessions'
% ----------------------------------------------
        nr = 2; nc = ceil(nsess) ./ 2;

        create_figure('design matrix', nr, nc);

        for i = 1:nsess
            subplot(nr, nc, i)
            set(gca, 'FontSize', 10);

            [Xs, dummy, C, dummy, names] = get_session_X(obj, i);

            plot_subfcn(obj, Xs, C, names);
            title(sprintf('Session %3.0f', i));

        end

% ----------------------------------------------
    case 'Concatenated sessions'
% ----------------------------------------------
        create_figure('design matrix');

        plot_subfcn(obj, obj.xX.X(:, obj.xX.iH), obj.xX.X(:, obj.xX.iC), obj.xX.name);

    otherwise
        error('Unknown build method for fmri_model object. See help for valid strings.');

end

end % main function

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

% SUB-functions

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

function plot_subfcn(obj, Xs, C, names)

% ----------------------------------------------
% SETUP
% ----------------------------------------------

% conditions for unique color codes
nconds = size(obj.xX.cond_assignments, 2);

% bf = obj.xBF.bf;
% nbf = size(bf, 2);

colors = {'r' 'g' 'b' 'm' [1 .5 0], [0 1 .5], [0 .5 1], [1 0 .5]};
while length(colors) < nconds, colors = [colors colors]; end

disp('Plotting design matrix cols');

% ----------------------------------------------
% Plot
% ----------------------------------------------

han = plot_matrix_cols([Xs C], 'horiz');
axis tight
drawnow

% ***need to fix for Separate Session design

for i = 1:nconds
%     whstart = nbf * (i - 1) + 1;
%     whend = nbf * i;
    wh = find(obj.xX.cond_assignments(:, i));
    set(han(wh), 'Color', colors{i});
end

if ~isempty(C)
    names = [names {'Covariates'}];
end

yvals = linspace(1, size([Xs C], 2), nconds + 2);
yvals = yvals(2:end-1);

set(gca, 'YTick', yvals, 'YTickLabel', names)

xlabel('Time (TRs)')

title(obj.build_method);

drawnow

end


function export(t,fname,varargin)
% export tensor to json file
%
% Syntax
%   m = matrix(T)
%   m = matrix(T,'voigt')
%
% Input
%  T - @tensor
%
% Output
%  m - matrix
%
% Options
%  voigt - give a 4 rank tensor in voigt notation, i.e. as a 6 x 6 matrix
%
% See also
%

CS.abg = [t.CS.alpha,t.CS.beta,t.CS.gamma]./degree;
CS.abc = norm([t.CS.aAxis,t.CS.bAxis,t.CS.cAxis]);
CS.pointGroup = t.CS.pointGroup;
CS.mineral = t.CS.mineral;
CS.alignment = t.CS.alignment;
warning off
data = struct(t);
warning on
data.M = matrix(t,'voigt');
data.CS = CS;

savejson(class(t),data,fname);


function [ops, stat, Fcell, FcellNeu]      = extractSignalsNoOverlaps(ops, m, stat)

ops.saveNeuropil = getOr(ops, 'saveNeuropil', 0);

Nk = numel(stat);

Ny = numel(ops.yrange);
Nx = numel(ops.xrange);

% make new set of basis functions (larger coverage)
ops.neuropilRange = 10;

S = getNeuropilBasis(ops, Ny, Nx, 'raisedcosyne'); % 'raisedcosyne', 'Fourier'
S = normc(S);

% S = m.S;

S = reshape(S, [], size(S, ndims(S)));
nBasis = size(S,2);

% initialize mask
maskNeu = ones(size(S,1), 1);

stat = getNonOverlapROIs(stat, Ny, Nx);

LtS = zeros(Nk, size(S,2));
for k = 1:Nk
    ix = stat(k).ipix(~stat(k).isoverlap);
    maskNeu(stat(k).ipix)= 0;
    if numel(ix)==0 || sum(~stat(k).isoverlap)==0
        LtS(k,:) = 0;
    else
        LtS(k,:) = stat(k).lam(~stat(k).isoverlap)' * S(ix, :);
    end
end

% add all pixels within X um
if isfield(ops, 'exclFracCell') && ops.exclFracCell>0
    H       = fspecial('disk', round(ops.diameter * ops.exclFracCell));
    maskNeu = reshape(maskNeu, Ny, Nx);
    maskNeu = imfilter(maskNeu, H, 'replicate');
    maskNeu = single(maskNeu(:) > 1-1e-3);
end
%% get signals
S    = bsxfun(@times, S, maskNeu(:));
StS = S' * S;
StS = StS + 1e-2 * eye(size(StS));

nimgbatch = 2000;

ix = 0;
fclose all;
fid = fopen(ops.RegFile, 'r');

tic
F        = zeros(Nk, sum(ops.Nframes), 'single');
Fneu    = zeros(Nk, sum(ops.Nframes), 'single');
if ops.saveNeuropil
    Ntraces = zeros(nBasis, sum(ops.Nframes), 'single');
end
% S    = bsxfun(@times, S, maskNeu(:));

[Ly Lx] = size(ops.mimg1);

mimg1 = ops.mimg1(ops.yrange, ops.xrange);
% find indices of good clusters
while 1
    data = fread(fid,  Ly*Lx*nimgbatch, '*int16');
    if isempty(data)
       break;
    end
    data = reshape(data, Ly, Lx, []);
    data = data(ops.yrange, ops.xrange, :);
    data = single(data);
    NT   = size(data,3);

    % process the data
    data = bsxfun(@minus, data, mimg1);
    data = my_conv2(data, ops.sig, [1 2]);
    data = bsxfun(@rdivide, data, m.sdmov);
    data = single(reshape(data, [], NT));

    %
    Ftemp = zeros(Nk, NT, 'single');
    for k = 1:Nk
       ipix = stat(k).ipix(~stat(k).isoverlap)';
       if ~isempty(ipix)
           Ftemp(k,:) = stat(k).lam(~stat(k).isoverlap)' * data(ipix,:);
       end
    end
    F(:,ix + (1:NT))    = Ftemp;

    Tneu                = StS\(S' * data);
    Ftemp2              = LtS * Tneu;
    Fneu(:,ix + (1:NT)) = Ftemp2;

%     Fneu(:,ix + (1:NT))     = m.LtS * Fdeconv(1+Nk:end, :); % estimated neuropil
%     F(:,ix + (1:NT))        = Fneu(:,ix + (1:NT)) + Fdeconv(1:Nk, :); % estimated ROI signal

    if ops.saveNeuropil
        Ntraces(:,ix + (1:NT)) = Tneu;
    end

    ix = ix + NT;
    if rem(ix, 3*NT)==0
        fprintf('Frame %d done in time %2.2f \n', ix, toc)
    end
end
fclose(fid);
%% add the means back in to both neuropil and total
data = my_conv2(mimg1, ops.sig, [1 2]);
data = bsxfun(@rdivide, data, m.sdmov);
data = single(reshape(data, [], 1));

scalefactors = nan(numel(stat),1);
Ftemp = zeros(Nk, 1, 'single');
for k = 1:Nk
    ipix = stat(k).ipix(~stat(k).isoverlap)';
    if ~isempty(ipix)
        Ftemp(k,:) = stat(k).lam(~stat(k).isoverlap)' * data(ipix,1);
        scalefactors(k) = mean(m.sdmov(ipix));
    end
end

Tneu                = StS\(S' * data);
Ftemp2              = LtS * Tneu;

Fneu     = bsxfun(@plus, Fneu, Ftemp2); % estimated neuropil
F        = bsxfun(@plus, F,    Ftemp);

Fneu     = bsxfun(@times, Fneu, scalefactors); % estimated neuropil
F        = bsxfun(@times, F,    scalefactors);

%%
% get activity stats
[stat, F, Fneu] = getActivityStats(ops, stat, F, Fneu);

%
csumNframes = [0 cumsum(ops.Nframes)];
Fcell       = cell(1, length(ops.Nframes));
FcellNeu    = cell(1, length(ops.Nframes));
for i = 1:length(ops.Nframes)
    Fcell{i}     = F(:, csumNframes(i) + (1:ops.Nframes(i)));
    FcellNeu{i}  = Fneu(:, csumNframes(i) + (1:ops.Nframes(i)));
end

if getOr(ops, 'saveNeuropil', 0)
    S = reshape(S, numel(ops.yrange), numel(ops.xrange), nBasis);
    save(sprintf('%s/NEU_%s_%s_plane%d.mat', ops.ResultsSavePath, ...
        ops.mouse_name, ops.date, ops.iplane),  'ops', 'S', 'Ntraces', '-v7.3')
end


% remesh    Surface simplification
%
% Usage:
%
%  [surface]   = remesh (surface, opt)
%  [surface]   = remesh (TRI, X, Y, Z, opt)
%  [TRI,X,Y,Z] = remesh (surface, opt)
%  [TRI,X,Y,Z] = remesh (TRI, X, Y, Z, opt)
%
% Description:
%
%  Reduces the vertex and face count of a surface using the QSlim
%  algorithm.
%
% Input:
%
%  TRIV    - ntx3 triangulation matrix with 1-based indices (as the one
%            returned by the MATLAB function delaunay).
%  X,Y,Z   - vectors with nv vertex coordinates.
%  surface - alternative way to specify the mesh as a struct, having .TRIV,
%            .X, .Y, and .Z as its fields.
%  opt       - (optional) settings
%              .placement  [-O] Optimal placement policy (default: 3)
%                                0 - end points,
%                                1 - end or mid points,
%                                2 - line,
%                                3 - optimal
%              .boundary   [-B] Use boundary preservation planes with given weight
%                               (default: 1000)
%              .weight     [-W] Quadric weighting policy (default: 1)
%                                0 - uniform,
%                                1 - area,
%                                2 - angle
%              .contract   [-F] Contraction of faces ('faces') or edges ('edges')
%                               (default: 'edges')
%              .penalty    [-m] Penalty for bad meshes (default: 1)
%              .compact    [-c] Compactness ratio (default: 0)
%              .join       [-j] Join only without removing faces (default: 'false')
%              .faces      [-t] Target number of faces
%              .vertices        Target number of vertices (default: 2000)
%              .verbose         Verbosity level (default: 1)
%                                0 - no display,
%                                1 - display results
%
% Output:
%
%  TRIV    - ntx3 triangulation matrix of the simplified surface.
%  X,Y,Z   - list of vertices of the simplified surface.
%  surface - alternative way to specify the simplified surface.
%
% References:
%
% [1] http://www.cs.cmu.edu/~garland/quadrics/
%
% TOSCA = Toolbox for Surface Comparison and Analysis
% Web: http://tosca.cs.technion.ac.il
% Version: 0.9
%
% (C) QSlim 2.0 copyright Michael Garland, 1998.
% (C) Mex iterface copyright Alex Bronstein, 2007.

function [TRIV_, X_, Y_, Z_] = remesh(surface, options)

if isstruct(surface),
    TRI = surface.TRIV;
    X = surface.VERT(:,1);
    Y = surface.VERT(:,2);
    Z = surface.VERT(:,3);
else
    TRI = surface;
    X = varargin{1};
    Y = varargin{2};
    Z = varargin{3};
    varargin = varargin(4:end);
end

opt = [3 1000 1 0 1 0 0];
% verts = min(length(X), 2000);
verts = min(length(X), 1e4);
faces = 0;
verbose = 0;

if nargin > 1,
    if isfield(options, 'placement'),
        opt(1) = options.placement;
    end
    if isfield(options, 'boundary'),
        opt(2) = options.boundary;
    end
    if isfield(options, 'weight'),
        opt(3) = options.weight;
    end
    if isfield(options, 'contract'),
        if strcmpi(value,'face') | strcmpi(value,'faces'),
            opt(4) = 1;
        elseif strcmpi(value,'edge') | strcmpi(value,'edges'),
            opt(4) = 0;
        else
            error('Invalid value setting for .contract. Must be "faces" or "edges".');
        end
    end
    if isfield(options, 'penalty'),
        opt(5) = options.penalty;
    end
    if isfield(options, 'compact'),
        opt(6) = options.compact;
    end
    if isfield(options, 'join'),
        if strcmpi(options.join,'true') | value == 1,
            opt(7) = 1;
        elseif strcmpi(options.join,'false') | value == 0,
            opt(7) = 0;
        else
            error('Invalid value setting for .join. Must be "true" or "false".');
        end
    end
    if isfield(options, 'vertices'),
        verts = options.vertices;
    end
    if isfield(options, 'faces'),
        faces = options.faces;
    end
    if isfield(options, 'verbose'),
        verbose = options.verbose;
    end

end

if verts < 1 & faces < 1,
    error('Either face or vertex positive count targets have to be specified.');
end

switch opt(1),
    case 0, placement_policy = 'end point';
    case 1, placement_policy = 'end or mid point';
    case 2, placement_policy = 'line';
    case 3, placement_policy = 'optimal';
    otherwise, error('Invalid placement policy. Use .placement = 0-3.');
end

switch opt(3),
    case 0, weighting_policy = 'uniform';
    case 1, weighting_policy = 'area';
    case 2, weighting_policy = 'angle';
    otherwise, error('Invalid weighting policy. Use .weigh = 0-2.');
end

if opt(4), contract = 'face', else contract = 'edge'; end
if opt(7), join = 'on', else join = 'off'; end

if verbose > 0,
    fprintf (1, 'Surface simplification\n');
    fprintf (1, 'Placement policy:         %s\n', placement_policy);
    fprintf (1, 'Weighting policy:         %s\n', weighting_policy);
    fprintf (1, 'Boundary preserv. weight: %-8.6g\n', opt(2));
    fprintf (1, 'Contraction:              %s\n', contract);
    fprintf (1, 'Bad mesh penalty:         %-8.6g\n', opt(5));
    fprintf (1, 'Compactness ratio:        %-8.6g\n', opt(6));
    fprintf (1, 'Join only:                %s\n', join);
    fprintf (1, 'Original faces:           %-d\n', size(TRI,1));
    fprintf (1, 'Original vertices:        %-d\n', length(X));
    fprintf (1, 'Target faces:             %-d\n', faces);
    fprintf (1, 'Target vertices:          %-d\n', verts);
end

[TRIV_,X_,Y_,Z_] = qslim(TRI, X, Y, Z, faces, verts, opt);
if verbose > 0,
    fprintf (1, 'Done. faces = %d vertices = %d\n\n', size(TRIV_,1), length(X_));
end

idx = find( X_.^2 + Y_.^2 + Z_.^2 > 0 );
N = max(idx);
X_ = X_(1:N);
Y_ = Y_(1:N);
Z_ = Z_(1:N);

if nargout <= 1,
    surface_ = [];
    surface_.TRIV = TRIV_;
    surface_.VERT    = [X_ Y_ Z_];
    surface_.n = size(surface_.VERT,1);
    surface_.m = size(surface_.TRIV,1);
    TRIV_ = surface_;
    if isstruct(surface) & isfield(surface,'D'),
        warning('The returned result is an uninitialized surface. Use init_surface to initialize.');
    end
end


function Save_EWT2D_LP(ewt2d,name)

%=========================================================================
%
% function Save_EWT2D_LP(ewt2d,name)
%
% Save each subband image in separate files named 'LPxname.png' where n
% is the subband number.
% The images are renormalized with respect to the min and max of all
% images.
%
% Author: Jerome Gilles
% Institution: UCLA - Department of Mathematics
% Year: 2013
% Version: 1.0
% ========================================================================

minI=255.0;
maxI=0.0;

% Find the min and max over all images
for n=1:length(ewt2d)
    minI=min(minI,min(ewt2d{n}(:)));
    maxI=max(maxI,max(ewt2d{n}(:)));
end

% Plot each subband with the same normalization
for n=1:length(ewt2d)
%        gname=sprintf('LP%d%s.png',n,name);
        gname=sprintf('R%d%s.png',n,name);

        imwrite((ewt2d{n}-min(ewt2d{n}(:)))/(max(ewt2d{n}(:))-min(ewt2d{n}(:))),gname,'png');
%        imwrite((ewt2d{n}-minI)/(maxI-minI),gname,'png');
end


function [res, fusion] = imMergeEnclosedRegions(lbl, varargin)
% Merge regions within a label image, based on an inclusion criteria.
%
%   Merge regions in an image. Criterion is a inclusion criterion: if a
%   region is mostly within the convex image of a neighbor region, then the
%   two region merge.
%
%	See Also
%	  imMergeRegions, imRAG
%

% ------
% Author: David Legland
% e-mail: david.legland@inrae.fr
% INRAE - BIA Research Unit - BIBS Platform (Nantes)
% Created: 2021-09-17,    using Matlab 9.9.0.1570001 (R2020b) Update 4
% Copyright 2021 INRAE.

%   HISTORY
%   17/08/2004 create as independant function, and merge 2D and 3D cases
%   17/09/2021 rename as imMergeEnclosedRegions

%% Parse input arguments

% create default structuring element
se = zeros([3 3 3]);
se(1,2,2) = 1;
se(3,2,2) = 1;
se(2,:,:) = [0 1 0;1 1 1;0 1 0];

verbose = true;
while length(varargin) > 1
    name = varargin{1};
    if strcmp(name, 'verbose')
        verbose = varargin{2};
    else
        error('Can not interpret input option: %s', name);
    end
    varargin(1:2) = [];
end

%% Initialisations

% init
res = lbl;

% compute adjacency graph
% (use a wrong node list, because of memory problems, but dont really need
% it)
if verbose
    disp('compute adjacency graph');
end
lastLabel = double(max(lbl(:)));
nodes = [(1:lastLabel)';(1:lastLabel)'];
edges = imRAG(lbl);

% compute volume of each cell
if verbose
    disp('compute area');
end
area = zeros(lastLabel, 1);
for i = 1:lastLabel
    area(i) = sum(lbl(:)==i);
end

% init fusion information
fusion = [];

for i = 1:lastLabel
    if verbose
        disp(sprintf('cell: %d/%d', i, lastLabel)); %#ok<DSPS>
    end

    % check:
    %   1 - cell still exist
    %   2 - cell is large enough (as some problem can occur in convexImage)
    if area(i) < 10
        continue;
    end

    % compute convex image of current cell
    im = imConvexImage(lbl==i);

    % find neighbours
    neigh = unique(edges(edges(:,1)==i | edges(:,2)==i, 1:2));
    neigh = neigh(neigh~=i);

    mergeFlag = false;
    for i2 = 1:length(neigh)
        % compute area
        common = sum(im(:)&res(:) == neigh(i2));
        if common / area(neigh(i2)) > .7
            disp(sprintf('fusion of regions %d and %d', i, neigh(i2))); %#ok<DSPS>

            % update RAG and fusion process information
            [nodes, edges] = grMergeNodes(nodes, edges, [i neigh(i2)]);
            fusion(size(fusion, 1)+1, 1:2) = [i neigh(i2)]; %#ok<AGROW>

            % update result image
            res(res==neigh(i2)) = i;
            mergeFlag = true;
        end
    end

    % fill in the space between merged regions
    if mergeFlag
        res(imerode(imclose(res==i, se), se)) = i;
    end
end

function [nodes, edges] = grMergeNodes(nodes, edges, mnodes)
% Merge two (or more) nodes in a graph.
%
% Usage:
%   [NODES2 EDGES2] = grMergeNodes(NODES, EDGES, NODE_INDS)
%   NODES and EDGES are wo arrays representing a graph, and NODE_INDS is
%   the set of indices of the nodes to merge.
%   The nodes corresponding to indices in NODE_INDS are removed from the
%   list, and edges between two nodes are removed.
%
%   Example: merging of labels 1 and 2
%   Edges:         Edges2:
%   [1 2]           [1 3]
%   [1 3]           [1 4]
%   [1 4]           [3 4]
%   [2 3]
%   [3 4]
%

refNode = mnodes(1);
mnodes = mnodes(2:length(mnodes));

% replace merged nodes references by references to refNode
edges(ismember(edges, mnodes))=refNode;

% remove "loop edges" from and to reference node
edges = edges(edges(:,1) ~= refNode | edges(:,2) ~= refNode, :);

% format output
edges = sortrows(unique(sort(edges, 2), 'rows'));


function X = redo_scaling(X_scal,param)

% redo scaling (from scaled data to original data)
%
% INPUT
% X_scal:   pretreated data matrix (samples x variables)
% param:    output data structure from data_pretreatment routine
%
% OUTPUT
% X:        data matrix (samples x variables)
%
% version 1.0 - september 2009
% Davide Ballabio
% Milano Chemometrics and QSAR Research Group
% www.disat.unimib.it/chm

a = param.a;
s = param.s;
m = param.m;
M = param.M;
pret_type = param.pret_type;

if strcmp(pret_type,'cent')
    for j=1:size(X_scal,2)
        X(:,j) = X_scal(:,j) + a(j);
    end
elseif strcmp(pret_type,'scal')
    for j=1:size(X_scal,2)
        X(:,j) = X_scal(:,j)*s(j);
    end
elseif strcmp(pret_type,'auto')
    for j=1:size(X_scal,2)
        X(:,j) = X_scal(:,j)*s(j) + a(j);
    end
elseif strcmp(pret_type,'rang')
    for j=1:size(X_scal,2)
        X(:,j) = X_scal(:,j)*(M(j) - m(j)) + m(j);
    end
else
    X = X_scal;
end