function tests = test_spm_get_lm
% Unit Tests for spm_get_lm
%__________________________________________________________________________
% Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging

% $Id: test_spm_get_lm.m 6534 2015-08-24 16:02:56Z guillaume $

tests = functiontests(localfunctions);

function test_spm_get_lm_2D(testCase)
dim     = [5 5];
vol     = rand(dim(1),dim(2));
subvol  = vol(2:4,2:4);
vol(3,3) = max(subvol(:)) + 0.1;
[X,Y] = ndgrid(1:dim(1),1:dim(2));
gm      = sub2ind(size(vol),3,3);
idx     = spm_get_lm(vol,[X(:)';Y(:)']);
testCase.verifyTrue(any(idx == gm));

function test_spm_get_lm_3D(testCase)
dim     = [5 5 5];
vol     = rand(dim(1),dim(2),dim(3));
subvol  = vol(2:4,2:4,2:4);
vol(3,3,3) = max(subvol(:)) + 0.1;
[X,Y,Z] = ndgrid(1:dim(1),1:dim(2),1:dim(3));
gm      = sub2ind(size(vol),3,3,3);
idx     = spm_get_lm(vol,[X(:)';Y(:)';Z(:)']);
testCase.verifyTrue(any(idx == gm));


function VoigtSpectrGUI
%this is a GUI program i wrote about simulating absorption lineshape and
%spectrum from HITRAN output data
% this program simulate the spectrum using the HITRAN data and
% Calculating the Voigt porfile According to the paper:
%   Applied spectro. V58, 468(2004);
%   Phi= A*K(x,y)
% The lineshape depends on Guassian (vD) width and Lorentzian width(vL).
% Absorption depends on number density and absorption length, I/I0 = Exp(-aNL);
% Notice the Half Width at Half Maxium for the vD and vL inputs;

    fh = figure('Visible','off','Name','Spectrum Simulation',...
             'position',[50,50, 850, 600]);

    hax = axes('Units','pixels','Position',[60,60,500,500]);

    %construct the components
    hp = uipanel('Units','pixels','ShadowColor',[0.1,1,0.01],...
              'Position',[628 160 200 430]);

    hpb1 = uicontrol('Style','pushbutton','String','Open HITRFile',...
          'Foregroundcolor',[1 0.1 0.2],'FontWeight','bold',...
           'Position',[650 540, 110, 30],'Callback',{@fileopen_Callback});

    het1 = uicontrol('Style','edit','String','file name',...
           'Foregroundcolor',[0.2 0.4 0.1],'FontWeight','bold',...
           'Position',[650,510,110,30],'Callback',{@edittext_Callback});

    hst1 = uicontrol('Style','text', 'String','HWHM[vD vL]/cm-1',...
            'Foregroundcolor',[0.2 0.3 0.3],'FontWeight','bold',...
             'Backgroundcolor',[0.7 0.98 0.98],...
             'Position', [650 470 160 15]);

    het2 = uicontrol('Style','edit', 'String','0.003',...
            'Foregroundcolor',[0.30 0.1 1],'FontWeight','bold',...
             'Backgroundcolor',[0.97842 0.98 1],...
             'Position', [650 445 75 20]);

    het3 = uicontrol('Style','edit', 'String','0.006',...
            'Foregroundcolor',[0.30 0.1 1],'FontWeight','bold',...
             'Backgroundcolor',[1 0.99 1],...
             'Position', [735 445 75 20]);

    hst2 = uicontrol('Style','text', 'String','NumDensity/Lightpath/cm',...
            'Foregroundcolor',[0.2 0.3 0.3],'FontWeight','bold',...
             'Backgroundcolor',[0.7 0.98 1],...
             'Position', [650 410 160 15]);

    het4 = uicontrol('Style','edit', 'String','1E+10',...
            'Foregroundcolor',[0.30 0.1 1],'FontWeight','bold',...
             'Backgroundcolor',[0.97842 0.98 1],...
             'Position', [650 385 75 20]);

    het5 = uicontrol('Style','edit', 'String','1E+5',...
            'Foregroundcolor',[0.30 0.1 1],'FontWeight','bold',...
             'Backgroundcolor',[1 0.99 1],...
             'Position', [735 385 75 20]);

    hpb2 = uicontrol('Style','pushbutton','String','Simu-LineShape',...
        'Foregroundcolor',[1 0.1 0.2],'FontWeight','bold',...
           'Position',[650 340, 110, 30],'Callback',{@SimuLS_Callback});

    het6 = uicontrol('Style','edit', 'String','VoigtWidth',...
        'Foregroundcolor',[0.30 0.1 1],'FontWeight','bold',...
         'Backgroundcolor',[0.4 0.9 0.7],...
         'Position', [735 315 75 20]);

    hpb3 = uicontrol('Style','pushbutton','String','Simu-Absorption',...
        'Foregroundcolor',[1 0.1 0.2],'FontWeight','bold',...
           'Position',[650 280, 110, 30],'Callback',{@SimuAp_Callback});

    hpb4 = uicontrol('Style','pushbutton','String','Open ExpSpec',...
        'Foregroundcolor',[1 0.1 0.2],'FontWeight','bold',...
           'Position',[650 240, 110, 30],'Callback',{@ExpSpectr_Callback});

    hst4 = uicontrol('Style','text', 'String','Display Options',...
          'Backgroundcolor',[0.678402 0.98 1],...
            'Foregroundcolor',[0.2 0.3 0.3],'FontWeight','bold',...
             'Position',[650 210 130 15]);

    hpm = uicontrol('Style','popupmenu',...
                'String',{'LineShape','Absorption','CombinedPlot'},...
                'Foregroundcolor',[0.99 0.01 0.01],'FontWeight','bold',...
                'Value',1,'Position',[690 170 110 30],'Callback',{@popup_Callback});

    hp2 = uipanel('Units','pixels','ShadowColor',[0.1 0.1 1],...
               'Position',[628 40 200 100]);

    het7 = uicontrol('Style','edit','String','FileName.dat',...
             'Foregroundcolor',[0.2 0.4 0.1],'FontWeight','bold',...
             'Position',[640,105,90,25]);

    hcb1 = uicontrol('Style','checkbox','String','Line Shape',...
                'Position',[655 75 85 25],'Foregroundcolor',[0.2 0.3 0.9]);
    hcb2 = uicontrol('Style','checkbox','String','Absorption',...
                'Position',[655 50 85 25],'Foregroundcolor',[0.2 0.3 0.9]);

    hpb5 = uicontrol('Style','pushbutton','String','Save',...
              'Foregroundcolor',[0.6 0.2 0.3],'FontWeight','bold',...
              'Position',[750 66, 60, 50],'Callback',{@save_Callback});

      % to align the controls
    align([hp,het1,het6,hpb1,hpb2,hpb3,hpb4,hst1,hst2,hst4,hpm,hp2],'Center','None');

    % Initialize the GUI.
    % Change units to normalized so components resize automatically.
    set([hp,het1,het2,het3,het4,het5,het6,het7,hpb1,hpb2,hax,hst1,hst2,...
       hst4,hpm,hpb3,hpb4,hp2,hcb1,hcb2,hpb5],'Units','normalized');

    %make figure visible.
    set(fh, 'Visible','on');
    set(fh, 'NumberTitle','off')%% supress the NumverTitle

    % define some variables
    format long e ; %% define numerical format
    stp=0.0002; %% calculation(convolution) stepsize
    Dd = 0.5; %% define the edge extended beyond the spectrum region
    Nd = 1E+10; %% Number density
    L  = 1E+5; %% Optical path length cm

    gL = 0.001; %% in cm -1, pressure broadening cofffient at 50 torr.
    gD = 0.003; %% 0.0032 doppler broadening in cm-1
    SgmvTot= zeros(1,10);  %% initiate the arrays
    expx = zeros(1,10);
    expy = zeros(1,10);
    A = zeros(1,10);
    dtfl = zeros(1,10);
    grd = zeros(1,10); %% default grid

    %%file open callback
    function fileopen_Callback(source,eventdata)
        % **********uiputfile for open the save file dialog*********

        [flnm, flpth] = uigetfile({'*.out','All Files' },...
                         'Select HITRAN outputfile','fl.out');
        %specify application data, so it can be used by other objects;
        % setappdata(h,'name',value)
        setappdata(hpb1,'fname',flnm);

        set(het1, 'String',flnm);
        % set the edit text box value.

     end

  % read in the HITRAN data and simulate Line Shape spectrum
    function SimuLS_Callback(source, eventdata)%callback is just a regular func

        format long e ;
        % get the value of specified data
        % value = getappdata(h,name)
        % values = getappdata(h)
        flnm = getappdata(hpb1,'fname');

        fid = fopen(flnm);
        C = textscan(fid,...
        '%d%f%f%u%f%f%f%f %d%d%d%d%d %d%d%d%d %d%d%d%d %d%d%d%d%d%d%d%d%d%d%d%d%d ');
        fclose(fid);  %% returned C is a cell

        N = length(C{2}); %% Number of lines/ Cell length
        %% define a grid
        rangeL= -Dd + min(C{2});  %% spectrum region: First line minus 1 cm-1
        rangeH = Dd + max(C{2}); %% Last line position + 1 cm-1
        grd=[rangeL:stp:rangeH];  %% define the grid

        v = grd;
        gD = str2num(get(het2, 'string'));
        gL = str2num(get(het3, 'string'));
        gV = 0.5346*gL + sqrt(0.2166*gL^2 + gD^2); %% Voigt profile half width
        x = gL/gV;
        SgmvTot = 0;

        for i=1:N  %% calculate the line shape for each peak

            v0(i) = C{2}(i);
            S(i) = C{3}(i);
            y = abs(v-v0(i))/gV;
            Sgmv0(i) = S(i)/(2*gV*(1.065 + 0.447*x + 0.058*x^2));
            Sgmv = Sgmv0(i)*((1-x)*exp(-0.693.*y.^2) + (x./(1+y.^2)) + ...
              0.016*(1-x)*x*(exp(-0.0841.*y.^2.25)-1./(1 + 0.021.*y.^2.25)));

         SgmvTot = SgmvTot + Sgmv;

        end

        plot(grd,SgmvTot,'-b.');
        xlabel('WaveLength in cm-1');
        ylabel('Effective absorption Cross Section in cm2');

        set(hpm, 'Value',1)% change the popup menu settings;

        %% display the Voigt width;
        strg = sprintf('gV= %1.4f',gV);
        set(het6,'string',strg);
        set(het6,'Backgroundcolor',[0.9 0.9 0.9])

        %%figure, plot(v,A);
        %%ylabel('Absorption')
    end

    function SimuAp_Callback(source, eventdata)
        %% calculate absorption

        Nd = str2num(get(het4, 'string')); %% Number density in molecule/cm3
        L = str2num(get(het5, 'string')); %% effective length path in cm
        A = 1 - exp(-SgmvTot.*Nd*L); %% I/I0 = Exp(-aNL);

        plot(grd,A,'-m');
        xlabel('WaveLength in cm-1');
        set(hpm, 'Value',2)% change the popup menu settings;

    end

    %slice X callback
    function ExpSpectr_Callback(source, eventdata)

        format long e ;
        [flnm, flpth] = uigetfile({'*.dat','All Files' },'Select Exp. file','ExpSpectr.dat');
        fid = fopen(flnm, 'r');
        a = fscanf(fid, '%f %f', [2 inf]);    % It has two rows now.
        a = a';
        fclose(fid)
        expx = a(:,1);
        expy = a(:,2);
        hold on;
        plot3 = plot(expx,expy,'-.b');
        ylabel('Absorption')

        hold off;

    end

   %popup menu callback
    function popup_Callback(source,eventdata)
        str = get(source, 'String');
        val = get(hpm, 'Value'); %use either function handle 'hpm' or 'source';
        % the string of popup menu is a cell array {}, cell{num} returns num th
        % element of the cell.
        switch val
        case 1  %'showImage'
             %disp(str{val});
                hold off;
                plot(grd,SgmvTot,'-b.');
                xlabel('WaveLength in cm-1')
                ylabel('Effective absorption Cross Section in cm2')

        case 2
                hold off;
                plot(grd,A,'-m');

        case 3 %combined plot
                hold on;
                plot(expx,expy,'-.b');
                ylabel('Absorption')

                hold off;

        end
    end

    function save_Callback(source, eventdata)

        if get(hcb1,'Value')> 0.9 % it should be 1.0
            dtfl = [grd;SgmvTot]; %% create a data matrix for data saving
            fid = fopen(get(het7, 'string'), 'wt');
            fprintf(fid, '%6.4f %e\n', dtfl); %% set the data format
            fclose(fid);

        end

        if get(hcb2,'Value')> 0.9 % it should be 1.0

           dtfl = [grd;A]; %% create a data matrix for data saving
           fid = fopen(get(het7, 'string'), 'wt');
           fprintf(fid, '%6.4f %5.6f\n', dtfl); %% set the data format
           fclose(fid);
        end

        if get(hcb1,'Value')> 0.9 && get(hcb2,'Value')> 0.9 % it should be 1.0

            dtfl = [grd;SgmvTot;A]; %% create a data matrix for data saving

            fid = fopen(get(het7, 'string'), 'wt');
            fprintf(fid, '%6.4f %e %5.6f\n', dtfl); %% set the data format
            fclose(fid);

        end
    end

%%% read in the HITRAN file to obtain line positions and intensities.
end


function x = cs_reach(L,b)                                                  %#ok
%CS_REACH non-recursive reach (interface to CSparse cs_reach)
% find nonzero pattern of x=L\sparse(b).  L must be sparse, real, and lower
% triangular.  b must be a real sparse vector.
%
% Example:
%   x = cs_reach(L,b)
% See also: cs_demo

%   Copyright 2006-2007, Timothy A. Davis.
%   http://www.cise.ufl.edu/research/sparse

error ('cs_reach mexFunction not found') ;


function h = cbarDraw(cbar, parent);
%
% h = cbarDraw(cbar, [parent=gca]);
%
% Render a color bar, according to the settings specified in the cbar
% struct.
%
% These color bars differ from the built-in matlab color bar tools in a few
% basic respects:
%
%   * They draw colorbars based on any colormap the user inputs, rather
%   than the color map assigned to the current figure. This is useful for
%   illustrating color codes on true color images, or images with overlaid
%   responses (like fMRI activation maps)
%
%   * In addition to being able to render vertical and horizontal color bars,
%   these tools may also render 'color wheel' colorbars, showing e.g. polar
%   angle. Other possible renderings (like rings) may be added down the
%   line.
%
% cbar is a struct with the following fields:
%
%   cmap: color map (nColors x 3) for the color bar. (Columns ar [R G B],
%   from 0-255).
%
%   nColors: # of colors to use in the cmap.
%
%   clim: color limits (aka 'clip mode'), which determines primarily
%   the labeling of the color bar. Can be set to 'auto', in which case
%   the labeling will be from 1:nColors. Otherwise, will label according to
%   the clim values (format is [min max]).
%
%   colorWheel: use a color wheel instead of a bar (e.g., to show polar
%   angle for a polar angle map).
%
%   colorWheelStart: degrees clockwise from 12-o-clock which map to beginning of
%   color map.
%
%   colorWheelDirection: direction of the color wheel. Can be:
%   1 or 'clockwise' (equivalent); or, 2 or 'counterclockwise' (equiv.)
%
%   colorWheelExtent: degrees (1 - 360) subtended by the color map, for polar
%   angle maps.
%
% ras, 08/2006
if ~exist('cbar', 'var') | isempty(cbar), cbar = cbarDefault; end
if ~exist('parent', 'var') | isempty(parent), parent = gca; end

if cbar.colorWheel==1
    % draw a color wheel
    if isequal(lower(cbar.colorWheelDirection), 'clockwise')
        direction = 0;
    else
        direction = 1;
    end
    startAngle = cbar.colorWheelStart;
	cmap = cbar.cmap;
	p.doPlot = 0; p.trueColor = 1; p.background = get(gcf, 'Color');
	p.visualField = 'b'; % 'both' fields in cmapWedge
	h = image(cmapWedge(cmap, startAngle, direction, p), 'Parent', parent);
    axis(parent, 'image'); axis(parent, 'off');

%     AX = axis;
%     xText = AX(2) + .1*(AX(2)-AX(1));
%     yText = AX(3) + .5*(AX(4)-AX(3));
%     text(xText, yText, cbar.label, 'Parent', parent);

%     % correct funky aspect ratios (gum):
%     pos = get(parent, 'Position');
%     aspectRatio = pos(3) / pos(4);
%     if aspectRatio > 4 | aspectRatio < 1/4
%         set(parent, 'Position', [pos(1) 0 pos(3) 1]);
%     end

elseif isequal(cbar.direction, 'horiz');
    % draw a horizontal bar
    if isequal(cbar.clim, 'auto') | isempty(cbar.clim)
        clim = [1 cbar.nColors];
    else
        clim = cbar.clim;
    end
    img = ind2rgb(1:cbar.nColors, cbar.cmap);

	% show the image
	% (The Y values maintain an aspect ratio of 35:1)
	aspRatio = 1/15;
    h = image(clim, clim ./ aspRatio, img, 'Parent', parent);

% 	axis(parent, 'image');
% 	axis(parent, [clim clim .* aspRatio]);
    set(parent, 'YTick', []);
    cbar.label(cbar.label=='_') = '-';
    xlabel(parent, cbar.label, 'FontSize', cbar.fontsz, ...
		  'FontName', cbar.font, 'Interpreter', 'none');

else
    % draw a vertical bar
    if isequal(cbar.clim, 'auto')
        clim = [1 cbar.nColors];
    else
        clim = cbar.clim;
	end
    img = ind2rgb([cbar.nColors:-1:1]', cbar.cmap);

	% show the image
	% (The X values maintain an aspect ratio of 15:1)
	aspRatio = 1/15;
	h = image(clim ./ 20, fliplr(clim), img, 'Parent', parent);

% 	axis(parent, 'image');
	axis(parent, [clim .* aspRatio, clim]);
    set(parent, 'XTick', [], 'Ydir', 'normal');
	if checkfields(cbar, 'labelSide') & cbar.labelSide==1
		set(parent, 'YAxisLocation', 'right');
	end
    cbar.label(cbar.label=='_') = '-';
    ylabel(parent, cbar.label, 'FontSize', cbar.fontsz, ...
			'FontName', cbar.font, 'Interpreter', 'none');

end

return


% mlf2pdf_ex is an example for how to use mlf2pdf.
% It creates two buttons (Exit and PDF), which you may use either to exit the
% script or to create the pdf file from the current figure. So you can edit
% the plot "online" and create the pdf from the figure the way it is.

function mlf2pdf_ex

fpl=figure('units','centimeters',...%plotfigure
           'Position',[10 10 10 5]); % position: [llx lly width height]
f=figure('units','centimeters','Position',[5 10 2 2]);     %Buttons
uicontrol(f,'Style','pushbutton','String','-> PDF',...
            'Units','normalized','Pos',[0 0 1 .5],'Callback',@callback_mlf2pdf);
uicontrol(f,'Style','pushbutton','String','Exit',...
            'Units','normalized','Pos',[0 0.5 1 .5],'Callback','close all');
figure(fpl);                %activate plot figure

filename='yourfilename';    %enter your filename here
yourplot;                   %place your plot commands here

 function callback_mlf2pdf(dummy1,dummy2)
    mlf2pdf(fpl,filename,'SIUnits');
 end

 function yourplot
        X=0:pi/10:2*pi;
        Y=sin(X);
        plot(X,Y);
        axis([0,2*pi,-1.5,1.5]);
        grid on;
end
end


function cS = magnetite

%
cs_Mag = crystalSymmetry('m3m');
N = Miller({1,0,0},{1,1,1},cs_Mag);
dist = [0.95, 1];
cS = crystalShape(N./dist);


function errMsg = validateNumber(x, numberName, lb, ub, isInt, prevErrMsgs, enteredStr)
%validateNumber Summary of this function goes here
%   Detailed explanation goes here

    errMsg=prevErrMsgs;
    if(not(isnumeric(x)) || isnan(x))
        enteredStr = ['(Entered: ', enteredStr, ')'];
        errMsg{end+1} = [numberName, ' must be numeric.  ', enteredStr];
        return;
    end

    enteredStr = ['(Entered: ', num2str(x), ')'];

    if(isInt==true)
        if(not(ceil(x) == floor(x)))
            errMsg{end+1} = [numberName, ' must be an integer.  ', enteredStr];
        end
    end

    if(x<lb || x>ub)
        rngStr = ['[',num2str(lb), ', ', num2str(ub)   ,']'];
        errMsg{end+1} = [numberName, ' must be within the range ', rngStr, '.  ', enteredStr];
    end
end


function out = mtimes(a,b,varargin)
% outer quaternion multiplication
%
% Syntax
%   out = a * b
%   out = a * v
%
% Input
%  a - @SO3Grid
%  b - @quaternion
%  v - @vector3d
%
% Output
%  out - @SO3Grid / @vector3d

if isa(a,'SO3Grid') % right multiplication

  if isa(b,'SO3Grid'), b = orientation(b); end

  out = orientation(a) * b;

elseif isa(a,'quaternion')

  if length(a) == 1 % rotate center only

    r = mtimes@orientation(a,b);
    out = b;
    out.a = r.a;
    out.b = r.b;
    out.c = r.c;
    out.d = r.d;
    out.i = r.i;
    if isempty(b.center)
      out.center = a;
    else
      out.center = a * out.center;
    end

  else

    out = a * orientation(b);

  end

else
  error('type mismatch!')
end


function test_suite = test_isLeftOriented
% One-line description here, please.
%   output = test_isLeftOriented(input)
%
%   Example
%   test_isLeftOriented
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2009-04-22,    using Matlab 7.7.0.471 (R2008b)
% Copyright 2009 INRA - Cepia Software Platform.

test_suite = functiontests(localfunctions);

function test_HorizLeft(testCase) %#ok<*DEFNU>

line = [10 20 3 0];
p1 = [15 25];

testCase.assertTrue(isLeftOriented(p1, line));

function test_HorizRight(testCase) %#ok<*DEFNU>

line = [10 20 3 0];
p1 = [15 5];

testCase.assertFalse(isLeftOriented(p1, line));

function test_PointArray(testCase) %#ok<*DEFNU>

% one line, three points
line = [10 20 3 0];
pts = [15 25; 15 15; 15 05];

% expect 3-by-1 array
exp = [true; false; false];
testCase.assertEqual(exp, isLeftOriented(pts, line));

function test_LineArray(testCase)

% four lines, one point
lines = [....
    10 10 3 0; ...  % left
    10 10 0 3; ...  % right
    10 10 1.5 1.5; ...  % left
    10 10 1.5 -1.5; ... % left
];
pt = [21.1 32.2];

% expect 1-by-4 array
exp = [true false true true];

testCase.assertEqual(exp, isLeftOriented(pt, lines));


function [i] = plotgp(i, t, sys, y, std)
% Function plots results of simulation or one-step-ahead
% prediction.
%
%% Syntax
% [i] = plotgp(i, t, sys, y, std);
%
%% Description
% In the upper 2/3 of the figure the output together with 95%
% confidence band and target is plotted, in the lower third of the figure
% the error with corresponding 95% confidence band is plotted. Can be used
% to plot in new or currently active figure.
%
% Input:
% * i   ... the figure handle, if i==0 function plots in current figure
% * t   ... the time vector (x-axis)
% * sys ... the target output
% * y   ... the predicted output
% * std ... the predicted standard deviation
%
% Output:
% * i ... the figure handle
%
% See Also:
% plotgpy, plotgpe
%
% Examples:
% demo_example_gp_simulation.m
%
%%
% * Written by Dejan Petelin

% check sizes of vectors
sz = size(t);
if((size(t,1)~=sz(1) | size(sys,1)~=sz(1) |size(y,1)~=sz(1) | size(std,1)~=sz(1))...
        | (size(t,2)~=sz(2) | size(sys,2)~=sz(2) |size(y,2)~=sz(2) | size(std,2)~=sz(2)))
    warning(['figure ', num2str(i), ': vectors: t, tt, y, std must be same size']);
    disp(strcat(['t: ', num2str(size(t))]));
    disp(strcat(['sys: ', num2str(size(sys))]));
    disp(strcat(['y: ', num2str(size(y))]));
    disp(strcat(['std: ', num2str(size(std))]));
    out = -1;
    return;
end

ix_plot = 1:length(t);
% reduce vector if borders are wanted in figure,
% e.g. ixplot = 2:length(t)-1;

xfill = [t(ix_plot); flipdim(t(ix_plot),1)];
yfill = [y(ix_plot)+2*std(ix_plot);flipdim(y(ix_plot)-2*std(ix_plot),1)];

% if i==0 use current axis (figure)
if (i~=0)
figure(i);
end

% upper part of figure: y
subplot(3,1,1:2)
fill(xfill, yfill, [7 7 7]/8, 'EdgeColor', [0 0 0]/8);
hold on
plot(t,y, 'k-', 'LineWidth',1);
plot(t,sys, 'k--', 'LineWidth',2);

hold off
grid on
xlabel('t');
ylabel('y');
title('GP model simulation')
legend('\mu \pm 2\sigma', '\mu', 'system','Location','NorthEast');
AX=axis;
AX(1:2)=[t(1) t(end)];
axis(AX);

% lower part of figure: e
subplot(3,1,3)
xfill = [t(ix_plot); flipdim(t(ix_plot),1)];
yfill = [2*std(ix_plot);zeros(size(std(ix_plot)))];
fill(xfill, yfill, [7 7 7]/8, 'EdgeColor', [0 0 0]/8);

hold on
plot(t,abs(y-sys), 'k-', 'LineWidth',1);
hold off
legend('2\sigma', '|e|', 'Location','NorthEast');
grid
xlabel('t');
ylabel('e');
AX=axis;
AX(1:2)=[t(1) t(end)];
axis(AX);

return


function jac = autoJac(fun,x0,varargin)
%AUTOJAC  Returns a Automatically Differentiated (AD) Jacobian
%
%   jac = autoJac(fun,x0) uses the user supplied Matlab function to
%   generate the Jacobian using automatic differentiation. The user
%   function must be a Matlab function and must not call external code or
%   class / toolbox functions. If your function breaks any of these
%   conditions consider using mklJac instead.
%
%   The underlying AD algorithm is adiff by William McIlhagga and its
%   documentation pdf is provided in the Differentiation folder. See the
%   BSD license below the code.

%   Copyright (C) 2011 Jonathan Currie (I2C2)

if(~isa(fun,'function_handle'))
    error('Fun should be a function handle!');
end

[~,jac] = adiffget(fun(adiff(x0),varargin{:}));

end

% Copyright (c) 2010, William McIlhagga
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.


report_this_filefun(mfilename('fullpath'));

figure

[xx,yy]=meshgrid(vlon,vlat);
surfl(yy,xx,tmap/1000),shading interp;

li = light('Position',[ 0 0 100],'Style','infinite');
material shiny
lighting gouraud
% axis([ min(vlat) max(vlat) min(vlon) max(vlon) ]);

set(gca,'FontSize',12,'FontWeight','bold',...
    'LineWidth',1.5,...
    'Box','on','SortMethod','childorder','TickDir','out')
axis ij
view([ -90 90])
colormap(gray)

set(gca,'Ylim',[min(vlon) max(vlon)]);
set(gca,'Xlim',[min(vlat) max(vlat)]);

hold on

%pl = plot3(a.Latitude,a.Longitude,a.Longitude*0+6000,'or');


classdef NodalFieldPlotter < handle

    properties (Access = private)
        mesh
        field
    end

    methods (Access = public)

        function obj = NodalFieldPlotter(cParams)
            obj.init(cParams)
        end

        function plot(obj)
            x = obj.mesh.coord(:,1);
            y = obj.mesh.coord(:,2);
            z = obj.field;
            %figure()
            trisurf(obj.mesh.connec,x,y,z)
            view(0,90)
            colorbar
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.mesh = cParams.mesh;
            obj.field = cParams.field;
        end

    end

end


function out = ConvertToCursor(i)

% Converts an RGB image to a matlab compatiable cursor CData.
%
% White Pixels and black pixels will be kept. All other values
% will be converted to NaN (transparent)
%
% Author: Richard Medlock. (2003)

nRows = size(i,1);
nCols = size(i,2);

for r = 1:nRows

    for c = 1:nCols

        if i(r,c,1) == 255 & i(r,c,2) == 255 & i(r,c,3) == 255 % White

            out(r,c) = 2;

        elseif i(r,c,1) == 0 & i(r,c,2) == 0 & i(r,c,3) == 0 % Black

            out(r,c) = 1;

        else % Any other colour

            out(r,c) = NaN;

        end
    end
end


%% dbDivision.m
% This script randomly divides database into 3 parts - training (TRN),
% validating (VAL) and testing (TST).
%
% 16-07-10 Michal Uricar
% 21-03-12 Michal Uricar, LFW annotation in one file

clearvars; close all;

%% Timestamp

fprintf(1,'Started on %s\n\n', datestr(now));

%% Load pruned database

addpath('./Functions');

% load('./MAT/eyefd_on_lfw_pruned.mat');
load('./MAT/db_good.mat');

tmp_as = annotation_struct;

N = annotation_struct.N;

per60 = round(60/100*N);
per20 = round(20/100*N);

tic
indices_perm = randperm(N);
toc

% 60% of images will form training set
training = indices_perm(1:per60); indices = training;
indices_perm(1:per60) = [];
% save training set
%image = tmp_image(training);
annotation_struct.bbox = tmp_as.bbox(training, :);
annotation_struct.names = tmp_as.names(training);
annotation_struct.eye_r = tmp_as.eye_r(training, :);
annotation_struct.eye_l = tmp_as.eye_l(training, :);
annotation_struct.canthus_rr = tmp_as.canthus_rr(training, :);
annotation_struct.canthus_rl = tmp_as.canthus_rl(training, :);
annotation_struct.canthus_lr = tmp_as.canthus_lr(training, :);
annotation_struct.canthus_ll = tmp_as.canthus_ll(training, :);
annotation_struct.mouth = tmp_as.mouth(training, :);
annotation_struct.mouth_corner_r = tmp_as.mouth_corner_r(training, :);
annotation_struct.mouth_corner_l = tmp_as.mouth_corner_l(training, :);
annotation_struct.nose = tmp_as.nose(training, :);
annotation_struct.N = numel(annotation_struct.names);

% save('./MAT/training.mat', 'image');
save('./MAT/TRN.mat', 'annotation_struct', 'indices');

% 20% of images will form validating set
validating = indices_perm(1:per20); indices = validating;
indices_perm(1:per20) = [];
% save validating set
% image = tmp_image(validating);
annotation_struct.bbox = tmp_as.bbox(validating, :);
annotation_struct.names = tmp_as.names(validating);
annotation_struct.eye_r = tmp_as.eye_r(validating, :);
annotation_struct.eye_l = tmp_as.eye_l(validating, :);
annotation_struct.canthus_rr = tmp_as.canthus_rr(validating, :);
annotation_struct.canthus_rl = tmp_as.canthus_rl(validating, :);
annotation_struct.canthus_lr = tmp_as.canthus_lr(validating, :);
annotation_struct.canthus_ll = tmp_as.canthus_ll(validating, :);
annotation_struct.mouth = tmp_as.mouth(validating, :);
annotation_struct.mouth_corner_r = tmp_as.mouth_corner_r(validating, :);
annotation_struct.mouth_corner_l = tmp_as.mouth_corner_l(validating, :);
annotation_struct.nose = tmp_as.nose(validating, :);
annotation_struct.N = numel(annotation_struct.names);
% save('./MAT/validating.mat', 'image');
save('./MAT/VAL.mat', 'annotation_struct', 'indices');

% 20% (the rest) of images will form testing set
testing = indices_perm; indices = testing;
% save testing set
% image = tmp_image(testing);
annotation_struct.bbox = tmp_as.bbox(testing, :);
annotation_struct.names = tmp_as.names(testing);
annotation_struct.eye_r = tmp_as.eye_r(testing, :);
annotation_struct.eye_l = tmp_as.eye_l(testing, :);
annotation_struct.canthus_rr = tmp_as.canthus_rr(testing, :);
annotation_struct.canthus_rl = tmp_as.canthus_rl(testing, :);
annotation_struct.canthus_lr = tmp_as.canthus_lr(testing, :);
annotation_struct.canthus_ll = tmp_as.canthus_ll(testing, :);
annotation_struct.mouth = tmp_as.mouth(testing, :);
annotation_struct.mouth_corner_r = tmp_as.mouth_corner_r(testing, :);
annotation_struct.mouth_corner_l = tmp_as.mouth_corner_l(testing, :);
annotation_struct.nose = tmp_as.nose(testing, :);
annotation_struct.N = numel(annotation_struct.names);
% save('./MAT/testing.mat', 'image');
save('./MAT/TST.mat', 'annotation_struct', 'indices');

%% Timestamp

fprintf(1,'Finished on %s\n\n', datestr(now));


% cart2topo() - convert xyz-cartesian channel coordinates
%               to polar topoplot() coordinates. Input data
%               are points on a sphere centered at (0,0,0)
%               or at optional input 'center'. This function
%               is now DEPRECATED! See Important warning below.
%
% Usage:  >> [th r] = cart2topo(xyz);   % 3-column [x y z] position data
%         >> [th r] = cart2topo(x,y,z); % separate x,y,z vectors
%         >> [th r x y z] = cart2topo(xyz,'key', 'val', ...);
%         >> [th r x y z] = cart2topo(x,y,z,'key', 'val', ...);
%
% Optional inputs:
%    'center'  = [X Y Z] use a known sphere center {Default: [0 0 0]}
%    'squeeze' = plotting squeeze factor (0[default]->1). -1 -> optimize
%                the squeeze factor automatically so that maximum radius is 0.5.
%    'optim'   = [0|1] find the best-fitting sphere center minimizing the
%                standard deviation of the radius values.
%    'gui'     = ['on'|'off'] pops up a gui for optional arguments.
%                Default is off.
%
% Example: >> [th r] = cart2topo(xyz,[1 0 4]);
%
% Notes: topoplot() does not plot channels with radius>0.5
%        Shrink radii to within this range to plot all channels.
%        [x y z] are returned after the optimization of the center
%        and optionally squeezing r towards it by factor 'squeeze'
%
% Important:
%   DEPRECATED: cart2topo() should NOT be used if elevation angle is less than 0
%   (for electrodes below zero plane) since then it returns INNACURATE results.
%   SUBSTITUTE: Use cart2topo = cart2sph() -> sph2topo().
%
% Authors: Scott Makeig, Luca Finelli & Arnaud Delorme SCCN/INC/UCSD,
%          La Jolla, 11/1999-03/2002
%
% See also: topo2sph(), sph2topo(), chancenter()

% Copyright (C) 11/1999 Scott Makeig, SCCN/INC/UCSD, scott@sccn.ucsd.edu
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

% 3-16-00 improved help message -sm
% 1-25-02 put spherror subfunction inside cart2topo -ad
% 1-25-02 help pops-up if no arguments -ad
% 01-25-02 reformated help & license -ad
% 02-13-02 now center fitting works, need spherror outside cart2topo -lf
% 02-14-02 radii are squeezed of squeeze in to fit topoplot circle -lf
% 03-31-02 center fitting is optional
% 04-01-02 automatic squeeze calculation -ad & sm

function [th,r,xx,yy,zz] = cart2topo(x,varargin)

if nargin<1
    help cart2topo
    return;
end;
if nargin >= 2
	if ~ischar(varargin{1})
		y = varargin{1};
		z = varargin{2};
		varargin = varargin(3:end);
	end;
end;
if exist('y') ~= 1
	if size(x,2)==3 % separate 3-column data
		z = x(:,3);
		y = x(:,2);
		x = x(:,1);
	else
		error('Insufficient data in first argument');
	end
end;

g = [];
if ~isempty(varargin)
    try, g = struct(varargin{:});
    catch, error('Argument error in the {''param'', value} sequence'); end;
end;

try, g.optim;      catch, g.optim = 0; end;
try, g.squeeze;    catch, g.squeeze = 0; end;
try, g.center;     catch, g.center = [0 0 0]; end;
try, g.gui;        catch, g.gui = 'off'; end;

if g.squeeze>1
  fprintf('Warning: Squeeze must be less than 1.\n');
  return
end

if ~isempty(g.center) & size(g.center,2) ~= 3
  fprintf('Warning: Center must be [x y z].\n');
  return
end

% convert to columns
x = -x(:); % minus os for consistency between measures
y = -y(:);
z = z(:);

if any(z < 0)
    disp('WARNING: some electrodes lie below the z=0 plane, result may be innacurate')
    disp('         Instead use cart2sph() then sph2topo().')
end;
if strcmp(g.gui, 'on')
	[x y z newcenter] = chancenter(x, y, z, [], 1);
else
	if g.optim == 1
		[x y z newcenter] = chancenter(x, y, z, []);
	else
		[x y z newcenter] = chancenter(x, y, z, g.center);
	end;
end;
radius = (sqrt(x.^2+y.^2+z.^2));   % assume xyz values are on a sphere
xx=-x; yy=-y; zz=z;
x = x./radius; % make radius 1
y = y./radius;
z = z./radius;

r = x; th=x;

for n=1:size(x,1)
  if x(n)==0 & y(n)==0
    r(n) = 0;
  else
    r(n)  = pi/2-atan(z(n)./sqrt(x(n).^2+y(n).^2));
  end
end

r = r/pi;        % scale r to max 0.500
if g.squeeze < 0
    g.squeeze = 1 - 0.5/max(r); %(2*max(r)-1)/(2*rmax);
    fprintf('Electrodes will be squeezed together by %2.3g to show all\n', g.squeeze);
end;
r = r-g.squeeze*r; % squeeze electrodes in squeeze*100% to have all inside

for n=1:size(x,1)
  if abs(y(n))<1e-6
    if x(n)>0
      th(n) = -90;
    else % x(n) <= 0
      th(n) = 90;
    end
  else
    th(n) = atan(x(n)./y(n))*180/pi+90;
    if y(n)<0
      th(n) = th(n)+180;
    end
  end
  if th(n)>180
     th(n) = th(n)-360;
  end
  if th(n)<-180
     th(n) = th(n)+360;
  end
end


function [priormeans,posteriormeans,covmatrix,rbfposteriormeans,rbfcovmatrix] = gpnddisimPredict(model,predtimes,predict_rna,with_obsnoise);

% GPASIMPREDICT Compute predictions (means and a covariance matrix)
% of POL2 and RNA values for the GPASIM model.
%
% FORMAT
%---------------------------------
% DESC computes predictions for the asynchronous Gaussian
% process single input motif model.
%
% ARG model : the model for which the gradient is computed.
%
% ARG pol2times : the time points where predictions for POL2 are needed
%
% ARG rnatime : the time points where predictions for RNA are needed
%
% RETURN means : the predicted mean values, first the POL2
% predictions and then the RNA predictions.
%
% RETURN covmatrix : the covariance matrix between the
% predictions; for example, the diagonal values are the variances
% of each prediction.
%---------------------------------
%
% SEEALSO : gpasimCreate
%
% COPYRIGHT : Jaakko Peltonen, 2011

% GPASIMPREDICT

%predtimes
%pause

if nargin < 4,
  with_obsnoise = 1;
end

numGenes=model.numGenes;
if predict_rna==0,
  numGenes=0;
end;

% compute prior means
if iscell(predtimes)==0,
  pol2priormeans=ones(size(predtimes,1),1)*model.simMean;
else
  pol2priormeans=ones(size(predtimes{1},1),1)*model.simMean;
end;
%model.pol2mean;

if numGenes>0,
  % Mean for the mRNA is nonconstant over time and depends on the
  % B,D,S parameters and on the POL2 mean
  Bj=model.B(1);
  Dj=model.D(1);
  Sj=model.S(1);
  if model.use_disimstartmean==1,
    disimStartMean=model.disimStartMean(1);
  end;
end;

if numGenes>0,
  % compute the RNA mean curve
%  if model.use_disimstartmean==1,
%    rnapriormeans=(Bj+model.simMean*Sj)/Dj+(disimStartMean-(Bj+model.simMean*Sj)/Dj)*exp(Dj*(-predtimes));
%  else
%    rnapriormeans=(Bj+model.simMean*Sj)/Dj*ones(size(predtimes));
%  end;

  rnapriormeans=[];
  tempind1=1;
  for k=1:numGenes,
    if iscell(predtimes)==0,
      nt=length(predtimes);
    else
      nt=length(predtimes{k+1});
    end;

    rnapriormeans=[rnapriormeans;nan*ones(nt,1)];
    if (model.use_disimstartmean==1),
      if iscell(predtimes)==0,
        tempt=predtimes;
      else
        tempt=predtimes{k+1};
      end;
      delayedt=tempt-model.delay(k);

      I=find(delayedt<0);
      delayedt(I)=0;
      rnapriormeans(tempind1:tempind1+nt-1)=...
          model.disimStartMean(k)*exp(model.D(k)*(-tempt)) ...
          +(model.B(k)/model.D(k))*(1-exp(-model.D(k)*tempt)) ...
          +(model.simMean*model.S(k)/model.D(k))*(1-exp(-model.D(k)*delayedt));
    else
      if iscell(predtimes)==0,
        tempt=predtimes;
      else
        tempt=predtimes{k+1};
      end;
      delayedt=tempt-model.delay(k);
      I=find(delayedt<0);
      delayedt(I)=0;
      rnapriormeans(tempind1:tempind1+nt-1)=...
          ((model.B(k)+model.simMean*model.S(k))/model.D(k))*exp(model.D(k)*(-tempt))...
          +((model.B(k)+model.simMean*model.S(k))/model.D(k))*(1-exp(-model.D(k)*delayedt));
    end;
    tempind1=tempind1+nt;
  end;
  %size(rnapriormeans)
  %size(pol2priormeans)
end;

if 1,
if with_obsnoise,
  % This version of K_new does include observation noise
  K_new=kernCompute(model.kern, predtimes);
else
  % This version of K_new does not include observation noise
  K_new=kernCompute(model.kern, predtimes, predtimes);
end

predmodeltimes=model.t;
if (iscell(predtimes)==1) && (iscell(model.t)==0),
  predmodeltimes={model.t,model.t};
end;
if (iscell(predtimes)==0) && (iscell(model.t)==1),
  predtimes={predtimes,predtimes};
end;

K_new_old=kernCompute(model.kern, predtimes, predmodeltimes);
K_old=model.K;
K_old_new=K_new_old';
end;

%K_old
%pause

if 0,
K_old_ndsim=ndsimKernCompute(model.kern.comp{1}.comp{1},model.t);
K_old_nddisim=nddisimKernCompute(model.kern.comp{1}.comp{2},model.t);
K_old_nddisimXndsim=nddisimXndsimKernCompute(model.kern.comp{1}.comp{2},model.kern.comp{1}.comp{1},model.t);
K_old=[K_old_ndsim K_old_nddisimXndsim';K_old_nddisimXndsim K_old_nddisim];
K_old=real(K_old);

K_new_ndsim=ndsimKernCompute(model.kern.comp{1}.comp{1},predtimes);
K_new_nddisim=nddisimKernCompute(model.kern.comp{1}.comp{2},predtimes);
K_new_nddisimXndsim=nddisimXndsimKernCompute(model.kern.comp{1}.comp{2},model.kern.comp{1}.comp{1},predtimes);
K_new=[K_new_ndsim K_new_nddisimXndsim';K_new_nddisimXndsim K_new_nddisim];
K_new=real(K_new);

K_new_old_ndsim=ndsimKernCompute(model.kern.comp{1}.comp{1},predtimes,model.t);
K_new_old_nddisim=nddisimKernCompute(model.kern.comp{1}.comp{2},predtimes,model.t);
K_new_old_ndsimXnddisim=nddisimXndsimKernCompute(model.kern.comp{1}.comp{2},model.kern.comp{1}.comp{1},model.t,predtimes)';
K_new_old_nddisimXndsim=nddisimXndsimKernCompute(model.kern.comp{1}.comp{2},model.kern.comp{1}.comp{1},predtimes,model.t);
K_new_old=[K_new_old_ndsim K_new_old_ndsimXnddisim;K_new_old_nddisimXndsim K_new_old_nddisim];
K_new_old=real(K_new_old);

K_old_new=K_new_old';

noisekern_new=kernCompute(model.kern.comp{2}, predtimes);
noisekern_old=kernCompute(model.kern.comp{2}, model.t);
K_old=K_old+noisekern_old;
K_new=K_new+noisekern_new;
end;

tempm=model.m;

% If we do not want to predict using RNA observations, throw out kernel parts related to RNA
if numGenes==0,
  if iscell(model.t)==0,
    ot=length(model.t);
    nt=length(predtimes);
  else
    % ot=0;
    % nt=0;
    % for k=1:length(model.t),
    %   ot=ot+size(model.t{k},1);
    %   nt=nt+size(predtimes{k},1);
    % end;
    ot=length(model.t{1});
    nt=length(predtimes{1});
  end;
  K_old=K_old(1:ot,1:ot);
  K_new_old=K_new_old(1:nt,1:ot);
  K_old_new=K_old_new(1:ot,1:nt);
  K_new=K_new(1:nt,1:nt);
  tempm=tempm(1:ot);
end;

if numGenes>0,
  priormeans=[pol2priormeans;rnapriormeans];
else
  priormeans=pol2priormeans;
end;

%predict_rna
%K_old
%K_new_old
%pause
%figure; imagesc(K_old);
%pause

posteriormeans=priormeans+K_new_old*(K_old\tempm);
%covmatrix=K_new-K_new_old*inv(K_old)*K_old_new;

covmatrix=K_new-K_new_old*(K_old\K_old_new);
if(min(diag(covmatrix))<0),
  % Try omitting the first row and column of the kernel
  % since it might be all zeroes

  if iscell(model.t)==0,
    ot_pol2=length(model.t);
    ot_rna=length(model.t);
    nt_pol2=length(predtimes);
    nt_rna=length(predtimes);
  else
    ot_pol2=size(model.t{1},1);
    ot_rna=size(model.t{2},1);
    nt_pol2=size(predtimes{1},1);
    nt_rna=size(predtimes{2},1);
  end;

  if (numGenes>0),
    okentries=[(2:ot_pol2) (ot_pol2+2:ot_pol2+ot_rna)];
  else
    okentries=[2:ot_pol2];
  end;

  K_old=K_old(okentries,okentries);
  K_new_old=K_new_old(:,okentries);
  K_old_new=K_old_new(okentries,:);
  covmatrix=K_new-K_new_old*(K_old\K_old_new);
end;

if 0,
  % Compute predictions for the driving RBF-kernel GP; only valid for
  % the SIM-DISIM model.

  % extract RBF transforms settings from DISIM part of the SIM-DISIM kernel
  disimkern=model.kern.comp{1}.comp{2};
  if isfield(disimkern, 'options') ...
        && isfield(disimkern.options, 'isNegativeS') ...
        && kern.options.isNegativeS,
    error('DISIM kern uses negative variance, cannot decide transform settings for RBF-SIM-DISIM prediction');
  else
    rbftransformsettings{1}=disimkern.transforms(1).transformsettings; % setting for inverse width
    rbftransformsettings{2}=[0 10]; % setting for RBF variance, not
                                    % used in GPNDDISIM model
  end

  % create a RBF kernel to match the settings in the NDSIM-NDDISIM model
  rbfkern=kernCreate(predtimes,'rbf');
  rbfkern=kernExpandParamTransformSettings(rbfkern,rbftransformsettings);
  %[rbfpars,rbfnams]=kernExtractParam(rbfkern);
  [modelpars,modelnams]=gpnddisimExtractParam(model);
 % modelpars
 % modelnams
 % pause
  fprintf(1,'Calling gpdisimExpandParam\n');
  model=gpnddisimExpandParam(model,modelpars);
  fprintf(1,'Calling gpdisimExpandParam done\n');

  rbfpar_inversewidth=modelpars(1);  % assumes that inverse width is parameter 1 in the NDSIM-NDDISIM model
  rbfpar_variance=sigmoidabTransform(1, 'xtoa', rbftransformsettings{2});
  rbfpars(1)=rbfpar_inversewidth;
  rbfpars(2)=rbfpar_variance;
  rbfkern=kernExpandParam(rbfkern,rbfpars);
%  rbfkern
%  rbftransformsettings

  % create fake SIM and DISIM kernels corresponding to the NDSIM
  % and NDDISIM kernels... this is just a quick hack

  K_rbf=kernCompute(rbfkern,predtimes);
  K_rbf_sim=simXrbfKernCompute(model.kern.comp{1}.comp{1},rbfkern,model.t,predtimes)';
  K_rbf_disim=disimXrbfKernCompute(model.kern.comp{1}.comp{2},rbfkern,model.t,predtimes)';
  K_rbf_old=[K_rbf_sim K_rbf_disim];
  K_old_rbf=K_rbf_old';
  %size(K_rbf_old)
  %size(K_old)
  %size(model.m)

  K_old=model.K;
  rbfposteriormeans=0+K_rbf_old*(K_old\model.m);
  rbfcovmatrix=K_rbf-K_rbf_old*inv(K_old)*K_old_rbf;

%  rbfposteriormeans=real(rbfposteriormeans);
%  rbfcovmatrix=real(rbfcovmatrix);
else
  rbfposteriormeans=[];
  rbfcovmatrix=[];
end;


function [] = analyzeParVariation(logprefix, signalname, signalname_ref)
%
% Author: Thomas Herrmann <thomas.herrmann@tum.de>     Date: 22-10-2020
%
% Description:
%   extracts log data from all Simulink simulation logs and displays in one
%   plot. Purpose of this script is the tuning of the TMPC algorithm.
%
% Input:
%   logprefix:      Prefix of all log files from simulation
%   signalname:     name of signal to be compared
%   signalname_ref: name of reference signal
%
%% Algorithm

% Get all log files with specific prefix
F = dir([logprefix, '*.*']);
% Allocate legend
lgd = struct();
F_data_struct = struct();

figure; hold on; grid on;
legend('-DynamicLegend');

for i = 1:length(F)
    % Get data from log file
    data_tmp = load(F(i).name);

    % get file identifier with specific parameter set
    fname = strrep(...
        strrep(F(i).name,[logprefix, '_'],''), ...
        '.mat', '');

    % append to struct for later use
    F_data_struct.(fname) = getfield(data_tmp.debug, signalname);

    % plot different paramter set signals over s coordinate
    plot(data_tmp.debug.debug_mvdc_path_matching_debug_ActualTrajPoint_s_glob_m.Data, ...
        F_data_struct.(fname).Data, ...
        'DisplayName', fname);

    set(0, 'DefaultLegendInterpreter', 'none')

end

signal_ref = getfield(data_tmp.debug, signalname_ref);
plot(data_tmp.debug.debug_mvdc_path_matching_debug_ActualTrajPoint_s_glob_m.Data, ...
    signal_ref.Data, ...
    'DisplayName', 'ref');
set(0, 'DefaultLegendInterpreter', 'none')
xlabel('s in m'); ylabel('v in mps');

end


function varargout = test_smooth( f, N, DOM )
% TEST_SMOOTH Runs diagnostic checks on a TFOCS smooth function object.
% TEST_SMOOTH( F )
%   tests whether the function handle F works as a TFOCS smooth
%   function object.
%
%   Requirements: f = F(X) must return the value of the function at X.
%       [f,g] = F(X) must return the value, f, and the gradient, g.
%
%   For an example, see SMOOTH_QUAD.M
%
% TEST_SMOOTH( F, N )
%    specifies the size of the domain space.  If N is a scalar,
%    then the domain space is the set of  N x 1 vectors.
%    If N is a matrix of the form [n1, n2], the the domain
%    space is the set of n1 x n2 matrices.
%
% TEST_SMOOTH( ..., DOM )
%    specifies the domain of F.  DOM can be of the form [a,b]
%    which signifies the 1D set (a,b).
%
% OK = TEST_SMOOTH(...)
%    returns "true" if all tests are passed, and "false" otherwise.
%
% See also private/tfocs_smooth, smooth_huber

OK = false;
PLOT = true;

error(nargchk(1,3,nargin));

if ~isa(f,'function_handle')
    fail('TFOCS smooth function must be a FUNCTION HANDLE');
    return;
end
fprintf('== Testing the smooth function %s ==\n', func2str(f) );

FORCE_N = false;  % always require a vector input
if nargin < 2 || isempty(N),   N = 10;
else FORCE_N = true;
end
if nargin < 3 || isempty(DOM), DOM = [-1,1];    end

a = DOM(1); b = DOM(2);

x = (a+b)/2;
fprintf('Testing scalar inputs... \n');
try
    vi = f(x);
catch
    fail('TFOCS smooth function failed to return a function value');
    return;
end
if isinf(vi)
    fail('TFOCS smooth function tester: default domain is invalid. Please specify valid domain');
    return;
end
fprintf('\t\t\t\t...passed. \n');

% Now, also ask for the gradient
fprintf('Testing gradient output... \n');
try
    [vi,gi] = f(x);
catch
    fail('TFOCS smooth function failed to return a derivative value');
    return;
end
fprintf('\t\t\t\t...passed. \n');

% Now, try a vector
if isscalar(N)
    x = repmat(x,N,1);
else
    x = repmat(x,N(1),N(2));
    % if a > 0, assume we want a PSD matrix:
    if a >= 0
        x = ones(N(1),N(2)) + eye(N(1),N(2) );
    end
end
fprintf('Testing vector inputs... \n');
try
    [vi,gi] = f(x);
catch
    fail('TFOCS smooth function failed when supplied a vector input');
    return;
end
fprintf('\t\t\t\t...passed. \n');

% 1D example.  Does not require function to be vectorized
n   = 100;  % number of grid points
h   = (b-a)/n;
grid = (a+h/2):h:(b-h/2);

v    = zeros(size(grid));
g    = zeros(size(grid));
first = @(x) x(1);
for i = 1:length(grid)
    v(i) = f(grid(i));
    if isinf(v(i))
        g(i) = v(i);
    else
        [v(i),gi] = f(grid(i));
        g(i) = first(gi);
    end
end

if PLOT
    figure;
    clf;
    plot(grid,v,'.-');
    hold all
    plot(grid,g,'.-');
    legend('function','derivative');
%     title(func2str(f),'interpreter','none');
    line([a,b], 0*[1,1],'color','k' )
    if a < 0 && b > 0
        line( 0*[1,1], get(gca,'ylim'),'color','k' );
    end
end

OK = true;

if nargout > 0
    varargout{1} = OK;
end

disp('Test passed succesfully.');

function fail(str)
    disp('Test failed.  Reason:');
    disp(str);

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


function g = indexardKernGradient(kern, x, varargin)

% INDEXARDKERNGRADIENT Gradient of INDEXARD kernel's parameters.
% FORMAT
% DESC computes the gradient of functions with respect to the
% index ard based covariance function
% kernel's parameters. As well as the kernel structure and the
% input positions, the user provides a matrix PARTIAL which gives
% the partial derivatives of the function with respect to the
% relevant elements of the kernel matrix.
% ARG kern : the kernel structure for which the gradients are being
% computed.
% ARG x : the input locations for which the gradients are being
% computed.
% ARG partial : matrix of partial derivatives of the function of
% interest with respect to the kernel matrix. The argument takes
% the form of a square matrix of dimension  numData, where numData is
% the number of rows in X.
% RETURN g : gradients of the function of interest with respect to
% the kernel parameters. The ordering of the vector should match
% that provided by the function kernExtractParam.
%
% FORMAT
% DESC computes the derivatives as above, but input locations are
% now provided in two matrices associated with rows and columns of
% the kernel matrix.
% ARG kern : the kernel structure for which the gradients are being
% computed.
% ARG x1 : the input locations associated with the rows of the
% kernel matrix.
% ARG x2 : the input locations associated with the columns of the
% kernel matrix.
% ARG partial : matrix of partial derivatives of the function of
% interest with respect to the kernel matrix. The matrix should
% have the same number of rows as X1 and the same number of columns
% as X2 has rows.
% RETURN g : gradients of the function of interest with respect to
% the kernel parameters.
%
% SEEALSO indexardKernParamInit, kernGradient, indexardKernDiagGradient, kernGradX
%
% COPYRIGHT : Neil D. Lawrence, 2011

% KERN

  g = zeros(1, length(kern.indices));
  covGrad = varargin{end};
  if nargin < 4
    x2 = x;
  else
    x2 = varargin{1};
  end
  for i = 1:length(kern.indices);
    g(i) = sparse(round(x)==kern.indices(i))'*covGrad*sparse(round(x2)==kern.indices(i));
  end
end


function hm=plotsurf(node,face,varargin)
%
% hm=plotsurf(node,face,opt)
%
% plot 3D surface meshes (2d manifold) or polylines (1d manifold)
%
% author: Qianqian Fang <fangq at nmr.mgh.harvard.edu>
%
% input:
%      node: node coordinates, dimension (nn,3); if node has a
%            4th column, it will be used to set the color at each node.
%      face: triangular surface face list; if face has a 4th column,
%            it will be used to separate the surface into
%            sub-surfaces and display them in different colors;
%            face can be a cell array, each element of the array represents
%            a polyhedral facet of the mesh, if an element is an array with
%            two array subelements, the first one is the node index, the
%            second one is a scalar as the group id of the facet.
%      opt:  additional options for the plotting, see plotmesh
%
% output:
%   hm: handle or handles (vector) to the plotted surfaces
%
% example:
%
%   h=plotsurf(node,face);
%   h=plotsurf(node,face,'facecolor','r');
%   h=plotsurf(node,edges,'linestyle','-','linewidth',2,'color','r');
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

rngstate = rand ('state');

if(nargin>=2)
  randseed=hex2dec('623F9A9E'); % "U+623F U+9A9E"
  if(isoctavemesh) randseed=randseed+3; end
  if(~isempty(getvarfrom({'caller','base'},'ISO2MESH_RANDSEED')))
        randseed=getvarfrom({'caller','base'},'ISO2MESH_RANDSEED');
  end
  rand('state',randseed);

  if(iscell(face))
    sc=sparse(10,3); % face colormap
    sc(1:10,:)=rand(3,10)';
    len=length(face);
    newsurf=cell(1);
    % reorganizing each labeled surface into a new cell
    for i=1:len
        fc=face{i};
        if(iscell(fc) && length(fc)>=2)
            if(fc{2}+1>10)
                sc(fc{2}+1,:)=rand(1,3);
            end
            if(fc{2}+1>length(newsurf))
                newsurf{fc{2}+1}={};
            end
            newsurf{fc{2}+1}{end+1}=fc{1};
        else % unlabeled facet is tagged by 0
            if(iscell(fc))
                newsurf{1}{end+1}=cell2mat(fc);
            else
                newsurf{1}{end+1}=fc;
            end
        end
    end
    hold on;
	h=[];
    newlen=length(newsurf);

    for i=1:newlen
        if(isempty(newsurf{i})); continue; end
        try
            subface=cell2mat(newsurf{i}')';
            if(size(subface,1)>1 && ismatrix(subface))
               subface=subface';
            end
            h=[h patch('Vertices',node,'Faces',subface,'facecolor',sc(i,:),varargin{:})];
        catch
            for j=1:length(newsurf{i})
                h=[h patch('Vertices',node,'Faces',newsurf{i}{j},'facecolor',sc(i,:),varargin{:})];
            end
        end
    end
  else
    if(size(face,2)==4)
        tag=face(:,4);
		types=unique(tag);
        hold on;
		h=[];
	    for i=1:length(types)
            if(size(node,2)==3)
                h=[h plotasurf(node,face(tag==types(i),1:3),'facecolor',rand(3,1),varargin{:})];
            else
                h=[h plotasurf(node,face(tag==types(i),1:3),varargin{:})];
            end
        end
    else
        h=plotasurf(node,face,varargin{:});
    end
  end
end
if(~isempty(h))
  axis equal;
  if(all(get(gca,'view')==[0 90]))
      view(3);
  end
end
if(~isempty(h) && nargout>=1)
  hm=h;
end

rand ('state',rngstate);

%-------------------------------------------------------------------------
function hh=plotasurf(node,face,varargin)
isoct=isoctavemesh;
if(size(face,2)<=2)
    h=plotedges(node,face,varargin{:});
else
  if(size(node,2)==4)
	if(isoct && ~exist('trisurf','file'))
	    h=trimesh(face(:,1:3),node(:,1),node(:,2),node(:,3),node(:,4),'edgecolor','k',varargin{:});
	else
	    h=trisurf(face(:,1:3),node(:,1),node(:,2),node(:,3),node(:,4),varargin{:});
	end
  else
	if(isoct && ~exist('trisurf','file'))
	    h=trimesh(face(:,1:3),node(:,1),node(:,2),node(:,3),'edgecolor','k',varargin{:});
	else
	    h=trisurf(face(:,1:3),node(:,1),node(:,2),node(:,3),varargin{:});
    end
  end
end
if(exist('h','var')) hh=h; end


function C = cell_add(A,B,a,b)

% cell_add - add two cell arrays
%
%   C = cell_add(A,B,a,b);
%
%   C{i} = a*A{i} + b*B{i};
%
%   Copyright (c) 2008 Gabriel Peyre

if nargin<3
    a = 1;
end
if nargin<4
    b = 1;
end

if iscell(A)
    if length(A)~=length(B)
        error('A and B must be of the same size');
    end
    for i=1:length(A)
        C{i} = cell_add(A{i},B{i},a,b);
    end
    return;
end

C = a*A + b*B;


function minimize( varargin )

%MINIMIZE Specifiies a convex (or affine) objective to be maximized.

cvx_problem = evalin( 'caller', 'cvx_problem', '[]' );
if isempty( cvx_problem ) || ~isa( cvx_problem, 'cvxprob' ),
    error( 'A cvx problem does not exist in this scope.' );
end
if ~isempty( cvx_problem.direction ),
    if isequal( cvx_problem.direction, 'find' ),
        error( 'Objective functions cannot be added to sets.' );
    else
        error( 'An objective function has already been supplied.' );
    end
end

if nargin < 1,
    error( 'Objective expression missing.' );
elseif iscellstr( varargin ),
    arg = evalin( 'caller', sprintf( '%s ', varargin{:} ) );
elseif nargin > 1,
    error( 'Too many input arguments.' );
else
    arg = varargin{1};
end

if ~isa( arg, 'cvx' ) && ~isa( arg, 'double' ) && ~isa( arg, 'sparse' ),
    error( 'Cannot accept an objective of type ''%s''.', class( arg ) );
end
persistent remap
if isempty( remap ),
    remap = cvx_remap( 'convex', 'log-convex' );
end
vx = remap( cvx_classify( arg ) );
if ~all( vx ),
    error( 'Disciplined convex programming error:\n   Cannot minimize a(n) %s expression.', cvx_class(arg(vx==0),false,true) );
end

newobj( cvx_problem, 'minimize', arg );

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


classdef blockCoeff
%BLOCKCOEFF   Class to convert linear operator to derivative coefficents.
%   This class is not intended to be called directly by the end user.
%
% See also LINOP, CHEBOP, CHEBOPPREF.

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Developer notes
%
% This class converts a linBlock object into a list of coefficients for the
% (descending) powers of the derivative in the operator.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS PROPERTIES:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    properties ( Access = public )
        coeffs = [];
        domain
        pref = chebfunpref;
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS CONSTRUCTOR:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function A = blockCoeff(varargin)
            % When called with no arguments, the returned object causes the
            % block's stack to be evaluated with these methods to produce
            % coefficients.
            if ( isempty(varargin{1}) )
                pref = cheboppref;
                A.domain = pref.domain;
                return

            % Calling the constructor with a linBlock argument initiates the
            % process of evaluating the stack with a dummy object of this class.
            elseif ( isa(varargin{1}, 'linBlock') )
                L = varargin{1};
                dummy = blockCoeff([]);
                dummy.domain = L.domain;
                if ( nargin == 2 )
                    dummy.pref = varargin{2};
                end
                A = L.stack(dummy);

            % If the constructor is called with data, just make a regular object
            % out of it.
            else
                f = varargin{1};
                if ( ~iscell(f) )
                    f = {f};
                end
                A.coeffs = f;
                A.domain = varargin{2};
                if ( nargin == 3 )
                    A.pref = varargin{3};
                end
            end
        end
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% OTHER BASIC CONSTRUCTORS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        % These are the basic constructors.

        function I = eye(A)
            I = blockCoeff(chebfun(1, A.domain, A.pref), A.domain);
        end

        function I = zeros(A)
            I = blockCoeff(chebfun(0, A.domain, A.pref), A.domain);
        end

        function F = mult(A, f)
            F = blockCoeff(f, A.domain);
        end

        function C = cumsum(A, m)
            error('CHEBFUN:BLOCKCOEFF:cumsum:notSupported', ...
                'Conversion of integration to coefficients is not supported.')
        end

        function D = diff(A, order)

            if ( nargin < 2 )
                order = 1;
            end

            if ( ~isempty(A.coeffs) )
                % This syntax is used by the mtimes method to differentiate
                % an existing operator.
                D = A;
            else
                % Initialize with an identity.
                D = eye(A);
            end

            % Differentiate the requested number of times.
            c = D.coeffs;
            for d = 1:order
                m = numel(c);
                c = c([1, 1:m]);
                for k = 2:m
                    c{k} = diff(c{k}) + c{k+1};
                end
                c{m+1} = diff(c{m+1});
            end
            D = blockCoeff(c, A.domain);

        end

        function S = sum(A)
            error('CHEBFUN:BLOCKCOEFF:sum:notSupported', ...
                'Conversion of integration to coefficients is not supported.')
        end

        function E = feval(A, location, direction)
            error('CHEBFUN:BLOCKCOEFF:feval:notSupported', ...
                'Conversion of evaluation to coefficients is not supported.')
        end

        function F = inner(f)
            error('CHEBFUN:BLOCKCOEFF:inner:notSupported', ...
                'Conversion of inner product to coefficients is not supported.')
        end

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function C = mtimes(A, B)

            if ( isnumeric(A) )
                % Allow multiplying a BLOCKCOEFF with a scalar.
                c = B.coeffs;
                for k = 1:numel(B.coeffs)
                    c{k} = A*c{k};
                end

                % Create the result.
                C = blockCoeff(c, B.domain);
                return
            elseif ( isnumeric(B) )
                C = mtimes(B, A);
                return
            end

            if ( isempty(A.coeffs) || isempty(B.coeffs) )
                C = blockCoeff([]);
                return
            end

            % Initialize constant term of A times the coeffs of B.
            c = B.coeffs;
            for k = 1:numel(B.coeffs)
                c{k} = A.coeffs{end}.*c{k};
            end

            % Do a convolution-style multiplication for the rest of A.
            if ( numel(A.coeffs) > 1 )
                z = {0*c{1}};  % an appropriate zero chebfun
            end
            for j = 1:numel(A.coeffs)-1
                B = diff(B);  % differentiate this operator
                c = [z, c];
                for k = 1:numel(B.coeffs)
                    c{k} = c{k} + A.coeffs{end-j}.*B.coeffs{k};
                end
            end

            % Create the result.
            C = blockCoeff(c, A.domain);
        end

        function C = plus(A, B)
            sA = numel(A.coeffs);
            sB = numel(B.coeffs);

            % Empty operand returns empty result.
            if ( (sA == 0) || (sB == 0) )
                C = blockCoeff([]);
                return
            end

            % Get to same length.
            if ( sA < sB )
                z = {0*A.coeffs{1}};
                A.coeffs = [repmat(z, 1, sB-sA), A.coeffs];
                sA = sB;
            elseif ( sB < sA )
                z = {0*B.coeffs{1}};
                B.coeffs = [repmat(z, 1, sA-sB), B.coeffs];
            end

            % Do the work.
            c = cell(1, sA);
            for k = 1:sA
                c{k} = A.coeffs{k} + B.coeffs{k};
            end
            C = blockCoeff(c, A.domain);
        end

        function A = uminus(A)
            A.coeffs = cellfun(@uminus, A.coeffs, 'uniform', false);
         end

        function A = uplus(A)
        end

    end

end


function [ y2, m2, d2, f2 ] = ymdf_inc_islamic ( y1, m1, d1, f1, days )

%*****************************************************************************80
%
%% YMDF_INC_ISLAMIC increments an Islamic YMDF date by DAYS days.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 April 2103
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y1, M1, D1, real F1,
%    the YMDF date.
%
%    Input, real DAYS, the number of days to advance the date.
%
%    Output, integer Y2, M2, D2, real F2,
%    the incremented YMDF date.
%

%
%  Copy the parameters.
%
  y2 = y1;
  m2 = m1;
  d2 = d1;
  f2 = f1 + days;
%
%  Check the parameters.
%
  [ y2, m2, d2, f2, ierror ] = ymdf_check_islamic ( y2, m2, d2, f2 );

  return
end


function a = uplus(a)
%UPLUS        Implements  +a  for intervals
%

% written  10/16/98     S.M. Rump
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged, improved performance
%


%%
% Calculates b based on time using Mc and plots it - called from
% cumulative window
%%

report_this_filefun(mfilename('fullpath'));

inter = 50;
incr = 10;

%%
% set step_cat as a dummy variable so that newt2 can be reassigned
% for use in mcperc_ca3.  newt2 is reset at end.
%%

step_cat = newt2;
bv2 = [];
bv3 = [] ;
me = [];
bvm = [];
ctr = 0;
i=1;
Nmin=50;
%% b=newt2;  %% initialization for bvalca3.m
day_start=0;
day_end=0;

inpr1 = 5;

nibt = 200;
win_step = 200;
for ind = 1:win_step:length(step_cat)-win_step
    newt2 = step_cat(ind:ind+nibt,:);

    %%
    % calculation based on best combination of 90% and 95% probability -- default
    %%

    %         elseif inpr1 == 5
    mcperc_ca3;
    if isnan(Mc95) == 0
        magco = Mc95;
    elseif isnan(Mc90) == 0
        magco = Mc90;
    else
        [bv magco stan av me mer me2,  pr] =  bvalca3(newt2,1,1);
    end
    l = newt2.Magnitude >= magco-0.05;
    if length(newt2(l,6)) <= Nmin
        %                disp(['%%Warning --bwithtimc--%%  less than 50 events in step ']);
    end
    [ntl,ntw] = size(newt2(l,:));
    if ntl <= 1
        disp('%%ERROR --bwithtimc--%%  Not enough data to plot');
        newt2 = step_cat;
        return
    end
    [mea bv stand,  av] = bmemag(newt2(l,:));

    days = (max(newt2.Date)-min(newt2.Date))*365.0;

    bvm = [bvm; bv step_cat(ind,3) step_cat(ind+nibt,3) magco days ind ind+nibt av];
end  %% end of for loop!!
%end

[bvml,bvmw] = size(bvm);
if bvml <= 1
    disp('%%ERROR --bwithtimc--%%  Not enough data to calculate Mc');
    newt2 = step_cat;
    return
end
if ind + win_step < length(step_cat)
    newt2 = step_cat(ind+win_step+1:length(step_cat),:);
    %%
    % calculation based on best combination of 90% and 95% probability -- default
    %%

    if inpr1 == 5
        mcperc_ca3;
        if isnan(Mc95) == 0
            magco = Mc95;
        elseif isnan(Mc90) == 0
            magco = Mc90;
        else
            [bv magco stan av me mer me2,  pr] =  bvalca3(newt2,1,1);
        end
        l = newt2.Magnitude >= magco-0.05;
        if length(newt2(l,6)) <= Nmin
            %                disp(['%%Warning --bwithtimc--%%  less than 50 events in step ']);
        end
        [ntl,ntw] = size(newt2(l,:));
        if ntl <= 1
            disp('%%ERROR --bwithtimc--%%  Not enough data to plot');
            newt2 = step_cat;
            return
        end
        [mea bv stand,  av] = bmemag(newt2(l,:));

    end
end
bvm = [bvm; bv step_cat(ind+win_step,3) step_cat(length(step_cat),3) magco days ind ind+nibt av];

%bvm(length(bvm)+1,:) = bvm(ind,:)
newt2 = step_cat;


%Voice Based Biometric System
%By Ambavi K. Patel.

function mfcc3=melcep(mel1,powspc1,noc1,fsize1,nwin1)
mfcc1(1:noc1,1:nwin1)=0;
for j=1:nwin1
 n=floor(fsize1/2);
 mfcc1(:,j)=dct(log(mel1*abs(powspc1(1:n,j).^2)));
 %converting the power-spectrum to a melfrequency spectrum &taking the logarithm of that spectrum and by computing its inverse using
 %discrete cosine transform
end;
mfcc2(1:13,1:nwin1)=0;
mfcc2(1:13,1:nwin1)=mfcc1(3:15,1:nwin1);
mfcc3=nanclr(mfcc2);


function [ new_input_args ] = reorient_chipper_args( symmetry, datasize, varargin)
%REORIENT_CHIPPER_ARGS Applies a transform to the chipper indexing
%
% This function does nothing but transform the arguments into a chipper
% function based on the symmetry specified.
%
% A chipper function is a simplified function of a file reader.  It takes
% only three arguments: [minIndexInDimension1 maxIndexInDimension1],
% [minIndexInDimension2 maxIndexInDimension2], [subsampleInDimension1,
% subsampleInDimension2].  All other information such as the file handle
% and other auxilliary information must be contained within the chipper
% function.
%
% The SYMMETRY parameter is used to perform symmetry operations on the
% imported image data.  A combination of horizontal mirroring (hm), vertical
% mirroring (vm) and transpose(tr) is used to accomplish the symmetry
% operations.  The 'symmetry' input parameter is defined as [ hm vm tr ], where
% each of the elements can be either 0 or 1 to indicate whether to apply a
% transformation or not.
%
%   [ 0 0 0 ] - default setting; successive pixels on disk are interpreted
%               to fill the first dimension in a MATLAB array (vertical, if
%               viewed in imagesc/imshow without any reorienting)
%   [ 1 0 1 ] -  90 degrees CCW from [ 0 0 0 ]
%   [ 0 1 1 ] -  90 degrees  CW from [ 0 0 0 ]
%   [ 1 1 0 ] - 180 degrees     from [ 0 0 0 ]
%
%   [ 0 0 1 ] - transpose of [ 0 0 0 ];
%   [ 0 1 0 ] -  90 degrees CCW from [ 0 0 1 ]
%   [ 1 0 0 ] -  90 degrees  CW from [ 0 0 1 ]
%   [ 1 1 1 ] - 180 degrees     from [ 0 0 1 ]
%
% Written by: Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

if symmetry(3)
    new_input_args={};
    if(nargin>=3), new_input_args{2}=varargin{1}; end;
    if(nargin>=4), new_input_args{1}=varargin{2}; end
    if(nargin>=5), new_input_args{3}=varargin{3}(end:-1:1); end;
else
    new_input_args=varargin;
end
if symmetry(1)
    if(nargin>=3)
        new_input_args{1}=double(datasize(1))-new_input_args{1}(end:-1:1)+1;
        % The double around datasize allows this to work on empty arguments.
    end
end
if symmetry(2)
    if(nargin>=4)
        new_input_args{2}=double(datasize(2))-new_input_args{2}(end:-1:1)+1;
    end
end

end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function outn=eq(x,y)

precAndSize

for ii=1:max(ex,ey)
 imag=false;
 if ex==1
  [xrval,xival]=getVals(x,1);
  [yrval,yival]=getVals(y,ii);
 elseif ey==1
  [xrval,xival]=getVals(x,ii);
  [yrval,yival]=getVals(y,1);
 else
  [xrval,xival]=getVals(x,ii);
  [yrval,yival]=getVals(y,ii);
 end
  outn(ii)=mpfr_eq(precision,xrval,yrval);
  if outn(ii)==0, outn(ii)=1; else, outn(ii)=0; end
end % for ii=1:max(ex,


function I = eye(disc)
%EYE   Identity operator for VALSDISCRETIZATION discretization.

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

n = disc.dimension;
I = eye(sum(n));

end


function [ekg_RSlinB_am_ELF, ekg_RSlinB_bw_ELF, ekg_RSlinB_fm_ELF] = ELF_is(ekg_RSlinB_am, ekg_RSlinB_bw, ekg_RSlinB_fm, up)
%ELF eliminates very low frequencies from resampled respiratory

for rel_var_name_no = 1 : length(up.al.options.FMe)
%     temp = strfind(rel_var_names{rel_var_name_no},'_');
%     start_el = temp(1); clear temp
%     eval(['save_name = ''' curr_sig, up.paths.filenames.elim_vlf2, rel_var_names{rel_var_name_no}(start_el:end) ''';']); clear start_el
%     exist_log = check_exists(savepath, save_name);
%     if exist_log
%         continue
%     end

    %% Load relevant data
    rel_name = ['ekg_RSlinB_' up.al.options.FMe{rel_var_name_no} ];
    %loadpath = [up.paths.data_save_folder, num2str(subj), up.paths.filenames.int_respSigs];
    %load(loadpath, rel_name);
    eval(['old_data = ' rel_name ';']);

    %% Eliminate VLFs
    data.hpfilt.t = old_data.t;
    try
        data.hpfilt.v = elim_vlfs(old_data, up);
    catch
        % if there aren't enough points to use the filter, simply carry forward the previous data
        data.hpfilt.v = old_data.v;
    end
    data.hpfilt.fs = old_data.fs;
    %eval(['save_name = ' rel_name '_ELF']);
    save_name = [rel_name '_ELF'];
    eval([save_name ' = data.hpfilt;']);

    %% Save processed data
    %save_or_append_data
end

end


function [n,ind]=my_histcounts(X,edges,normalization)
persistent old_matlab
if isempty(old_matlab)
    old_matlab=verLessThan('matlab','8.4');
end
if old_matlab
    %We make histc behave like histcounts
    [n,ind]=histc(X,edges);
    ind(ind==length(n))=length(n)-1;
    n(end-1)=n(end-1)+n(end);
    n(end)=[];

    switch normalization
        case 'probability'
            n=n./sum(n);
        case 'count'
        otherwise
            warning('Other types of normalization are not supported on older Matlab versions')
    end
else
    [n, ~, ind]=histcounts(X,edges,'Normalization',normalization);
end
end


function [M_final,shifts,template,options,col_shift] = normcorre(Y,options,template)

% online motion correction through DFT subpixel registration
% Based on the dftregistration.m function from Manuel Guizar and Jim Fienup

% INPUTS
% Y:                Input data, can be already loaded in memory as a 3D
%                   tensor, a memory mapped file, or a pointer to a tiff stack
% options:          options structure for motion correction (optional, rigid registration is performed if not provided)
% template:         provide template (optional)

% OUTPUTS
% M_final:          motion corrected data
% shifts:           originally calculated shifts
% template:         calculated template
% options:          options structure (if modified)
% col_shift:        relative shift due to bi-directional scanning

%% first determine filetype

nd = 2 + (options.d3 > 1); %max(length(sizY)-1,2);                    % determine whether imaging is 2d or 3d

if isa(Y,'char')
    [~,~,ext] = fileparts(Y);
    ext = ext(2:end);
    if strcmpi(ext,'tif') || strcmpi(ext,'tiff')
        tiffInfo = imfinfo(Y);
        filetype = 'tif';
        T = length(tiffInfo);
        if nd == 3
            sizY = [tiffInfo(1).Height,tiffInfo(1).Width,T,1];
        else
            sizY = [tiffInfo(1).Height,tiffInfo(1).Width,T];
        end
    elseif strcmpi(ext,'mat')
        filetype = 'mem';
        Y = matfile(Y,'Writable',true);
        details = whos(Y);
        var_sizes = [details.bytes];
        [~,var_ind] = max(var_sizes);
        var_name = details(var_ind).name;
        sizY = size(Y,var_name);
    elseif strcmpi(ext,'hdf5') || strcmpi(ext,'h5')
        filetype = 'hdf5';
        fileinfo = hdf5info(Y);
        sizY = fileinfo.GroupHierarchy.Datasets.Dims;
    end
elseif isobject(Y)
    filetype = 'mem';
    var_name = 'Y';
    sizY = size(Y,var_name);
else % array loaded in memory
    filetype = 'mat';
    Y = single(Y);
    sizY = size(Y);
end

if length(sizY) == nd
    T = 1;
else
    T = sizY(nd+1);
end
sizY = sizY(1:nd);

%% set default parameters if not present

if ~exist('options','var') || isempty(options)
    options = NoRMCorreSetParms('d1',sizY(1),'d2',sizY(2));
    if nd > 2; options.d3 = sizY(3); end
end

options.bin_width = min(options.bin_width,T+1);
options.mem_batch_size = min(options.mem_batch_size,T);
options.buffer_width = min(options.buffer_width,ceil(T/options.bin_width));
options.init_batch = min(options.init_batch,T);

memmap = options.memmap;
grid_size = options.grid_size;
mot_uf = options.mot_uf;
min_patch_size = options.min_patch_size;
overlap_pre = options.overlap_pre;
overlap_post = options.overlap_post;
upd_template = options.upd_template;
bin_width = options.bin_width;
buffer_width = options.buffer_width;
max_dev = options.max_dev;
init_batch = options.init_batch;
us_fac = options.us_fac;
method = options.method;
plot_flag = options.plot_flag*(nd==2);
filename = options.mem_filename;
use_parallel = options.use_parallel;
make_avi = options.make_avi;
name = options.name;
fr = options.fr;
iter = options.iter;
add_value = options.add_value;
max_shift = options.max_shift;
print_msg = options.print_msg;
if strcmpi(options.boundary,'nan')
    fill_value = NaN;
else
    fill_value = add_value;
end

%% first check for offset due to bi-directional scanning

if options.correct_bidir && isempty(options.col_shift)
    col_shift = correct_bidirectional_offset(Y,options.nFrames,options.bidir_us);
elseif ~isempty(options.col_shift)
    col_shift = options.col_shift;
else
    col_shift = 0;
end
options.col_shift = col_shift;
if col_shift
    if print_msg; fprintf('Offset %1.1d pixels due to bidirectional scanning detected. \n',col_shift); end
    if strcmpi(options.shifts_method,'fft')
        options.shifts_method = 'cubic';
        if print_msg; fprintf('Cubic shifts will be applied. \n'); end
    end
end
%% read initial batch and compute template
init_batch = min(T,init_batch);
interval = ceil(T/2-init_batch/2+1):floor(T/2+init_batch/2);
if exist('template','var')
    init_batch = min(init_batch,1);
end
switch filetype
    case 'tif'
        Y_temp = read_file(Y,interval(1),init_batch,[],tiffInfo);
    case 'hdf5'
        Y_temp = read_file(Y,interval(1),init_batch);
    case 'mem'
        if nd == 2; Y_temp = Y.(var_name)(:,:,interval); elseif nd == 3; Y_temp = Y.(var_name)(:,:,:,interval); end
    case 'mat'
        if nd == 2; Y_temp = Y(:,:,interval); elseif nd == 3; Y_temp = Y(:,:,:,interval); end
end

data_type = class(Y_temp);
Y_temp = single(Y_temp);

if nargin < 3 || isempty(template)
    if print_msg; fprintf('Registering the first %i frames just to obtain a good template....',init_batch); end
    template_in = median(Y_temp,nd+1)+add_value;
    fftTemp = fftn(template_in);
    for t = 1:size(Y_temp,nd+1)
        if nd == 2
            [~,Greg] = dftregistration_min_max(fftTemp,fftn(Y_temp(:,:,t)),us_fac,-max_shift,max_shift,options.phase_flag);
        end
        if nd == 3
            [~,Greg] = dftregistration_min_max_3d(fftTemp,fftn(Y_temp(:,:,:,t)),us_fac,-max_shift,max_shift,options.phase_flag);
        end
        M_temp = real(ifftn(Greg));
        template_in = template_in*(t-1)/t + M_temp/t;
    end
    template_in = template_in + add_value;
    if print_msg; fprintf('..done. \n'); end
else
    template_in = single(template + add_value);
end

[d1,d2,d3,~] = size(Y_temp);
if nd == 2; d3 = 1; end
%% setup grids for patches

[xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,xx_us,xx_uf,yy_us,yy_uf,zz_us,zz_uf] = construct_grid(grid_size,mot_uf,d1,d2,d3,min_patch_size);
shifts = struct('shifts',cell(T,1),'shifts_up',cell(T,1),'diff',cell(T,1));
temp_cell = mat2cell_ov(template_in,xx_us,xx_uf,yy_us,yy_uf,zz_us,zz_uf,overlap_post,sizY);

%% precompute some quantities that are used repetitively for template matching and applying shifts
Nr = cell(size(temp_cell));
Nc = cell(size(temp_cell));
Np = cell(size(temp_cell));
Bs = cell(size(temp_cell));
for i = 1:length(xx_us)
    for j = 1:length(yy_us)
        for k = 1:length(zz_us)
            [nr,nc,np] = size(temp_cell{i,j,k});
            nr = ifftshift(-fix(nr/2):ceil(nr/2)-1);
            nc = ifftshift(-fix(nc/2):ceil(nc/2)-1);
            np = ifftshift(-fix(np/2):ceil(np/2)-1);
            [Nc{i,j,k},Nr{i,j,k},Np{i,j,k}] = meshgrid(nc,nr,np);
            extended_grid = [max(xx_us(i)-overlap_post(1),1),min(xx_uf(i)+overlap_post(1),d1),max(yy_us(j)-overlap_post(2),1),min(yy_uf(j)+overlap_post(2),d2),max(zz_us(k)-overlap_post(3),1),min(zz_uf(k)+overlap_post(3),d3)];
            Bs{i,j,k} = permute(construct_weights([xx_us(i),xx_uf(i),yy_us(j),yy_uf(j),zz_us(k),zz_uf(k)],extended_grid),[2,1,3]);
        end
    end
end
if nd == 2; Np = cellfun(@(x) 0,Nr,'un',0); end

%%
%maxNumCompThreads(2);
template = mat2cell_ov(template_in,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY);
temp_mat = template_in;
fftTemp = cellfun(@fftn,template,'un',0);
fftTempMat = fftn(temp_mat);
if nd == 2; buffer = mat2cell_ov(zeros(d1,d2,bin_width,'single'),xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY); end
if nd == 3; buffer = mat2cell_ov(zeros(d1,d2,d3,bin_width,'single'),xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY); end

if ~strcmpi(options.output_type,'mat')
    %options.mem_batch_size = min(round(options.mem_batch_size/bin_width)*bin_width,T);
    if nd == 2; mem_buffer = zeros(d1,d2,options.mem_batch_size,'single'); end
    if nd == 3; mem_buffer = zeros(d1,d2,d3,options.mem_batch_size,'single'); end
end

switch lower(options.output_type)
    case 'mat'
        M_final = zeros([sizY,T],data_type);
    case 'memmap'
        M_final = matfile(filename,'Writable',true);
        if nd == 2; M_final.Y(d1,d2,T) = zeros(1,data_type); end
        if nd == 3; M_final.Y(d1,d2,d3,T) = zeros(1,data_type); end
        M_final.Yr(d1*d2*d3,T) = zeros(1,data_type);
    case {'hdf5','h5'}
        if exist(options.h5_filename,'file')
            [pathstr,fname,ext] = fileparts(options.h5_filename);
            new_filename = fullfile(pathstr,[fname,'_',datestr(now,30),ext]);
            warning_msg = ['File ',options.h5_filename,'already exists. Saving motion corrected file as',new_filename];
            warning('%s',warning_msg);
            options.h5_filename = new_filename;
        end
        M_final = options.h5_filename;
        if nd == 2
            h5create(options.h5_filename,['/',options.h5_groupname],[d1,d2,Inf],'Chunksize',[d1,d2,options.mem_batch_size],'Datatype',data_type);
        elseif nd == 3
            h5create(options.h5_filename,['/',options.h5_groupname],[d1,d2,d3,Inf],'Chunksize',[d1,d2,d3,options.mem_batch_size],'Datatype',data_type);
        end
    case {'tif','tiff'}
        M_final = options.tiff_filename;
        opts_tiff.append = true;
        opts_tiff.big = true;
        if nd == 3
            error('Saving volumetric tiff stacks is currently not supported. Use a different filetype');
        end
    otherwise
        error('This filetype is currently not supported')
end

%%
if plot_flag
    if make_avi
        vidObj = VideoWriter(name);
        set(vidObj,'FrameRate',fr);
        open(vidObj);
    end
    if strcmpi(filetype,'mat')
        nnY = quantile(Y(:),0.005);
        mmY = quantile(Y(:),0.995);
    else
        nnY = quantile(Y_temp(:),0.005);
        mmY = quantile(Y_temp(:),0.995);
    end
    fig = figure;
        screensize = get(0,'Screensize' );
        fac = min(min((screensize(3:4)-200)./[d2,d1]),10);
        set(gcf, 'PaperUnits', 'points', 'Units', 'points');
        set(gcf, 'Position', round([100 100 fac*d2 fac*d1]));
end
cnt_buf = 0;
if print_msg; fprintf('Template initialization complete.  Now registering all the frames with new template. \n'); end
%%
prevstr = [];
for it = 1:iter
    if it < iter; plot_flag = 0; else plot_flag = options.plot_flag; end
    for t = 1:T
        switch filetype
            case 'tif'
                Yt = single(imread(Y,'Index',t,'Info',tiffInfo));
            case 'hdf5'
                Yt = single(h5read(Y,'/mov',[ones(1,nd),t],[sizY(1:nd),1]));
            case 'mem'
                if nd == 2; Yt = single(Y.(var_name)(:,:,t)); end
                if nd == 3; Yt = single(Y.(var_name)(:,:,:,t)); end
            case 'mat'
                if nd == 2; Yt = single(Y(:,:,t)); end
                if nd == 3; Yt = single(Y(:,:,:,t)); end
        end
        minY = min(Yt(:));
        maxY = max(Yt(:));
        Yt = Yt + add_value;
        ind = rem(t,bin_width) + bin_width*(rem(t,bin_width)==0);
        Yc = mat2cell_ov(Yt,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY);
        fftY = cellfun(@fftn, Yc, 'un',0);

        M_fin = cell(length(xx_us),length(yy_us),length(zz_us)); %zeros(size(Y_temp));
        shifts_temp = zeros(length(xx_s),length(yy_s),length(zz_s),nd);
        diff_temp = zeros(length(xx_s),length(yy_s),length(zz_s));
        if numel(M_fin) > 1
            if nd == 2; out_rig = dftregistration_min_max(fftTempMat,fftn(Yt),us_fac,-max_shift,max_shift,options.phase_flag); lb = out_rig(3:4); ub = out_rig(3:4); end
            if nd == 3; out_rig = dftregistration_min_max_3d(fftTempMat,fftn(Yt),1,-max_shift,max_shift,options.phase_flag); lb = out_rig(3:5); ub = out_rig(3:5); end
        else
            lb = -max_shift(1,nd);
            ub = max_shift(1,nd);
            max_dev = 0*max_dev;
        end
        if ~use_parallel
            for i = 1:length(xx_s)
                for j = 1:length(yy_s)
                    for k = 1:length(zz_s)
                        if nd == 2
                            %[output,Greg] = dftregistration_max(fftTemp{i,j,k},fftY{i,j,k},us_fac,max_shift);
                            [output,Greg] = dftregistration_min_max(fftTemp{i,j,k},fftY{i,j,k},us_fac,lb-max_dev(1:2),ub+max_dev(1:2),options.phase_flag);
                        elseif nd == 3
                            %[output,Greg] = dftregistration_max_3d(fftTemp{i,j,k},fftY{i,j,k},us_fac,max_shift);
                            [output,Greg] = dftregistration_min_max_3d(fftTemp{i,j,k},fftY{i,j,k},us_fac,lb-max_dev,ub+max_dev,options.phase_flag);
                            shifts_temp(i,j,k,3) = output(5);
                        end
                        M_temp = real(ifftn(Greg));
                        M_temp = remove_boundaries(M_temp,output(3:end),'copy',template{i,j,k});
                        if nd == 2; buffer{i,j,k}(:,:,ind) = M_temp;  end
                        if nd == 3; buffer{i,j,k}(:,:,:,ind) = M_temp;  end
                        shifts_temp(i,j,k,1) = output(3);
                        shifts_temp(i,j,k,2) = output(4);
                        diff_temp(i,j,k) = output(2);
                        if all([length(xx_s),length(yy_s),length(zz_s)] == 1)
                            M_fin{i,j,k} = remove_boundaries(M_temp,output(3:end),options.boundary,template{i,j,k},add_value);
                        end
                    end
                end
            end
        else
            Mt2 = cell(length(xx_s)*length(yy_s)*length(zz_s),1);
            shifts_cell = cell(length(xx_s)*length(yy_s)*length(zz_s),1);
            diff_cell = cell(length(xx_s)*length(yy_s)*length(zz_s),1);
            for ii = length(xx_s)*length(yy_s)*length(zz_s):-1:1
                [i,j,k] = ind2sub([length(xx_s),length(yy_s),length(zz_s)],ii);
                if nd == 2; future_results(ii) = parfeval(@dftregistration_min_max,2,fftTemp{i,j,k},fftY{i,j,k},us_fac,lb-max_dev(1:2),ub+max_dev(1:2),options.phase_flag); end
                if nd == 3; future_results(ii) = parfeval(@dftregistration_min_max_3d,2,fftTemp{i,j,k},fftY{i,j,k},us_fac,lb-max_dev,ub+max_dev,options.phase_flag); end
            end
            for i = 1:length(xx_s)*length(yy_s)*length(zz_s)
                [ii,output,Greg] = fetchNext(future_results);
                M_temp = real(ifftn(Greg));
                Mt2{ii} = M_temp;
                shifts_cell{ii} = output(3:end);
                diff_cell{ii} = output(2);
            end
%             parfor ii = 1:length(xx_s)*length(yy_s)*length(zz_s)
%                 [i,j,k] = ind2sub([length(xx_s),length(yy_s),length(zz_s)],ii);
%                 %if nd == 2; [output,Greg] = dftregistration_max(fftTemp{i,j,k},fftY{i,j,k},us_fac,max_shift); end
%                 %if nd == 3; [output,Greg] = dftregistration_max_3d(fftTemp{i,j,k},fftY{i,j,k},us_fac,max_shift); end
%                 if nd == 2; [output,Greg] = dftregistration_min_max(fftTemp{i,j,k},fftY{i,j,k},us_fac,lb-max_dev(1:2),ub+max_dev(1:2),options.phase_flag); end
%                 if nd == 3; [output,Greg] = dftregistration_min_max_3d(fftTemp{i,j,k},fftY{i,j,k},us_fac,lb-max_dev,ub+max_dev,options.phase_flag); end
%                 M_temp = real(ifftn(Greg));
%                 Mt2{ii} = M_temp;
%                 shifts_cell{ii} = output(3:end);
%                 diff_cell{ii} = output(2);
%             end
            for ii = 1:length(xx_s)*length(yy_s)*length(zz_s)
                 [i,j,k] = ind2sub([length(xx_s),length(yy_s),length(zz_s)],ii);
                 if nd == 2; buffer{i,j,k}(:,:,ind) = Mt2{ii}; end
                 if nd == 3; buffer{i,j,k}(:,:,:,ind) = Mt2{ii}; end
                 if mot_uf == 1
                     M_fin{i,j,k} = Mt2{ii};
                 end
                 shifts_temp(i,j,k,:) = shifts_cell{ii};
                 diff_temp(i,j,k) = diff_cell{ii};
            end
        end
        shifts(t).shifts = shifts_temp;
        shifts(t).diff = diff_temp;

        switch lower(options.shifts_method)
            case 'fft'
                if any([length(xx_s),length(yy_s),length(zz_s)] > 1)
                    if ~isfield(options,'shifts_method'); options.shifts_method = 'FFT'; end
                    if mot_uf(3) > 1
                        do = [length(xx_us),length(yy_us),length(zz_us)]./[length(xx_s),length(yy_s),length(zz_s)];
                        ds = [length(xx_s),length(yy_s),length(zz_s)];
                        dim = [length(xx_us),length(yy_us),length(zz_us)];
                        [Xq,Yq,Zq] = meshgrid(linspace((1+1/do(2))/2,ds(2)+(1-1/do(2))/2,dim(2)),linspace((1+1/do(1))/2,ds(1)+(1-1/do(1))/2,dim(1)),linspace((1+1/do(3))/2,ds(3)+(1-1/do(3))/2,dim(3)));
                        %tform = affine3d(diag([mot_uf(:);1]));
                        %tform = affine3d(diag([mot_uf([2,1,3])';1]));
                        %diff_up = imwarp(diff_temp,tform,'OutputView',imref3d([length(xx_uf),length(yy_uf),length(zz_uf)]));
                        %diff_up = imwarp(diff_temp,tform,'OutputView',imref3d([length(xx_uf),length(yy_uf),length(zz_uf)]),'SmoothEdges',true);
                        diff_up = interp3(diff_temp,Xq,Yq,Zq,'makima');
                        shifts_up = zeros([size(diff_up),3]);
                        %for dm = 1:3; shifts_up(:,:,:,dm) = imwarp(shifts_temp(:,:,:,dm),tform,'OutputView',imref3d([length(xx_uf),length(yy_uf),length(zz_uf)]),'SmoothEdges',true); end
                        for dm = 1:3; shifts_up(:,:,:,dm) = interp3(shifts_temp(:,:,:,dm),Xq,Yq,Zq,'makima'); end
                    else
                        shifts_up = imresize(shifts_temp,[length(xx_uf),length(yy_uf)]);
                        diff_up = imresize(diff_temp,[length(xx_uf),length(yy_uf)]);
                    end

                    shifts(t).shifts_up = shifts_up;
                    shifts(t).diff = diff_up;
                    for i = 1:length(xx_uf)
                        for j = 1:length(yy_uf)
                            for k = 1:length(zz_uf)
                                extended_grid = [max(xx_us(i)-overlap_post(1),1),min(xx_uf(i)+overlap_post(1),d1),max(yy_us(j)-overlap_post(2),1),min(yy_uf(j)+overlap_post(2),d2),max(zz_us(k)-overlap_post(3),1),min(zz_uf(k)+overlap_post(3),d3)];
                                I_temp = Yt(extended_grid(1):extended_grid(2),extended_grid(3):extended_grid(4),extended_grid(5):extended_grid(6));
                                M_fin{i,j,k} = shift_reconstruct(I_temp,shifts_up(i,j,k,:),diff_up(i,j,k),us_fac,Nr{i,j,k},Nc{i,j,k},Np{i,j,k},options.boundary,add_value);
                                %M_fin{i,j,k} = shift_reconstruct2(I_temp,shifts_up(i,j,k,:),'bilinear',diff_up(i,j,k),us_fac,Nr{i,j,k},Nc{i,j,k},Np{i,j,k},options.boundary,add_value);
                            end
                        end
                    end
                else
                    shifts_up = shifts_temp;
                    shifts(t).shifts_up = shifts(t).shifts;
                end
                gx = max(abs(reshape(diff(shifts_up,[],1),[],1)));
                gy = max(abs(reshape(diff(shifts_up,[],2),[],1)));
                gz = max(abs(reshape(diff(shifts_up,[],3),[],1)));
                flag_interp = max([gx;gy;gz;0])<0.5;      % detect possible smearing

                if flag_interp
                    Mf = cell2mat_ov_sum(M_fin,xx_us,xx_uf,yy_us,yy_uf,zz_us,zz_uf,overlap_post,sizY,Bs) - add_value;
                else
                    Mf = cell2mat_ov(M_fin,xx_us,xx_uf,yy_us,yy_uf,zz_us,zz_uf,overlap_post,sizY) - add_value;
                end

            otherwise
                shifts(t).shifts_up = shifts(t).shifts;
                if nd == 3
                    shifts_up = zeros([options.d1,options.d2,options.d3,3]);
                    do = size(shifts_up)./size(shifts_temp);
                    ds = size(shifts_temp);
                    dim = [options.d1,options.d2,options.d3];
                    if (0)
                        [Xq,Yq,Zq] = meshgrid(linspace(1,ds(2),dim(2)),linspace(1,ds(1),dim(1)),linspace(1,ds(3),dim(3)));
                    else
                        [Xq,Yq,Zq] = meshgrid(linspace((1+1/do(2))/2,ds(2)+(1-1/do(2))/2,dim(2)),linspace((1+1/do(1))/2,ds(1)+(1-1/do(1))/2,dim(1)),linspace((1+1/do(3))/2,ds(3)+(1-1/do(3))/2,dim(3)));
                        Xq(Xq<1)=1; Xq(Xq>dim(2))=dim(2);
                        Yq(Yq<1)=1; Yq(Yq>dim(1))=dim(1);
                        Zq(Zq<1)=1; Zq(Zq>dim(3))=dim(3);
                    end
                    if numel(shifts_temp) > 3
                        for dm = 1:3; shifts_up(:,:,:,dm) = interp3(shifts_temp(:,:,:,dm),Xq,Yq,Zq,'makima'); end
                        %tform = affine3d(diag([do([2,1,3])';1]));
                        %for dm = 1:3; shifts_up(:,:,:,dm) = imwarp(shifts_temp(:,:,:,dm),tform,'OutputView',imref3d([options.d1,options.d2,options.d3]),'SmoothEdges',true); end
                    else
                        for dm = 1:3; shifts_up(:,:,:,dm) = shifts_temp(dm); end
                    end
                    shifts_up(2:2:end,:,:,2) = shifts_up(2:2:end,:,:,2) + col_shift;
                    Mf = imwarp(Yt,-cat(4,shifts_up(:,:,:,2),shifts_up(:,:,:,1),shifts_up(:,:,:,3)),options.shifts_method,'FillValues',fill_value);
                else
                    shifts_up = imresize(shifts_temp,[options.d1,options.d2]);
                    shifts_up(2:2:end,:,2) = shifts_up(2:2:end,:,2) + col_shift;
                    Mf = imwarp(Yt,-cat(3,shifts_up(:,:,2),shifts_up(:,:,1)),options.shifts_method,'FillValues',fill_value);
                end

             Mf(Mf<minY) = minY;
             Mf(Mf>maxY) = maxY;
        end

        if ~strcmpi(options.output_type,'mat')
            rem_mem = rem(t,options.mem_batch_size);
            if rem_mem == 0; rem_mem = options.mem_batch_size; end
            if nd == 2; mem_buffer(:,:,rem_mem) = cast(Mf,data_type); end
            if nd == 3; mem_buffer(:,:,:,rem_mem) = cast(Mf,data_type); end
        end
        switch lower(options.output_type)
            case 'mat'
                if nd == 2; M_final(:,:,t) = cast(Mf,data_type); end
                if nd == 3; M_final(:,:,:,t) = cast(Mf,data_type); end
            case 'memmap'
                if rem_mem == options.mem_batch_size || t == T
                    if nd == 2; M_final.Y(:,:,t-rem_mem+1:t) = mem_buffer(:,:,1:rem_mem); end
                    if nd == 3; M_final.Y(:,:,:,t-rem_mem+1:t) = mem_buffer(:,:,:,1:rem_mem); end
                    M_final.Yr(:,t-rem_mem+1:t) = reshape(mem_buffer(1:d1*d2*d3*rem_mem),d1*d2*d3,rem_mem);
                end
            case {'hdf5','h5'}
                if rem_mem == options.mem_batch_size || t == T
                    if nd == 2; h5write(options.h5_filename,['/',options.h5_groupname],mem_buffer(:,:,1:rem_mem),[ones(1,nd),t-rem_mem+1],[sizY(1:nd),rem_mem]); end
                    if nd == 3; h5write(options.h5_filename,['/',options.h5_groupname],mem_buffer(:,:,:,1:rem_mem),[ones(1,nd),t-rem_mem+1],[sizY(1:nd),rem_mem]); end
                end
            case {'tif','tiff'}
                if rem_mem == options.mem_batch_size || t == T
                    saveastiff(cast(mem_buffer(:,:,1:rem_mem),data_type),options.tiff_filename,opts_tiff);
                end
        end

        if mod(t,bin_width) == 0 && upd_template
            if print_msg
                str=[num2str(t), ' out of ', num2str(T), ' frames registered, iteration ', num2str(it), ' out of ', num2str(iter), '..'];
                refreshdisp(str, prevstr, t);
                prevstr=str;
                %fprintf('%i out of %i frames registered, iteration %i out of %i \n',t,T,it,iter)
            end
            cnt_buf = cnt_buf + 1;
            if strcmpi(method{2},'mean')
                new_temp = cellfun(@(x) nanmean(x,nd+1), buffer, 'UniformOutput',false);
            elseif strcmpi(method{2},'median');
                new_temp = cellfun(@(x) nanmedian(x,nd+1), buffer, 'UniformOutput', false);
            end
            if strcmpi(method{1},'mean')
                cnt = t/bin_width + 1;
                template = cellfun(@plus, cellfun(@(x) x*(cnt-1)/cnt, template,'un',0), cellfun(@(x) x*1/cnt, new_temp,'un',0), 'un',0);
            elseif strcmpi(method{1},'median');
                if cnt_buf <= buffer_width
                    if nd == 2; buffer_med(:,:,cnt_buf) = cell2mat_ov(new_temp,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY); end
                    if nd == 3; buffer_med(:,:,:,cnt_buf) = cell2mat_ov(new_temp,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY); end
                else
                    buffer_med = circshift(buffer_med,[zeros(1,nd),-1]);
                    if nd == 2; buffer_med(:,:,buffer_width) = cell2mat_ov(new_temp,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY); end
                    if nd == 3; buffer_med(:,:,:,buffer_width) = cell2mat_ov(new_temp,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY); end
                end
                template = mat2cell_ov(nanmedian(buffer_med,nd+1),xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY);
            end
            fftTemp = cellfun(@fftn, template, 'un',0);
            temp_mat = cell2mat_ov(template,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY);
            fftTempMat = fftn(temp_mat);
        end

        if plot_flag && mod(t,1) == 0
            subplot(221); imagesc(Yt-add_value,[nnY,mmY]); title('Raw data','fontweight','bold','fontsize',14);
                            xlabel(sprintf('Frame %i out of %i',t,T),'fontweight','bold','fontsize',14); set(gca,'Xtick',[],'Ytick',[]);
            subplot(222); imagesc(Mf,[nnY,mmY]);  title('Motion Corrected','fontweight','bold','fontsize',14); colormap('bone'); axis off;
            subplot(223); quiver(shifts_up(:,:,:,1),shifts_up(:,:,:,2),'Autoscale','off'); title('Motion vector field','fontweight','bold','fontsize',14); axis off;
            subplot(224); imagesc(cell2mat_ov(template,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY)-add_value,[nnY,mmY]); title('Matching Template','fontweight','bold','fontsize',14); axis off
            drawnow;
            if make_avi
                currFrame = getframe(fig);
                writeVideo(vidObj,currFrame);
            end
        end
    end

if print_msg; fprintf('\n'); end

if it == iter
    template = cellfun(@(x) x - add_value,template,'un',0);
    template = cell2mat_ov(template,xx_s,xx_f,yy_s,yy_f,zz_s,zz_f,overlap_pre,sizY);
end
if memmap
    M_final.shifts = shifts;
    M_final.template = template;
end

if make_avi && plot_flag
    close(vidObj);
end
maxNumCompThreads('automatic');
if print_msg; fprintf('done. \n'); end
end