% This file is part of the project NILM-Eval (https://github.com/beckel/nilm-eval).
% Licence: GPL 2.0 (http://www.gnu.org/licenses/gpl-2.0.html)
% Copyright: ETH Zurich, 2014
% Author: Romano Cicchetti

function [result] = disag_fhmm(evaluation_and_training_days, setup, fid)

    % load parameters of algorithm
    dataset = setup.dataset;
    household = setup.household;
    granularity = setup.granularity;
    filteringMethod = setup.filtering;
    filtLength = setup.filtLength;
    evaluation_days = evaluation_and_training_days{1};
    training_days = evaluation_and_training_days{2};
    num_appliances = setup.num_appliances;

    % prepare plug and smart meter data for training
    appliances = {};
    sum_of_plug_data = zeros(1, size(training_days,1) * 24 * 3600);
%     sum_of_plug_data = sum_of_plug_data(1:100);
    for i=1:num_appliances
        appliance = struct;
        eval(['appliance.name = setup.appliance' num2str(i) ';']);
        appliance.id = getApplianceID(appliance.name);
        fprintf('Reading data from appliance %s - id: %d\n', appliance.name, appliance.id);
        appliance.plug_data_training = read_plug_data(dataset, household, appliance.id, training_days, granularity);
%         appliance.plug_data_training = appliance.plug_data_training(1:100);
        sum_of_plug_data = sum_of_plug_data + appliance.plug_data_training;
        eval(['appliance.num_states = setup.num_states_appliance' num2str(i) ';']);

        appliances{i} = appliance;
    end

    % prepare "other" plug
    if setup.states_other > 0
        smart_meter_data_training = read_smartmeter_data(dataset, household, training_days, granularity, 'powerallphases');
%         smart_meter_data_training = smart_meter_data_training(1:100);
        other_data = smart_meter_data_training - sum_of_plug_data;
        other_appliance = struct;
        appliance.name = 'other';
        appliance.plug_data_training = other_data;
        appliance.num_states = setup.states_other;
        appliances{end+1} = appliance;
    end

    smart_meter_data_evaluation = read_smartmeter_data(dataset, household, evaluation_days, granularity, 'powerallphases');
%     smart_meter_data_evaluation = smart_meter_data_evaluation (1:100);

    % perform training
    pyObj = py.nilmtk.disaggregate.chris.fhmm.Fhmm();
    pyObj.train(appliances);

    fprintf('Done with training');

    ret = pyObj.disaggregate(smart_meter_data_evaluation);

    states = cell(ret){1};
    consumption = cell(ret){2};

    result = struct;
    inferred_consumption = zeros(num_appliances, length(smart_meter_data_evaluation));
    appliance_names = {};
    for i=1:num_appliances
        eval(['name = setup.appliance' num2str(i) ';']);
        appliance_names{end+1} = name;
        % eval(['app_result.states = cell2mat(cell(py.list(struct(states).' app_result.name ')));']);
        eval(['cons = cell2mat(cell(py.list(struct(consumption).' name ')));']);
        inferred_consumption(i,:) = cons;
    end
    result.appliance_names = appliance_names;
    result.consumption = inferred_consumption;
end


% The COBRAToolbox: testSampleCbModel.m
%
% Purpose:
%     - tests the sampleCbModel function using the E. coli Core Model
%

% Check Requirements
% quad minos and dqqMinos cannot be used due to parallel processing
% for some reason, matlab fails on this system if it runs in parallel.
solverPkgs = prepareTest('needsUnix',true, 'needsLP',true, 'excludeSolvers',{'mosek', 'dqqMinos','quadMinos','matlab','pdco'},'requiredToolboxes', {'statistics_toolbox'}); %TODO: Check, whether UNIX is really still required for the test.

% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testSampleCbModel'));
cd(fileDir);
% define the samplers
samplers = {'CHRR','CHRR_EXP','ACHR'}; %'MFE'

% create a parallel pool (if possible)
try
    minWorkers = 2;
    myCluster = parcluster(parallel.defaultClusterProfile);

    if myCluster.NumWorkers >= minWorkers
        poolobj = gcp('nocreate');  % if no pool, do not create new one.
        if isempty(poolobj)
            parpool(minWorkers);  % launch minWorkers workers
        end
    end
catch
    %No pool
end

fprintf('   Testing sampleCbModel ... \n' );
for k = 1:length(solverPkgs.LP)
    fprintf(' -- Running testSampleCbModel using the solver interface: %s ... ', solverPkgs.LP{k});

    % set the solver
    solverOK = changeCobraSolver(solverPkgs.LP{k}, 'LP', 0);

    % Load model
    model = getDistributedModel('ecoli_core_model.mat');

    for i = 1:length(samplers)

        samplerName = samplers{i};

        switch samplerName
            case 'ACHR'
                fprintf('\nTesting the artificial centering hit-and-run (ACHR) sampler\n.');

                options.nFiles = 4;
                options.nStepsPerPoint = 5;
                options.nPointsReturned = 20;
                options.nPointsPerFile = 5;
                options.nFilesSkipped = 0;
                options.nWarmupPoints = 200;

                [modelSampling, samples, volume] = sampleCbModel(model, 'EcoliModelSamples', 'ACHR', options);

                % check if sample files created
                assert(exist('EcoliModelSamples_1.mat', 'file') == 2 && exist('EcoliModelSamples_2.mat', 'file') == 2 && exist('EcoliModelSamples_3.mat', 'file') == 2 && exist('EcoliModelSamples_4.mat', 'file') == 2)
                removedRxns = find(~ismember(model.rxns, modelSampling.rxns));
                assert(all(removedRxns == [26; 27; 29; 34; 45; 47; 52; 63]))

            case 'CHRR'
                fprintf('\nTesting the coordinate hit-and-run with rounding (CHRR) sampler\n.');

                options.nStepsPerPoint = 1;
                options.nPointsReturned = 10;
                options.toRound = 1;

                [modelSampling, samples, volume] = sampleCbModel(model, 'EcoliModelSamples', 'CHRR', options);

                assert(norm(samples) > 0)

            case 'CHRR_EXP'
                fprintf('\nTesting the coordinate hit-and-run with rounding (CHRR) sampler, with exponential target distribution.\n.');

                options.nStepsPerPoint = 1;
                options.nPointsReturned = 10;
                options.toRound = 1;
                numRxns = length(model.c);
                options.lambda = 0*model.c + 1;

                [modelSampling, samples, volume] = sampleCbModel(model, 'EcoliModelSamples', 'CHRR_EXP', options);

                assert(norm(samples) > 0)
        end
    end
end

% print a line for success of loop i
fprintf(' Done.\n');

% change the directory
cd(currentDir)


function [events, times] = get_events_of_multi_phase_appliance(input_params)

    dataset = input_params.dataset;
    household = input_params.household;
    evaluation_days = input_params.evaluation_days;
    granularity = input_params.granularity;
    filteringMethod = input_params.filtering_method;
    filtLength = input_params.filtLength;
    edgeThreshold = input_params.filtLength;
    plevelMinLength = input_params.plevelMinLength;
    eventPowerStepThreshold = input_params.eventPowerStepThreshold;
    maxEventDuration = input_params.maxEventDuration;

    events = {};
    times = {};
    for phase = [1:3]
        % get real, apparent and reactive (distoritve and translative
        % component) power
        power = getPower(dataset, household, evaluation_days, granularity, phase);

        % apply filter to normalized apparent power and get edges
        function_handle = str2func(filteringMethod);
        normalized_apparent_power_filtered = function_handle(power.normalized_apparent, filtLength);
        [rows, cols] = find(abs(diff(normalized_apparent_power_filtered)) > edgeThreshold);
        edges = sparse(rows, cols, ones(length(rows),1), 1, size(normalized_apparent_power_filtered,2)-1);

        % get power levels (period between two edges with similar power values)
        [plevel] = getPowerLevelsStartAndEndTimes(edges, plevelMinLength);
        if isempty(plevel.startidx)
            continue;
        end

        % get characteristics of power levels
        plevel = getPowerLevelProperties(plevel, power, plevelMinLength);

        % generate event vectors by taking the diffference between two consecutive power levels
        event_vecs = zeros(length(plevel.startidx)-1, 4);
        eventIsValid = zeros(length(plevel.startidx), 1);
        numOfEvents = 0;
        for i = 1:length(plevel.startidx)-1
               if abs(plevel.mean.end(i,1) - plevel.mean.start(i+1,1)) > eventPowerStepThreshold && plevel.startidx(i+1) - plevel.endidx(i) < maxEventDuration
                    eventIsValid(i) = 1;
                    numOfEvents = numOfEvents + 1;
                    event_vecs(numOfEvents, 1:3) = plevel.mean.start(i+1, :) - plevel.mean.end(i, :);
                    max_std_true_power = max(plevel.std(i,1), plevel.std(i+1,1));
                    max_std_reactive_power = max(plevel.std(i,2), plevel.std(i+1,2));
                    oscillationTerm = norm([max_std_true_power, max_std_reactive_power]);
                    event_vecs(numOfEvents, 4) = oscillationTerm;
               end
        end
        event_vecs = event_vecs(1:numOfEvents, :);
        timeOfEvents = plevel.endidx(eventIsValid==1)';

        events{end+1} = event_vecs;
        times{end+1} = timeOfEvents;
    end
end


function [poseMat] = getGroundTruth (base_dir, imuFrames)
% Based on KITTI RAW DATA DEVELOPMENT KIT
%
% Outputs ground truth poses
%
% Input arguments:
% base_dir .... absolute path to sequence base directory (ends with _sync)
% sequence base directory

% load oxts data
oxts = loadOxtsliteData(base_dir);

% transform to poses
pose = convertOxtsToPose(oxts);

poseMat = zeros(4,4);

for i = 1:length(imuFrames)
    if i == 1
        firstPose = pose{imuFrames(i)};
    end
    poseMat(:,:,i) = inv(firstPose)*pose{imuFrames(i)};
end


function [s,it]=display(c,tab,it)

  if nargin>1
    [s,it]=display(c.algorithm,tab,it);
    return;
  end

  disp(c.algorithm.name);
  disp(['data dimensions:'])

  global X; global Y;

  if isempty(c.myX)
    s=(['X = ' num2str(size(X(c.index,c.findex),1)) 'x' ...
	  num2str(size(X(c.index,c.findex),2))  ]);
  else
    s=(['X = ' num2str(size(c.myX,1)) 'x' num2str(size(c.myX,2))  ]);
  end

  if isempty(c.myY)
    if ~isempty(Y)
      disp([s '  Y = ' num2str(size(Y(c.index,:),1)) 'x' ...
	    num2str(size(Y(c.index,:),2))  ]);
    else
      disp([s '  Y = 0x0']);
    end
  else
    disp([s '  Y = ' num2str(size(c.myY,1)) 'x' num2str(size(c.myY,2))  ]);
  end


function tests = tapas_physio_filter_cardiac_test()
% Tests whether bandpass filter on PPU example data works as expected
%
%   tests = tapas_physio_filter_cardiac_test()
%
% IN
%
% OUT
%
% EXAMPLE
%   tapas_physio_filter_cardiac_test
%
%   See also

% Author:   Lars Kasper
% Created:  2019-07-02
% Copyright (C) 2019 TNU, Institute for Biomedical Engineering,
%                    University of Zurich and ETH Zurich.
%
% This file is part of the TAPAS PhysIO Toolbox, which is released under
% the terms of the GNU General Public License (GPL), version 3. You can
% redistribute it and/or modify it under the terms of the GPL (either
% version 3 or, at your option, any later version). For further details,
% see the file COPYING or <http://www.gnu.org/licenses/>.

tests = functiontests(localfunctions);
end

function test_philips_ppu7t_filter_cheby2(testCase)
%% Compares previously saved Chebychev Type 2 IIR-filtered cropped cardiac
% time course with current re-run of same batch from Philips 7T PPU data
% run GE example and extract physio

pathPhysioPublic = fullfile(fileparts(mfilename('fullpath')), '..', '..', '..');
pathExamples =  fullfile(pathPhysioPublic, '..', 'examples');

pathCurrentExample = fullfile(pathExamples, 'Philips/PPU7T');
cd(pathCurrentExample); % for prepending absolute paths correctly
fileExample = fullfile(pathCurrentExample, 'philips_ppu7t_spm_job.m');
run(fileExample); % retrieve matlabbatch

% remove unnecessary verbosity and processing of resp data
matlabbatch{1}.spm.tools.physio.verbose.level = 0;
matlabbatch{1}.spm.tools.physio.log_files.respiration = {''};

physio = tapas_physio_job2physio(matlabbatch{1}.spm.tools.physio);

%% Run and test for cheby2 filter
physio.preproc.cardiac.filter.type = 'cheby2';
physio.preproc.cardiac.filter.include = 1;
physio.preproc.cardiac.filter.passband = [0.5 3];
physio.preproc.cardiac.filter.stopband = [0.4 3.9];
actPhysio = tapas_physio_main_create_regressors(physio);

% load physio from reference data
fileReferenceData = fullfile(pathExamples, 'TestReferenceResults', 'preproc', ...
    'physio_filter_cardiac_cheby2.mat');
load(fileReferenceData, 'physio');
expPhysio = physio;

% extract cpulse from actual and expected solution and compare
actSolution = actPhysio.ons_secs.c;
expSolution = expPhysio.ons_secs.c;

verifyEqual(testCase, actSolution, expSolution);
end

function test_philips_ppu7t_filter_butter(testCase)
%% Compares previously saved butterworth-filtered cropped cardiac time course
% with current re-run of same batch from Philips 7T PPU data

% run GE example and extract physio
pathPhysioPublic = fullfile(fileparts(mfilename('fullpath')), '..', '..', '..');
% TODO: Make generic!
pathExamples =  fullfile(pathPhysioPublic, '..', 'examples');

pathCurrentExample = fullfile(pathExamples, 'Philips/PPU7T');
cd(pathCurrentExample); % for prepending absolute paths correctly
fileExample = fullfile(pathCurrentExample, 'philips_ppu7t_spm_job.m');
run(fileExample); % retrieve matlabbatch

% remove unnecessary verbosity and processing of resp data
matlabbatch{1}.spm.tools.physio.verbose.level = 0;
matlabbatch{1}.spm.tools.physio.log_files.respiration = {''};

physio = tapas_physio_job2physio(matlabbatch{1}.spm.tools.physio);

%% run and test for butterworth filter
physio.preproc.cardiac.filter.include = 1;
physio.preproc.cardiac.filter.type = 'butter';
physio.preproc.cardiac.filter.passband = [0.6 3];
physio.preproc.cardiac.filter.stopband = [];
actPhysio = tapas_physio_main_create_regressors(physio);

% load physio from reference data
fileReferenceData = fullfile(pathExamples, 'TestReferenceResults', 'preproc', ...
    'physio_filter_cardiac_butter.mat');
load(fileReferenceData, 'physio');
expPhysio = physio;

% extract cpulse from actual and expected solution and compare
actSolution = actPhysio.ons_secs.c;
expSolution = expPhysio.ons_secs.c;

verifyEqual(testCase, actSolution, expSolution);
end


function hmObj = buildHeadModel(eeg,surfFile,templateFile,plotModel,scalingFactor)
% surfFile is the path to the output surface file that will be generated
% templateFile is the path to an existing template file

% electrode locations [X Y Z]
elocs   = [[eeg.chanlocs.X]' [eeg.chanlocs.Y]' [eeg.chanlocs.Z]']*scalingFactor;
labels  = {eeg.chanlocs.labels};

% remove any electrodes which lack locations
unknownLocs = find(arrayfun(@(x) isempty(x.X), eeg.chanlocs));
if ~isempty(unknownLocs)
    lbl = cellfun(@(x) [x ', '],labels(unknownLocs),'UniformOutput',false);
    lbl{end} = lbl{end}(1:end-2);
    fprintf('Electrodes [%s] do not have locations. Removing...\n',char(lbl{:})');
    labels(unknownLocs) = [];
end

%
% % build the head model object
% hmObj = headModel('surfaces',surfFile,'atlas',template.atlas,'fiducials',template.fiducials,'channelSpace',elocs,'label',labels);
% if plotModel
%     plotHeadModel(hmObj);
% end

hmObj = headModel('channelSpace',elocs,'label',labels);
hmObj.warpTemplate2channelSpace(templateFile,surfFile);
% hmObj.warpChannelSpace2Template(templateFile,surfFile);

if plotModel
    plotHeadModel(hmObj);
end

%% solving the forward problem with OpenMEEG
conductivity = [0.33 0.022 0.33]; % brain and scalp = 0.33 S/m, skull = 0.022 S/m; these conductivies were taken from
                                  % Valdes-Hernandez et al., 2009, Oostendrop TF, 2000; Wendel and Malmivuo, 2006
normal2surface = true;
hmObj.computeLeadFieldBEM(conductivity,normal2surface);


function test_ft_headmovement

% MEM 3gb
% WALLTIME 00:20:00
% DEPENDENCY ft_headmovement

dataset = dccnpath('/home/common/matlab/fieldtrip/data/ftp/test/ctf/SubjectRest.ds');

cfg = [];
cfg.dataset = dataset;
cfg.method  = 'updatesens';
data1 = ft_headmovement(cfg);

cfg = [];
cfg.dataset = dataset;
cfg.method = 'cluster';
cfg.numclusters = 10;
data2 = cell(1,cfg.numclusters);
[data2{:}] = ft_headmovement(cfg);

cfg          = [];
cfg.dataset  = dataset;
cfg.trl      = [(1:1000:100000)' (1000:1000:100000)'];
cfg.trl(:,3) = 0;
cfg.method = 'pertrial_cluster';
cfg.numclusters = 10;
data3 = cell(1,cfg.numclusters);
[data3{:}] = ft_headmovement(cfg);

cfg         = [];
cfg.dataset = dataset;
cfg.trl      = [(1:1000:100000)' (1000:1000:100000)'];
cfg.trl(:,3) = 0;
cfg.method  = 'avgoverrpt';
data4 = ft_headmovement(cfg);


function aux_MLS(params, hParentFigure)
% function aux_MLS(params, hParentFigure);
%-------------------------------------------
% Function to plot the best fitting model of seismicity variation parameters using the maximum likelihood score determination
%
% Incoming variables:
% params        : all variables
% hParentFigure : Handle of the parent figure
%
% J.Woessner, woessner@seismo.ifg.ethz.ch
% last update: 04.11.02

% Get the axes handle of the plotwindow
axes(sv_result('GetAxesHandle', hParentFigure, [], guidata(hParentFigure)));
hold on;
% Select a point in the plot window with the mouse
[fX, fY] = ginput(1);
disp(['X: ' num2str(fX) ' Y: ' num2str(fY)]);
% Plot a small circle at the chosen place
plot(fX,fY,'ok');

% Get closest gridnode for the chosen point on the map
[fXGridNode fYGridNode,  nNodeGridPoint] = calc_ClosestGridNode(params.mPolygon, fX, fY);
plot(fXGridNode, fYGridNode, '*r');
hold off;

% Get the data for the grid node
mNodeCatalog_ = params.mCatalog(params.caNodeIndices{nNodeGridPoint}, :);
%%%% Doe: Determine next grid point and earthquakes associated with it %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

params.fTimePeriod = params.fTimePeriod/365;
% Split the gridpoint catalog according to the defined Splittime
[mFirstCatalog, mSecondCatalog, fFirstPeriodExact, fSecondPeriodExact, fFirstPeriod,...
        result.fSecondPeriod] = ex_SplitCatalog(mNodeCatalog_, params.fSplitTime, params.bTimePeriod,...
    params.fTimePeriod, params.bTimePeriod, params.fTimePeriod);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Start First Plot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

nModel = params.mValueGrid(nNodeGridPoint,6)
switch nModel
case 1
    [fProb_nochange, fBic_nochange] = calc_loglikelihood_nochange(mFirstCatalog, mSecondCatalog);
    sTxt_nochange = ['No change!']
case 2
    [fdM, fProb_dM, fBic_dM, mLikeli_dM] = calc_loglikelihood_dM(mFirstCatalog, mSecondCatalog);
    plot_mls1p(mLikeli_dM(:,1), mLikeli_dM(:,2), 1);
    fdM = fdM;
    sTxt_dM = ['Simple magnitude shift: dM = ' num2str(fdM) ' , '...
            ' Max. likelihood score = ' num2str(fProb_dM) ' , BIC = ' num2str(fBic_dM)]
case 3
    [fS, fProb_stretch, fBic_stretch, mLikeli_dS] = calc_loglikelihood_stretch(mFirstCatalog, mSecondCatalog);
    plot_mls1p(mLikeli_dS(:,1), mLikeli_dS(:,2), 2);
    fdS = fS;
    sTxt_stretch = ['Magnitude stretch: c = ' num2str(fS) ' , '...
            ' Max. likelihood score = ' num2str(fProb_stretch) ' , BIC = ' num2str(fBic_stretch)]
case 4
    [fFac, fProb_Rate, fBic_Rate, mLikeli_Rate] = calc_loglikelihood_rate(mFirstCatalog, mSecondCatalog);
    plot_mls1p(mLikeli_Rate(:,1), mLikeli_Rate(:,2), 3);
    fRf = fFac;
    sTxt_rate = ['Rate change: R_f = ' num2str(fFac) ' , '...
            ' Max. likelihood score = ' num2str(fProb_Rate) ' , BIC = ' num2str(fBic_Rate)]
case 5
    [fdM_rate, fdM_Fac, fProb_dMrate, fBic_dMrate, mLikeli_dMrate] = calc_loglikelihood_dM_rate(mFirstCatalog, mSecondCatalog);
    plot_mls2p(mLikeli_dMrate(:,1), mLikeli_dMrate(:,2), mLikeli_dMrate(:,3),3);
    fdM = fdM_rate;
    fRf = fdM_Fac;
    sTxt_dMrate = ['Magnitude shift and rate change: dM = ' num2str(fdM_rate) ' , R_f =' num2str(fdM_Fac) ' , '...
            ' Max. likelihood score = ' num2str(fProb_dM) ' , BIC = ' num2str(fBic_dMrate)]
case 6
    [fdM_st, fStretch, fProb_Trans, fBic_Trans, mLikeli_Trans] = calc_loglikelihood_Trans(mFirstCatalog, mSecondCatalog);
    plot_mls2p(mLikeli_Trans(:,1), mLikeli_Trans(:,2), mLikeli_Trans(:,3), 1);
    fdM = fdM_st;
    fdS = fStretch;
    sTxt_Trans = ['Magnitude transformation: c = ' num2str(fStretch) ' , dM_st = ' num2str(fdM_st) ' , '...
            ' Max. likelihood score = ' num2str(fProb_Trans) ' , BIC = ' num2str(fBic_Trans)]
case 7
    [fdS_rate, fdS_Fac, fProb_dSrate, fBic_dSrate mLikeli_dSrate] = calc_loglikelihood_stretch_rate(mFirstCatalog, mSecondCatalog);
    plot_mls2p(mLikeli_dSrate(:,1), mLikeli_dSrate(:,2), mLikeli_dSrate(:,3), 2);
    fdS = fdS_rate;
    fRf = fdS_Fac;
    sTxt_dSrate = ['Stretch and rate change: c = ' num2str(fdS_rate) ' , R_f =' num2str(fdS_Fac) ' , '...
            ' Max. likelihood score = ' num2str(fProb_dSrate) ' , BIC = ' num2str(fBic_dSrate)]
case 8
    [fdM_all, fdS_all, fFac_all, fProb_all, fBic_all, mLikeli_all] = calc_loglikelihood_dMdSrate(mFirstCatalog, mSecondCatalog);
    plot_mls3p(mLikeli_all(:,1), mLikeli_all(:,2), mLikeli_all(:,3), mLikeli_all(:,4));
    fdM = fdM_all;
    fdS = fdS_all;
    fRf = fFac_all;
    sTxt_dSdMrate = ['Shift, Stretch and Rate change: dM = ' num2str(fdM_all) ' , c = ' num2str(fdS_all) ' , R_f =' num2str(fFac_all) ' , '...
            ' Max. likelihood score = ' num2str(fProb_all) ' , BIC = ' num2str(fBic_all)]
otherwise
    errordlg('No model chosen','Model error');
    return;
end
% Plot model
plot_svmodel(fdM, fdS, fRf, mFirstCatalog, mSecondCatalog);

% Determine all Bics and show
[fProb_nochange, fBic_nochange] = calc_loglikelihood_nochange(mFirstCatalog, mSecondCatalog);
[fdM, fProb_dM, fBic_dM, mLikeli_dM] = calc_loglikelihood_dM(mFirstCatalog, mSecondCatalog);
[fS, fProb_stretch, fBic_stretch, mLikeli_dS] = calc_loglikelihood_stretch(mFirstCatalog, mSecondCatalog);
[fFac, fProb_Rate, fBic_Rate, mLikeli_Rate] = calc_loglikelihood_rate(mFirstCatalog, mSecondCatalog);
[fdM_rate, fdM_Fac, fProb_dMrate, fBic_dMrate, mLikeli_dMrate] = calc_loglikelihood_dM_rate(mFirstCatalog, mSecondCatalog);
[fdS_rate, fdS_Fac, fProb_dSrate, fBic_dSrate mLikeli_dSrate] = calc_loglikelihood_stretch_rate(mFirstCatalog, mSecondCatalog);
[fdM_st, fStretch, fProb_Trans, fBic_Trans, mLikeli_Trans] = calc_loglikelihood_Trans(mFirstCatalog, mSecondCatalog);
[fdM_all, fdS_all, fFac_all, fProb_all, fBic_all, mLikeli_all] = calc_loglikelihood_dMdSrate(mFirstCatalog, mSecondCatalog);

vBic = [fBic_nochange; fBic_dM; fBic_stretch; fBic_Rate; fBic_dMrate;  fBic_Trans; fBic_dSrate; fBic_all]


% This file should NOT change when run through MBeautify
% If you find anything that is difficult or failed in some MBeautify
% version, please add it here.

% unary operator testcases

+2
+2.
+.2
'   string  with  lots  of  spaces   '
1 + 2
f(+1) + 1

x = y
x + 1. + 2
x + 1. + +.1
x + 1 + 2
x = 1
x = -1
x = +1
x = +.1
+(-[-.1])
z = [1, 2, 3, 4]

if 1 > +2
    return
end; % comment +-+-+- +++ 123 ***
if 1 > -2
end
% different meanings of 'end'
if any(z == -[-1, -2, -3, -4])
    ifmyvariablenamecontainsif = z(1:end);
end

% old-style function calls
disp +end+ this is not any keyword if else endif while +1
% bracket handling
while (1)
    a = [0, 1];
    a(1) = 2 * [a(0)];
    break
end;

% transpose
-x' + +1 + x'' + 2 * x''' * 1
a = eye(27)
a(3, 4:5) = [3, 1]

% norm notation
1.e-6

% #36
a(1, 1:2) = [3, 1]
a(3, :) = [3, 1]
b = zeros(3, 3, 3);
b(:, :, 2) = rand(2, 2);

 %if AddCommasToMatrices=1
a=[@(x) minus(x,1),]

%if AddCommasToCellArrays=1
a={@(x) minus(x,1),  @(x,y) minus(x,y)}

% #34
if -1 > -2
end
if +1 > -2
end

% #59
a = [1, 2, 3];
a = [1, a...
.* 2]

% #58
a = [1, a ... % 111
    .* 2, ... % 222
    123, 4- ...
    5] % 333

a = {'', ... % hello
    1, 4+ ... %hello2
     2} % hello3

if true || ... % aaa
        true || ... asd
        false % //
end

%80
a + sprintf("%d", b)%comment
a + sprintf("'%d'", b) %comment
a + sprintf("""%d""", b) % comment
a + sprintf('"%d"', b)
a.' + sprintf('''%d''', b)
a' + sprintf('%d', b)

% Remove extra space after @
f = @ (x) a
% Remove extra space before unary operator
f = @(x) - a
num@MySuper(obj) - a
% remove spaces around @
num @ MySuper(obj) - a

% if AddCommasToMatrices=1
% add comma after b
[a, - b c + d]
% add comma before b
[a -b]
% one comma added after b
[a *b (c -d)]

% treat whitespace as delimiter regardless of AddCommasToMatrices
[1 (2) {3}]
% same for cells
{1 (2) {3}}


function [a] = sortrow(a)
% a=ceil(rand(10,4)*3);
a=sortrows(a,1);
tmp=unique(a(:,1));
tmp_count=histc(a(:,1),tmp);
start_box=0;
end_box=0;
i=1;
startloc=1;
endloc=0;
while(i<length(tmp_count)+1)
    endloc=endloc+tmp_count(i);
    if tmp_count(i)>1
      a(startloc:endloc,:) = sortrows(a(startloc:endloc,:),2);
      start_box=[start_box startloc];
      end_box=[end_box endloc];
    end
    startloc=startloc+tmp_count(i);
    i=i+1;
end
for i=2:length(start_box)
    tmp=unique(a(start_box(i):end_box(i),2));
    tmp_count=histc(a(start_box(i):end_box(i),2),tmp);
    ii=1;
    startloc=start_box(i);
    endloc=start_box(i)-1;
    while(ii<length(tmp_count)+1)
    endloc=endloc+tmp_count(ii);
    if tmp_count(ii)>1
      a(startloc:endloc,:) = sortrows(a(startloc:endloc,:),3);
    end
    startloc=startloc+tmp_count(ii);
    ii=ii+1;
    end
end


function [iclust, lambda, lambda0] = getIclust(stat, cl)

iclust = zeros(cl.Ly, cl.Lx);
lambda = zeros(cl.Ly, cl.Lx);
lambda0 = zeros(cl.Ly, cl.Lx);

for j = 1:numel(stat)
   ipix = stat(j).ipix(:);

   inew = stat(j).lam(:)>lambda(ipix) + 1e-6;
%    lambda(ipix(inew)) = stat(j).lam(inew);
%    lambda0(ipix(inew)) = stat(j).lambda(inew);

   lambda(ipix(inew)) = stat(j).lam(inew);
   lambda0(ipix(inew)) = stat(j).lam(inew);

   iclust(ipix(inew)) = j;
end


%% patch2obj
% Below is a demonstration of the features of the |patch2obj| function

%%
clear; close all; clc;

%% Syntax
% |patch2obj(objFileName,F,V);|
% |patch2obj(objFileName,F,V,C);|
% |patch2obj(objFileName,F,V,C,cMap);|
% |patch2obj(objFileName,F,V,C,cMap,cLim);|
% |patch2obj(objFileName,F,V,C,cMap,cLim,mtlStruct);|

%% Description
% This function exports the patch data defined by the faces (F), vertices
% (V) and the color data (C) to the OBJ (Wavefront .obj) format. The
% function generates a .obj file, a .mtl file, and a .jpg image file. The
% .obj file contains the geometry information and texture/color coordinates
% to use. The .mtl file contains the material information and refers to the
% image to use to look up the colors based on the texture coordinates in
% the .obj file.
% The color data C should ideally define either the vertex or face colors
% in the form of an nx1 array. If face colors are provided these are
% re-sampled (averaged) to vertex colors which is the required format for
% OBJ files. Colors are obtained from the input color map as well as the
% color limits. The input structure mtlStruct defines the MTL file
% components. With the default entries:
%
% mtlStruct.Ka=[1 1 1]; %Ambient color
% mtlStruct.Kd=[1 1 1]; %Diffuse color
% mtlStruct.Ks=[0 0 0]; %Specular color, black=off
% mtlStruct.Ns=0; %Specular component [0-1000]
% mtlStruct.Ni=1.45; %Optical density/index of refraction
% mtlStruct.d=1; %"dissolved"/transparancy [0-1]
% mtlStruct.Tr=0; %1 - d, used instead of d by some software
% mtlStruct.illum=1; %Illumination model
%
% Illumination models:
% 0. Color on and Ambient off
% 1. Color on and Ambient on
% 2. Highlight on
% 3. Reflection on and Ray trace on
% 4. Transparency: Glass on, Reflection: Ray trace on
% 5. Reflection: Fresnel on and Ray trace on
% 6. Transparency: Refraction on, Reflection: Fresnel off and Ray trace on
% 7. Transparency: Refraction on, Reflection: Fresnel on and Ray trace on
% 8. Reflection on and Ray trace off
% 9. Transparency: Glass on, Reflection: Ray trace off
% 10. Casts shadows onto invisible surfaces
%
%
% For more information on the OBJ file format see:
% https://en.wikipedia.org/wiki/Wavefront_.obj_file
% http://paulbourke.net/dataformats/obj/minobj.html

%% EXAMPLES

clear; close all; clc;

%% Example 1: Export colored patch data to the OBJ format

%Define patch data
testCase=1;
switch testCase
    case 1 %David
        [F,V]=graphicsModels(9);
        t=V(:,1)-min(V(:,1));
        t=t./max(t(:));
        C=sin(2*t*2*pi);
        C=abs(C);
        cMap=gjet(250); %Define colormap
    case 2
        [X,Y,Z]=peaks(25);
        [F,V,~]=grid2patch(X,Y,Z,Z);
        C=V(:,3);
        cMap=turbo(250); %Define colormap
    case 3 %Femur
        [F,V]=graphicsModels(5);
        C=V(:,1);
        cMap=turbo(250); %Define colormap
    case 4
        [F,V]=stanford_bunny;
        C=V(:,1);
        cMap=viridis(250); %Define colormap
end

%Define file name
gibbonFolder = fileparts(fileparts(mfilename('fullpath')));
savePath=fullfile(gibbonFolder,'data','OBJ');

fileName=fullfile(savePath,'test.obj');

%%
% Visualiza patch data

cFigure; hold on;
title('MATLAB patch','FontSize',25);
hp=gpatch(F,V,C,'none'); hp.FaceColor='interp';
axisGeom;
colormap(cMap);
camlight headlight;
gdrawnow;

%%
% Export to obj

patch2obj(fileName,F,V,C,cMap);

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


function pixels = makebitmap(y, width, height, ThreeDee)
% Copyright (c) 2009, The MathWorks, Inc.
%
% Creates a bitmap image of marix y
% Size of the bitmap is determined by arguments
% width and height, and more (2D or 3D visualization)
% by argument ThreeDee.

persistent bitmapHandle;

if ishandle(bitmapHandle)
    % if figure exists, use that for plotting
    figure(bitmapHandle);
    cla;
else
    % create figure if it doesn't exist
    bitmapHandle = figure('Visible', 'off');
    set(bitmapHandle, 'Color', [1 1 1]);
    set(bitmapHandle, 'PaperPositionMode', 'auto');
end;
set(bitmapHandle, 'Visible', 'off');

% Store figure location
a = get(bitmapHandle, 'Position');
a(3) = width;
a(4) = height;

if ThreeDee
    surf(y);
else
    plot(y);
end;

axis tight;
% Resize figure
set(bitmapHandle, 'Position', a);
pixels = hardcopy(bitmapHandle,'-dOpenGL','-r0');
% Size of the bitmap produced by hardcopy may be larger than that
% specified by the figure width & height.
% Figure is transposed to get the correct bitmap orientation for .ToVector
for i = 3:-1:1,
    pixs(:,:,i) = pixels(1:height,1:width,i)'; %#ok : not growing
end;
pixels = pixs(:); % In order to use .ToVector in C#


function spy(disc, varargin)
%TODO: Either remove this method, or uncomment lines below and ensure this
%method works. The following is broken:
%   D = chebop(@(x,u) diff(u));
%   spy(chebcolloc2(linop(D)))

error('CHEBFUN:OPDISCRETIZATION:spy:noSupported', ...
    'OPDISCRETIZATION currently does not support spy().');
end
% %SPY    Visualize a LINOP.
% %   SPY(DISC) creates a picture of the nonzero pattern of the given LiNOP
% %   discretization DISC. Block boundaries are indicated by gray lines, and
% %   side condition rows are marked off by dashed lines (boundary and
% %   continuity conditions).
% %
% %   SPY(DISC,DIM) uses the dimension vector DIM to override the dimension
% %   property of DISC.
% %
% %   SPY(DISC,S) or SPY(DISC,DIM,S) allows modification of the plot
% %   attributes, as with the built in method.
% %
% % See also LINOP.SPY.
%
% % Copyright 2017 by The University of Oxford and The Chebfun Developers.
% % See http://www.chebfun.org for Chebfun information.
%
% % Obtain domain information.
% dom = disc.domain;
%
% % Parse the inputs:
% if ( ( nargin > 1 ) && isnumeric(varargin{1}) )
%     dim = varargin{1};
%     if ( numel(dim) == 1 )
%         % Scalar expand the dimension here.
%         dim = repmat(dim, 1, length(dom) - 1);
%     end
%
%     disc.dimension = dim;
%     varargin = varargin(2:end);
% end
% dim = disc.dimension;
%
% plotOpt = varargin;
%
% % Override hold state.
% holdState = ishold;
%
% % Check whether we need to derive continuity conditions.
% L = disc.source;
% if ( isempty(L.continuity) )
%     L = deriveContinuity(L, dom);
% end
% disc.source = L;
%
% % Spy the matrix, with a useful label.
% data = matrix(disc);
% spy(data, plotOpt{:}), hold on
% s =  sprintf('%i,', disc.dimension);    % list of sizes
% s = [ 'discretization = [', s(1:end-1), ']' ];
% xlabel(s)
%
% % Find the number of constraints and continuity conditions
% nbc = length(L.constraint);
% ncon = length(L.continuity);
% numInts = numel(dom) - 1;
%
% % Find all block sizes, substituting in the discretization size for Inf.
% [m, n] = blockSizes(L);
% m(isinf(m)) = sum(dim);
% n(isinf(n)) = sum(dim) + numInts*disc.dimAdjust(isinf(n));
%
% % Draw vertical block boundaries.
% cscol = cumsum(n(1,:));
% coldiv = cscol(1:end-1) + 1/2;
% rowmax = size(data, 1);
% plot([coldiv ; coldiv], [ 0; rowmax+1]*ones(size(coldiv)), 'color', [.6 .6 .6])
%
% % Draw horizontal block boundaries. Account for the down-sampling of each row.
% csrow = cumsum( m(:, 1)');                          % remove down-sampling
% rowdiv = csrow(1:end - 1) + 1/2;                    % boundary after each block
% rowdiv = nbc + ncon + rowdiv;                       % offset from top rows
% colmax = size(data, 2);
% % plot([0; colmax+1]*ones(size(rowdiv)), [rowdiv; rowdiv], 'color', [.6 .6 .6])
%
% % Draw horizontal BC and continuity boundaries.
% y = nbc + 1/2;
% plot([0; colmax+1], [y; y], '--', 'color', [.6 .6 .6])
% if ( ncon > 0 )
%     plot([0; colmax + 1], [y + ncon; y + ncon], '--', 'color', [.6 .6 .6])
% end
%
% % Reset hold state.
% if ( ~holdState )
%     hold off
% end
%
% end
%


function [cerrFeatS,pyFeatS] = computeRadiomicsFromCERRAndPyrad(planC,structNum,...
    cerrParamFilePath,pyParamFilePath)
%
% function [cerrFeatS,pyFeatS] = computeRadiomicsFromCERRAndPyrad(planC,structNum,...
%     cerrParamFilePath,pyParamFilePath)
%
% This function returns radiomics features from CERR and PyRadiomics.
% planC: CERR's planC data structure.
% structNum: Structure index in planC to compute radiomics.
% cerrParamFilePath: Radiomics settings for CERR.
% pyParamFilePath: Radiomics settings for PyRadiomics.
%
% This routine assumes that PyRadiomics and SciPy are already added to Python path.
% For example, on Windows OS
% P = py.sys.path;
% insert(P,int64(0),'C:\Program Files\Python37\Lib\site-packages\radiomics');
% P = py.sys.path;
% insert(P,int64(0),'C:\Program Files\Python37\Lib\site-packages\scipy');

%------------------------------------------------------------------------
% APA 01/08/2022

%% 1. Compute features using CERR
% cerrParamFilePath = fullfile(fileparts(fileparts(getCERRPath)),...
%             'Unit_Testing/settings_for_comparisons/cerrOrigNoInterp.json');
paramS = getRadiomicsParamTemplate(cerrParamFilePath);

% strC = {planC{indexS.structures}.structureName};
% structNum = getMatchingIndex(paramS.structuresC{1},strC,'exact');
scanNum = getStructureAssociatedScan(structNum,planC);
cerrFeatS = calcGlobalRadiomicsFeatures...
    (scanNum, structNum, paramS, planC);

filtName = 'Original';

%% 2. Compute features using Pyradiomics
% pyParamFilePath = fullfile(fileparts(fileparts(getCERRPath)),...
%             'Unit_Testing/settings_for_comparisons/pyOrigNoInterp.yaml');
% pyParamFilePath = 'L:\Aditya\forJung\TCIA_Jung\features_1_6_2022\pyOrigWithInterp.yaml';
pyCalcS = calcRadiomicsFeatUsingPyradiomics(planC,structNum,pyParamFilePath);

%Map to cerr fieldnames
pyFeatS = struct();

% First-order
pyFirstOrdFeatS = getPyradFeatDict(pyCalcS,{['original','_firstorder']});
pyFirstOrdFeatS = mapPyradFieldnames(pyFirstOrdFeatS,'original','firstorder');
pyFeatS.(filtName).firstOrderS = pyFirstOrdFeatS;

% GLCM
pyGlcmFeatS = getPyradFeatDict(pyCalcS,{['original','_glcm']});
pyGlcmFeatS = mapPyradFieldnames(pyGlcmFeatS,'original','glcm');
pyFeatS.(filtName).glcmFeatS = pyGlcmFeatS;

% GLRLM
pyGlrlmFeatS = getPyradFeatDict(pyCalcS,{['original','_glrlm']});
pyGlrlmFeatS = mapPyradFieldnames(pyGlrlmFeatS,'original','glrlm');
pyFeatS.(filtName).rlmFeatS = pyGlrlmFeatS;

% NGLDM
pyGldmFeatS = getPyradFeatDict(pyCalcS,{['original','_gldm']});
pyGldmFeatS = mapPyradFieldnames(pyGldmFeatS,'original','ngldm');
pyFeatS.(filtName).ngldmFeatS = pyGldmFeatS;

%GLSZM
pyGlszmFeatS = getPyradFeatDict(pyCalcS,{['original','_glszm']});
pyGlszmFeatS = mapPyradFieldnames(pyGlszmFeatS,'original','glszm');
pyFeatS.(filtName).szmFeatS = pyGlszmFeatS;

end


clear
% define the root name of database
root = '../data_preparation/prepared_data/';

% which scales we're doing
sigma = 1;
num_samples = 2e6;

scales = [0.25,0.35,0.5,1.0];
frontalView = 1;

profileViewInds = [2];

version = 'wild';
ratio_neg = 10;
norm = 1;

data_loc = 'wild_';
rng(0);

% where to save generated patches for external training
% (e.g. for training CEN patches)
patches_loc = './patches/';
patch_folder = [patches_loc version '/'];

for s=scales
    Save_all_patches(root, frontalView, profileViewInds,...
        s, sigma, version, patch_folder, 'ratio_neg', ratio_neg,...
        'num_samples', num_samples, 'data_loc', data_loc,...
        'normalisation_size', 19);
end


% DEMCMU35SEQUENCEOPTIMISE

% FGPLVM

% Fix seeds
randn('seed', 1e5);
rand('seed', 1e5);

dataSetName = 'cmu35gplvm';

% load data
[Y, lbls, Ytest, lblstest] = lvmLoadData(dataSetName);
skel = acclaimReadSkel('35.asf');
[tmpchan, skel] = acclaimLoadChannels('35_01.amc', skel);

% REMOVE LEG TEST
% Indices associated with right leg.
legInd = [8:14];
% Indices associated with upper body.
bodyInd = [21:50];

% Load saved model.
capName = dataSetName;
capName(1) = upper(capName(1));

for experimentNo = 1:3;
  load(['dem' capName num2str(experimentNo) '.mat']);
  for missing = 1:2
    if missing==1
      type = 'Leg';
      missingInd = legInd;
    else
      type = 'Body';
      missingInd = bodyInd;
    end
    if exist(['dem' capName 'Yvals' type num2str(experimentNo) '.mat'], 'file')==2
      load(['dem' capName 'Yvals' type num2str(experimentNo) '.mat'])
    else
      disp('Reconstructing ...');
      startInd = 63;

      Ytest(startInd:end, missingInd) = NaN;
      model = gpComputeAlpha(model);
      ll = [];
      for j = 1:size(model.X_u, 1)
        for i = 1:size(Ytest, 1);
          ll(i, j) = fgplvmPointLogLikelihood(model, model.X_u(j, :), ...
                                              Ytest(i, :));
        end
      end
      [void, ind] = max(ll, [], 2);
      Xinit = model.X_u(ind, :);
      Xpred = fgplvmOptimiseSequence(model, Xinit, Ytest, 1, 1000);
      Xpred = Xpred(startInd:end, :);
      Ytest = Ytest(startInd:end, :);
      Ypred = gpOut(model, Xpred);

      save(['dem' capName 'Yvals' type num2str(experimentNo) '.mat'], ...
           'Xpred', 'Ypred');
    end
  end
end


function output = calllmirank(interfacedata)

% Retrieve needed data
options = interfacedata.options;
F_struc = interfacedata.F_struc;
c       = interfacedata.c;
K       = interfacedata.K;
x0      = interfacedata.x0;
ub      = interfacedata.ub;
lb      = interfacedata.lb;

% Bounded variables converted to constraints
if ~isempty(ub)
    [F_struc,K] = addStructureBounds(F_struc,K,ub,lb);
end

pars = options.lmirank;
pars.fid = double(options.verbose);

if ~options.warmstart
    interfacedata.options.verbose =  max(0,interfacedata.options.verbose - 1);
    initialsolver = eval(['@' interfacedata.solver.initialsolver.call]);
    start = K.l;
    b = zeros(size(F_struc,2)-1,1);
    for j=1:length(K.s)
        if K.s(j)~=K.rank(j)
            ind = find(speye(K.s(j)));
            for i=1:size(F_struc,2)-1
                b(i,1) = b(i,1) + sum(F_struc(start+ind,1+i));
            end
        end
        start=start+K.s(j)^2;
    end
    interfacedata.c = b;
    interfacedata.solver = interfacedata.solver.initialsolver;
    output = feval(initialsolver,interfacedata);
    if output.problem ~= 1
        options.warmstart = 1;
        x0 = output.Primal;
    else
        return;
    end
end

if options.savedebug
    At = -F_struc(:,2:end);
    C  = F_struc(:,1);
    save lmirankdebug C At K pars x0
end

if options.showprogress;showprogress(['Calling ' interfacedata.solver.tag],options.showprogress);end
solvertime = tic;
if options.warmstart
    [y,info] = lmirank(-F_struc(:,2:end),F_struc(:,1),K,pars,x0);
else
    [y,info] = lmirank(-F_struc(:,2:end),F_struc(:,1),K,pars);
end
solvertime = toc(solvertime);
x = y;

switch info.solved
    case 1
        problem = 0;
    otherwise
        problem = 11;
end

% Save ALL data sent to solver
if options.savesolverinput
    solverinput.At = -F_struc(:,2:end);
    solverinput.c = F_struc(:,1);
    solverinput.K = K;
    solverinput.pars = pars;
    solverinput.x0 = x0;
else
    solverinput = [];
end

% Save ALL data from the solution?
if options.savesolveroutput
    solveroutput.y = y;
    solveroutput.info = info;
else
    solveroutput = [];
end

% Standard interface
output = createOutputStructure(x,[],[],problem,interfacedata.solver.tag,solverinput,solveroutput,solvertime);


filename='Gripping_tetrahedra_fine';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'nonadjoint_compliance'};
weights = [1, 0.1];
constraint = {'volumeConstraint'};
constraint_case = 'INEQUALITY';
optimizer = 'IPOPT'; incrementFactor = 1;
filterType = 'P1';

nsteps = 1;
Vfrac_final = 0.2;
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 [XYZ, Z, M] = pr_get_spm_results
% Fetch SPM results and return as point list
% FORMAT [XYZ, Z, M] = pr_get_spm_results
%
% Outputs
% XYZ    - XYZ point list in voxels (empty if not found)
% Z      - values at points in XYZ
% M      - 4x4 voxel -> world transformation matrix
%__________________________________________________________________________

% Matthew Brett
% $Id: pr_get_spm_results.m 6623 2015-12-03 18:38:08Z guillaume $

errstr = '''Cannot find SPM results in workspace''';
[XYZ,Z,M] = deal([]);

have_res = evalin('base', 'exist(''xSPM'', ''var'')');
if ~have_res, return, end
xSPM = evalin('base', 'xSPM', ['error(' errstr ')']);
XYZ = xSPM.XYZ;
Z   = xSPM.Z;
M   = xSPM.M;


function A = suma_stitch(imaname)
% A function to put together a series of suma recorder images
% Very crude, only for the intrepid.
% Example: A = suma_stitch('imageseries_');
%The would be the images as spat out by the recorder window after
% a suma 'r' key stroke with SUMA_SnapshotOverSampling > 1

figure(1); clf
[e, em, lst] = zglobb({sprintf('%s*', imaname)});
N_im = length(lst)
N_1 = round(sqrt(N_im))
k=1
figure(1); clf
for (i=1:1:N_1),
   for (j=1:1:N_1),
      %k = ((i-1)+(j-1)*N_1)+1
      lst(k).name
      a = imread(lst(k).name); size(a)
      if (k==1), A = zeros(N_1.*size(a,1), N_1.*size(a,2), size(a,3), 'uint8'); end
      istrt = (N_1-i)*size(a,1) + 1;
      istp = istrt + size(a,1) - 1;
      jstrt = (j-1)*size(a,2) + 1;
      jstp = jstrt + size(a,2) - 1;
      istrt, istp-istrt, jstrt, jstp-jstrt,
      A(istrt:istp,jstrt:jstp,:) = a;
      subplot (N_1, N_1, k); image(a); title(lst(k).name); drawnow;
      k = k +1;
   end
end

figure(2); clf
image(A); axis square;  drawnow
info = imfinfo(lst(1).name);info.Format
imwrite(A, sprintf('%s_stitch.%s', imaname, info.Format), info.Format);


%--- help for mcmc/autocorrplot ---
%
%  Plots autocorrelations of a given parameter
%
%  ::
%
%     hdl=autocorrplot(obj,pname)
%     hdl=autocorrplot(obj,pname,chain_id)
%     hdl=autocorrplot(obj,pname,chain_id,order)
%
%  Args:
%
%     obj (mcmc object): mcmc object
%
%     pname (string): parameter name
%
%     chain_id (integer | {[]}): choice of chain for which to plot the
%       autocorrelation. If empty, all chains are used.
%
%     order (integer | {40}): maximum order of the autocorrelation
%
%  Returns:
%     :
%
%     - **hdl** [integer]: handle to the plot
%
%


function [tArchive,GbestRBF] = UpdateRBF(Problem,tArchive,SwarmRBF,GbestRBF)
% Update solutions in RBF-assisted swarm

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    [N,D] = size(SwarmRBF);
    D     = D - 1;
    [value,best] = min(SwarmRBF(:,1+D));

    new = Problem.Evaluation(SwarmRBF(best,1:D));
    SwarmRBF(best,D+1) = new.objs;
    if new.objs < GbestRBF(:,D+1)
        GbestRBF = SwarmRBF(best,:);
    end
    tArchive = [tArchive,new];

end


function [varargout]=mat2wfdb(varargin)
%
% [xbit]=mat2wfdb(X,fname,Fs,bit_res,adu,info,gain,sg_name,baseline,isquant, isdigital)
%
% Convert data from a matlab array into Physionet WFDB format file.
%
% Input Paramater are:
%
% X       -(required)  NxM matrix of M signals with N samples each. The
%                      signals can be of type double.The signals are assumed to be
%                      in physical units already and will be converted to
%                      ADU.
% fname   -(required)  String where the the header (*.hea) and data (*.dat)
%          files will be saved (one single name for both, with no sufix).
% Fs      -(Optional)  1x1 sampling frequency in Hz (all signals must have
%          been sampled at the same frquency). Default is 1 Hz.
% bit_res -(Optional)  1xM (or Mx1):scalar determining the bit depth of the conversion for
%                      each signal.
%                      1x1 : If all the signals should have the same bit depth
%          Options are: 8,  16, and 32 ( all are signed types). 16 is the default.
% adu     -(Optional) Describes the physical units (default is 'mV').
%          Three input formats:
%            - String delimited by forward slashes (e.g. 'V/mV/mmHg'), with
%            M-1 slash characters
%            - Single string (e.g. 'V'), in which case all signals will
%            have the same physical units.
%            - Cell array of strings, where the total units entered has to equal M
%            (number of channels).
% info    -(Optional)  String that will be added to the comment section of the header file.
%           For multi-lined comments, use a cell array of strings. Each
%           cell will be output on a new line. Note that comments in the
%           header file are automatically prefixed with a pound symbol (#)
% gain    -(Required for digital only) Scalar or Mx1 array of floats indicating the difference in sample values
%           that would be observed if a step of one physical unit occurred in the original
%           analog signal. If the 'isdigital' field is 1, this field is mandatory. Otherwise,
%           this field is ignored if present.
% baseline -(Required for digital only) Mx1 array of integers that specifies the sample value for each channel
%           corresponding to 0 physical units. Not to be confused with 'ADC zero' which
%           is currently always taken and written as 0 in this function. If
%           the 'isdigital' field is 1, this field is mandatory. Otherwise,
%           this field is ignored if present.
% sg_name -(Optional) Cell array of strings describing signal names.
%
% isquant   -(Optional) Logical value (default=0). Use this option if the
%           input signal is already quantitized and you want to remove round-off
%           error by mapping the original values to integers prior to fixed
%           point conversion. This field is only used for input physical
%           signals. If 'isdigital' is set to 1, this field is ignored.
%
% isdigital -(Optional) Logical value (default=0). Specifies whether the input signal is
%            digital or physical (default). If it is digital, the signal values will be
%            directly written to the file without scaling. If the signal is physical,
%            the optimal gain and baseline will be calculated and used to digitize the signal
%            to write the WFDB file. This flag also decides the allowed
%            input combinations of the 'gain' and 'baseline' fields.
%            Digital signals must have both, and physical signals must have
%            neither (as the ideal values will be automatically calculated).
%
% Ouput Parameter:
%
% xbit    -(Optional)  NxM the quantitized signals that written to file (possible
%          rescaled if no gain was provided at input). Useful for comparing
%          and estimating quatitization error with the input double signal X
%          (see examples below).
%
%
%  NOTE: The signals can have different amplitudes, they will all be scaled to
%  a reference gain, with the scaling factor saved in the *.hea file.
%
%Written by Ikaro Silva 2010
%Modified by Louis Mayaud 2011, Alistair Johson 2016
% Version 1.0
%
% Since 0.0.1
% See also wrsamp, wfdbdesc
%
%%%%%%%%%%  Example 1 %%%%%%%%%%%%
%
% display('***This example will write a  Ex1.dat and Ex1.hea file to your current directory!')
% s=input('Hit "ctrl + c" to quit or "Enter" to continue!');
%
% %Generate 3 different signals and convert them to signed 16 bit in WFDB format
% clear all;clc;close all
% N=1024;
% Fs=48000;
% tm=[0:1/Fs:(N-1)/Fs]';
% adu='V/mV/V';
% info='Example 1';
%
%
% %First signal a ramp with 2^16 unique levels and is set to (+-) 2^15 (Volts)
% %Thus the header file should have one quant step equal to (2^15-(-2^15))/(2^16) V.
% sig1=double(int16(linspace(-2^15,2^15,N)'));
%
% %Second signal is a sine wave with 2^8 unique levels and set to (+-) 1 (mV)
% %Thus the header file should one quant step equal a (1--1)/(2^8)  adu step
% sig2=double(int8(sin(2*pi*tm*1000).*(2^7)))./(2^7);
%
% %Third signal is a random binary signal set to to (+-) 1 (V) with DC (to be discarded)
% %Thus the header file should have one quant step equal a 1/(2^15) adu step.
% sig3=(rand(N,1) > 0.97)*2 -1 + 2^16;
%
% %Concatenate all signals and convert to WFDB format with default 16 bits (empty brackets)
% sig=[sig1 sig2 sig3];
% mat2wfdb(sig,'Ex1',Fs,[],adu,info)
%
% % %NOTE: If you have WFDB installed you can check the conversion by
% % %uncomenting and this section and running (notice that all signals are scaled
% % %to unit amplitude during conversion, with the header files keeping the gain info):
%
% % !rdsamp -r Ex1 > foo
% % x=dlmread('foo');
% % subplot(211)
% % plot(sig)
% % subplot(212)
% % plot(x(:,1),x(:,2));hold on;plot(x(:,1),x(:,3),'k');plot(x(:,1),x(:,4),'r')
%
%%%%%%%% End of Example 1%%%%%%%%%

%endOfHelp
machine_format='l'; % all wfdb formats are little endian except fmt 61 which this function does not support. Do NOT change this.
skip=0;

% Set default parameters
params={'x','fname','Fs','bit_res','adu','info','gain','sg_name','baseline','isquant', 'isdigital'};
Fs=1;
adu=[];
info=[];
isquant=0;
isdigital=0;
%Use cell array for baseline and gain in case of empty conditions
baseline=[];
gain=[];
sg_name=[];
x=[];
fname=[];
%Used to convert signal from double to appropiate type
bit_res = 16 ;
bit_res_suport=[8 16 32];

for i=1:nargin
    if(~isempty(varargin{i}))
        eval([params{i} '= varargin{i};']);
    end
end

disp(isdigital);
% Check valid gain and baseline combinations depending on whether the input is digital or physical.
if isdigital % digital input signal
    if (isempty(gain) || isempty(baseline))
        error('Input digital signals are directly written to files without scaling. Must also input gain and baseline for correct interpretation of written file.');
    end
    if (~isempty(find(baseline>2147483647))||~isempty(find(baseline<-2147483648))) % baseline stored as int in wfdb library.
        error('Baseline field must lie between 2^-31 and 2^31-1 for this WFDB version'); % Prevent bit overflow
    end
else % physical input signal
    if ( ~isempty(gain) || ~isempty(baseline)) % User inputs gain or baseline to map the physical to digital values.
        % Sorry, we cannot trust that they did it correctly...
        warning('Input gain and baseline fields ignored for physical input signal. This function automatically calculates and applies the ideal values');
    end
end

switch bit_res % Write formats.
    case 8
        fmt='80';
    case 16
        fmt='16';
    case 32
        fmt='32';
end

[N,M]=size(x);

if isempty(adu) % default unit: 'mV'
    adu=repmat({'mV'},[M 1]);
elseif iscell(adu)
    % adu directly input as a cell array of strings
elseif ischar(adu)
    if ~isempty(strfind(adu,'/'))
        adu=regexp(adu,'/','split');
    else
        adu = repmat({adu},[M,1]);
    end
end

% ensure we have the right number of units
if numel(adu) ~= M
    error('adu:wrongNumberOfElements','adu cell array has incorrect number of elements');
end

if(isempty(gain))
    gain=cell(M,1); %Generate empty cells as default
elseif(length(gain)==1)
    gain=repmat(gain,[M 1]);
end
% ensure gain is a cell array
if isnumeric(gain)
    gain=num2cell(gain);
end

if(isempty(sg_name))
    sg_name=repmat({''},[M 1]);
end
if ~isempty(setdiff(bit_res,bit_res_suport))
    error(['Bit res should be one of: ' num2str(bit_res_suport)]);
end
if(isempty(baseline))
    baseline=cell(M,1); %Generate empty cells as default
elseif(length(baseline)==1)
    baseline=repmat(baseline,[M 1]);
end
% ensure baseline is a cell array
if isnumeric(baseline)
    baseline=num2cell(baseline);
end

if isempty(isquant)
    isquant = zeros(M,1);
elseif numel(isquant)==1
    isquant = repmat(isquant,[M,1]);
elseif numel(isquant)~=M
    error('isquant:wrongNumberOfElements','isquant  array has incorrect number of elements');
end

%Head record specification line
head_str=cell(M+1,1);
head_str(1)={[fname ' ' num2str(M) ' ' num2str(Fs) ' ' num2str(N)]};

switch bit_res % Allocate space for digital signals
    case 8
        y=uint8(zeros(N,M));
    case 16
        y=int16(zeros(N,M));
    case 32
        y=int32(zeros(N,M));
end

%Loop through all signals, digitizing them and generating lines in header file
for m=1:M
    nameArray = regexp(fname,'/','split');
    if ~isempty(nameArray)
        fname = nameArray{end};
    end

    [tmp_bit1,bit_gain,baseline_tmp,ck_sum]=quant(x(:,m), ...
        bit_res, gain{m}, baseline{m}, isquant(m), isdigital);

    y(:,m)=tmp_bit1;

    % Header file signal specification lines
    % Should we specify precision of num2str(gain)?
    head_str(m+1)={[fname '.dat ' fmt ' ' num2str(bit_gain) '(' ...
        num2str(baseline_tmp) ')/' adu{m} ' ' num2str(bit_res) ' 0 ' num2str(tmp_bit1(1)) ' ' num2str(ck_sum) ' 0 ' sg_name{m}]};
end
if(length(y)<1)
    error(['Converted data is empty. Exiting without saving file...']);
end

%Write *.dat file
fid = fopen([fname '.dat'],'wb',machine_format);
if(~fid)
    error(['Could not create data file for writing: ' fname]);
end

if (bit_res==8)
    count=fwrite(fid, y','uint8',skip,machine_format);
else
    count=fwrite(fid, y',['int' num2str(bit_res)],skip,machine_format);
end

if(~count)
    fclose(fid);
    error(['Could not data write to file: ' fname]);
end

fprintf(['Generated *.dat file: ' fname '\n']);
fclose(fid);

%Write *.hea file
fid = fopen([fname '.hea'],'w');
for m=1:M+1
    if(~fid)
        error(['Could not create header file for writing: ' fname]);
    end
    fprintf(fid,'%s\n',head_str{m});
end

if(~isempty(info))
    if ischar(info)
        fprintf(fid,'#%s\n',info);
    elseif iscell(info)
        for m=1:numel(info)
            fprintf(fid,'#%s\n',info{m});
        end
    end
end

if(nargout==1)
    varargout(1)={y};
end
fprintf(['Generated *.hea file: ' fname '\n']);
fclose(fid);

end

%%%End of Main %%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Helper function
function [y,adc_gain,baseline,check_sum]=quant(x, bit_res, gain, baseline, isquant, isdigital)

min_x=min(x(~isnan(x)));
max_x=max(x(~isnan(x)));
nan_ind=isnan(x);
rg=max_x-min_x;

if(isdigital)
    % Digital input signal. Do not scale or shift the signal. The gain/baseline will only
    % be used to write the header file to interpret the output wfdb record.
    if ((min_x < -2^(bit_res-1)+1) || (max_x > (2^(bit_res-1)-1 )))
        error(['Digital input signal exceeds allowed range of specified output format: {' num2str(-2^(bit_res-1)+1) ' < x < ' num2str(2^(bit_res-1)-1) '}']);
    end
    adc_gain=gain;
    y=x;

else
    % Physical input signal - calculate the gain and baseline to minimize
    % the detail loss during ADC conversion: y = gain*x + baseline. Ignore any input gain or baseline

    % Calculate the adc_gain, baseline, and map the signal to digital
    % Make sure baseline doesn't go beyond 4 byte integer range

    if rg==0 % Flatline signal. Manually set adc_gain or it will be infinite.
          baseline=-(2^(bit_res-1))+1; % Set baseline to minimum value of bit res
          if x(1)==0
            adc_gain=1; % Arbitrary gain=1 for all 0 input signal. All values stored as baseline.
          else
            adc_gain=-baseline/x(1); % Set gain as inverse to store all values as exactly 0.
          end

    else % Non flatline signal: adc_gain = (range of encoding / range of Data) -- remember 1 quant level is for storing NaN
        % Constraint - baseline must be stored as a 4 byte integer for the WFDB library.
        if ((min_x>0) && (bit_res==32)) % All values are +ve, map with baseline = -2^31+1
            adc_gain=((2^32)-2)/max_x;
            baseline=-2147483647;
            if isquant==0 % Only display warning message if not recalculating later
                disp('Due to baseline constraints, output precision may be slightly less than 32 bits for the positive channel.');
            end
        elseif((max_x<0) && (bit_res==32)) % All values are -ve, map with baseline = 2^31-1
            adc_gain=((2^32)-2)/abs(min_x);
            baseline=2147483647;
            if isquant==0 % Only display warning message if not recalculating later
                disp('Due to baseline constraints, output precision may be slightly less than 32 bits for the negative channel.');
            end
        else % Signal has both +ve and -ve values or fmt is not 32. Use full range of bits.
            adc_gain=((2^bit_res)-2)/rg;
            baseline=round(-(2^(bit_res-1))+1-min_x*adc_gain);

        end
        if(isquant)
            % The (non flatline) input signal was already quantitized. Remove round-off error
            % by setting the original values to integers prior to fixed point conversion

            xvalues=sort(unique(x(~isnan(x)))); % All the values of x
            incmin=min(diff(xvalues)); % An estimate of the smallest possible increment in the input signal
            quantlevels=rg/incmin; % The estimated number of quantization levels in the input signal

            % We want to map 1 increment to 1 digital unit. First make sure
            % the full increment range is less than the 2^N-2 increments able to be encoded
            % by the chosen bit resolution. The incmin estimate will always
            % be equal to or larger than the true incmin, so it won't
            % wrongly trigger errors in this validation step.

            if (quantlevels>2^bit_res-2)
                if bit_res==32
                    disp(['The input signal has more quantization levels than 32 bits -1. ' ...
                        'Cannot directly map all input values to integers. Up to 1 bit of roundoff error may occur. Continuing...']);
                    calcquant=0; % Skip the integer matching and keep the old baseline/gain calculated.
                else
                    error(['The input signal has more quantization levels than the chosen bit resolution. ' ...
                        'Please choose a higher resolution or remove the isquant option to allow up to 1 bit of roundoff error']);
                end
            else
                calcquant=1;
            end

            % Calculate gain+offset. Baseline must be stored as a 4 byte integer for the WFDB library.
            if calcquant
                if ((min_x>0) && (bit_res==32)) % 32 bit +ve quant mapping
                    adc_gain=1/incmin;
                    baseline=round(2147483647-adc_gain*max_x); % map max_x to 2^31-1.
                    if (baseline<-2147483647) % Check if baseline goes below -2^31-1. If so, no quant. Recalculate gain and base.
                        adc_gain=((2^32)-2)/max_x;
                        baseline=-2147483647;
                        disp('Due to baseline constraints, the channel will not be quantized. Output precision may be less than 32 bits for the positive channel.');
                    end
                elseif((max_x<0) && (bit_res==32)) % 32 bit -ve quant mapping
                    adc_gain=1/incmin;
                    baseline=round(-2147483647-adc_gain*min_x); % map min_x to -2^31+1.
                    if (baseline>2147483647) % Check if baseline goes above 2^31-1. If so, no quant. Recalculate gain and base.
                        adc_gain=((2^32)-2)/abs(min_x);
                        baseline=2147483647;
                        disp('Due to baseline constraints, channel will not be quantized. Output precision may be less than 32 bits for the negative channel.');
                    end
                else % Signal has both +ve and -ve values or fmt is not 32. Can use full range of bits.
                    adc_gain=1/incmin; % 1 digital unit corresponds to the smallest physical increment.
                    baseline=round(-(2^(bit_res-1))+1-min_x*adc_gain); % xmin still maps to ymin. xmax will not go beyond y limit, baseline should not go beyond 32 bit limits.
                end
            end
        end
        % Check for 8 and 16 bit format 'baseline' field overflow. VERY
        % uncommon situation. Occurs if entire signal is +ve or -ve
        % with very high magnitude.
        if (baseline>2147483647) % Signal is all negative with large magnitude.
            warning('Large offset input channel entered. Output precision may be less than specified format for the negative channel.');
            baseline=2147483647; % Baseline is max int value, min_x maps to min bitres value.
            adc_gain=(-(2^(bit_res-1))+1-baseline)/min_x;
        elseif (baseline<-2147483647) % Signal is all positive with large magnitude.
            warning('Large offset input channel entered. Output precision may be less than specified format for the positive channel.');
            baseline=-2147483647; % Baseline is min int value, max_x maps to max bitres value.
            adc_gain=(2^(bit_res-1)-1-baseline)/max_x;
        end
    end

    y=x*adc_gain+baseline;

end % signal is in digital range. adc_gain and baseline have been calculated.

% Convert signals to appropriate integer type, and shift any WFDB NaN int values to
% a higher value so that they will not be read as NaN's by WFDB
switch bit_res % WFDB will interpret the smallest value as nan.
    case 8
        WFDBNAN=-128;
        y=int8(y);
    case 16
        WFDBNAN=-32768;
        y=int16(y);
    case 32
        WFDBNAN=-2147483648;
        y=int32(y);
end
iswfdbnan=find(y==WFDBNAN);
if(~isempty(iswfdbnan))
    y(iswfdbnan)=WFDBNAN+1;
end

%Set original NaNs to WFDBNAN
y(nan_ind)=WFDBNAN;

%Calculate the 16-bit signed checksum of all samples in the signal
check_sum=sum(y);
M=check_sum/(2^15);
if(M<0)
    check_sum=mod(check_sum,-2^15);
    if(~check_sum && abs(M)<1)
        check_sum=-2^15;
    elseif (mod(ceil(M),2))
        check_sum=2^15 + check_sum;
    end
else
    check_sum=mod(check_sum,2^15);
    if(mod(floor(M),2))
        check_sum=-2^15+check_sum;
    end
end

% Note that checksum must be calculated on actual digital samples for format 80,
% not the shifted ones. Therefore we only convert to real format now.
if bit_res==8
    y=uint8(int16(y)+128); % Convert into unsigned for writing byte offset format.
end

% Signal is ready to be written to dat file.

end

function y=get_names(str,deli)

y={};
old=1;
ind=regexp(str,deli);
ind(end+1)=length(str)+1;
for i=1:length(ind)
    y(end+1)={str(old:ind(i)-1)};
    old=ind(i)+1;
end

end


function F = ctranspose( F )
% '   Conjugate transpose of a CHEBFUN2V

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

% Transpose and then conjugate:
F = transpose( F );
F = conj( F );

end


function varargout = OregonatorGUI(varargin)
% OREGONATORGUI M-file for OregonatorGUI.fig
%      OREGONATORGUI, by itself, creates a new OREGONATORGUI or raises the existing
%      singleton*.
%
%      H = OREGONATORGUI returns the handle to a new OREGONATORGUI or the handle to
%      the existing singleton*.
%
%      OREGONATORGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in OREGONATORGUI.M with the given input arguments.
%
%      OREGONATORGUI('Property','Value',...) creates a new OREGONATORGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before OregonatorGUI_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to OregonatorGUI_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Copyright 2002-2003 The MathWorks, Inc.

% Edit the above text to modify the response to help OregonatorGUI

% Last Modified by GUIDE v2.5 02-Dec-2005 23:24:01

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @OregonatorGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @OregonatorGUI_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before OregonatorGUI is made visible.
function OregonatorGUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to OregonatorGUI (see VARARGIN)

% Choose default command line output for OregonatorGUI
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes OregonatorGUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = OregonatorGUI_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

x0=[1 1 1];

[t,x]=ode15s(@oregonator,[0 600],x0);

axes(handles.axes1);
plot(t,x(:,1),'r');
axis([300,600,0,100]);
title('figure1');
Xlabel('temps');
Ylabel('x(1)');

axes(handles.axes2);
plot(t,x(:,2),'g');
axis([300,600,0,3]);
title('figure2');
Xlabel('temps');
Ylabel('x(2)');

axes(handles.axes3);
plot(t,x(:,3),'m');
axis([300,600,0,100]);
title('figure3');
Xlabel('temps');
Ylabel('x(3)');


function varargout = surface(varargin)
%SURFACE  Plot surface of a SPHEREFUN.
%   See SURF for a complete description of the various forms of the input.
%
% See also SPHEREFUN/SURF.

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

[varargout{1:nargout}] = surface@separableApprox(varargin{:});

end


function [pf_, opf_] = t_node_test(quiet)
%T_NODE_TEST  Tests for network model with multipe node-creating elements.

%   MATPOWER
%   Copyright (c) 2021-2022, 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

cases = {'t_case9_gizmo', 'case4gs', 'case4_dist', 'case9', 'case14', 'case57', 'case300'};

t_begin(12*length(cases), quiet);

define_constants;
if quiet
    verbose = 0;
else
    verbose = 1;
end

mpopt = mpoption('out.all', 0, 'verbose', 0, 'pf.tol', 1e-10);
mpopt = mpoption(mpopt, 'opf.ignore_angle_lim', 1);
mpopt0 = mpopt;
mpopt0.exp.use_legacy_core = 1;
mpopt.exp.mpx = mp.xt_node_test();

for k = 1:length(cases)
    t = sprintf('PF - %s - ', cases{k});
    mpc = loadcase(cases{k});
    if strcmp(cases{k}, 't_case9_gizmo')
        mpc.bus(2, BS) = 1;
    end
    if ~isfield(mpc, 'gencost')
        ng = size(mpc.gen, 1);
        mpc.gencost = ones(ng, 1) * [2 0 0 2 1 0];
        if strcmp(cases{k}, 'case4gs')
            mpc.gen(:, PMAX) = 320;
            mpc.gen(:, QMAX) = 200;
        end
    end

    r = runpf(mpc, mpopt0);
    evm = r.bus(:, VM);
    eva = r.bus(:, VA);
    epg = r.gen(:, PG);
    eqg = r.gen(:, QG);
    t_ok(r.success, [t 'success 1']);

    pf = run_pf(mpc, mpopt);
    r2 = pf.dmc.export(pf.dm, pf.dm.source);
    va = r2.bus(:, VA);
    vm = r2.bus(:, VM);
    pg = r2.gen(:, PG);
    qg = r2.gen(:, QG);
    t_ok(pf.success, [t 'success 2']);
    t_is(va, eva, 9, [t 'va']);
    t_is(vm, evm, 9, [t 'vm']);
    t_is(pg, epg, 9, [t 'pg']);
    t_is(qg, eqg, 9, [t 'qg']);

    t = sprintf('OPF - %s - ', cases{k});
    r = runopf(mpc, mpopt0);
    t_ok(r.success, [t 'success 1']);
    evm = r.bus(:, VM);
    eva = r.bus(:, VA);
    epg = r.gen(:, PG);
    eqg = r.gen(:, QG);

    opf = run_opf(mpc, mpopt);
    r2 = opf.dmc.export(opf.dm, opf.dm.source);
    va = r2.bus(:, VA);
    vm = r2.bus(:, VM);
    pg = r2.gen(:, PG);
    qg = r2.gen(:, QG);
    t_ok(opf.success, [t 'success 2']);
    t_is(va, eva, 9, [t 'va']);
    t_is(vm, evm, 9, [t 'vm']);
    t_is(pg, epg, 9, [t 'pg']);
    t_is(qg, eqg, 9, [t 'qg']);
end

t_end;

if nargout
    pf_ = pf;
    if nargout > 1
        opf_ = opf;
    end
end


% GCI_creak_postproc.m
% Function to do the post-processing step to remove false positive GCIs
% detected in creaky voice regions
%
% Octave compatible
%
% Description
% Function to do the post-processing step to remove false positive GCIs
% detected in creaky voice regions
%
% Inputs
%  GCI             : [samples] [Mx1] Glottal closure instants
%  creak           : [binary]  [Nx1] Creak decision
%  search_reg      : [integer] [1x1] Search factor
%  rep             : [samples] [Nx1] Resonator output
%  removeThresh    : [integer] [1x1] Threshold for false GCI removal
%  repNum          : [integer] [1x1] number of repititions
%
% Outputs
%  GCI             : [samples] [Mx1] Glottal closure instants
%
% Example
%  GCI = GCI_creak_postproc(GCI,creak,search_reg,rep,removeThresh,repNum)
%
% References
%  [1] Kane, J., Gobl, C., (2013) `Evaluation of glottal closure instant
%       detection in a range of voice qualities', Speech Communication
%       55(2), pp. 295-314.
%
% Copyright (c) 2013 Trinity College Dublin
%
% License
%  This code is a part of the Voice Analysis Toolkit with the following
%  licence:
%  The software product (and any modifications thereof) is distributed under
%  a dual licence: an open source license for individual, non-commercial
%  purposes, and a commercial license. The opensource licence under which
%  the product is distributed is GNU GPL v2. For individual users, this
%  licence suits their use as these are not distributing proprietary
%  modifications, additions to, or derivatives of the product and don't
%  require legal protection of a commercial licence. For commercial users,
%  where open source does not meet their requirements, we offer commercial
%  licensing of the product. A commercial license permits customers to
%  modify, add or produce derivative products without the obligation of
%  making the subsequent code open source. For more information regarding
%  our commercial licence, please contact john.whelan@tcd.ie
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Author
%  John Kane kanejo@tcd.ie
%
% $Id <info set by the versioning system> $

function GCI = GCI_creak_postproc(GCI,creak,search_reg,rep,removeThresh,repNum)

% Separate GCIs detected in creaky voice regions from other regions
creak_GCI=GCI(creak(GCI)==1);
GCI(creak(GCI)==1)=[];

for m=1:repNum
    n=2;
    while n < length(creak_GCI)
        cur_rep_max = abs(min(rep(creak_GCI(n)-round(search_reg):creak_GCI(n)+round(search_reg))));

        if mean([abs(rep(creak_GCI(n-1))) abs(rep(creak_GCI(n+1)))])*removeThresh > cur_rep_max
             creak_GCI(n)=NaN;
            n=n+2;
        else n=n+1;
        end
    end
    creak_GCI(isnan(creak_GCI))=[];
end

GCI=sort(unique([GCI(:)' creak_GCI(:)']));


function showresult3(node,elem,u,expr,varargin)
%% SHOWRESULT3 display the mesh and the solution in 3-D
%
%  showresult3(node,elem,u,viewangle) displays the mesh and the solution in
%  one figure. The left one is the mesh, the middle
%  one is the contour of the solution, and the right one is the graph of
%  the function. The last viewangle is used to adjust the view angle of the
%  graph of the function.
%
%  Example:
%
% See also showrate, showmesh, showsolution
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

if ~exist('expr','var'), expr = []; end
set(gcf,'Units','normal');
set(gcf,'Position',[0.25,0.25,0.6,0.4]);
% show mesh
if size(elem,1) < 1e6
    subplot(1,2,1);
    showboundary3(node,elem,expr,varargin{:});
else
    subplot(1,2,1);
    title('The mesh is too dense to display')
end
% show solution
subplot(1,2,2);
showsolution3(node,elem,u,expr,varargin{:});
colorbar;
pause(0.05)


classdef TestDrawLineMatches
    %TestDrawLineMatches

    properties (Constant)
        img1 = fullfile(mexopencv.root(),'test','left01.jpg');
        img2 = fullfile(mexopencv.root(),'test','right01.jpg');
    end

    methods (Static)
        function test_1
            im1 = imread(TestDrawLineMatches.img1);
            im2 = imread(TestDrawLineMatches.img2);
            obj = cv.BinaryDescriptor();
            [klines1, feat1] = obj.detectAndCompute(im1);
            [klines2, feat2] = obj.detectAndCompute(im2);
            matcher = cv.BinaryDescriptorMatcher();
            m = matcher.match(feat1, feat2);

            im1 = cv.cvtColor(im1, 'GRAY2RGB');
            im2 = cv.cvtColor(im2, 'GRAY2RGB');
            out = cv.drawLineMatches(im1, klines1, im2, klines2, m);
            validateattributes(out, {class(im1)}, {'size',...
                [max(size(im1,1),size(im2,1)), size(im1,2)+size(im2,2), 3]});
        end

        function test_2
            im1 = imread(TestDrawLineMatches.img1);
            im2 = imread(TestDrawLineMatches.img2);
            obj = cv.BinaryDescriptor();
            [klines1, feat1] = obj.detectAndCompute(im1);
            [klines2, feat2] = obj.detectAndCompute(im2);
            matcher = cv.BinaryDescriptorMatcher();
            m = matcher.match(feat1, feat2);

            [~,ord] = sort([m.distance]);
            mask = false(size(ord));
            mask(ord(1:min(20,end))) = true;

            out = cv.drawLineMatches(im1, klines1, im2, klines2, m, ...
                'MatchesMask',mask, ...
                'OutImage',repmat(cat(2,im1,im2), [1 1 3]), ...
                'MatchColor',[255 0 0], 'SingleLineColor',[0 255 0], ...
                'NotDrawSingleLines',true);
            validateattributes(out, {class(im1)}, {'size',...
                [max(size(im1,1),size(im2,1)), size(im1,2)+size(im2,2), 3]});
        end

        function test_error_argnum
            try
                cv.drawLineMatches();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function [undistorted] = UndistortImage(image, LUT)

% UndistortImage - undistort an image using a lookup table
%
% [undistorted] = UndistortImage(image, LUT)
%
% eg.
% [ ~, ~, ~, ~, ~, LUT] = ...
%     ReadCameraModel('<models_dir>/stereo_wide_left_undistortion.bin');
% image = imread('<image_dir>/<timestamp>.png');
% undistorted = UndistortImage(image, LUT);
%
% INPUTS:
%   image: distorted image to be rectified
%   LUT: lookup table mapping pixels in the undistorted image to pixels in the
%     distorted image, as returned from ReadCameraModel
%
% OUTPUTS:
%   undistorted: image after undistortion

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright (c) 2016 University of Oxford
% Authors:
%  Geoff Pascoe (gmp@robots.ox.ac.uk)
%  Will Maddern (wm@robots.ox.ac.uk)
%
% This work is licensed under the Creative Commons
% Attribution-NonCommercial-ShareAlike 4.0 International License.
% To view a copy of this license, visit
% http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to
% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

undistorted = zeros(size(image), class(image));

for channel = 1:size(image,3)
  % Interpolate pixels from distorted image using lookup table
  channel_data = cast(reshape(interp2(cast(image(:,:,channel), 'single'), ...
                               LUT(:,1)+1, ...
                               LUT(:,2)+1, ...
                               'bilinear'), ...
                     fliplr(size(image(:,:,channel)))).', class(image));

  undistorted(:,:,channel) = channel_data;
end

end


function train_base_net_x4(varargin)
% load data & label
data = load('./data/train/SDR_youtube_80_x4.mat') ;
label = load('./data/train/HDR_youtube_80.mat') ;
imdb.images.data = data.SDR_data;
imdb.images.label = label.HDR_data;
imdb.images.set = cat(2, ones(1, size(data.SDR_data, 4)-500), 2*ones(1, 500));

% set CNN model
net = net_base_x4();

% set the learning rate and weight decay for biases
% default values are used for filters
for i = 2:2:114
    net.params(i).learningRate = 0.1;
    net.params(i).weightDecay = 0;
end
net.conserveMemory = true;

% options
opts.solver = @adam;
opts.train.batchSize = 16;
opts.train.continue = true;
opts.train.gpus = 1;
opts.train.prefetch = false ;
opts.train.expDir = './net/net_base_x4' ;
opts.train.learningRate = 5*1e-7*ones(1, 200);
opts.train.weightDecay = 0.0005;
opts.train.numEpochs = numel(opts.train.learningRate) ;
opts.train.derOutputs = {'objective', 1} ;
[opts, ~] = vl_argparse(opts.train, varargin) ;

% record
if(~isdir(opts.expDir))
    mkdir(opts.expDir);
end

% call training function
[net, info] = cnn_train_dag(net, imdb, @getBatch, opts) ;

function inputs = getBatch(imdb, batch, opts)
image = imdb.images.data(:, :, :, batch) ;
label = imdb.images.label(:, :, :, batch) ;

image = single(image)/255;
label = single(label)/1023;
inputs = {'input', gpuArray(image), 'label', gpuArray(label)};


function [x, output] = findExtremePathway(fbaModel, obj)
% Finds an extreme ray
%
% USAGE:
%
%    [x, output] = findExtremePathway(fbaModel, obj)
%
% INPUT:
%    fbaModel:    FBA type model
%
% OPTIONAL INPUT:
%    obj:         default = random vector with size depending on fbaModel.S
%
% OUTPUTS:
%    x:           vector from `result`, where `result` is an output of `solveCobraLP` function
%    output:      `output.objval` contains `result.obj`
%
% .. $Revision: 0.1 $  $Date: 2011/05/01 $

A    = fbaModel.S;
[nmet,nrxn] = size(A);

% Convert model to conic form
if isfield(fbaModel, 'ub') && isfield(fbaModel, 'lb')
    revRxns = fbaModel.lb < 0 & fbaModel.ub > 0;
else
    error('missing fields: revRxns or ub and lb\n');
end

A = [A, -A(:,revRxns)];
[~, n] = size(A);

if nargin < 2
    obj = rand(n,1);
end

% Set required model components
LPProblem = struct();
LPProblem.A = sparse([A; ones(1,n)]);
LPProblem.c   = obj;
LPProblem.csense = repmat('E',nmet+1,1);
LPProblem.b   = [zeros(nmet,1); 1];
% Set optional model components
LPProblem.osense= -1;
LPProblem.lb = 0* ones(n,1);
LPProblem.ub = inf* ones(n,1);

result = solveCobraLP(LPProblem);  % Find extreme ray (be aware, that this can easily be a loop of a reversible reaction.

x = result.full(1:nrxn);
x(revRxns) = x(revRxns) - result.full(nrxn+1:end);

output.objval = result.obj;


function [u,P] = spm_fx_tfm_P(u,P)
% returns exogenous input and input dependent parameters
% FORMAT [u,P] = spm_fx_tfm_P(u,P)
%
% arguments:
% u  - inputs
% P  - parameters
%
% returns:
% u  - exogenous (conductance) inputs driving states
% P  - input dependent parameters
%
% tthis is a help are routine for the, microcircuit models equations of
% motion - it simply separates inputs into those affecting (driving) his
% neuronal states and those modulating parameters. It returns the exogenous
% (conductance) inputs and input dependent parameters.
%___________________________________________________________________________
% Copyright (C) 2012 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_fx_tfm_P.m 7679 2019-10-24 15:54:07Z spm $

% input dependent (intrinsic connection) parameters
%==========================================================================
j     = [4 3 2 1];
for i = 2:size(P.C,2)
    P.G(:,j(i - 1)) = P.G(:,j(i - 1)) + P.C(:,i) + u(i);
end

% exogenous inputs
%--------------------------------------------------------------------------
u     = exp(P.C(:,1))*u(1);


function [batches, masked_batches, batch_padding] = rcnn_extract_regions(im, sp, reg2sp, boxes, rcnn_model)

% convert image to BGR and single
im = single(im(:,:,[3 2 1]));
num_boxes = size(boxes, 1);
batch_size = rcnn_model.cnn.batch_size;
num_batches = ceil(num_boxes / batch_size);
batch_padding = batch_size - mod(num_boxes, batch_size);
if(mod(num_boxes, batch_size)==0) batch_padding=0; end
crop_mode = rcnn_model.detectors.crop_mode;
image_mean = rcnn_model.cnn.image_mean;
crop_size = size(image_mean,1);
crop_padding = rcnn_model.detectors.crop_padding;

batches = cell(num_batches, 1);
masked_batches = cell(num_batches, 1);
for batch = 1:num_batches
%  disp(batch);
%parfor batch = 1:num_batches
  batch_start = (batch-1)*batch_size+1;
  batch_end = min(num_boxes, batch_start+batch_size-1);

  ims = zeros(crop_size, crop_size, 3, batch_size, 'single');
  masked_ims=zeros(crop_size, crop_size, 3, batch_size, 'single');
  for j = batch_start:batch_end
    bbox = boxes(j,:);
    m1=reg2sp(:,j);
    mask=double(m1(sp));
    [crop, mask_crop] = rcnn_im_crop_mask(im, mask, bbox, crop_mode, crop_size, ...
        crop_padding, image_mean);
    % swap dims 1 and 2 to make width the fastest dimension (for caffe)
    ims(:,:,:,j-batch_start+1) = permute(crop, [2 1 3]);
    masked_ims(:,:,:,j-batch_start+1) = permute(mask_crop, [2 1 3]);
  end

  batches{batch} = ims;
  masked_batches{batch} = masked_ims;
end


classdef AMICO_WATERFREE

properties
    id, name                % id and name of the model
    dPar                    % parallel diffusivity of the tensors [units of mm^2/s]
    dPer                    % perpendicular diffusivities of the tensors [units of mm^2/s]
    dIso                    % isotropic diffusivities [units of mm^2/s]
    OUTPUT_names            % suffix of the output maps
    OUTPUT_descriptions     % description of the output maps
end

methods

    % =================================
    % Setup the parameters of the model
    % =================================
	function obj = AMICO_WATERFREE()
        global CONFIG

        % set the parameters of the model
        obj.id        = 'WATERFREE';
        obj.name      = 'Water free';
        obj.dPar      = 1.7 * 1E-3;
        obj.dIso      = [2.0 3.0] * 1E-3;
        obj.dPer      = linspace(0.1,1.0,10) * 1E-3;

        obj.OUTPUT_names        = { 'ICVF', 'ISOVF' };
        obj.OUTPUT_descriptions = {'Intra-cellular volume fraction', 'Isotropic volume fraction'};

        % set the parameters to fit it
        CONFIG.OPTIMIZATION.SPAMS_param.mode    = 2;
        CONFIG.OPTIMIZATION.SPAMS_param.pos     = true;
        CONFIG.OPTIMIZATION.SPAMS_param.lambda  = 0;    % l1 regularization
        CONFIG.OPTIMIZATION.SPAMS_param.lambda2 = 1e-3; % l2 regularization
    end

    % ==================================================================
    % Generate high-resolution kernels and rotate them in harmonic space
    % ==================================================================
    function GenerateKernels( obj, ATOMS_path, schemeHR, AUX, idx_IN, idx_OUT )
        global CONFIG AMICO_data_path

        % Tensor compartments
        % ===================
        idx = 1;
        for i = 1:numel(obj.dPer)
            TIME = tic();
            fprintf( '\t\t- A_%03d... ', idx );

            % generate
            D = diag( [obj.dPer(i) obj.dPer(i) obj.dPar] );
            signal = obj.TensorSignal( D, schemeHR.camino );

            % rotate and save
            lm = AMICO_RotateKernel( signal, AUX, idx_IN, idx_OUT, false );
            save( fullfile( ATOMS_path, sprintf('A_%03d.mat',idx) ), '-v6', 'lm' )
            idx = idx + 1;

            fprintf( '[%.1f seconds]\n', toc(TIME) );
        end

        % Isotropic compartments
        % ======================
        for i = 1:numel(obj.dIso)
            TIME = tic();
            fprintf( '\t\t- A_%03d... ', idx );

            % generate
            D = diag( [obj.dIso(i) obj.dIso(i) obj.dIso(i)] );
            signal = obj.TensorSignal( D, schemeHR.camino );

            % resample and save
            lm = AMICO_RotateKernel( signal, AUX, idx_IN, idx_OUT, true );
            save( fullfile( ATOMS_path, sprintf('A_%03d.mat',idx) ), '-v6', 'lm' )
            idx = idx + 1;

            fprintf( '[%.1f seconds]\n', toc(TIME) );
        end

    end

    % ==============================================
    % Project kernels from harmonic to subject space
    % ==============================================
    function ResampleKernels( obj, ATOMS_path, idx_OUT, Ylm_OUT )
        global CONFIG AMICO_data_path KERNELS

        % Setup the KERNELS structure
        % ===========================
        n1 = numel(obj.dPer);
        n2 = numel(obj.dIso);
        KERNELS = {};
        KERNELS.nS       = CONFIG.scheme.nS;
        KERNELS.nA       = n1 + n2; % number of atoms
        KERNELS.A1       = zeros( [KERNELS.nS n1 181 181], 'single' );
        KERNELS.A2       = zeros( [KERNELS.nS n2], 'single' );

        % Tensors
        % =======
        idx = 1;
        for i = 1:n1
            TIME = tic();
            fprintf( '\t- A_%03d...  ', idx );

            load( fullfile( ATOMS_path, sprintf('A_%03d.mat',idx) ), 'lm' );
            KERNELS.A1(:,i,:,:) = AMICO_ResampleKernel( lm, idx_OUT, Ylm_OUT, false );
            idx = idx + 1;

            fprintf( '[%.1f seconds]\n', toc(TIME) );
        end

        % Isotropic
        % =========
        for i = 1:n2
            TIME = tic();
            fprintf( '\t- A_%03d...  ', idx );

            load( fullfile( ATOMS_path, sprintf('A_%03d.mat',idx) ), 'lm' );
            KERNELS.A2(:,i,:,:) = AMICO_ResampleKernel( lm, idx_OUT, Ylm_OUT, true );
            idx = idx + 1;

            fprintf( '[%.1f seconds]\n', toc(TIME) );
        end

    end

    % ===========================
    % Fit the model to each voxel
    % ===========================
    function [DIRs, MAPs] = Fit( obj )
        global CONFIG
        global niiSIGNAL niiMASK
        global KERNELS bMATRIX

        % setup the output files
        MAPs         = zeros( [CONFIG.dim(1:3) numel(obj.OUTPUT_names)], 'single' );
        DIRs         = zeros( [CONFIG.dim(1:3) 3], 'single' );
        niiY = niiSIGNAL;

        n1 = numel(obj.dPer);
        n2 = numel(obj.dIso);

        fprintf( '\n-> Fitting "%s" model to data:\n', obj.name );
        TIME = tic();
        for iz = 1:niiSIGNAL.hdr.dime.dim(4)
        for iy = 1:niiSIGNAL.hdr.dime.dim(3)
        for ix = 1:niiSIGNAL.hdr.dime.dim(2)
            if niiMASK.img(ix,iy,iz)==0, continue, end

            % read the signal
            b0 = mean( squeeze( niiSIGNAL.img(ix,iy,iz,CONFIG.scheme.b0_idx) ) );
            if ( b0 < 1e-3 ), continue, end
            y = double( squeeze( niiSIGNAL.img(ix,iy,iz,:) ) ./ ( b0 + eps ) );
            y( y < 0 ) = 0; % [NOTE] this should not happen!

            % build the DICTIONARY
            [ i1, i2 ] = AMICO_Dir2idx( Vt );
            A = double( [ KERNELS.A1(CONFIG.scheme.dwi_idx,:,i1,i2) KERNELS.A2(CONFIG.scheme.dwi_idx,:) ] );

            % fit AMICO
            y = y(CONFIG.scheme.dwi_idx);
            yy = [ 1 ; y ];
            AA = [ ones(1,size(A,2)) ; A ];

            % estimate CSF partial volume and remove it
            x = full( mexLasso( yy, AA, CONFIG.OPTIMIZATION.SPAMS_param ) );

            % STORE results
            DIRs(ix,iy,iz,:) = Vt; % fiber direction

            MAPs(ix,iy,iz,1) = sum( x(1:n1) ) / ( sum(x) + eps ); % intracellular volume fraction

            MAPs(ix,iy,iz,2) = 1 - MAPs(ix,iy,iz,1); % isotropic volume fraction

            x(n1+1:end) = 0;
            niiY.img(ix,iy,iz,CONFIG.scheme.dwi_idx) = AA(2:end,:)*x*b0;

        end
        end
        end
        save_untouch_nii(niiY, 'dwi_fw_corrected.nii');
        TIME = toc(TIME);
        fprintf( '   [ %.0fh %.0fm %.0fs ]\n', floor(TIME/3600), floor(mod(TIME/60,60)), mod(TIME,60) )

        % compute MAPS
        n1 = numel(obj.dPer);
        MAPs    = zeros( [1 numel(obj.OUTPUT_names)], 'single' );
        MAPs(1) = sum( x(1:n1) ) / ( sum(x) + eps ); % intracellular volume fraction
        MAPs(2) = 1 - MAPs(1);                       % isotropic volume fraction
    end

    % ================================================================
    % Simulate signal according to tensor model (1 fiber along z-axis)
    % ================================================================
    function [ signal ] = TensorSignal( obj, D, XYZB )
        nDIR   = size( XYZB, 1 );
        signal = zeros( nDIR, 1 );
        for d = 1:nDIR
            signal(d) = exp(-XYZB(d,4) * XYZB(d,1:3) * D * XYZB(d,1:3)');
        end
    end

end

end


function out = resample_flow(uv, sz, method)
% function out = resample_flow(uv, factor, method)
%RESAMPLE_FLOW   Resample flow field
%   OUT = RESAMPLE_FLOW(IN, FACTOR[, METHOD]) resamples (resizes) the flow
%   field IN using a factor of FACTOR.  The optional argument METHOD
%   specifies the interpolation method ('bilinear' (default) or
%   'bicubic').
%
%   This is a private member function of the class 'clg_2d_optical_flow'.
%
%   Author:  Stefan Roth, Department of Computer Science, TU Darmstadt
%   Contact: sroth@cs.tu-darmstadt.de
%   $Date$
%   $Revision$

% Copyright 2004-2007, Brown University, Providence, RI. USA
% Copyright 2007-2010 TU Darmstadt, Darmstadt, Germany.
%
%                          All Rights Reserved
%
% All commercial use of this software, whether direct or indirect, is
% strictly prohibited including, without limitation, incorporation into in
% a commercial product, use in a commercial service, or production of other
% artifacts for commercial purposes.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for research purposes is hereby granted without fee,
% provided that the above copyright notice appears in all copies and that
% both that copyright notice and this permission notice appear in
% supporting documentation, and that the name of the author and Brown
% University not be used in advertising or publicity pertaining to
% distribution of the software without specific, written prior permission.
%
% For commercial uses contact the Technology Venture Office of Brown University
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO
% THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR
% BROWN UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
% DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
% PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
% ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
% THIS SOFTWARE.

  % Make bilinear the default method
  if (nargin < 3)
    method = 'bilinear';
%     method = 'bicubic';
  end
%
%   % Resize u and v
%   tmp_u = ximresize(uv(:, :, 1), factor, method);
%   tmp_v = ximresize(uv(:, :, 2), factor, method);
%   out = cat(3, tmp_u, tmp_v)*factor;
%
  ratio = sz(1) / size(uv,1);
  u     = imresize(uv(:,:,1), sz, method)*ratio;
  v     = imresize(uv(:,:,2), sz, method)*ratio;
  out   = cat(3, u, v);


% read the NIST format wav files
% Author: Xiao Xiong
% Created: 1 Feb 2005
% Last modified: 1 Feb 2005

function [data] = readNIST(file_name,big_endian);

FILE = fopen( file_name );
if FILE <1
    error('File open failed: %s', file_name);
end
fread(FILE, 1024, 'int8');      %read the header first
if big_endian
    data = fread(FILE, 'int16=>short','b');
else
    data = fread(FILE, 'int16=>short','l');
end
% plot(data);
data = double(data(1:length(data)));        % store the vecors as column vector of wav
% plot(data);
fclose(FILE);


function M = obj_read(filename)
% Read Wavefront OBJ-formatted data from disk
% FORMAT M = obj_read(filename)
%
% filename - OBJ-formatted file name
% M        - data structure
%__________________________________________________________________________
%
% Wavefront OBJ Format Specification:
% https://en.wikipedia.org/wiki/Wavefront_.obj_file
%__________________________________________________________________________
% Copyright (C) 2017 Wellcome Trust Centre for Neuroimaging

% Guillaume Flandin
% $Id: obj_read.m 7390 2018-08-13 09:51:20Z guillaume $

fid = fopen(filename,'rt');
if fid == -1
    error('Cannot open %s.',filename);
end

M = struct('vertices',[],'faces',[]);

while true
    l = fgetl(fid);
    if ~ischar(l), break; end
    if numel(l) < 1 || isempty(strtrim(l)) || l(1) == '#', continue; end
    switch l(1)
        case 'v'
            switch l(2)
                case 't'
                    % texture coordinates, in (u, v [,w]) coordinates
                    t = sscanf(l(2:end),'%f %f %f');
                case 'n'
                    % vertex normals in (x,y,z) form
                    n = sscanf(l(2:end),'%f %f %f');
                case 'p'
                    % Parameter space vertices in (u [,v] [,w]) form
                    p = sscanf(l(2:end),'%f %f %f');
                otherwise
                    v = sscanf(l(2:end),'%f %f %f');
                    if numel(v) > 3, v = v(1:3); end
                    M.vertices(size(M.vertices,1)+1,:) = v;
            end
        case 'f'
            f = sscanf(l(2:end),'%d %d %d');
            if numel(f) ~= 3
                f = sscanf(l(2:end),'%d/%d'); % '%d/%d %d/d %d/%d'
                if numel(f) ~= 6
                    f = sscanf(l(2:end),'%d//%d'); % '%d//%d %d//d %d//%d'
                    if numel(f) ~= 6
                        f = sscanf(l(2:end),'%d/%d/%d'); % '%d/%d/%d %d/%d/%d %d/%d/%d'
                        if numel(f) == 9
                            f = f([1 4 7]);
                        else
                            fprintf('Not a triangle.\n');
                            continue;
                        end
                    else
                        f = f([1 3 5]);
                    end
                else
                    f = f([1 3 5]);
                end
            end
            i = find(f<0);
            if isempty(i), f(i) = size(M.vertices,1) + f(i); end
            M.faces(size(M.faces,1)+1,:) = f;
        case 'o'
            fprintf('Ignoring named objects.\n');
        case 'g'
            fprintf('Ignoring polygon groups.\n');
        case 's'
            fprintf('Ignoring smooth shading.\n');
        otherwise
            if strncmp('mtllib',l,6) || strncmp('usemtl',l,6)
                fprintf('Ignoring materials.\n');
            else
                fprintf('Ignoring line starting with %c.\n',l(1));
            end
    end
end

fclose(fid);