% caffe.reset_all();
if ~exist('imageList','var')
    BLUFR_config = 'D:\face project\BLUFR\config\lfw\blufr_lfw_config.mat';
    load(BLUFR_config);
end;
lfw_root = 'E:\datasets\lfw-aligned-wuxiang';
caffe.set_mode_gpu();
gpu_id = 0;  % we will use the first gpu in this demo
caffe.set_device(gpu_id);

% ROIx = 19:82;
% ROIy = 19:82;
ROIx = 9:136;
ROIy = 9:136;
feature_dim = 256;
mean_value = 0;
scale = 1 / 255;
batch_size = 50;
total_length = length(imageList);
total_iter = ceil(total_length / batch_size);

% ROIx = 1:64;
% ROIy = 1:64;
height = length(ROIx);
width = length(ROIy);

% net = caffe.Net('D:\face project\face_verification_experiment\proto\LightenedCNN_B_deploy.prototxt','D:\face project\experiment\fine-tune\wuxiang\face_train_test_iter_14000.caffemodel', 'test');
net = caffe.Net('D:\face project\face_verification_experiment\proto\LightenedCNN_B_deploy.prototxt','D:\face project\experiment\fine-tune\wuxiang\LightenedCNN_B.caffemodel', 'test');
Descriptors = zeros(total_iter * batch_size, feature_dim);
for i = 1 : total_iter
    disp([i total_iter]);
    J = zeros(height,width,1,batch_size,'single');
    for j = 1 : batch_size
        if (i-1)*batch_size+j > total_length
            break;
        end;
        file_name = imageList{(i-1)*batch_size+j};
        find_zero = strfind(file_name,'0');
        folder = file_name(1:find_zero(1)-2);

        I = imread(fullfile(lfw_root, folder, file_name));
        I = rgb2gray(I)';
        I = I(ROIx,ROIy,:);
        I = single(I) - mean_value;
        J(:,:,:,j) = I*scale;
    end;
    f1 = net.forward({J});
    f1 = f1{1};
    Descriptors((i-1)*batch_size+1:i*batch_size,:) = reshape(f1,[feature_dim,batch_size])';
end;
Descriptors = Descriptors(1:total_length,:);
save('lfw_feature.mat','Descriptors');


function [mNewCatalog] = syn_catalog(nNumberEvents, fBValue, fMc, fInc, fMinLat, fMaxLat, fMinLon, fMaxLon, fMinDepth, fMaxDepth, fMinTime, fMaxTime,nSynMode,mCatalog)
    % Creates a synthetic catalog.
    %
    % [mNewCatalog] = syn_catalog(nNumberEvents, fBValue, fMc, fInc, fMinLat, fMaxLat,
    %                                      fMinLon, fMaxLon, fMinDepth, fMaxDepth, fMinTime, fMaxTime)
    %
    %
    % Input parameters:
    %   nNumberEvents     Number of events in the catalog
    %   fBValue           b-value of the catalog
    %   fMc               Magnitude of completeness of the catalog (= minimum magnitude)
    %   fInc              Magnitude increment (usually 0.1)
    %   fMinLat           Minimum latitude value of events in the catalog
    %   fMaxLat           Maximun latitude value of events in the catalog
    %   fMinLon           Minimum longitude value of events in the catalog
    %   fMaxLon           Maximun longitude value of events in the catalog
    %   fMinDepth         Minimum depth of events in the catalog (positive value)
    %   fMaxDepth         Maximun depth of events in the catalog (positive value)
    %   fMinTime          Minimum date/time of events in the catalog (decimal year: e.g. 1983.5)
    %   fMaxTime          Maximun date/time of events in the catalog (decimal year: e.g. 1987.9)
    % nSynMode          Type of synthetic catalog 0:homogeneous distr; 1:based
    % on real catalog 2:hypocenter based on real catalog, magnitude and focal
    % time is randomly computed
    % mCatalog          declustered catalog needed only for nSynMode=1
    %
    % Output parameters:
    %   mNewCatalog       Synthetic catalog
    %
    % Danijel Schorlemmer
    % April 17, 2002
    % Updates
    % Mai  9, 2007  van Stiphout, Thomas     replaced datevec.m by decyear2mat.m

    report_this_filefun();

    % allocate matrix for synthetc catalog
    mNewCatalog = nan(nNumberEvents,14);

    % initial shift of hypocenter from reference event.
    fHypoShift=5;
    if nSynMode == 0
        %     % Create empty catalog
        %     mNewCatalog = nan(nNumberEvents, 10);

        % Create magnitudes
        mNewCatalog(:,6) = syn_create_magnitudes(mNewCatalog, fBValue, fMc, fInc);

        % Randomize
        rng('shuffle');

        % Create location
        mNewCatalog(:,1) = rand(nNumberEvents, 1) * (fMaxLon-fMinLon) + fMinLon;
        mNewCatalog(:,2) = rand(nNumberEvents, 1) * (fMaxLat-fMinLat) + fMinLat;
        mNewCatalog(:,7) = rand(nNumberEvents, 1) * (fMaxDepth-fMinDepth) + fMinDepth;

        % Randomize
        rng('shuffle');

        % Create focal times
        mNewCatalog(:,3) = rand(nNumberEvents, 1) * (fMaxTime-fMinTime) + fMinTime;
        % vst: datevec does not transform mNewCatalog(:,3) properly. Replaced by decyear2mat.
        mNewCatalog(:,3)=mNewCatalog(randperm(size(mNewCatalog,1)),3);
        [mNewCatalog(:,10) mNewCatalog(:,4) mNewCatalog(:,5) mNewCatalog(:,8) mNewCatalog(:,9) tmp] = decyear2mat(mNewCatalog(:,3));

        % Remove column 10 (seconds)
        mNewCatalog = mNewCatalog(:,1:end);

    elseif nSynMode==1
        % take from real catalog hypocenters and magnitudes  ....
        for i=1:nNumberEvents
            mNewCatalog(i,:)=mCatalog(ceil(rand(1,1)*size(mCatalog,1)),1:end);
        end
        % create new  times
        % Randomize
        rng('shuffle');
        % Create focal times
        mNewCatalog(:,3) = rand(nNumberEvents, 1) * (fMaxTime-fMinTime) + fMinTime;
        % vst: datevec does not transform mNewCatalog(:,3) properly. Replaced by decyear2mat.
        [mNewCatalog(:,10) mNewCatalog(:,4) mNewCatalog(:,5) mNewCatalog(:,8) mNewCatalog(:,9) tmp] = decyear2mat(mNewCatalog(:,3));
        mNewCatalog=mNewCatalog(:,1:10);
    elseif nSynMode == 2
        for i=1:nNumberEvents
            mNewCatalog(i,:) = mCatalog(ceil(rand(1,1)*size(mCatalog,1)),1:end);
        end
        % create new magnitudes
        mNewCatalog(:,6) = syn_create_magnitudes(nNumberEvents, fBValue, fMc, fInc);
        % create new  times
        % Randomize
        rng('shuffle');
        % Create focal times
        mNewCatalog(:,3) = rand(nNumberEvents, 1) * (fMaxTime-fMinTime) + fMinTime;
        % vst: datevec does not transform mNewCatalog(:,3) properly. Replaced by decyear2mat.
        [mNewCatalog(:,10) mNewCatalog(:,4) mNewCatalog(:,5) mNewCatalog(:,8) mNewCatalog(:,9) tmp] = decyear2mat(mNewCatalog(:,3));
        % shift hypocenters
        vTmp = km2deg(rand(nNumberEvents,2).*fHypoShift-fHypoShift/2);
        mNewCatalog(:,1:2)=mNewCatalog(:,1:2)+vTmp;
    end
end


filename='Cantilever_quad_coarse';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = [1, 0.1];
constraint = {'volumeConstraint'};
optimizer = 'SLERP';
incrementFactor = 1;
designVariable = 'LevelSet';
filterType = 'P1';

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

Vfrac_initial = 1;
optimality_initial = 1e-3;
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;


function image = draw_perimeter_image(image, map, intensity)
% draws a tight perimeter along ones in the map
% image(height, width, length(intensity))
% map(height, width, length(intensity))

scale = size(image, 1) / size(map, 1);
if size(image, 2) / size(map, 2) ~= scale
    disp('warning: map proportions not to scale!');
end

% get bounds
im_y = mod((0:size(map,2)*size(map, 1)-1), size(map, 1))+1;
im_x = floor((0:size(map,2)*size(map, 1)-1)/size(map, 1))+1;
solids_ind = find(map==1);
solids_x = im_x(solids_ind);
solids_y = im_y(solids_ind);

min_x = min(solids_x);
min_y = min(solids_y);
max_x = max(solids_x);
max_y = max(solids_y);

% draw and bottom top of perimeter
for x = min_x:max_x
    if min_y == 1 & map(min_y, x)
        image = draw_line_image2(image, ([x (x+1) min_y min_y]-1)'*scale+1, intensity);
    end
    if map(max_y, x)
            image = draw_line_image2(image, ([x (x+1) max_y+1 max_y+1]-1)'*scale+1, intensity);
    end
    for y = max(min_y,2):max_y

        if map(y, x)==1 & map(y-1, x)~=1
            image = draw_line_image2(image, ([x (x+1) y y]-1)'*scale+1, intensity);
        end
        if map(y, x)~=1 & map(y-1, x)==1
            image = draw_line_image2(image, ([x (x+1) y y]-1)'*scale+1, intensity);
        end
    end
end

% draw left and right of perimeter
for y = min_y:max_y
    if min_x == 1 & map(y, min_x)
        image = draw_line_image2(image, ([min_x min_x y (y+1)]-1)'*scale+1, intensity);
    end
    if map(y, max_x)
        image = draw_line_image2(image, ([max_x+1 max_x+1 y (y+1)]-1)'*scale+1, intensity);
    end
    for x = max(min_x, 2):max_x
        if map(y, x)==1 & map(y, x-1)~=1
            image = draw_line_image2(image, ([x x y (y+1)]-1)'*scale+1, intensity);
        end
        if map(y, x)~=1 & map(y, x-1)==1
            image = draw_line_image2(image, ([x x y (y+1)]-1)'*scale+1, intensity);
        end
    end
end


function blas0_test02 ( )

%*****************************************************************************80
%
%% BLAS0_TEST02 tests R8_ABS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 March 2014
%
%  Author:
%
%    John Burkardt
%
  r8_hi = 5.0;
  r8_lo = -3.0;
  test_num = 10;

  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'BLAS0_TEST02\n' );
  fprintf ( 1, '  R8_ABS returns the absolute value of an R8.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '      X         R8_ABS(X)\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
    [ r8, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
    r8_absolute = r8_abs ( r8 );
    fprintf ( 1, '  %10.6f  %10.6f\n', r8, r8_absolute );
  end

  return
end


function result_payload = my_finish_mean(payload, ECG_header)

result_payload.mean = payload.the_sum ./ payload.the_size;


function I = argmax(X, DIM)
%ARGMAX   Find the index of the maximum value of a matrix or vector along
% the dimension specified (DIM).
%
%   Inputs:
%       X                       = Input vector or matrix.
%       DIM                     = Dimension along which to computer maximum argument.
%
%   Outputs:
%       I                       = Index of the maximum value.
%
% Daniel McDuff, Ethan Blackford, January 2019
% Copyright (c)
% Licensed under the MIT License and the RAIL AI License.

[~,I] = max(X,[],DIM);


function [A]=comp2real(V)
%these function give vector of 'V' that have complex or non_complex number
%and separate real & imaginary part and attach those in one Matrix.
%this function put together real & imaginary part of any number in any row
m=length(V);
q=[];
for i=1:m
    q(i,1)=real(V(i));
    q(i,2)=imag(V(i));
end
A=q;


function res = le(a,b)
%LE           Implements  a <= b  for slopes, compares only a.r and b.r
%

% written  12/06/98     S.M. Rump
% modified 09/28/01     S.M. Rump  matrices and multi-dimensional arrays
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged
%

  if ~isa(a,'slope')
    asize = size(a);
    bsize = b.size;
    res = ( a(:)<=b.r(:,1) );
  elseif ~isa(b,'slope')
    asize = a.size;
    bsize = size(b);
    res = ( a.r(:,1)<=b(:) );
  else
    asize = a.size;
    bsize = b.size;
    res = ( a.r(:,1)<=b.r(:,1) );
  end

  if ~isequal(asize,bsize) & ( prod(asize)~=1 ) & ( prod(bsize)~=1 )
    error('incompatible size for slope <= ')
  end

  if prod(asize)==1
    res = reshape(res,bsize);
  else
    res = reshape(res,asize);
  end


function t_runmarket(quiet)
%T_RUNMARKET  Tests for code in RUNMKT, SMARTMKT AND AUCTION.

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

if nargin < 1
    quiet = 0;
end

n_tests = 20;

t_begin(n_tests, quiet);

[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
    VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
    MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
    QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;

if ~have_feature('smartmarket')
    t_skip(n_tests, 'smartmarket code not available');
else
    mpc = loadcase('t_auction_case');

    mpopt = mpoption('opf.ac.solver', 'MIPS', 'out.lim.all', 1, 'out.branch', 0, 'out.sys_sum', 0, 'out.all', 0, 'verbose', 1);
    % mpopt = mpoption('out.gen', 1, 'out.branch', 0, 'out.sys_sum', 0);

    offers.P.qty = [
        12 24 24;
        12 24 24;
        12 24 24;
        12 24 24;
        12 24 24;
        12 24 24;
    ];
    offers.P.prc = [
        20 50 60;
        20 40 70;
        20 42 80;
        20 44 90;
        20 46 75;
        20 48 60;
    ];
    bids.P.qty = [
        10 10 10;
        10 10 10;
        10 10 10;
    ];
    bids.P.prc = [
        100 70 60;
%         100 64.3 20;
%         100 30.64545 0;
        100 50 20;
        100 60 50;
    ];

    offers.Q.qty = [ 60; 60; 60; 60; 60; 60; 0; 0; 0 ];
    offers.Q.prc = [ 0; 0; 0; 0; 0; 3; 0; 0; 0 ];
    bids.Q.qty = [ 15; 15; 15; 15; 15; 15; 15; 12; 7.5 ];
%     bids.Q.prc = [ 0; 0; 0; 0; 0; 0; 0; 83.9056; 0 ];
    bids.Q.prc = [ 0; 0; 0; 0; 0; 0; 0; 20; 0 ];

    t = 'marginal Q offer, marginal PQ bid, auction_type = 5';
    mkt = struct(   'auction_type', 5, ...
                    't' , [], ...
                    'u0', [], ...
                    'lim', []   );
    [r, co, cb, f, dispatch, success, et] = runmarket(mpc, offers, bids, mkt, mpopt);
    co5 = co;
    cb5 = cb;

%     [ co.P.qty co.P.prc ]
%     [ cb.P.qty cb.P.prc ]
%     [ co.Q.qty co.Q.prc ]
%     [ cb.Q.qty cb.Q.prc ]

    i2e = r.bus(:, BUS_I);
    e2i = sparse(max(i2e), 1);
    e2i(i2e) = (1:size(r.bus, 1))';
    G = find( ~isload(r.gen) );   %% real generators
    L = find(  isload(r.gen) );   %% dispatchable loads
    Gbus = e2i(r.gen(G,GEN_BUS));
    Lbus = e2i(r.gen(L,GEN_BUS));

    t_is( co.P.qty, ones(6, 1) * [12 24 0], 2, [t ' : gen P quantities'] );
    t_is( co.P.prc(1,:), 50.1578*ones(1,3), 3, [t ' : gen 1 P prices'] );
    t_is( cb.P.qty, [10 10 10; 10 0.196 0; 10 10 0], 2, [t ' : load P quantities'] );
    t_is( cb.P.prc(2,:), 56.9853*ones(1,3), 4, [t ' : load 2 P price'] );
    t_is( co.P.prc(:,1), r.bus(Gbus, LAM_P), 8, [t ' : gen P prices'] );
    t_is( cb.P.prc(:,1), r.bus(Lbus, LAM_P), 8, [t ' : load P prices'] );

    t_is( co.Q.qty, [4.2722; 11.3723; 14.1472; 22.8939; 36.7886; 12.3375; 0; 0; 0], 2, [t ' : Q offer quantities'] );
    t_is( co.Q.prc, [0;0;0;0;0;3; 0.4861; 2.5367; 1.3763], 4, [t ' : Q offer prices'] );
    t_is( cb.Q.qty, [0;0;0;0;0;0; 15; 4.0785; 5], 2, [t ' : Q bid quantities'] );
    t_is( cb.Q.prc, [0;0;0;0;0;3; 0.4861; 2.5367; 1.3763], 4, [t ' : Q bid prices'] );
    t_is( co.Q.prc, r.bus([Gbus; Lbus], LAM_Q), 8, [t ' : Q offer prices'] );
    t_is( cb.Q.prc, co.Q.prc, 8, [t ' : Q bid prices'] );

    t = 'marginal Q offer, marginal PQ bid, auction_type = 0';
    mkt.auction_type = 0;
    [r, co, cb, f, dispatch, success, et] = runmarket(mpc, offers, bids, mkt, mpopt);
    t_is( co.P.qty, co5.P.qty, 8, [t ' : gen P quantities'] );
    t_is( cb.P.qty, cb5.P.qty, 8, [t ' : load P quantities'] );
    t_is( co.P.prc, offers.P.prc, 8, [t ' : gen P prices'] );
    t_is( cb.P.prc, bids.P.prc, 8, [t ' : load P prices'] );

    t_is( co.Q.qty, co5.Q.qty, 8, [t ' : gen Q quantities'] );
    t_is( cb.Q.qty, cb5.Q.qty, 8, [t ' : load Q quantities'] );
    t_is( co.Q.prc, offers.Q.prc, 8, [t ' : gen Q prices'] );
    t_is( cb.Q.prc, bids.Q.prc, 8, [t ' : load Q prices'] );
end

t_end;


report_this_filefun(mfilename('fullpath'));

%l = isnan(tmap);
%tmap(l) = 1;

l = tmap < 100;
tmap(l) = 100;

[lat,lon] = meshgrat(tmap,tmapleg);
%[smap,smapleg] = country2mtx('switzerland',100);
%[lat0, lon0] = meshgrat(smap,smapleg);

% tmap = km2deg(tmap/1);
%  [X , Y]  = meshgrid(gx,gy);

%sw = interp2(lon0,lat0,smap,lon,lat);

re4 = re3;

l = re4 < -3.9;
re4(l) = -3.9;
l = re4 > -1.4;
re4(l) = -1.3;

ren = interp2(X2,Y2,re4,lon,lat);

mi = min(min(ren));
l =  isnan(ren);
ren(l) = mi-20;

figure_w_normalized_uicontrolunits('pos',[150 500 1000 700])

hold on; axis off
axesm('MapProjection','eqaconic','MapParallels',[],...
    'MapLatLimit',[32.6 36.2],'MapLonLimit',[-118.3 -115.3])

meshm(ren,tmapleg,size(tmap),tmap);

daspectm('m',6);
tightmap
view([0 90])
hl = camlight ; lighting phong
set(gca,'projection','perspective');

aa = a;

for i = 1:length(maepi(:,3))
    dep = interp2(lon,lat,tmap,maepi(i,1),maepi(i,2));

    pl =plot3m(maepi(i,2),maepi(i,1),dep+175,'^k');
    set(pl,'Markersize',14,'markerfacecolor','w');

end

load usahi
[plat,plon] = extractm(stateline,'california');
pl =plot3m(plat,plon,175,'linewidth',2);
set(pl,'color','w');

%dep = interp2(lon,lat,tmap,faults(:,1),faults(:,2));
%pl = plotm(faults(:,2), faults(:,1),dep+10,'k','Linewidth',1.0);

dep = interp2(lon,lat,tmap,mainfault(:,1),mainfault(:,2));
pl = plotm(mainfault(:,2), mainfault(:,1),dep+10,'y','Linewidth',2.0);

%zdatam(handlem('allline'),10000) % keep line on surface
j = jet;
j = j(64:-1:1,:);
j = [ [ 0.85 0.9 0.9] ; j ; [0.9 0.9 0.9] ];
caxis([ -4 -1.3]);

colormap(j);
axis off; set(gcf,'color','k')
ax = axis;
axis([ax(1:4) 0 5000])

setm(gca,'ffacecolor','k')
setm(gca,'fedgecolor','w','flinewidth',3);

setm(gca,'mlabellocation',1)
setm(gca,'meridianlabel','on')
setm(gca,'plabellocation',1)
setm(gca,'parallellabel','on','Labelrotation','on')
setm(gca,'Fontcolor','w','Fontweight','bold','FontSize',14,'Labelunits','degrees')

h5 = colorbar;
set(h5,'position',[0.7 0.21 0.01 0.2],'TickDir','out','Ycolor','w','Xcolor','w',...
    'Fontweight','bold','FontSize',14);
set(gcf,'Inverthardcopy','off');

a = aa;


function estimateClinicalRF_Test(pathRF,nSplit,nBoot,seed)

startpath = pwd;

% INITIALIZATIONS
cd(pathRF)
training = load('training'); training = struct2cell(training); training = training{1};
testing = load('testing'); testing = struct2cell(testing); testing = testing{1};
nameOutcomes = fieldnames(training.outcomes); nOutcomes = numel(nameOutcomes);
fSetNames = fieldnames(training.textures.(nameOutcomes{1})); nFset = numel(fSetNames);
nClinical = size(training.clinical.table,2);
clinicNames = training.clinical.table.Properties.VariableNames';
testSplit = 1/3; % Proportion of test cases in the splits

% COMPUTATIONS
for o = 1:nOutcomes
    outcome = training.outcomes.(nameOutcomes{o});
    rng(seed), [trainSets,testSets] = getSplits(outcome,nSplit,testSplit);
    for f = 1:nFset
        text = training.textures.(nameOutcomes{o}).(fSetNames{f}); nText = size(text,2);
        indLeft = 1:nClinical;
        indChosen = [];
        for t = 1:nClinical
            maxMetric = 0;
            for i = 1:(nClinical-t+1)
                tableComb = [text,training.clinical.table(:,[indChosen,indLeft(i)])];
                cat = logical([zeros(1,nText),training.clinical.categories([indChosen,indLeft(i)])]);
                meanAUC = 0; meanSens = 0; meanSpec = 0;
                for s = 1:nSplit
                    Ttrain = tableComb(trainSets(:,s),:); Ttest = tableComb(testSets(:,s),:);
                    Ytrain = outcome(trainSets(:,s)); Ytest = outcome(testSets(:,s));
                    rng(seed), [RF] = trainRF_table(Ttrain,Ytrain,cat,nBoot);
                    [prob] = predictRF(Ttest,RF);
                    [aucSplit,sensSplit,specSplit,~] = calcPerformMetrics(prob,Ytest,0.5);
                    meanAUC = meanAUC + aucSplit;
                    meanSens = meanSens + sensSplit;
                    meanSpec = meanSpec + specSplit;
                end
                meanAUC = meanAUC/nSplit; meanSens = meanSens/nSplit; meanSpec = meanSpec/nSplit;
                %metric = 0.5*meanAUC + 0.5*(1-abs(meanSens - meanSpec));
                metric = meanAUC;
                if metric >= maxMetric
                    choice = indLeft(i);
                    indBye = i;
                    maxMetric = metric;
                end
            end
            indChosen = [indChosen,choice];
            var = clinicNames(indChosen);
            fprintf('\n  * Optimal added clinical variables for order %u, "%s", "%s" are: ',t,nameOutcomes{o},fSetNames{f});
            for v = 1:numel(var)-1
                fprintf([var{v},', '])
            end
            fprintf([var{end}])
            testing.clinical.bestAdd.(nameOutcomes{o}).(fSetNames{f}).(['Order',num2str(t)]).Indexes = indChosen;
            testing.clinical.bestAdd.(nameOutcomes{o}).(fSetNames{f}).(['Order',num2str(t)]).AUC = maxMetric;
            indLeft(indBye) = [];
        end
    end
end
save('testing','testing')
fprintf('\n')

cd(startpath)
end


%% Copyright (C) 2014, 2016 Colin B. Macdonald
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published
%% by the Free Software Foundation; either version 3 of the License,
%% or (at your option) any later version.
%%
%% This software is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
%% the GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public
%% License along with this software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defop  Method   @@symfun ldivide {(@var{f}, @var{g})}
%% @defopx Operator @@symfun {@var{f} .\ @var{g}} {}
%% Component-wise backslash division of symbolic functions.
%%
%% Simple example:
%% @example
%% @group
%% syms x
%% f(x) = [1 x sin(x)];
%% g(x) = [x x pi];
%% @end group
%%
%% @group
%% h = f .\ g
%%   @result{} h(x) = (symfun)
%%       ⎡        π   ⎤
%%       ⎢x  1  ──────⎥
%%       ⎣      sin(x)⎦
%% @end group
%% @end example
%%
%% @seealso{@@symfun/rdivide}
%% @end defop

function h = ldivide(f, g)
  [vars, s1, s2] = helper_symfun_binops(f, g);
  h = symfun(s1 .\ s2, vars);
end

%!test
%! syms x
%! f(x) = x^2;
%! assert( isa(f .\ f, 'symfun'))
%! assert( isa(f .\ x, 'symfun'))


function y = blkdiag( varargin )

%Disciplined convex/geometric programming information for BLKDIAG:
%   BLKDIAG imposes no convexity restrictions on its arguments.

nv = 0;
nz = 0;
sz = [ 0, 0 ];
for k = 1 : nargin,
    x  = cvx( varargin{k} );
    sx = x.size_;
    if length( sx ) > 2,
        error( 'N-D matrices not supported.' );
    end
    b  = x.basis_;
    sz = sz + sx;
    nv = max( nv, size( b, 1 ) );
    nz = nz + nnz( b );
    varargin{k} = x;
end
bz = sparse( [], [], [], prod( sz ), nz, nv );
roff = 0;
coff = 0;
for k = 1 : nargin,
    x  = varargin{k};
    b  = x.basis_;
    sx = x.size_;
    ndxr = ( roff : roff + sx( 1 ) - 1 )';
    ndxr = ndxr( :, ones( 1, sx( 2 ) ) );
    ndxc = ( coff : coff + sx( 2 ) - 1 );
    ndxc = ndxc( ones( 1, sx( 1 ) ), : );
    bz( 1 : size( b, 1 ), ndxc( : ) * sz( 1 ) + ndxr( : ) + 1 ) = b; %#ok
    roff = roff + sx( 1 );
    coff = coff + sx( 2 );
end
y = cvx( sz, bz );

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function varargout = clipMeshVertices(v, f, b, varargin)
%CLIPMESHVERTICES Clip vertices of a surfacic mesh and remove outer faces.
%
%   [V2, F2] = clipMeshVertices(V, F, B)
%   Clip a mesh represented by vertex array V and face array F, with the
%   box represented by B. The result is the set of vertices contained in
%   the box, and a new set of faces corresponding to original faces with
%   all vertices within the box.
%
%   [V2, F2] = clipMeshVertices(..., 'shape', 'sphere') Specify the shape.
%   Default is 'box'. But it is also possible to use 'sphere' or 'plane'.
%
%   [V2, F2] = clipMeshVertices(..., 'inside', false) removes the inner
%   faces instead of the outer faces.
%
%   [V2, F2] = clipMeshVertices(..., 'trimMesh', TF)
%   Also specifies if the isolated vertices need to be removed (TF=true) ot
%   not (TF=false). Default is false.
%
%
%   Example
%     [v, f] = createSoccerBall;
%     f = triangulateFaces(f);
%     box = [0 2 -1 2 -.5 2];
%     [v2, f2] = clipMeshVertices(v, f, box, 'inside', false);
%     figure('color','w'); view(3); axis equal
%     drawMesh(v, f, 'faceColor', 'none', 'faceAlpha', .2);
%     drawBox3d(box)
%     drawMesh(v2, f2, 'faceAlpha', .7);
%
%   See also
%   meshes3d, clipPoints3d
%

% ------
% Author: David Legland, oqilipo
% e-mail: david.legland@inra.fr
% Created: 2011-04-07,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

% if input is given as a structure, parse fields
if isstruct(v)
    if nargin > 2
        varargin = [b, varargin];
    end
    b = f;
    f = v.faces;
    v = v.vertices;
end

parser = inputParser;
validStrings = {'box', 'sphere', 'plane'};
addParameter(parser, 'shape', 'box', @(x) any(validatestring(x, validStrings)));
addParameter(parser, 'inside', true, @islogical);
addParameter(parser, 'trimMesh', false, @islogical);
parse(parser, varargin{:});

% clip the vertices
[v2, indVertices] = clipPoints3d(v, b,...
    'shape', parser.Results.shape, 'inside', parser.Results.inside);

% create index array for face indices relabeling
refInds = zeros(size(indVertices));
for i = 1:length(indVertices)
    refInds(indVertices(i)) = i;
end

% select the faces with all vertices within the box
if isnumeric(f)
    % Faces given as numeric array
    indFaces = sum(~ismember(f, indVertices), 2) == 0;
    f2 = refInds(f(indFaces, :));

elseif iscell(f)
    % Faces given as cell array
    nFaces = length(f);
    indFaces = false(nFaces, 1);
    for i = 1:nFaces
        indFaces(i) = sum(~ismember(f{i}, indVertices), 2) == 0;
    end
    f2 = f(indFaces, :);

    % re-label indices of face vertices (keeping horizontal index array)
    for i = 1:length(f2)
        f2{i} = refInds(f2{i})';
    end
end

if parser.Results.trimMesh
    [v2, f2] = trimMesh(v2, f2);
end

varargout = formatMeshOutput(nargout, v2, f2);


%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2 of the License, or
%  (at your option) any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; if not, write to the Free Software
%  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
%function momftfrt
%MOMFTFRT Unit test for the function MOMFTFR.

%	O. Lemoine - March 1996.

N=128;

% For a perfect line
[sig,ifl]=fmlin(N);
tfr=tfrideal(ifl);
[tm,D2]=momftfr(tfr);
tmth=(1:N);
if any(abs(tm-tmth')>sqrt(eps)),
  error('momftfr test 1 failed');
elseif any(abs(D2)>sqrt(eps)),
  error('momftfr test 2 failed');
end

% For a sinusoid
[sig,ifl]=fmsin(N,0,.5,N*2,1,0);
tfr=tfrideal(ifl);
[tm,D2]=momftfr(tfr');
tmth=round(ifl*2*(N-1))+1;
if any(abs(tm-tmth)>sqrt(1/N)),
  error('momftfr test 3 failed');
elseif any(abs(D2)>sqrt(eps)),
  error('momftfr test 4 failed');
end

N=117;

% For a perfect line
[sig,ifl]=fmlin(N);
tfr=tfrideal(ifl);
[tm,D2]=momftfr(tfr);
tmth=(1:N);
if any(abs(tm-tmth')>sqrt(eps)),
  error('momftfr test 5 failed');
elseif any(abs(D2)>sqrt(eps)),
  error('momftfr test 6 failed');
end

% For a sinusoid
[sig,ifl]=fmsin(N,0,.5,N*2,1,0);
tfr=tfrideal(ifl);
[tm,D2]=momftfr(tfr');
tmth=round(ifl*2*(N-1))+1;
if any(abs(tm-tmth)>sqrt(1/N)),
  error('momftfr test 7 failed');
elseif any(abs(D2)>sqrt(eps)),
  error('momftfr test 8 failed');
end


function k = indexardKernDiagCompute(kern, x)

% INDEXARDKERNDIAGCOMPUTE Compute diagonal of INDEXARD kernel.
% FORMAT
% DESC computes the diagonal of the kernel matrix for the index ard based covariance function kernel given a design matrix of inputs.
% ARG kern : the kernel structure for which the matrix is computed.
% ARG x : input data matrix in the form of a design matrix.
% RETURN k : a vector containing the diagonal of the kernel matrix
% computed at the given points.
%
% SEEALSO : indexKernParamInit, kernDiagCompute, kernCreate, indexKernCompute
%
% COPYRIGHT : Neil D. Lawrence, 2011

% KERN
  k = zeros(size(x, 1), 1);
  for i = 1:length(kern.indices)
    ind = find(round(x)==kern.indices(i));
    k(ind) = kern.indexScales(i);
  end
end


function edgewt = SC_EdgeResponse(thickness)
% Ideal model: k =  EdgeCoef0, (0.4), EdgeRange = EdgeRangeMM, (80)
% i.e., y = k*x + 0.78
% Herein, we used an approximation method to model the edge response
% function
% Date: 2021-05-24

% Emperical Thickness Threshold for Edge Segementation
edgewt = double(imbinarize(thickness, 50));
tmpmask = edgewt;
h = fspecial('average', [25, 25]);
for ii = 1:5
    edgewt = imfilter(edgewt, h);
end
tmp = tmpmask.*edgewt;
tmp(tmp==0) = NaN;
tmp = rescale(tmp, 0.6, 1);
tmp(isnan(tmp)) = 0;
edgewt = tmp;

end


function [etoe,idx] = EleToEle(t)
%--if an element shares an edge then it is a neighbor
%--returns element-to-element connectivity in crs format.
%--triangle ie is connected to etoe(idx(ie):idx(ie+1)-1,2) triangles
% kjr 2017, fixed August 2017 for self adj triangles (i.e., disjoint
% elements).
t = sort(t,2);
edges = [t(:,[1 2]);t(:,[1 3]);t(:,[2 3])];
nt = size(t,1);
trinum = repmat((1:nt)',3,1);
% use sort by converting edges to bytes for speed.
[~,tags]=sort(edges*[2^31;1]);
edges=edges(tags,:);
%[edges,tags] = sortrows(edges);
trinum = trinum(tags);
k = find(all(diff(edges,1)==0,2));
etoe=trinum([k,k+1]);
[~,dmy1]=sort(etoe(:,1));[~,dmy2]=sort(etoe(:,2));
% use sort by converting edges to bytes for speed
temp=[etoe(dmy1,:); fliplr(etoe(dmy2,:)); (1:nt)',(1:nt)'];
[~,tags]=sort(temp*[2^31;1]);
etoe=temp(tags,:);
%etoe=sortrows([etoe(dmy1,:); fliplr(etoe(dmy2,:)); (1:nt)',(1:nt)']);%added self adjs.
idx = find(diff(etoe(:,1))==1); idx=[idx;length(etoe)]; idx = [1;idx+1];
end


function count = compute_output(plaza)
count = 0;
[a, b] = size(plaza);
for j = 1:b
count = count + (plaza(a,j) > 0);
end


function [t, storedb] = getLinesearch(problem, x, d, storedb)
% Returns a hint for line-search algorithms.
%
% function [t, storedb] = getLinesearch(problem, x, d, storedb)
%
% For a line-search problem at x along the tangent direction d, computes
% and returns t such that retracting t*d at x yields a good point around
% where to look for a line-search solution. That is: t is a hint as to "how
% far to look" along the line.
%
% The cache database storedb is passed along, possibly modified and
% returned in the process.
%
% See also: canGetLinesearch

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, July 17, 2014.
% Contributors:
% Change log:

    if isfield(problem, 'linesearch')
    %% Compute the line-search hint function using linesearch.

		is_octave = exist('OCTAVE_VERSION', 'builtin');
		if ~is_octave
			narg = nargin(problem.linesearch);
		else
			narg = 3;
		end

        % Check whether the linesearch function wants to deal with the
        % store structure or not.
        switch narg
            case 2
                t = problem.linesearch(x, d);
            case 3
                % Obtain, pass along, and save the store structure
                % associated to this point.
                store = getStore(problem, x, storedb);
                [t, store] = problem.linesearch(x, d, store);
                storedb = setStore(problem, x, storedb, store);
            otherwise
                up = MException('manopt:getLinesearch:badfun', ...
                    'linesearch should accept 2 or 3 inputs.');
                throw(up);
        end

    else
    %% Abandon computing the line-search function.

        up = MException('manopt:getLinesearch:fail', ...
            ['The problem description is not explicit enough to ' ...
             'compute a line-search hint.']);
        throw(up);

    end

end


classdef TwoBodyImpactPointTime < AbstractConstraint
    %TwoBodyImpactPointTime Summary of this class goes here
    %   Detailed explanation goes here

    properties
        normFact = 1;
        event LaunchVehicleEvent
        eventNode(1,1) ConstraintStateComparisonNodeEnum = ConstraintStateComparisonNodeEnum.FinalState;

        lb(1,1) double = 0;
        ub(1,1) double = 0;

        evalType(1,1) ConstraintEvalTypeEnum = ConstraintEvalTypeEnum.FixedBounds;
        stateCompType(1,1) ConstraintStateComparisonTypeEnum = ConstraintStateComparisonTypeEnum.Equals;
        stateCompEvent LaunchVehicleEvent
        stateCompNode(1,1) ConstraintStateComparisonNodeEnum = ConstraintStateComparisonNodeEnum.FinalState;
    end

    methods
        function obj = TwoBodyImpactPointTime(event, lb, ub)
            obj.event = event;
            obj.lb = lb;
            obj.ub = ub;

            obj.id = rand();
        end

        function [lb, ub] = getBounds(obj)
            lb = obj.lb;
            ub = obj.ub;
        end

        function [c, ceq, value, lwrBnd, uprBnd, type, eventNum, valueStateComp] = evalConstraint(obj, stateLog, celBodyData)
            type = obj.getConstraintType();

            switch obj.eventNode
                case ConstraintStateComparisonNodeEnum.FinalState
                    stateLogEntry = stateLog.getLastStateLogForEvent(obj.event);

                case ConstraintStateComparisonNodeEnum.InitialState
                    stateLogEntry = stateLog.getFirstStateLogForEvent(obj.event);

                otherwise
                    error('Unknown event node.');
            end

            value = lvd_TwoBodyImpactPointTasks(stateLogEntry, 'timeToImpact');

            if(isnan(value))
                value = 1E99; %need to throw in a real number
            end

            if(obj.evalType == ConstraintEvalTypeEnum.StateComparison)
                switch obj.stateCompNode
                    case ConstraintStateComparisonNodeEnum.FinalState
                        stateLogEntryStateComp = stateLog.getLastStateLogForEvent(obj.stateCompEvent).deepCopy();

                    case ConstraintStateComparisonNodeEnum.InitialState
                        stateLogEntryStateComp = stateLog.getFirstStateLogForEvent(obj.stateCompEvent).deepCopy();

                    otherwise
                        error('Unknown event node.');
                end

                cartElem = stateLogEntryStateComp.getCartesianElementSetRepresentation();
                cartElem = cartElem.convertToFrame(stateLogEntry.centralBody.getBodyCenteredInertialFrame());
                stateLogEntryStateComp.setCartesianElementSet(cartElem);

                valueStateComp = lvd_TwoBodyImpactPointTasks(stateLogEntryStateComp, 'timeToImpact');

                if(isnan(valueStateComp))
                    valueStateComp = 1E99; %need to throw in a real number
                end
            else
                valueStateComp = NaN;
            end

            [c, ceq] = obj.computeCAndCeqValues(value, valueStateComp);

            lwrBnd = obj.lb;
            uprBnd = obj.ub;

            eventNum = obj.event.getEventNum();
        end

        function sF = getScaleFactor(obj)
            sF = obj.normFact;
        end

        function setScaleFactor(obj, sF)
            obj.normFact = sF;
        end

        function tf = usesStage(obj, stage)
            tf = false;
        end

        function tf = usesEngine(obj, engine)
            tf = false;
        end

        function tf = usesTank(obj, tank)
            tf = false;
        end

        function tf = usesEngineToTankConn(obj, engineToTank)
            tf = false;
        end

        function tf = usesEvent(obj, event)
            tf = obj.event == event;
            if(obj.evalType == ConstraintEvalTypeEnum.StateComparison)
                tf = tf || obj.stateCompEvent == event;
            end
        end

        function tf = usesStopwatch(obj, stopwatch)
            tf = false;
        end

        function tf = usesExtremum(obj, extremum)
            tf = false;
        end

        function tf = canUseSparseOutput(obj)
            tf = true;
        end

        function event = getConstraintEvent(obj)
            event = obj.event;
        end

        function type = getConstraintType(obj)
            type = 'Two-Body Time To Impact';
        end

%         function name = getName(obj)
%             name = sprintf('%s - Event %i', obj.getConstraintType(), obj.event.getEventNum());
%         end

        function [unit, lbLim, ubLim, usesLbUb, usesCelBody, usesRefSc] = getConstraintStaticDetails(obj)
            unit = 'sec';
            lbLim = -Inf;
            ubLim = Inf;
            usesLbUb = true;
            usesCelBody = false;
            usesRefSc = false;
        end

        function addConstraintTf = openEditConstraintUI(obj, lvdData)
%             addConstraintTf = lvd_EditGenericMAConstraintGUI(obj, lvdData);

            output = AppDesignerGUIOutput({false});
            lvd_EditGenericMAConstraintGUI_App(obj, lvdData, output);
            addConstraintTf = output.output{1};
        end
    end

    methods(Static)
        function constraint = getDefaultConstraint(~, ~)
            constraint = TwoBodyImpactPointTime(LaunchVehicleEvent.empty(1,0),0,0);
        end
    end
end


function preproc = spm_cfg_preproc8
% Configuration file for 'Combined Segmentation and Spatial Normalisation'
%__________________________________________________________________________
% Copyright (C) 2008-2016 Wellcome Trust Centre for Neuroimaging

% John Ashburner
% $Id: spm_cfg_preproc8.m 7629 2019-06-27 12:35:45Z john $

%--------------------------------------------------------------------------
% vols Volumes
%--------------------------------------------------------------------------
vols         = cfg_files;
vols.tag     = 'vols';
vols.name    = 'Volumes';
vols.help    = {
    'Select scans from this channel for processing.'
    'If multiple channels are used (eg T1 & T2), then the same order of subjects must be specified for each channel and they must be in register (same position, size, voxel dims etc..).'
    }';
vols.filter  = 'image';
vols.ufilter = '.*';
vols.num     = [1 Inf];
vols.preview = @(f) spm_check_registration(char(f));

%--------------------------------------------------------------------------
% biasreg Bias regularisation
%--------------------------------------------------------------------------
biasreg         = cfg_menu;
biasreg.tag     = 'biasreg';
biasreg.name    = 'Bias regularisation';
biasreg.help    = {
    'MR images are usually corrupted by a smooth, spatially varying artifact that modulates the intensity of the image (bias). These artifacts, although not usually a problem for visual inspection, can impede automated processing of the images.'
    ''
    'An important issue relates to the distinction between intensity variations that arise because of bias artifact due to the physics of MR scanning, and those that arise due to different tissue properties.  The objective is to model the latter by different tissue classes, while modelling the former with a bias field. We know a priori that intensity variations due to MR physics tend to be spatially smooth, whereas those due to different tissue types tend to contain more high frequency information. A more accurate estimate of a bias field can be obtained by including prior knowledge about the distribution of the fields likely to be encountered by the correction algorithm. For example, if it is known that there is little or no intensity non-uniformity, then it would be wise to penalise large values for the intensity non-uniformity parameters. This regularisation can be placed within a Bayesian context, whereby the penalty incurred is the negative logarithm of a prior probability for any particular pattern of non-uniformity.'
    'Knowing what works best should be a matter of empirical exploration.  For example, if your data has very little intensity non-uniformity artifact, then the bias regularisation should be increased.  This effectively tells the algorithm that there is very little bias in your data, so it does not try to model it.'
    }';
biasreg.labels = {
                  'no regularisation (0)'
                  'extremely light regularisation (0.00001)'
                  'very light regularisation (0.0001)'
                  'light regularisation (0.001)'
                  'medium regularisation (0.01)'
                  'heavy regularisation (0.1)'
                  'very heavy regularisation (1)'
                  'extremely heavy regularisation (10)'
                  }';
biasreg.values = {
                  0
                  1e-05
                  0.0001
                  0.001
                  0.01
                  0.1
                  1
                  10
                  }';
biasreg.val    = {0.001};

%--------------------------------------------------------------------------
% biasfwhm Bias FWHM
%--------------------------------------------------------------------------
biasfwhm         = cfg_menu;
biasfwhm.tag     = 'biasfwhm';
biasfwhm.name    = 'Bias FWHM';
biasfwhm.help    = {
    'FWHM of Gaussian smoothness of bias.'
    'If your intensity non-uniformity is very smooth, then choose a large FWHM. This will prevent the algorithm from trying to model out intensity variation due to different tissue types. The model for intensity non-uniformity is one of i.i.d. Gaussian noise that has been smoothed by some amount, before taking the exponential. Note also that smoother bias fields need fewer parameters to describe them. This means that the algorithm is faster for smoother intensity non-uniformities.'
    }';
biasfwhm.labels = {
                   '30mm cutoff'
                   '40mm cutoff'
                   '50mm cutoff'
                   '60mm cutoff'
                   '70mm cutoff'
                   '80mm cutoff'
                   '90mm cutoff'
                   '100mm cutoff'
                   '110mm cutoff'
                   '120mm cutoff'
                   '130mm cutoff'
                   '140mm cutoff'
                   '150mm cutoff'
                   'No correction'
                   }';
biasfwhm.values = {
                   30
                   40
                   50
                   60
                   70
                   80
                   90
                   100
                   110
                   120
                   130
                   140
                   150
                   Inf
                   }';
biasfwhm.val    = {60};

%--------------------------------------------------------------------------
% write Save Bias Corrected
%--------------------------------------------------------------------------
write         = cfg_menu;
write.tag     = 'write';
write.name    = 'Save Bias Corrected';
write.help    = {
    'Option to save a bias corrected version of your images from this channel, or/and the estimated bias field.'
    'MR images are usually corrupted by a smooth, spatially varying artifact that modulates the intensity of the image (bias). These artifacts, although not usually a problem for visual inspection, can impede automated processing of the images.  The bias corrected version should have more uniform intensities within the different types of tissues.'
    }';
write.labels = {
                'Save Nothing'
                'Save Bias Corrected'
                'Save Bias Field'
                'Save Field and Corrected'
                }';
write.values = {
                [0 0]
                [0 1]
                [1 0]
                [1 1]
                }';
write.val    = {[0 0]};

%--------------------------------------------------------------------------
% channel Channel
%--------------------------------------------------------------------------
channel         = cfg_branch;
channel.tag     = 'channel';
channel.name    = 'Channel';
channel.val     = {vols biasreg biasfwhm write };
channel.help    = {
    'Specify a channel for processing.'
    'If multiple channels are used (eg PD & T2), then the same order of subjects must be specified for each channel and they must be in register (same position, size, voxel dims etc..). The different channels can be treated differently in terms of inhomogeneity correction etc. You may wish to correct some channels and save the corrected images, whereas you may wish not to do this for other channels.'
    }';

%--------------------------------------------------------------------------
% data Data
%--------------------------------------------------------------------------
data         = cfg_repeat;
data.tag     = 'data';
data.name    = 'Data';
data.val     = {channel };
data.help    = {
    'Specify the number of different channels (for multi-spectral classification).'
    'If you have scans of different contrasts for each of the subjects, then it is possible to combine the information from them in order to improve the segmentation accuracy. Note that only the first channel of data is used for the initial affine registration with the tissue probability maps.'
    }';
data.values  = {channel };
data.num     = [1 Inf];

%--------------------------------------------------------------------------
% tpm Tissue probability map
%--------------------------------------------------------------------------
tpm         = cfg_files;
tpm.tag     = 'tpm';
tpm.name    = 'Tissue probability map';
tpm.help    = {
    'Select the tissue probability image for this class.'
    'These should be maps of eg grey matter, white matter or cerebro-spinal fluid probability. A nonlinear deformation field is estimated that best overlays the tissue probability maps on the individual subjects'' image.'
    ''
    'Rather than assuming stationary prior probabilities based upon mixing proportions, additional information is used, based on other subjects'' brain images.  Priors are usually generated by registering a large number of subjects together, assigning voxels to different tissue types and averaging tissue classes over subjects. Three tissue classes are used: grey matter, white matter and cerebro-spinal fluid. A fourth class is also used, which is simply one minus the sum of the first three. These maps give the prior probability of any voxel in a registered image being of any of the tissue classes - irrespective of its intensity.'
    ''
    'The model is refined further by allowing the tissue probability maps to be deformed according to a set of estimated parameters. This allows spatial normalisation and segmentation to be combined into the same model.'
    }';
tpm.filter  = 'image';
tpm.ufilter = '.*';
tpm.num     = [1 1];
tpm.preview = @(f) spm_image('Display',char(f));

%--------------------------------------------------------------------------
% ngaus Num. Gaussians
%--------------------------------------------------------------------------
ngaus         = cfg_menu;
ngaus.tag     = 'ngaus';
ngaus.name    = 'Num. Gaussians';
ngaus.help    = {
    'The number of Gaussians used to represent the intensity distribution for each tissue class can be greater than one.'
    'In other words, a tissue probability map may be shared by several clusters. The assumption of a single Gaussian distribution for each class does not hold for a number of reasons. In particular, a voxel may not be purely of one tissue type, and instead contain signal from a number of different tissues (partial volume effects). Some partial volume voxels could fall at the interface between different classes, or they may fall in the middle of structures such as the thalamus, which may be considered as being either grey or white matter. Various other image segmentation approaches use additional clusters to model such partial volume effects. These generally assume that a pure tissue class has a Gaussian intensity distribution, whereas intensity distributions for partial volume voxels are broader, falling between the intensities of the pure classes. Unlike these partial volume segmentation approaches, the model adopted here simply assumes that the intensity distribution of each class may not be Gaussian, and assigns belonging probabilities according to these non-Gaussian distributions. Typical numbers of Gaussians could be two for grey matter, two for white matter, two for CSF, three for bone, four for other soft tissues and two for air (background).'
    'Note that if any of the Num. Gaussians is set to non-parametric, then a non-parametric approach will be used to model the tissue intensities. This may work for some images (eg CT), but not others - and it has not been optimised for multi-channel data. Note that it is likely to be especially problematic for images with poorly behaved intensity histograms due to aliasing effects that arise from having discrete values on the images.'
    }';
ngaus.labels = {
                '1'
                '2'
                '3'
                '4'
                '5'
                '6'
                '7'
                '8'
                'Nonparametric'
                }';
ngaus.values = {
                1
                2
                3
                4
                5
                6
                7
                8
                Inf
                }';
ngaus.val    = {Inf};

%--------------------------------------------------------------------------
% native Native Tissue
%--------------------------------------------------------------------------
native         = cfg_menu;
native.tag     = 'native';
native.name    = 'Native Tissue';
native.help    = {'The native space option allows you to produce a tissue class image (c*) that is in alignment with the original/* (see Figure \ref{seg1})*/. It can also be used for ``importing'''' into a form that can be used with the Dartel toolbox (rc*).'};
native.labels = {
    'None'
    'Native Space'
    'Dartel Imported'
    'Native + Dartel Imported'
    }';
native.values = {
                 [0 0]
                 [1 0]
                 [0 1]
                 [1 1]
                 }';
native.val    = {[1 0]};

%--------------------------------------------------------------------------
% warped Warped Tissue
%--------------------------------------------------------------------------
warped         = cfg_menu;
warped.tag     = 'warped';
warped.name    = 'Warped Tissue';
warped.help    = {
    'You can produce spatially normalised versions of the tissue class - both with (mwc*) and without (wc*) modulation (see below). These can be used for voxel-based morphometry. All you need to do is smooth them and do the stats.'
    ''
    '``Modulation'''' is to compensate for the effect of spatial normalisation.  When warping a series of images to match a template, it is inevitable that volumetric differences will be introduced into the warped images.  For example, if one subject''s temporal lobe has half the volume of that of the template, then its volume will be doubled during spatial normalisation. This will also result in a doubling of the voxels labelled grey matter.  In order to remove this confound, the spatially normalised grey matter (or other tissue class) is adjusted by multiplying by its relative volume before and after warping.  If warping results in a region doubling its volume, then the correction will halve the intensity of the tissue label. This whole procedure has the effect of preserving the total amount of grey matter signal in the normalised partitions.  Actually, in this version of SPM the warped data are not scaled by the Jacobian determinants when generating the "modulated" data.  Instead, the original voxels are projected into their new location in the warped images.  This exactly preserves the tissue count, but has the effect of introducing aliasing artifacts - especially if the original data are at a lower resolution than the warped images.  Smoothing should reduce this artifact though.'
    'Note also that the "unmodulated" data are generated slightly differently in this version of SPM. In this version, the projected data are corrected using a kind of smoothing procedure. This is not done exactly as it should be done (to save computational time), but it does a reasonable job. It also has the effect of extrapolating the warped tissue class images beyond the range of the original data.  This extrapolation is not perfect, as it is only an estimate, but it may still be a good thing to do.'
    }';
warped.labels = {
                 'None'
                 'Modulated'
                 'Unmodulated'
                 'Modulated + Unmodulated'
                 }';
warped.values = {
                 [0 0]
                 [0 1]
                 [1 0]
                 [1 1]
                 }';
warped.val    = {[0 0]};

%--------------------------------------------------------------------------
% tissue Tissue
%--------------------------------------------------------------------------
tissue         = cfg_branch;
tissue.tag     = 'tissue';
tissue.name    = 'Tissue';
tissue.val     = {tpm ngaus native warped};
tissue.help    = {'A number of options are available for each of the tissues.  You may wish to save images of some tissues, but not others. If planning to use Dartel, then make sure you generate ``imported'''' tissue class images of grey and white matter (and possibly others).  Different numbers of Gaussians may be needed to model the intensity distributions of the various tissues.'};

%--------------------------------------------------------------------------
% tissues Tissues
%--------------------------------------------------------------------------
tissues         = cfg_repeat;
tissues.tag     = 'tissues';
tissues.name    = 'Tissues';
tissues.values  = {tissue};
tissues.num     = [0 Inf];

tissues.val     = {tissue tissue tissue tissue tissue tissue};
tpm_nam = fullfile(spm('dir'),'tpm','TPM.nii');
ngaus   = [1 1 2 3 4 2];
% Change to: ngaus   = [2 2 2 3 4 2];
nval    = {[1 0],[1 0],[1 0],[1 0],[1 0],[0 0]};
for k=1:numel(ngaus),
    tissue.val{1}.val = {{[tpm_nam ',' num2str(k)]}};
    tissue.val{2}.val = {ngaus(k)};
    tissue.val{3}.val = {nval{k}};
    tissues.val{k}    = tissue;
end

tissues.help    = {'The data for each subject are classified into a number of different tissue types.  The tissue types are defined according to tissue probability maps, which define the prior probability of finding a tissue type at a particular location. Typically, the order of tissues is grey matter, white matter, CSF, bone, soft tissue and air/background (if using tpm/TPM.nii).'};
tissues.preview = @(f) spm_check_registration(char([f.tpm]));

%--------------------------------------------------------------------------
% mrf MRF Parameter
%--------------------------------------------------------------------------
mrf         = cfg_entry;
mrf.tag     = 'mrf';
mrf.name    = 'MRF Parameter';
mrf.help    = {'When tissue class images are written out, a few iterations of a simple Markov Random Field (MRF) cleanup procedure are run.  This parameter controls the strength of the MRF. Setting the value to zero will disable the cleanup.'};
mrf.strtype = 'r';
mrf.num     = [1 1];
mrf.val     = {1};

%--------------------------------------------------------------------------
% cleanup Clean up any partitions
%--------------------------------------------------------------------------
cleanup         = cfg_menu;
cleanup.tag     = 'cleanup';
cleanup.name    = 'Clean Up';
cleanup.help    = {
    'This uses a crude routine for extracting the brain from segmented images.'
    'It begins by taking the white matter, and eroding it a couple of times to get rid of any odd voxels.  The algorithm continues on to do conditional dilations for several iterations, where the condition is based upon gray or white matter being present.This identified region is then used to clean up the grey and white matter partitions.  Note that the fluid class will also be cleaned, such that aqueous and vitreous humour in the eyeballs, as well as other assorted fluid regions (except CSF) will be removed.'
    ''
    'If you find pieces of brain being chopped out in your data, then you may wish to disable or tone down the cleanup procedure. Note that the procedure uses a number of assumptions about what each tissue class refers to.  If a different set of tissue priors are used, then this routine should be disabled.'
    }';
cleanup.labels = {
                  'Dont do cleanup'
                  'Light Clean'
                  'Thorough Clean'
}';
cleanup.values = {0 1 2};
cleanup.val    = {1};

%--------------------------------------------------------------------------
% reg Warping Regularisation
%--------------------------------------------------------------------------
reg         = cfg_entry;
reg.tag     = 'reg';
reg.name    = 'Warping Regularisation';
reg.help    = {...
    'Registration involves simultaneously minimising two terms.  One of these is a measure of similarity between the images (mean-squared difference in the current situation), whereas the other is a measure of the roughness of the deformations.  This measure of roughness involves the sum of the following terms:',...
    '* Absolute displacements need to be penalised by a tiny amount.  The first element encodes the amount of penalty on these.  Ideally, absolute displacements should not be penalised, but it is necessary for technical reasons.',...
    '* The `membrane energy'' of the deformation is penalised (2nd element), usually by a relatively small amount. This penalises the sum of squares of the derivatives of the velocity field (ie the sum of squares of the elements of the Jacobian tensors).',...
    '* The `bending energy'' is penalised (3rd element). This penalises the sum of squares of the 2nd derivatives of the velocity.',...
    '* Linear elasticity regularisation is also included (4th and 5th elements).  The first parameter (mu) is similar to that for linear elasticity, except it penalises the sum of squares of the Jacobian tensors after they have been made symmetric (by averaging with the transpose).  This term essentially penalises length changes, without penalising rotations.',...
    '* The final term also relates to linear elasticity, and is the weight that denotes how much to penalise changes to the divergence of the velocities (lambda).  This divergence is a measure of the rate of volumetric expansion or contraction.',...
    'The amount of regularisation determines the tradeoff between the terms. More regularisation gives smoother deformations, where the smoothness measure is determined by the bending energy of the deformations.'};
reg.strtype = 'r';
reg.num     = [1  5];
reg.val     = {[0 0.001 0.5 0.05 0.2]};

%--------------------------------------------------------------------------
% affreg Affine Regularisation
%--------------------------------------------------------------------------
affreg         = cfg_menu;
affreg.tag     = 'affreg';
affreg.name    = 'Affine Regularisation';
affreg.help    = {
    'The procedure is a local optimisation, so it needs reasonable initial starting estimates. Images should be placed in approximate alignment using the Display function of SPM before beginning. A Mutual Information affine registration with the tissue probability maps (D''Agostino et al, 2004) is used to achieve approximate alignment. Note that this step does not include any model for intensity non-uniformity. This means that if the procedure is to be initialised with the affine registration, then the data should not be too corrupted with this artifact.If there is a lot of intensity non-uniformity, then manually position your image in order to achieve closer starting estimates, and turn off the affine registration.'
    ''
    'Affine registration into a standard space can be made more robust by regularisation (penalising excessive stretching or shrinking).  The best solutions can be obtained by knowing the approximate amount of stretching that is needed (e.g. ICBM templates are slightly bigger than typical brains, so greater zooms are likely to be needed). For example, if registering to an image in ICBM/MNI space, then choose this option.  If registering to a template that is close in size, then select the appropriate option for this.'
    }';
affreg.labels = {
                 'No Affine Registration'
                 'ICBM space template - European brains'
                 'ICBM space template - East Asian brains'
                 'Average sized template'
                 'No regularisation'
                 }';
affreg.values = {
                 ''
                 'mni'
                 'eastern'
                 'subj'
                 'none'
                 }';
affreg.val    = {'mni'};

%--------------------------------------------------------------------------
% fwhm Smoothness
%--------------------------------------------------------------------------
smo         = cfg_entry;
smo.tag     = 'fwhm';
smo.name    = 'Smoothness';
smo.help    = {
    'This is used to derive a fudge factor to account for correlations between neighbouring voxels.'
    'Smoother data have more spatial correlations, rendering the assumptions of the model inaccurate.'
    'For PET or SPECT, set this value to about 5 mm, or more if the images have smoother noise.  For MRI, you can usually use a value of 0 mm.'
    }';
smo.strtype = 'r';
smo.num     = [1  1];
smo.val     = {0};

%--------------------------------------------------------------------------
% samp Sampling distance
%--------------------------------------------------------------------------
samp         = cfg_entry;
samp.tag     = 'samp';
samp.name    = 'Sampling distance';
samp.help    = {
    'This encodes the approximate distance between sampled points when estimating the model parameters.'
    'Smaller values use more of the data, but the procedure is slower and needs more memory. Determining the ``best'''' setting involves a compromise between speed and accuracy.'
    }';
samp.strtype = 'r';
samp.num     = [1  1];
samp.val     = {3};

%--------------------------------------------------------------------------
% write Deformation Fields
%--------------------------------------------------------------------------
write         = cfg_menu;
write.tag     = 'write';
write.name    = 'Deformation Fields';
write.help    = {
    'Deformation fields can be saved to disk, and used by the Deformations Utility.'
    'For spatially normalising images to MNI space, you will need the forward deformation, whereas for spatially normalising (eg) GIFTI surface files, you''ll need the inverse. It is also possible to transform data in MNI space on to the individual subject, which also requires the inverse transform. Deformations are saved as .nii files, which contain three volumes to encode the x, y and z coordinates.'
    };
write.labels = {
                'None'
                'Inverse'
                'Forward'
                'Inverse + Forward'
                }';
write.values = {
                [0 0]
                [1 0]
                [0 1]
                [1 1]
                }';
write.val    = {[0 0]};

%--------------------------------------------------------------------------
% bb Bounding box
%--------------------------------------------------------------------------
bb         = cfg_entry;
bb.tag     = 'bb';
bb.name    = 'Bounding box';
bb.help    = {'The bounding box (in mm) of the volume which is to be written (relative to the anterior commissure).'};
bb.strtype = 'r';
bb.num     = [2 3];
bb.val     = {[NaN NaN NaN; NaN NaN NaN]};
bb.hidden  = true;

%--------------------------------------------------------------------------
% vox Voxel sizes
%--------------------------------------------------------------------------
vox         = cfg_entry;
vox.tag     = 'vox';
vox.name    = 'Voxel sizes';
vox.help    = {'The voxel size (isotropic, in mm) of the written normalised or imported images.'};
vox.strtype = 'r';
vox.num     = [1 1];
vox.val     = {NaN};
vox.hidden  = true;

%--------------------------------------------------------------------------
% warp Warping
%--------------------------------------------------------------------------
warp         = cfg_branch;
warp.tag     = 'warp';
warp.name    = 'Warping & MRF';
warp.val     = {mrf cleanup reg affreg smo samp write vox bb};
warp.help    = {
    'A number of warping options.'
    'The main one that you could consider changing is the one for specifying whether deformation fields or inverse deformation fields should be generated.'
    }';

%--------------------------------------------------------------------------
% preproc Segment
%--------------------------------------------------------------------------
preproc      = cfg_exbranch;
preproc.tag  = 'preproc';
preproc.name = 'Segment';
preproc.val  = {data tissues warp};
preproc.help = {
    'Segmentation, bias correction and spatially normalisation - all in the same model.'
    ''
    'This procedure is an extension of the old unified segmentation algorithm (and was known as "New Segment" in SPM8). The algorithm is essentially the same as that described in the Unified Segmentation paper /* \cite{ashburner05}*/, except for (i) a slightly different treatment of the mixing proportions, (ii) the use of an improved registration model, (iii) the ability to use multi-spectral data, (iv) an extended set of tissue probability maps, which allows a different treatment of voxels outside the brain. Some of the options in the toolbox do not yet work, and it has not yet been seamlessly integrated into the SPM8 software.  Also, the extended tissue probability maps need further refinement. The current versions were crudely generated (by JA) using data that was kindly provided by Cynthia Jongen of the Imaging Sciences Institute at Utrecht, NL.'
    ''
    'This function segments, bias corrects and spatially normalises - all in the same model/* \cite{ashburner05}*/. Many investigators use tools within older versions of SPM for a technique that has become known as "optimised" voxel-based morphometry (VBM). VBM performs region-wise volumetric comparisons among populations of subjects. It requires the images to be spatially normalised, segmented into different tissue classes, and smoothed, prior to performing statistical tests/* \cite{wright_vbm,am_vbmreview,ashburner00b,john_should}*/. The "optimised" pre-processing strategy involved spatially normalising subjects'' brain images to a standard space, by matching grey matter in these images, to a grey matter reference.  The historical motivation behind this approach was to reduce the confounding effects of non-brain (e.g. scalp) structural variability on the registration. Tissue classification in older versions of SPM required the images to be registered with tissue probability maps. After registration, these maps represented the prior probability of different tissue classes being found at each location in an image.  Bayes rule can then be used to combine these priors with tissue type probabilities derived from voxel intensities, to provide the posterior probability.'
    ''
    'This procedure was inherently circular, because the registration required an initial tissue classification, and the tissue classification requires an initial registration.  This circularity is resolved here by combining both components into a single generative model. This model also includes parameters that account for image intensity non-uniformity. Estimating the model parameters (for a maximum a posteriori solution) involves alternating among classification, bias correction and registration steps. This approach provides better results than simple serial applications of each component.'
    }';
preproc.prog = @spm_local_preproc_run;
preproc.vout = @vout;

%==========================================================================
function varargout = spm_local_preproc_run(job)
varargout{1} = spm_preproc_run(job);

%==========================================================================
function dep = vout(job)
% This depends on job contents, which may not be present when virtual
% outputs are calculated.

cdep = cfg_dep;
cdep(end).sname      = 'Seg Params';
cdep(end).src_output = substruct('.','param','()',{':'});
cdep(end).tgt_spec   = cfg_findspec({{'filter','mat','strtype','e'}});

for i=1:numel(job.channel)
    if job.channel(i).write(1)
        cdep(end+1)          = cfg_dep;
        cdep(end).sname      = sprintf('Bias Field (%d)',i);
        cdep(end).src_output = substruct('.','channel','()',{i},'.','biasfield','()',{':'});
        cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
    end
    if job.channel(i).write(2)
        cdep(end+1)          = cfg_dep;
        cdep(end).sname      = sprintf('Bias Corrected (%d)',i);
        cdep(end).src_output = substruct('.','channel','()',{i},'.','biascorr','()',{':'});
        cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
    end
end

for i=1:numel(job.tissue)
    if job.tissue(i).native(1)
        cdep(end+1)          = cfg_dep;
        cdep(end).sname      = sprintf('c%d Images',i);
        cdep(end).src_output = substruct('.','tiss','()',{i},'.','c','()',{':'});
        cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
    end
    if job.tissue(i).native(2)
        cdep(end+1)          = cfg_dep;
        cdep(end).sname      = sprintf('rc%d Images',i);
        cdep(end).src_output = substruct('.','tiss','()',{i},'.','rc','()',{':'});
        cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
    end
    if job.tissue(i).warped(1)
        cdep(end+1)          = cfg_dep;
        cdep(end).sname      = sprintf('wc%d Images',i);
        cdep(end).src_output = substruct('.','tiss','()',{i},'.','wc','()',{':'});
        cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
    end
    if job.tissue(i).warped(2)
        cdep(end+1)          = cfg_dep;
        cdep(end).sname      = sprintf('mwc%d Images',i);
        cdep(end).src_output = substruct('.','tiss','()',{i},'.','mwc','()',{':'});
        cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
    end
end

if job.warp.write(1)
    cdep(end+1)          = cfg_dep;
    cdep(end).sname      = 'Inverse Deformations';
    cdep(end).src_output = substruct('.','invdef','()',{':'});
    cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
end

if job.warp.write(2)
    cdep(end+1)          = cfg_dep;
    cdep(end).sname      = 'Forward Deformations';
    cdep(end).src_output = substruct('.','fordef','()',{':'});
    cdep(end).tgt_spec   = cfg_findspec({{'filter','image','strtype','e'}});
end

dep = cdep;


%GM_PHD_Predict_Existing
%Last modified 27th August 2013
%Matlab code by Bryan Clarke b.clarke@acfr.usyd.edu.au

%This file performs prediction for existing targets
s = sprintf('Step 2: Prediction for existing targets.');
disp(s);

mk_k_minus_1_before_prediction = mk_minus_1;

for j = 1:size(mk_minus_1,2)
    wk_minus_1(j) = prob_survival * wk_minus_1(j);
    mk_minus_1(:,j) = F * mk_minus_1(:,j); %Assume constant velocity.

    P_range = calculateDataRange4(j);
    P_i = Q + F * Pk_minus_1(:,P_range) * F';

    prevState = mk_k_minus_1_before_prediction(:,j);
    newState = mk_minus_1(:,j);

    Pk_minus_1(:,P_range) = P_i;

    if(VERBOSE == 1)
        s = sprintf('\t\tExisting target %d. Previously at %3.4f %3.4f, now at %3.4f %3.4f.', j, prevState(1), prevState(2), newState(1), newState(2));
        disp(s);

        s = sprintf('\t\tP was %3.4f %3.4f, NOW %3.4f %3.4f', Pk_minus_1(1,P_range(1)), Pk_minus_1(2,P_range(2)), P_i(1,1), P_i(2,2));
        disp(s);
    end
end

%% Now we combine the birthed targets with the existing ones.
%Append newly birthed targets (in m_k_minus_1) to back of old ones
wk_k_minus_1 = [wk_minus_1, w_birth, w_spawn];
mk_k_minus_1 = [mk_minus_1, m_birth, m_spawn];
Pk_k_minus_1 = [Pk_minus_1, P_birth, P_spawn];
numTargets_Jk_k_minus_1 = numTargets_Jk_minus_1 + numBirthedTargets + numSpawnedTargets;
%Create a backup to allow for augmenting the measurement in the update
mk_k_minus_1_before_prediction = [mk_k_minus_1_before_prediction, m_birth_before_prediction];%m_birth_before_prediction also contains the spawned targets before prediction

if(VERBOSE == 1)
    s = sprintf('\tPerformed prediction for %d birthed and existing targets in total.', numTargets_Jk_k_minus_1);
    disp(s);
end


function [nodes, edges, values] = createTestGraph01(varargin)
%CREATETESTGRAPH01  One-line description here, please.
%
%   output = createTestGraph01(input)
%
%   Example
%   createTestGraph01
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-05-18,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

nodes = [ ...
    290 250; ...
    200 300; ...
    100 300; ...
    100 200; ...
    200 200; ...
    240 110; ...
    330 160; ...
    420 200];

edges = [...
    1 2; ...
    1 5; ...
    1 7; ...
    2 3; ...
    2 5; ...
    3 4; ...
    4 5; ...
    5 6; ...
    6 7; ...
    7 8];

values = [80;10; 70; 60; 50; 20; 30; 40];


function depth_first_search(A,u,dfs_visitor,varargin)
% DEPTH_FIRST_SEARCH Fully wrap the Boost depth_first_search call
% including the dfs_visitor.
%
% depth_first_search(A,u,dfs_visitor) performs a depth first traversal
% of A starting from vertex u.  For each event defined by the dfs_visitor
% structure below, the visitor is called with the either the name of the
% vertex (u), or the edge index and it's source and target (ei,u,v).
%
% See http://www.boost.org/libs/graph/doc/DFSVisitor.html for a description
% of the events.
%
% dfs_visitor is a struct with the following optional fields
%    vis.initialize_vertex(u)
%    vis.start_vertex(u)
%    vis.discover_vertex(u)
%    vis.examine_edge(ei,u,v)
%    vis.tree_edge(ei,u,v)
%    vis.back_edge(ei,u,v)
%    vis.forward_or_cross_edge(ei,u,v)
%    vis.finish_vertex(u)
% Each dfs_visitor parameter should be a function pointer, which returns 0
% if the dfs should stop.  (If the function does not return anything, the
% dfs continues.)
%
% This method works on directed graphs.
% The runtime is O(V+E), excluding the complexity of the visitor
% operations.
%
% Realistically, this function must be used with the
% pass-by-reference/in-place modification library.
%
% ... = depth_first_search(A,u,vis,...) takes a set of
% key-value pairs or an options structure.  See set_matlab_bgl_options
% for the standard options.
%   options.full: compute the full dfs instead of the dfs of
%      the current component (see Note 1) [{0} | 1]
%
% Note 1: When computing the full dfs, the vertex u is ignored, vertex 1 is
% always used as the starting vertex.
%
% Note: this function does not depend upon the non-zero values of A, but
% only uses the non-zero structure of A.
%
% Example:
%   This example finds the distance to a single point and stops the search.
%   function dist_uv(A,u,v)
%     vstar = v;
%     dmap = ipdouble(zeros(size(A,1),1));
%     function stop=on_tree_edge(ei,u,v)
%       dmap(v) = dmap(u)+1;
%       stop = (v ~= vstar);
%     end
%     depth_first_search(A,u,struct('tree_edge',@on_tree_edge));
%   end
%
% See also DFS

% David Gleich
% Copyright, Stanford University, 2007-2008

%% History
%  2006-05-21: Initial version
%  2006-05-31: Added full2sparse check
%  2007-07-24: Fixed example
%  2008-10-07: Changed options parsing
%%

[trans check full2sparse] = get_matlab_bgl_options(varargin{:});
if full2sparse && ~issparse(A), A = sparse(A); end

if check
    % no additional input checks
    check_matlab_bgl(A,struct());
end

if trans, A = A'; end

% parse the optional parameters
full = 0;
if ~isempty(varargin)
    optionsu = merge_options(struct(),varargin{:});
    if (isfield(optionsu,'full'))
        full = optionsu.full;
    end
end

if full
    % 202 is the call for dfs with full searches
    bfs_dfs_vis_mex(A,u,dfs_visitor,202);
else
    % 201 is the call for dfs with partial searches
    bfs_dfs_vis_mex(A,u,dfs_visitor,201);
end


function [out,out_se,out_dist] = testM(M,n)
% function [out,out_se,out_dist] = testM(M,n)
%
% tests an M structure against n random permutations
% returns structures with info on the design goodness
% of the random designs.
%
% tor wager, 11/18/01

M = modelDiagnostics2(M,'noplot');

    out.energy = zeros(1,size(M.energy,2));
    out.conEnergy = zeros(1,size(M.conEnergy,2));
    out.eff_fitness = zeros(1,size(M.eff_fitness,2));
    out.eff = zeros(1,size(M.eff,2));
    out.se_contrasts = zeros(1,size(M.se_contrasts,2));
    out.resample_eff_loss = zeros(1,size(M.resample_eff_loss,2));
    out.smoothing_eff_loss = zeros(1,size(M.smoothing_eff_loss,2));
    out.vif = zeros(1,size(M.vif,2));
    out.conVif = zeros(1,size(M.conVif,2));
    out.cond = zeros(1,size(M.cond,2));
    out.conCond = zeros(1,size(M.conCond,2));
    out.conColin = zeros(size(M.conColin));
    out.hrf_eff_fitness = zeros(1,size(M.hrf_eff_fitness,2));
    out.hrf_eff = zeros(1,size(M.hrf_eff,2));
    out.hrf_eff_avg = zeros(1,size(M.hrf_eff_avg,2));
    out.cBal = zeros(1,size(M.cBal,2));

    out_se = out;
    out_dist = out;

    N = fieldnames(out);

    for j = N'
        eval([j{1} ' = [];']);
    end

warning off

for i = 1:n

    Mr = M;
    Mr.stimlist = getRandom(Mr.stimlist);

    Mr = modelDiagnostics2(Mr,'noplot');

    for j = N'
        eval(['out.' j{1} ' = out.' j{1} ' + Mr.' j{1} ';'])
        eval(['out_dist.' j{1} ' = [out_dist.' j{1} '; (Mr.' j{1} ')];'])
    end

    if mod(i,100) == 0, fprintf(1,'.'), end

end

warning on

for j = N'
    eval(['out.' j{1} ' = out.' j{1} ' / n;'])
    eval(['out_se.' j{1} ' = std(out_dist.' j{1} ') ./ sqrt(n);'])
end

return


%% Copyright (C) 2014, 2016 Colin B. Macdonald
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published
%% by the Free Software Foundation; either version 3 of the License,
%% or (at your option) any later version.
%%
%% This software is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
%% the GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public
%% License along with this software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defmethod @@sym rhs (@var{f})
%% Right-hand side of symbolic expression.
%%
%% Example:
%% @example
%% @group
%% syms x
%% eqn = 5*x <= 3*x + 6
%%   @result{} eqn = (sym) 5⋅x ≤ 3⋅x + 6
%% rhs(eqn)
%%   @result{} ans = (sym) 3⋅x + 6
%% @end group
%% @end example
%%
%% Gives an error if any of the symbolic objects have no right-hand side.
%%
%% @seealso{@@sym/lhs, @@sym/children, @@sym/formula, @@sym/argnames}
%% @end defmethod

function R = rhs(f)

  R = elementwise_op ('lambda a: a.rhs', f);

end

%% most tests are in lhs
%!test
%! syms x
%! f = x + 1 == 2*x;
%! assert (isequal (rhs(f), 2*x))

%!error <AttributeError>
%! syms x
%! rhs(x)


% imbibition capillary pressure curve
% Written by Ali A. Eftekhari
% Note that pc_max_o is specified as pc_min in the input json files for
% slightly more consistency witht the polynomial Pc
function res=pc_imb(sw, pce_w, pce_o, swc, sor, labda_w, labda_o, pc_max_w, pc_max_o)
  pc1=pc_drain(sw, pce_w, swc, labda_w, pc_max_w);
  pc2=pc_drain(1-sw, pce_o, sor, labda_o, pc_max_o);
  res=pc1-pc2;
end


% closest larva, based on dhead2central
function [data,units,mind] = compute_closestlarva_head2central(trx,n,dosave_d)

 if nargin < 3,
   dosave_d = true;
 end

larvae = trx.exp2flies{n};
nlarvae = numel(larvae);
closestlarva = cell(1,nlarvae);
mind = cell(1,nlarvae);

for i1 = 1:nlarvae,
  larva1 = larvae(i1);
  fprintf('fly1 = %d\n',larva1);
  larvae2 = larvae;
  d = nan(numel(larvae2),trx(larva1).nframes);

  for i2 = 1:numel(larvae2),
    larva2 = larvae2(i2);
    if larva1 == larva2,
      continue;
    end
    d(i2,:) = dhead2central_pair(trx,larva1,larva2);
  end
  [mind{i1},closesti] = min(d,[],1);
  closestlarva{i1} = larvae2(closesti);
  closestlarva{i1}(isnan(mind{i1})) = nan;
end

% so that we don't compute dcenter twice
 if dosave_d,
   data = mind; %#ok<NASGU>
   units = parseunits('mm'); %#ok<NASGU>
   filename = trx.GetPerFrameFile('dhead2central',n);

   save(filename,'data','units');
 end

data = closestlarva;
units = parseunits('unit');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Specify project path
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
root_path = get_project_path();
export_path = fullfile(root_path,'export','sim');
if ~exist(export_path,'dir')
    mkdir(export_path);
end
addpath(export_path);

%%
robot = acrobot();
robot.configureDynamics();

[frame, fric_coef, geom] = get_contact_frame(robot);
robot = addContact(robot,frame,fric_coef,geom);

%% relative degree two outputs:
ya_2 = robot.States.x(4:end);
t = SymVariable('t');
p = SymVariable('p',[2,1]);
tau = (t-p(2))/(p(1)-p(2));
y2 = VirtualConstraint(robot,ya_2,'joints','DesiredType','Bezier','PolyDegree',5,...
    'RelativeDegree',2,'PhaseType','TimeBased',...
    'PhaseVariable',tau,'PhaseParams',p,'Holonomic',true);

robot = addVirtualConstraint(robot,y2);

%%
robot.compile(export_path);
%%
params.ajoints = [ones(1,6)*0.1;zeros(2,6)];
params.pjoints = [0,1];
params.kjoints = [100,20]; %[kp,kd]

t0 = 0;
tf = 10;
eventnames = [];
sim_opts = [];
logger = SimLogger(robot);
x0 = [zeros(6,1);zeros(6,1)];
io_control  = IOFeedback('IO');
tic
robot.simulate(t0, x0, tf, io_control, params, logger, eventnames, sim_opts);
toc

%%
[conGUI] = load_animator(robot, logger.flow.t, logger.flow.states.x)

%%
t = logger.flow.t;
force = logger.flow.inputs.ConstraintWrench.ffoot;
plot_zmp(t,force);


function pass = test_subsassgn(pref)

%% Setup.
if ( nargin == 0 )
    pref = chebfunpref();
end

%% See #2280

V = chebmatrix({1,2});

V(1) = pi;
pass(1) = V{1} == pi;

V{1} = -pi;
pass(2) = V{1} == -pi;

end


% Author: Ricardo Baptista and Matthias Poloczek
% Date:   June 2018
%
% See LICENSE.md for copyright information
%

function [x_bin_new, x_new_idx] = binary_resampling(binary_models, weights)
% BINARY_RESAMPLING: Function re-samples binary particles based on the
% current weights using systematic resampling.

% Determine the size of x_bin
[n_samples,n_var] = size(binary_models);

% Declare a vector to store new samples and indices
x_bin_new  = zeros(n_samples, n_var);
x_new_idx  = zeros(n_samples, 1);

% Initialize system (u = U[0,1] & v = weights*n_samples & c = v(1))
u = rand;
v = weights*n_samples;
c = v(1);

% Declare iteration counter
counter = 1;

% Resample each particle
for i=1:n_samples

    % Update counter and c value
    while c < u
        counter = counter+1;
        c       = c + v(counter);
    end

    % Assign new binary vector and probability
    x_bin_new(i,:) = binary_models(counter,:);
    x_new_idx(i)   = counter;

    % Update random value
    u = u+1;

end

end