%FeatureMatch Feature correspondence object
%
% This class represents the correspondence between two PointFeature
% objects.  A vector of FeatureMatch objects can represent the
% correspondence between sets of points.
%
% Methods::
% plot       Plot corresponding points
% show       Show summary statistics of corresponding points
%
% ransac     Determine inliers and outliers
% inlier     Return inlier matches
% outlier    Return outlier matches
% subset     Return a subset of matches
% remove
%
% display    Display value of match
% char       Convert value of match to string
%
% Properties::
% p1         Point coordinates in view 1 (2x1)
% p2         Point coordinates in view 2 (2x1)
% p          Point coordinates in view 1 and 2 (4x1)
% distance   Match strength between the points
%
% Properties of a vector of FeatureMatch objects are returned as a vector.
% If F is a vector (Nx1) of FeatureMatch objects then F.p1 is a 2xN matrix
% with each column the corresponding view 1 point coordinate.
%
% Note::
%  - FeatureMatch is a reference object.
%  - FeatureMatch objects can be used in vectors and arrays
%  - Operates with all objects derived from PointFeature, such as
%    ScalePointFeature, SurfPointFeature and SiftPointFeature.
%
% See also PointFeature, SurfPointFeature, SiftPointFeature.

% TODO:
% distance, strength should be converted to similarity
% p should be p12

% Copyright (C) 1993-2011, by Peter I. Corke
%
% This file is part of The Machine Vision Toolbox for Matlab (MVTB).
%
% MVTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% MVTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with MVTB.  If not, see <http://www.gnu.org/licenses/>.

classdef FeatureMatch < handle

    properties
        % the trailing underscore is to distinguish these properties from the methods
        % of almost similar name.  Finding the property of a vector of objects
        % F.x results in a list rather than a vector.  You need to write [F.x] so we
        % create methods to provide this.  Using dependent properties does not work.
        xy_          % x1 y1 x2 y2 of corresponding points
        distance_    % strength of match
        inlier_      % NaN - indeterminate
                    % true - inlier
                    % false - outlier
    end

    methods

        function m = FeatureMatch(f1, f2, s)
        %FeatureMatch.FeatureMatch Create a new FeatureMatch object
        %
        % M = FeatureMatch(F1, F2, S) is a new FeatureMatch object describing a
        % correspondence between point features F1 and F2 with a strength of S.
        %
        % M = FeatureMatch(F1, F2) as above but the strength is set to NaN.
        %
        % Notes::
        % - Only the coordinates of the PointFeature are kept.
        %
        % See also PointFeature, SurfPointFeature, SiftPointFeature.

            if nargin == 0
                m.xy_ = [];
                m.distance_ = [];
                m.inlier_ = [];
                return;
            end

            m.xy_ = [f1.u_ f1.v_ f2.u_ f2.v_]';
            if nargin < 3
                m.distance = NaN;
            else
                m.distance_ = s;
            end
            m.inlier_ = NaN;
        end

        function v = inlier(m)
        %FeatureMatch.inlier Inlier features
        %
        % M2 = M.inlier() is a subset of the FeatureMatch vector M that are
        % considered to be inliers.
        %
        % Notes::
        % - Inliers are not determined until after RANSAC is run.
        %
        % See also FeatureMatch.outlier, FeatureMatch.ransac.
            v = m([m.inlier_] == true);
        end

        function v = outlier(m)
        %FeatureMatch.outlier Outlier features
        %
        % M2 = M.outlier() is a subset of the FeatureMatch vector M that are
        % considered to be outliers.
        %
        % Notes::
        % - Outliers are not determined until after RANSAC is run.
        %
        % See also FeatureMatch.inlier, FeatureMatch.ransac.
            v = m([m.inlier_] == false);
        end

        function v = distance(m)
            v = [m.distance_];
        end

        function v = inlierx(m)
            v = find([m.inlier_]);
        end

        function display(m)
        %FeatureMatch.display Display value
        %
        % M.display() displays a compact human-readable representation of the
        % feature pair.  If M is a vector then the elements are printed one per line.
        %
        % Notes::
        % - This method is invoked implicitly at the command line when the result
        %   of an expression is a FeatureMatch object and the command has no trailing
        %   semicolon.
        %
        % See also FeatureMatch.char.

            disp(' ');
            disp([inputname(1), ' = '])
            disp(' ');
            if length(m) > 20
                fprintf('%d corresponding points (listing suppressed)\n', length(m));
            else
                disp( char(m) );
            end
        end % display()

        function s = char(matches)
        %FeatureMatch.char Convert to string
        %
        % S = M.char() is a compact string representation of the match object.
        % If M is a vector then the string has multiple lines, one per element.

            s = '';
            for m=matches
                ss = sprintf('(%g, %g) <-> (%g, %g), dist=%f', ...
                    m.xy_, m.distance_);
                switch m.inlier_
                case true
                    ss = [ss ' +'];
                case false
                    ss = [ss ' -'];
                end
                s = strvcat(s, ss);
            end
        end

        function s = show(m)
        %FeatureMatch.show Display summary statistics of the FeatureMatch vector
        %
        % M.show() is a compact summary of the FeatureMatch vector M that gives
        % the number of matches, inliers and outliers (and their percentages).
            s = sprintf('%d corresponding points\n', length(m));
            in = [m.inlier_];
            s = [s sprintf('%d inliers (%.1f%%)\n', ...
                sum(in==true), sum(in==true)/length(m)*100)];
            s = [s sprintf('%d outliers (%.1f%%)\n', ...
                sum(in==false), sum(in==false)/length(m)*100) ];
        end

        function v = subset(m, n, varargin)
        %FeatureMatch.subset Subset of matches
        %
        % M2 = M.subset(N) is a FeatureMatch vector with no more than N elements
        % sampled uniformly from M.

            opt.random = false;
            opt = tb_optparse(opt, varargin);

            if opt.random
                i = randi(length(m), n);
            else
                i = round(linspace(1, length(m), n));
            end
            v = m(i);
        end

        function s = p1(m, k)
        %FeatureMatch.p1 Feature point coordinates from view 1
        %
        % P = M.p1() is a 2xN matrix containing the feature points coordinates
        % from view 1.  These are the (u,v) properties of the feature F1 passed
        % to the constructor.
        %
        % See also FeatureMatch.FeatureMatch, FeatureMatch.p2, FeatureMatch.p.
            xy = [m.xy_];
            s = xy(1:2,:);
        end

        function s = p2(m, k)
        %FeatureMatch.p2 Feature point coordinates from view 2
        %
        % P = M.p2() is a 2xN matrix containing the feature points coordinates
        % from view 1.  These are the (u,v) properties of the feature F2 passed
        % to the constructor.
        %
        % See also FeatureMatch.FeatureMatch, FeatureMatch.p1, FeatureMatch.p.

            xy = [m.xy_];
            xy = [m.xy_];
            s = xy(3:4,:);
        end

        function s = p(m, k)
        %FeatureMatch.p Feature point coordinate pairs
        %
        % P = M.p() is a 4xN matrix containing the feature point coordinates.
        % Each column contains the coordinates of a pair of corresponding
        % points [u1,v1,u2,v2].
        %
        % See also FeatureMatch.p1, FeatureMatch.p2.
            s = [m.xy_];
        end

        function plot(m, varargin)
        %FeatureMatch.plot Show corresponding points
        %
        % M.plot() overlays the correspondences in the FeatureMatch vector M
        % on the current figure.  The figure must comprise views 1 and 2 side
        % by side, for example by:
        %
        %      idisp({im1,im2})
        %      m.plot()
        %
        % M.plot(LS) as above but the optional line style arguments LS are
        % passed to plot.
        %
        % Notes::
        % - Using IDISP as above adds UserData to the figure, and an error is
        %   created if this UserData is not found.
        % See also IDISP.

            opt.offset = [];
            [opt,args] = tb_optparse(opt, varargin);

            if isempty(opt.offset)
            try
                ud = get(gca, 'UserData');
                u0 = ud.u0;
            catch
                error('Current image is not a pair displayed by idisp');
            end
            opt.offset = [0 u0(2) 0 0];
            end

            xy = [m.xy_];
            hold on
            for k=1:numcols(xy),
                plot([xy(1,k)+opt.offset(1) xy(3,k)+opt.offset(2)], ...
                    [xy(2,k)+opt.offset(3), xy(4,k)+opt.offset(4)],  args{:});
            end
            hold off
            figure(gcf);
        end % plot

        function [MM,rr] = ransac(m, func, varargin)
        %FeatureMatch.ransac Apply RANSAC
        %
        % M.ransac(FUNC, OPTIONS) applies the RANSAC algorithm to fit the point
        % correspondences to the model described by the function FUNC.  The
        % OPTIONS are passed to the RANSAC() function.  Elements of the
        % FeatureMatch vector have their status updated in place to indicate
        % whether they are inliers or outliers.
        %
        % Example::
        %      f1 = isurf(im1);
        %      f2 = isurf(im2);
        %      m = f1.match(f2);
        %      m.ransac( @fmatrix, 1e-4);
        %
        % See also FMATRIX, HOMOGRAPHY, RANSAC.

            opt.retry = 1;
            [opt,args] = tb_optparse(opt, varargin);
            if opt.verbose
                args = [args 'verbose'];
            end

            while true
                try
                    [M,in,resid] = ransac(func, [m.xy_], args{:});
                    break;
                catch err
                    opt.retry = opt.retry - 1;
                    if opt.retry > 0
                        continue;
                    else
                        rethrow(err);
                    end
                end
            end

            % mark all as outliers
            for i=1:length(m)
                m(i).inlier_ = false;
            end
            for i=in
                m(i).inlier_ = true;
            end

            if nargout >= 1
                MM = M;
            end
            if nargout >= 2
                rr = resid;
            end
        end
    end

end


function err = err_fit(params, sample, tes)
% return residual

%size(sample)
%size(signal(params, tes))

err = sample - signal(params, tes);


function [gp, indA] = passgp(gp, x, y, varargin)
%PASSGP   Optimize active set and hyperparameters of PASS-GP
%
%  Description
%    [GP, INDA] = PASSGP(GP, X, Y, OPTIONS)
%    Returns GP structure with hyperparameters optimized according to
%    PASS-GP routine (Henao & Winther, 2012) and active set indices
%    INDA for X and Y
%
%   OPTIONS is optional parameter-value pair
%      npass - Number of passes the algorithm takes over the whole training
%              data set
%      ninit - Initial active set size
%      nsub  - Number of subsets we process at each pass (in how many
%              parts we divide the whole data)
%      pinc  - Predictive density threshold for inclusion in active set.
%      pdel  - LOO-predictive density threshold for deletion from active
%              set
%      pexc  - Exchange proportion for fixed PASS-GP
%      opt   - Options structure for optimizer
%      fixed - Whether we use fixed size of active set or not. Default
%               'off'
%      display - Whether to display additional info or not. Default 'off'
%      optimn - Whether to optimize always or only after every nth
%               deletion/addition to active set. Default 1 (every time). If
%               given e.g. value 3, optimizes after every 3rd
%               addition/deletion.
%
%  See also
%    GP_SET, LIK_*
%
%  Reference:
%    Ricardo Henao & Ole Winther (2012). Preditive active set selection
%    methods for Gaussian processes. Neurocomputing 80 (2012), 10-18.

% Copyright (c) 2013 Ville Tolvanen

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

  ip=inputParser;
  ip.FunctionName = 'PASSGP';
  ip.addRequired('gp',@(x) isstruct(x) || iscell(x));
  ip.addRequired('x', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
  ip.addRequired('y', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
  ip.addParamValue('npass', 3, @(x) isscalar(x) && x > 0)
  ip.addParamValue('ninit', 100, @(x) isscalar(x) && x > 0)
  ip.addParamValue('nsub', 10, @(x) isscalar(x) && x > 0)
  ip.addParamValue('pinc', 0.5, @(x) isscalar(x) && x > 0)
  ip.addParamValue('pdel', 0.99, @(x) isscalar(x) && x > 0)
  ip.addParamValue('pexc', 0.1, @(x) isscalar(x) && x > 0)
  ip.addParamValue('opt', [], @(x) isstruct(x))
  ip.addParamValue('fixed', 'off', @(x) ismember(x,{'on','off'}))
  ip.addParamValue('display', 'off', @(x) ismember(x,{'on','off'}))
  ip.addParamValue('optimn', 1', @(x) isscalar(x) && x > 0 && rem(10*x,2)==0)
  ip.addParamValue('z', [], @(x) isreal(x) && all(isfinite(x(:))))
  ip.parse(gp, x, y, varargin{:});
  opt=ip.Results.opt;
  fixed=ip.Results.fixed;
  options.z = ip.Results.z;
  npass=ip.Results.npass;
  ninit=ip.Results.ninit;
  nsub=ip.Results.nsub;
  pinc=ip.Results.pinc;
  pdel=ip.Results.pdel;
  pexc=ip.Results.pexc;
  display=ip.Results.display;
  optimn=ip.Results.optimn;

  if isequal(display,'on')
    display=1;
  else
    display=0;
  end
  if isequal(fixed, 'on')
    fixed=1;
  else
    fixed=0;
  end

  if ninit > size(x,1)
    error('Initial active set must be subset of original data');
  end
  if nsub > (size(x,1) - ninit)
    error('nsub must be lower than size(x,1) - ninit');
  end

  [n,nin]=size(x);

  % Initial active set

  indA=sort(randperm(n, ninit),'ascend');
  % Inclusions/deletions per iteration for fixed pass-gp
  nexc=floor(ninit*pexc);
  iter=optimn-1;
  for i=1:npass
    if display
      fprintf('Pass %d / %d.\n', i, npass)
    end
    [tmp,indSub]=cvit(n, nsub, floor(10*rand(1)));
    for j=1:nsub
      iter=iter+1;
      inds=indSub{j};
      % Remove indices that are already in active set
      inds(ismember(inds,indA))=[];

      if iter==optimn
        % Optimize hyperparameters
        gp = gp_optim(gp, x(indA,:), y(indA), 'opt', opt, options);
        iter=0;
      end

      % Calculate weights for active set inputs (loo predictive densities)
      [tmp,tmp,lpyt]=gp_loopred(gp,x(indA,:),y(indA), options);

      % Remove active set indices according to removal rule
      if ~fixed
        indA(find(exp(lpyt)>pdel))=[];
      else
        [tmp,ii]=sort(lpyt, 'descend');
        indA(ii(1:nexc))=[];
      end
      % Calculate weights for inputs not in active set (predictive density)
      [tmp,tmp,lpyt]=gp_pred(gp, x(indA,:), y(indA), x(inds,:), 'yt', y(inds), options);

      % Add indices to active set according to addition rule
      if ~fixed
        ind=find(exp(lpyt)<pinc)';
      else
        [tmp,ii]=sort(lpyt, 'ascend');
        ind=ii(1:nexc);
      end
      indA=[indA inds(ind)];

    end

  end

end


function g = gpTimeDynamicsLogLikeGradients(model)

% GPTIMEDYNAMICSLOGLIKEGRADIENTS Gradients of the GP dynamics wrt parameters.
% FORMAT
% DESC Computes the gradients with respect to the log likelihood of
% the GP dynamics in a GP-LVM model.
% ARG model : the GP model for which log likelihood is to be
% computed.
% RETURN g : the gradients of the log likelihood with respect to
% the latent points and (optionally) parameters.
%
% SEEALSO : gpLogLikeGradients, gpTimeDynamicsCreate, gpTimeDynamicsLogLikelihood, modelLogLikelihood
%
% COPYRIGHT : Neil D. Lawrence, 2006, 2009

% FGPLVM

if model.k ==0 & ~model.learn & ~model.learnScales
  g = [];
  return
end

g = gpLogLikeGradients(model);

if ~model.learn
  % If we aren't learning model parameters extract only X_u;
  % this is inefficient (but neater in the code) as we have also computed parameters
  if ~model.learnScales
    if isfield(model, 'fixInducing') & model.fixInducing
      g = [];
    else
      g = g(1:model.k*model.q);
    end
  else
    switch model.approx
     case 'ftc'
      g =  [g(end-model.d + 1:end)];
     case {'dtc', 'dtcvar', 'fitc', 'pitc'}
      if isfield(model, 'fixInducing') & model.fixInducing
        g = g(end-model.d:end-1);
      else
        g =  [g(1:model.k*model.q) g(end-model.d:end-1)];
      end
    end
  end
end


function CrossCutter(img, cb_name, cb_format)
%
%        CrossCutter(img, cb_name, cb_format)
%
%
%        Input:
%           -img: input environment map encoded as a cubemap
%           -name: a string representing the prefix name for each face of
%            the cubemap. For example: 'output_cubemap' (default)
%           -format: the output format of each face of the cubemap. For
%           example: 'hdr' (default)
%        Output:
%           -ret: it is set to 1 if the function succeeded
%
%     Copyright (C) 2011  Francesco Banterle
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
%

if(~exist('cb_name', 'var'))
    cb_name = 'output_cube_map';
end

if(~exist('cb_format', 'var'))
    cb_name = 'hdr';
end

c = size(img, 2);

cubeSize = round(c / 3);

%CUBE_POS_Y
imgPosY = img(1:cubeSize,(cubeSize+1):(2*cubeSize),:);
imgPosY = imrotate(imgPosY, -270);
hdrimwrite(imgPosY,[cb_name,'_POS_Y.',cb_format]);

%CUBE_POS_X
hdrimwrite(img((cubeSize+1)    :(2*cubeSize),(cubeSize+1):(2*cubeSize),:),[cb_name,'_POS_X.',cb_format]);

%CUBE_NEG_Y
imgNegY = img((2*cubeSize+1):(3*cubeSize),(cubeSize+1):(2*cubeSize),:);
hdrimwrite(imrotate(imgNegY,-90),[cb_name,'_NEG_Y.',cb_format]);

%CUBE_NEG_X
imgNegX = img((3*cubeSize+1):(4*cubeSize),(cubeSize+1):(2*cubeSize),:);
for i=1:3
    imgNegX(:,:,i) = flipud(imgNegX(:,:,i));
    imgNegX(:,:,i) = fliplr(imgNegX(:,:,i));
end
hdrimwrite(imgNegX,[cb_name,'_NEG_X.',cb_format]);

%CUBE_POS_Z
hdrimwrite(img((cubeSize+1):(2*cubeSize),1:cubeSize,:),[cb_name,'_POS_Z.',cb_format]);

%CUBE_NEG_Z
hdrimwrite(img((cubeSize+1):(2*cubeSize),(2*cubeSize+1):(3*cubeSize),:),[cb_name,'_NEG_Z.', cb_format]);

end


function OBJ=read_wobj(fullfilename)
% Read the objects from a Wavefront OBJ file
%
% OBJ=read_wobj(filename);
%
% OBJ struct containing:
%
% OBJ.vertices : Vertices coordinates
% OBJ.vertices_texture: Texture coordinates
% OBJ.vertices_normal : Normal vectors
% OBJ.vertices_point  : Vertice data used for points and lines
% OBJ.material : Parameters from external .MTL file, will contain parameters like
%           newmtl, Ka, Kd, Ks, illum, Ns, map_Ka, map_Kd, map_Ks,
%           example of an entry from the material object:
%       OBJ.material(i).type = newmtl
%       OBJ.material(i).data = 'vase_tex'
% OBJ.objects  : Cell object with all objects in the OBJ file,
%           example of a mesh object:
%       OBJ.objects(i).type='f'
%       OBJ.objects(i).data.vertices: [n x 3 double]
%       OBJ.objects(i).data.texture:  [n x 3 double]
%       OBJ.objects(i).data.normal:   [n x 3 double]
%
% Example,
%   OBJ=read_wobj('examples\example10.obj');
%   FV.vertices=OBJ.vertices;
%   FV.faces=OBJ.objects(3).data.vertices;
%   figure, patch(FV,'facecolor',[1 0 0]); camlight
%
% Function is written by D.Kroon University of Twente (June 2010)

verbose=true;

if(exist('fullfilename','var')==0)
    [filename, filefolder] = uigetfile('*.obj', 'Read obj-file');
    fullfilename = [filefolder filename];
end
filefolder = fileparts( fullfilename);
if(verbose),disp(['Reading Object file : ' fullfilename]); end

% Read the DI3D OBJ textfile to a cell array
file_words = file2cellarray( fullfilename);
% Remove empty cells, merge lines split by "\" and convert strings with values to double
[ftype fdata]= fixlines(file_words);

% Vertex data
vertices=[]; nv=0;
vertices_texture=[]; nvt=0;
vertices_point=[]; nvp=0;
vertices_normal=[]; nvn=0;
material=[];

% Surface data
no=0;

% Loop through the Wavefront object file
for iline=1:length(ftype)
    if(mod(iline,10000)==0),
        if(verbose),disp(['Lines processed : ' num2str(iline)]); end
    end

    type=ftype{iline}; data=fdata{iline};

    % Switch on data type line
    switch(type)
        case{'mtllib'}
            if(iscell(data))
                datanew=[];
                for i=1:length(data)
                    datanew=[datanew data{i}];
                    if(i<length(data)), datanew=[datanew ' ']; end
                end
                data=datanew;
            end

            filename_mtl=fullfile(filefolder,data);
            material=readmtl(filename_mtl,verbose);
        case('v') % vertices
            nv=nv+1;
            if(length(data)==3)
                % Reserve block of memory
                if(mod(nv,10000)==1), vertices(nv+1:nv+10001,1:3)=0; end
                % Add to vertices list X Y Z
                vertices(nv,1:3)=data;
            else
                % Reserve block of memory
                if(mod(nv,10000)==1), vertices(nv+1:nv+10001,1:4)=0; end
                % Add to vertices list X Y Z W
                vertices(nv,1:4)=data;
            end
        case('vp')
            % Specifies a point in the parameter space of curve or surface
            nvp=nvp+1;
            if(length(data)==1)
                % Reserve block of memory
                if(mod(nvp,10000)==1), vertices_point(nvp+1:nvp+10001,1)=0; end
                % Add to vertices point list U
                vertices_point(nvp,1)=data;
            elseif(length(data)==2)
                % Reserve block of memory
                if(mod(nvp,10000)==1), vertices_point(nvp+1:nvp+10001,1:2)=0; end
                % Add to vertices point list U V
                vertices_point(nvp,1:2)=data;
            else
                % Reserve block of memory
                if(mod(nvp,10000)==1), vertices_point(nvp+1:nvp+10001,1:3)=0; end
                % Add to vertices point list U V W
                vertices_point(nvp,1:3)=data;
            end
        case('vn')
            % A normal vector
            nvn=nvn+1; if(mod(nvn,10000)==1),  vertices_normal(nvn+1:nvn+10001,1:3)=0; end
            % Add to vertices list I J K
            vertices_normal(nvn,1:3)=data;
        case('vt')
            % Vertices Texture Coordinate in photo
            % U V W
            nvt=nvt+1;
            if(length(data)==1)
                % Reserve block of memory
                if(mod(nvt,10000)==1), vertices_texture(nvt+1:nvt+10001,1)=0; end
                % Add to vertices texture list U
                vertices_texture(nvt,1)=data;
            elseif(length(data)==2)
                % Reserve block of memory
                if(mod(nvt,10000)==1), vertices_texture(nvt+1:nvt+10001,1:2)=0; end
                % Add to vertices texture list U V
                vertices_texture(nvt,1:2)=data;
            else
                % Reserve block of memory
                if(mod(nvt,10000)==1), vertices_texture(nvt+1:nvt+10001,1:3)=0; end
                % Add to vertices texture list U V W
                vertices_texture(nvt,1:3)=data;
            end
        case('l')
            no=no+1; if(mod(no,10000)==1), objects(no+10001).data=0; end
            array_vertices=[];
            array_texture=[];
            for i=1:length(data),
                switch class(data)
                    case 'cell'
                        tvals=str2double(stringsplit(data{i},'/'));
                    case 'string'
                        tvals=str2double(stringsplit(data,'/'));
                    otherwise
                        tvals=data(i);
                end
                val=tvals(1);
                if(val<0), val=val+1+nv; end
                array_vertices(i)=val;
                if(length(tvals)>1),
                    val=tvals(2);
                    if(val<0), val=val+1+nvt; end
                    array_texture(i)=val;
                end
            end
            objects(no).type='l';
            objects(no).data.vertices=array_vertices;
            objects(no).data.texture=array_texture;
        case('f')
            no=no+1; if(mod(no,10000)==1), objects(no+10001).data=0; end
            array_vertices=[];
            array_texture=[];
            array_normal=[];
            for i=1:length(data);
                switch class(data)
                    case 'cell'
                        tvals=str2double(stringsplit(data{i},'/'));
                    case 'string'
                        tvals=str2double(stringsplit(data,'/'));
                    otherwise
                        tvals=data(i);
                end
                val=tvals(1);

                if(val<0), val=val+1+nv; end
                array_vertices(i)=val;
                if(length(tvals)>1),
                    if(isfinite(tvals(2)))
                        val=tvals(2);
                        if(val<0), val=val+1+nvt; end
                        array_texture(i)=val;
                    end
                end
                if(length(tvals)>2),
                    val=tvals(3);
                    if(val<0), val=val+1+nvn; end
                    array_normal(i)=val;
                end
            end

            % A face of more than 3 indices is always split into
            % multiple faces of only 3 indices.
            objects(no).type='f';
            findex=1:min (3,length(array_vertices));

            objects(no).data.vertices=array_vertices(findex);
            if(~isempty(array_texture)),objects(no).data.texture=array_texture(findex); end
            if(~isempty(array_normal)),objects(no).data.normal=array_normal(findex); end
            for i=1:length(array_vertices)-3;
                no=no+1; if(mod(no,10000)==1), objects(no+10001).data=0; end
                findex=[1 2+i 3+i];
                findex(findex>length(array_vertices))=findex(findex>length(array_vertices))-length(array_vertices);
                objects(no).type='f';
                objects(no).data.vertices=array_vertices(findex);
                if(~isempty(array_texture)),objects(no).data.texture=array_texture(findex); end
                if(~isempty(array_normal)),objects(no).data.normal=array_normal(findex); end
            end
        case{'#','$'}
            % Comment
            tline='  %';
            if(iscell(data))
                for i=1:length(data), tline=[tline ' ' data{i}]; end
            else
                tline=[tline data];
            end
            if(verbose), disp(tline); end
        case{''}
        otherwise
            no=no+1;
            if(mod(no,10000)==1), objects(no+10001).data=0; end
            objects(no).type=type;
            objects(no).data=data;
    end
end

% Initialize new object list, which will contain the "collapsed" objects
objects2(no).data=0;

index=0;

i=0;
while (i<no), i=i+1;
    type=objects(i).type;
    % First face found
    if((length(type)==1)&&(type(1)=='f'))
        % Get number of faces
        for j=i:no
            type=objects(j).type;
            if((length(type)~=1)||(type(1)~='f'))
                j=j-1; break;
            end
        end
        numfaces=(j-i)+1;

        index=index+1;
        objects2(index).type='f';
        % Process last face first to allocate memory
        objects2(index).data.vertices(numfaces,:)= objects(i).data.vertices;
        if(isfield(objects(i).data,'texture'))
            objects2(index).data.texture(numfaces,:) = objects(i).data.texture;
        else
            objects2(index).data.texture=[];
        end
        if(isfield(objects(i).data,'normal'))
            objects2(index).data.normal(numfaces,:)  = objects(i).data.normal;
        else
            objects2(index).data.normal=[];
        end
        % All faces to arrays
        for k=1:numfaces
            objects2(index).data.vertices(k,:)= objects(i+k-1).data.vertices;
            if(isfield(objects(i).data,'texture'))
                objects2(index).data.texture(k,:) = objects(i+k-1).data.texture;
            end
            if(isfield(objects(i).data,'normal'))
                objects2(index).data.normal(k,:)  = objects(i+k-1).data.normal;
            end
        end
        i=j;
    else
        index=index+1;
        objects2(index).type=objects(i).type;
        objects2(index).data=objects(i).data;
    end
end

% Add all data to output struct
OBJ.objects=objects2(1:index);
OBJ.material=material;
OBJ.vertices=vertices(1:nv,:);
OBJ.vertices_point=vertices_point(1:nvp,:);
OBJ.vertices_normal=vertices_normal(1:nvn,:);
OBJ.vertices_texture=vertices_texture(1:nvt,:);
if(verbose),disp('Finished Reading Object file'); end

function twords=stringsplit(tline,tchar)
% Get start and end position of all "words" separated by a char
i=find(tline(2:end-1)==tchar)+1; i_start=[1 i+1]; i_end=[i-1 length(tline)];
% Create a cell array of the words
twords=cell(1,length(i_start)); for j=1:length(i_start), twords{j}=tline(i_start(j):i_end(j)); end

function file_words=file2cellarray(filename)
% Open a DI3D OBJ textfile
fid=fopen(filename,'r');
file_text=fread(fid, inf, 'uint8=>char')';
fclose(fid);
file_lines = regexp(file_text, '\n+', 'split');
file_words = regexp(file_lines, '\s+', 'split');

function [ftype fdata]=fixlines(file_words)
ftype=cell(size(file_words));
fdata=cell(size(file_words));

iline=0; jline=0;
while(iline<length(file_words))
    iline=iline+1;
    twords=removeemptycells(file_words{iline});
    if(~isempty(twords))
        % Add next line to current line when line end with '\'
        while(strcmp(twords{end},'\')&&iline<length(file_words))
            iline=iline+1;
            twords(end)=[];
            twords=[twords removeemptycells(file_words{iline})];
        end
        % Values to double

        type=twords{1};
        stringdold=true;
        j=0;
        switch(type)
            case{'#','$'}
                for i=2:length(twords)
                    j=j+1; twords{j}=twords{i};
                end
            otherwise
                for i=2:length(twords)
                    str=twords{i};
                    val=str2double(str);
                    stringd=~isfinite(val);
                    if(stringd)
                        j=j+1; twords{j}=str;
                    else
                        if(stringdold)
                            j=j+1; twords{j}=val;
                        else
                            twords{j}=[twords{j} val];
                        end
                    end
                    stringdold=stringd;
                end
        end
        twords(j+1:end)=[];
        jline=jline+1;
        ftype{jline}=type;
        if(length(twords)==1), twords=twords{1}; end
        fdata{jline}=twords;
    end
end
ftype(jline+1:end)=[];
fdata(jline+1:end)=[];

function b=removeemptycells(a)
j=0; b={};
for i=1:length(a);
    if(~isempty(a{i})),j=j+1; b{j}=a{i}; end;
end

function  objects=readmtl(filename_mtl,verbose)
if(verbose),disp(['Reading Material file : ' filename_mtl]); end
file_words=file2cellarray(filename_mtl);
% Remove empty cells, merge lines split by "\" and convert strings with values to double
[ftype fdata]= fixlines(file_words);

% Surface data
objects.type(length(ftype))=0;
objects.data(length(ftype))=0;
no=0;
% Loop through the Wavefront object file
for iline=1:length(ftype)
  type=ftype{iline}; data=fdata{iline};

    % Switch on data type line
    switch(type)
        case{'#','$'}
            % Comment
            tline='  %';
            if(iscell(data))
                for i=1:length(data), tline=[tline ' ' data{i}]; end
            else
                tline=[tline data];
            end
            if(verbose), disp(tline); end
        case{''}
        otherwise
            no=no+1;
            if(mod(no,10000)==1), objects(no+10001).data=0; end
            objects(no).type=type;
            objects(no).data=data;
    end
end
objects=objects(1:no);
if(verbose),disp('Finished Reading Material file'); end


function GammaExposureTMOv(hdrv, filenameOutput, tmo_gamma, tmo_fstop, tmo_quality, tmo_video_profile)
%
%
%       GammaExposureTMOv(hdrv, filenameOutput, tmo_gamma, tmo_fstop, tmo_quality, tmo_video_profile)
%
%       This function applies gamma + exposure correction for each frame of the HDR stream
%
%       Input:
%           -hdrv: a HDR video structure; use hdrvread to create a hdrv
%           structure
%           -filenameOutput: output filename (if it has an image extension,
%           single files will be generated)
%           -tmo_gamma: gamma for encoding the frame. If it is negative,
%           sRGB econding is applied
%           -tmo_fstop: f-stop value
%           -tmo_quality: the output quality in [1,100]. 100 is the best quality
%           1 is the lowest quality.%
%           -tmo_video_profile: the compression profile (encoder) for compressing the stream.
%           Please have a look to the profile of VideoWriter from the MATLAB
%           help. Depending on the version of MATLAB some profiles may be not
%           be present.
%
%       Output:
%           -frameOut: the tone mapped frame
%
%     Copyright (C) 2016  Francesco Banterle
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%
%     This function applies a static TMO to an operator without taking into
%     account for temporal coherency
%

if(~exist('filenameOutput', 'var'))
    date_str = strrep(datestr(now()), ' ', '_');
    date_str = strrep(date_str, ':', '_');
    filenameOutput = ['static_tmo_output_', date_str, '.avi'];
end

if(~exist('tmo_gamma', 'var'))
    tmo_gamma = 2.2;
end

if(~exist('tmo_fstop', 'var'))
    tmo_fstop = 0.0;
end

if(~exist('tmo_quality', 'var'))
    tmo_quality = 95;
end

if(~exist('tmo_video_profile', 'var'))
    tmo_video_profile = 'MPEG-4';
end

if(tmo_gamma < 0)
    bsRGB = 1;
else
    bsRGB = 0;
end

name = RemoveExt(filenameOutput);
ext = fileExtension(filenameOutput);

bVideo = 0;
writerObj = 0;

if(strcmp(ext, 'avi') == 1 | strcmp(ext, 'mp4') == 1)
    bVideo = 1;
    writerObj = VideoWriter(filenameOutput, tmo_video_profile);
    writerObj.FrameRate = hdrv.FrameRate;
    writerObj.Quality = tmo_quality;
    open(writerObj);
end

hdrv = hdrvopen(hdrv);

exposure = 2^tmo_fstop;

disp('Tone Mapping...');
for i=1:hdrv.totalFrames
    disp(['Processing frame ',num2str(i)]);
    [frame, hdrv] = hdrvGetFrame(hdrv, i);

    %only physical values
    frame = RemoveSpecials(frame);
    frame(frame < 0) = 0;

    %gamma/sRGB encoding
    if(bsRGB)
        frameOut = ClampImg(ConvertRGBtosRGB(frame * exposure, 0), 0, 1);
    else
        frameOut = ClampImg(GammaTMO(frame, tmo_gamma, tmo_fstop, 0), 0, 1);
    end

    if(bVideo)
        writeVideo(writerObj, frameOut);
    else
        nameOut = [name, sprintf('%.10d',i), '.', ext];
        imwrite(frameOut, nameOut);
    end

end
disp('OK');

if(bVideo)
    close(writerObj);
end

hdrvclose(hdrv);

end


function [ResultsAllCellLines,OverViewResults] = setQuantConstraints(model, samples, tol, minGrowth, obj, no_secretion, no_uptake, medium, addExtraExch, addExtraExch_value, path)
% This function takes a model and quantitative extracellular metabolomic data and returns a model in which the data is integrated as constraints described
% in "MetaboTools: A Comprehensive Toolbox for Analysis of Genome-Scale Metabolic Models", 2016, Front. Physiol., and the supplemental data "Tutorial II: Workflow for the integration
% of quantitative extracellular metabolomic data into the network context." (Data Sheet 3.pdf)
%
% USAGE:
%
%    [ResultsAllCellLines, OverViewResults] = setQuantConstraints(model, samples, tol, minGrowth, obj, no_secretion, no_uptake, medium, addExtraExch, addExtraExch_value, path, epsilon)
%
% INPUTS:
%       model:                Global metabolic model (Recon)
%       samples:              Vector specifying the samples used (there must be an output file of function .... for each sample)
%       tol:                  Cutoff value for small numbers (e.g., -1e-8). All number smaller than tol will be treated as zero
%       minGrowth:            Will be the lower bound of the objective function (e.g., 0.008). Forces the output model(s) to be able to produce a minimal objective value
%       obj:                  Objective function, e.g. `biomass_reaction2`
%       no_secretion:         Define metabolites that should not be secreted (e.g., {`EX_o2(e)`})
%       no_uptake:            Define metabolites that should not be consumed (e.g., {`EX_o2s(e)`, `EX_h2o2(e)`})
%       medium:               Define if certain exchanges should be excluded from minimization of exchanges (e.g., {}, if no medium except the exometabolomic data has been defined)
%       addExtraExch:         After adding secretions, models are still not growing, this variable allows one to recover exchanges with a defined small value
%       addExtraExch_value:   e.g. 1 as arbitrary small flux value / the resulting ub = 1, lb = -1.
%       path:                 Location of the .mat files for samples.
%
%
% OUTPUTS:
%       ResultsAllCellLines:  Structure that contains pruned and unpruned model, Vector of the Exchange_reactions, the exchange reactions added by `minExCard`, `minFLux` and `maxFlux` of the added reactions, maximal objective value, and the results of the gene deletion
%       OverViewResults:      Overview of model statistics, e.g., number of reactions, metabolites, genes, number of essential genes, min and max objective values for easy comparison between sets of models
%
%
% Depends on `changeRxnBounds`, `fluxVariability`, `optimizeCbModel`, `generateCompactExchModel` as well its dependent functions `pruneModel`, `findMinCardModel`, `findOptExchRxns`
%
% .. Author: - Maike K. Aurich 18/02/15

cntO=1;
% Set overview variable
OverViewResults{1,cntO} ='cell line';cntO = cntO+1;
OverViewResults{1,cntO} = 'num Added Rxns';cntO = cntO+1;
OverViewResults{1,cntO} = 'num rxns pruned model';cntO = cntO+1;
OverViewResults{1,cntO} = 'num mets pruned model';cntO = cntO+1;
OverViewResults{1,cntO} = 'num genes pruned model';cntO = cntO+1;
OverViewResults{1,cntO} = 'max growth rate';cntO = cntO+1;
OverViewResults{1,cntO} = 'num exch rxns';cntO = cntO+1;
OverViewResults{1,cntO} = 'O2 requirement';cntO = cntO+1;
OverViewResults{1,cntO} = 'extra Exchanges Added';cntO = cntO+1;
OverViewResults{1,cntO} = 'num recovered exchanges';cntO = cntO+1;

for j = 1:length(samples)

    j
    %   load([path filesep 'model.mat']); %% uncomment for Recon1
    ExtraExchAdded = 0;

    FILENAME = char(samples(j,1));
    load([path filesep FILENAME '.mat'])%, 'uptake_value', 'secr_value' , 'uptake' ,'secretion', 'cell_line' );

    % Map exo-metabolomic data
    model2=model;
    model2.lb(find(ismember(model2.rxns,obj)))=minGrowth;% based on slowlest cell line in data

    % Map uptake
    for k=1:length(uptake)
        Uptake_rxns=uptake(k);
        lb = uptake_value(k,2);
        ub = uptake_value(k,3);
        model2 = changeRxnBounds(model2,Uptake_rxns,ub,'u'); %enforce uptake of metabolites taken up by cells in the experiment
        model2 = changeRxnBounds(model2,Uptake_rxns,lb,'l'); %enforce uptake of metabolites taken up by cells in the experiment

    end
    clear A sol
    model2ori=model2;
    SecretionRxnsRecovered =[];
    cnt2=1;

    % Map secretion
    for k=1:length(secretion)
        secretion_rxns= secretion(k);
        lb = secr_value(k,3);
        ub = secr_value(k,2);
        model2 = changeRxnBounds(model2, secretion_rxns,lb,'l');% enforce secretion of metabolites that are secreted by the cells in the experiment
        model2 = changeRxnBounds(model2, secretion_rxns,ub,'u');% enforce secretion of metabolites that are secreted by the cells in the experiment

        % check if model works after adding constraints
        SOL = optimizeCbModel(model2);
        if SOL.f<=abs(tol)
            sol(k,1)=SOL.f;
            secretion_rxns
            model2=model2ori; % model2ori is overwritten after each successful iteration so its not the original model (without any secretions)
            model2 = changeRxnBounds(model2, secretion_rxns,ub,'u');% set secretion of metabolite to measured upper bound nevertheless
            SecretionRxnsRecovered{cnt2,1}=secretion_rxns{1,:}; cnt2 = cnt2 +1;
        else
            sol(k,1)=SOL.f;
            model2ori=model2;
        end
    end

    % sets bounds to the lowest measured uptake/secretion rate
    for k=1:length(No_upt_secr)
        No_upt_secr_rxns= No_upt_secr(k);
        bound = min(abs([max(uptake_value(:,3));min(secr_value(:,3))]));
        model2 = changeRxnBounds(model2, No_upt_secr_rxns,-bound,'l');
        model2 = changeRxnBounds(model2, No_upt_secr_rxns,bound,'u');% sets bounds to the lowest measured uptake/secretion rate
    end

    % do not allow secretion or uptake of certain metabolites
    model2 = changeRxnBounds(model2, no_secretion,0,'u');% enforce secretion of metabolites that are secreted by the cells in the experiment
    model2 = changeRxnBounds(model2, no_uptake,0,'l');% enforce secretion of metabolites that are secreted by the cells in the experiment

    %% test if model can grow AT ALL
    SOL = optimizeCbModel(model2);
    if abs(SOL.f) < abs(tol)

        model2 = changeRxnBounds(model2, addExtraExch,-addExtraExch_value,'l');% sets bounds to the lowest measured uptake/secretion rate
        model2 = changeRxnBounds(model2, addExtraExch,addExtraExch_value,'u');% sets bounds to the lowest measured uptake/secretion rate
        ExtraExchAdded = 1;
    end

    SOL = optimizeCbModel(model2);
    if abs(SOL.f) > abs(tol)
        %Generate submodel
        [modelMin, modelPruned, Ex_Rxns] = generateCompactExchModel(model2,minGrowth);

        %added 23/07/2015
        modelPruned.c = zeros(length(modelPruned.rxns),1);
        modelPruned.c(find(ismember(modelPruned.rxns,obj)),1)=1;
        %added 23/07/2015

        sol= optimizeCbModel(modelPruned);
        Ex_RxnsAdded = Ex_Rxns;

        % remove reactions that are in uptake and secretion
        US = unique([secretion;uptake]);
        Ex_RxnsAdded(ismember(Ex_RxnsAdded,US))=[];
        [a(:,1),a(:,2)]=fluxVariability(modelPruned,1,[],Ex_RxnsAdded);

        % print Results

        ResultsAllCellLines.(samples{j}).modelPruned = modelPruned;
        ResultsAllCellLines.(samples{j}).modelMin = modelMin;
        ResultsAllCellLines.(samples{j}).Ex_Rxns = Ex_Rxns;
        ResultsAllCellLines.(samples{j}).Ex_RxnsAdded = Ex_RxnsAdded;
        ResultsAllCellLines.(samples{j}).MinMaxAddedRxns = a;
        ResultsAllCellLines.(samples{j}).maxBiomass = sol;

        ResultsAllCellLines.(samples{j}).SecretionRxnsRecovered = SecretionRxnsRecovered;

        cntO=1;
        OverViewResults{j+1,cntO} = samples{j};cntO = cntO+1;% cell line
        OverViewResults{j+1,cntO} = num2str(length(ResultsAllCellLines.(samples{j}).Ex_RxnsAdded));cntO = cntO+1;% num Added Rxns
        OverViewResults{j+1,cntO} = num2str(length(ResultsAllCellLines.(samples{j}).modelPruned.rxns));cntO = cntO+1;% num rxns
        OverViewResults{j+1,cntO} = num2str(length(ResultsAllCellLines.(samples{j}).modelPruned.mets));cntO = cntO+1;% num mets
        OverViewResults{j+1,cntO} = num2str(length(ResultsAllCellLines.(samples{j}).modelPruned.genes));cntO = cntO+1;% num genes
        OverViewResults{j+1,cntO} = num2str(ResultsAllCellLines.(samples{j}).maxBiomass.f);cntO = cntO+1;% max growth rate
        OverViewResults{j+1,cntO} = num2str(length(ResultsAllCellLines.(samples{j}).Ex_Rxns));cntO = cntO+1;% num Exchange rxns
        if ~isempty(strmatch('EX_o2(e)',ResultsAllCellLines.(samples{j}).Ex_RxnsAdded))
            OverViewResults{j+1,cntO} = num2str(1);cntO = cntO+1;% O2 requirement
        else
            OverViewResults{j+1,cntO} = num2str(0);cntO = cntO+1;% O2 requirement
        end

        OverViewResults{j+1,cntO} = num2str(ExtraExchAdded);cntO = cntO+1;% num Exchange rxns
        OverViewResults{j+1,cntO} = num2str(length(SecretionRxnsRecovered));cntO = cntO+1;% num Exchange rxns

    else
        ResultsAllCellLines.(samples{j}).model = [];
        ResultsAllCellLines.(samples{j}).AddedExchange = [];
        ResultsAllCellLines.(samples{j}).maxBiomass = [];
        cntO=1;
        OverViewResults{j+1,cntO} = samples{j};cntO = cntO+1;% cell line
    end
    clear sol Extra* addExtraExch* model2 modelMin* modelU* modelP* model2ori No* upt* secr* gr* Rxn* cnt* Blocked* h* FBA* j k m bound ans lb Close* Ex_Rxns1* Ex_Rxns2*  Sol U* Ori* i* ma* rev* t un* us* w a SOL a1 ub ToDe* ReP* Ex_* Secr* AddedExchang*
    save([path filesep 'setQuantConstraints.mat'], '-v7.3');
end

end


%--------------------------------------------------------------------------------------------------------
% The system is created based on the principles described in the following paper
% Jimmy SJ. Ren, Li Xu, Qiong Yan, Wenxiu Sun, "Shepard Convolutional Neural Networks",
% Advances in Neural Information Processing Systems (NIPS 2015)
% email: jimmy.sj.ren@gmail.com
%--------------------------------------------------------------------------------------------------------
addpath applications/Shepard_CNN/Shepard_super_res/
addpath utils/
addpath cuda/
addpath mem/
addpath layers/
addpath layers_adapters/
addpath optimization/
addpath pipeline/
addpath data/

clearvars -global config;
clearvars -global mem;
clear gen_mask_patch_cat_idx_for_super_res;
clear;
global config mem;
shepard_sr_x2_configure();
init(0);

load('data/Shepard_CNN/Shepard_super_res/x2/val_1ch/val_1');

images_t = reshape(images_t, size(images_t,1), size(images_t,2), 1, size(images_t,3));
labels_t = reshape(labels_t, size(labels_t,1), size(labels_t,2), 1, size(labels_t,3));

perm = randperm(size(images_t, 4));
images_t = images_t(:,:,:,perm);
labels_t = labels_t(:,:,:,perm);
test_samples = config.NEW_MEM(images_t(:,:,:,1:1000));
test_labels = config.NEW_MEM(labels_t(:,:,:,1:1000));

mask = config.NEW_MEM([1 0; 0 0]);
mask = repmat(mask, config.input_size(1)/2, config.input_size(2)/2, config.chs);
mask = repmat(mask, 1,1,1,config.batch_size);

count = 0;
cost_avg = 0;
epoc = 0;
points_seen = 0;
display_points = 5000;
save_points = 50000;
max_grad = 1;
fprintf('%s\n', datestr(now, 'dd-mm-yyyy HH:MM:SS FFF'));
for pass = 1:10
    for p = 1:50
        load(strcat('data/Shepard_CNN/Shepard_super_res/x2/train_1ch/patches_', num2str(p), '.mat'));

        images = reshape(images, size(images,1), size(images,2), 1, size(images,3));
        labels = reshape(labels, size(labels,1), size(labels,2), 1, size(labels,3));

        perm = randperm(20000);
        images = images(:,:,:,perm);
        labels = labels(:,:,:,perm);
        train_imgs = config.NEW_MEM(images);
        train_labels = config.NEW_MEM(labels);

        for i = 1:size(train_labels, 4) / config.batch_size
            points_seen = points_seen + config.batch_size;
            in = train_imgs(:,:,:,(i-1)*config.batch_size+1:i*config.batch_size);
            %in = train_labels(:,:,:,(i-1)*config.batch_size+1:i*config.batch_size);
            out = train_labels(:,:,:,(i-1)*config.batch_size+1:i*config.batch_size);
            out = out((size(in, 1) - config.output_size(1)) / 2 + 1:(size(in, 1) - config.output_size(1)) / 2 + config.output_size(1), ...
                      (size(in, 2) - config.output_size(2)) / 2 + 1:(size(in, 2) - config.output_size(2)) / 2 + config.output_size(2), :, :);

            % make the mask list
            mask_li = {};
            mask_li{1} = mask;
            % operate the training pipeline
            op_train_pipe_with_mask(in.*mask, mask_li, out);
            % update the weights
            config.UPDATE_WEIGHTS();

            if(cost_avg == 0)
                cost_avg = config.cost;
            else
                cost_avg = (cost_avg + config.cost) / 2;
            end

            % display point
            if(mod(points_seen, display_points) == 0)
                count = count + 1;
                fprintf('%d ', count);
            end
            % save point
            if(mod(points_seen, save_points) == 0)
                fprintf('\n%s', datestr(now, 'dd-mm-yyyy HH:MM:SS FFF'));
                epoc = epoc + 1;
                test_cost = 0;
                for t = 1:size(test_samples, 4) / config.batch_size
                    t_label = test_labels(:,:,:,(t-1)*config.batch_size+1:t*config.batch_size);
                    t_label = config.NEW_MEM(t_label((size(in, 1) - config.output_size(1)) / 2 + 1:(size(in, 1) - config.output_size(1)) / 2 + config.output_size(1), ...
                                            (size(in, 2) - config.output_size(2)) / 2 + 1:(size(in, 2) - config.output_size(2)) / 2 + config.output_size(2), :));

                    op_test_pipe_with_mask(test_samples(:,:,:,(t-1)*config.batch_size+1:t*config.batch_size).*mask, mask_li, t_label);

                    test_out = gather(mem.output);
                    test_cost = test_cost + config.cost;
                end
                test_cost = test_cost / (size(test_samples, 4) / config.batch_size);
                fprintf('\nepoc %d, training avg cost: %f, test avg cost: %f\n', epoc, cost_avg, test_cost);

                save_weights(strcat('applications/Shepard_CNN/Shepard_super_res/results/shepard_layer_x2/epoc', num2str(epoc), '.mat'));

                cost_avg = 0;
            end
        end
    end
end


function [yAvg, tHRF, nTrials] = hmrG_SubjAvg_Nirs(yAvgSubjs, tHRFSubjs, nTrialsSubjs)
% SYNTAX:
% [yAvg, tHRF, nTrials] = hmrG_SubjAvg_Nirs(yAvgSubjs, tHRFSubjs, nTrialsSubjs)
%
% UI NAME:
% Subj_Average
%
% DESCRIPTION:
% Calculate avearge HRF of all subjects in a group .
%
% INPUTS:
% yAvgSubjs:
% tHRFSubjs:
% nTrialsSubjs:
%
% OUTPUTS:
% yavg: the averaged results
% tHRF: the time vector
% nTrials: the number of trials averaged for each condition across all
%          subjects
%
% USAGE OPTIONS:
% Subj_Average_on_Concentration_Data: [dcAvg, tHRF, nTrials] = hmrG_SubjAvg_Nirs(dcAvgSubjs, tHRFSubjs, nTrialsSubjs)
% Subj_Average_on_Delta_OD_Data:      [dodAvg, tHRF, nTrials] = hmrG_SubjAvg_Nirs(dodAvgSubjs, tHRFSubjs, nTrialsSubjs)
%
%

yAvg       = [];
tHRF       = [];
nTrials    = [];

subjCh = [];
nStim = 0;
grp1=[];
nSubj = length(yAvgSubjs);

for iSubj = 1:nSubj

    if isempty(yAvgSubjs{iSubj}) || isempty(tHRFSubjs{iSubj}) || isempty(nTrialsSubjs{iSubj})
        continue;
    end

    yAvg      = yAvgSubjs{iSubj};
    tHRF      = tHRFSubjs{iSubj};
    nTrials   = nTrialsSubjs{iSubj};

    nCond = size(nTrials,2);

    if ndims(yAvg) == (4-(nCond<2))

        if iSubj==1
            grp1 = zeros(size(yAvg,1), size(yAvg,2), size(yAvg,3), nCond);
        end

        nCh  = size(yAvg,3);
        if isempty(subjCh)
            subjCh = zeros(nCh, nCond);
        end

        for iC = 1:nCond
            if nTrials(:,iC)==0
                continue;
            end

            if iSubj==1 | iC>nStim
                for iCh = 1:size(yAvg,3)
                    for iHb=1:3
                        grp1(:,iHb,iCh,iC) = interp1(tHRF,yAvg(:,iHb,iCh,iC),tHRF(:));
                    end
                end
                nStim = iC;
            else
                for iCh = 1:size(yAvg,3)
                    for iHb=1:3
                        grp1(:,iHb,iCh,iC) = grp1(:,iHb,iCh,iC) + interp1(tHRF,yAvg(:,iHb,iCh,iC),tHRF(:));
                    end
                end
            end
            subjCh(:,iC) = subjCh(:,iC) + 1; %#ok<*AGROW>
        end

        yAvg = [];
        if ~isempty(grp1)
            for iC = 1:size(grp1,4)
                for iCh = 1:size(grp1,3)
                    yAvg(:,1,iCh,iC) = grp1(:,1,iCh,iC) / subjCh(iCh,iC);
                    yAvg(:,2,iCh,iC) = grp1(:,2,iCh,iC) / subjCh(iCh,iC);
                    yAvg(:,3,iCh,iC) = grp1(:,3,iCh,iC) / subjCh(iCh,iC);
                end
            end
        end

    elseif ndims(yAvg) == (3-(nCond<2))

        if iSubj==1
            grp1 = zeros(size(yAvg,1),size(yAvg,2),nCond);
        end

        nCh  = size(yAvg,2);
        if isempty(subjCh)
            subjCh = zeros(nCh, nCond);
        end

        for iC = 1:nCond
            if nTrials(:,iC)==0
                continue;
            end

            for iWl = 1:2
                if iSubj==1 | iC>nStim
                    for iCh = 1:size(yAvg,2)
                        grp1(:,iCh,iC) = interp1(tHRF,yAvg(:,iCh,iC),tHRF(:));
                    end
                    nStim = iC;
                else
                    for iCh = 1:size(yAvg,3)
                        grp1(:,iCh,iC) = grp1(:,iCh,iC) + interp1(tHRF,yAvg(:,iCh,iC),tHRF(:));
                    end
                end
                subjCh(:,iC) = subjCh(:,iC) + 1;
            end
        end

        yAvg = [];
        if ~isempty(grp1)
            for iC = 1:size(grp1,3)
                for iCh = 1:size(grp1,2)
                    yAvg(:,iCh,iC) = grp1(:,iCh,iC) / subjCh(iCh,iC);
                    yAvg(:,iCh,iC) = grp1(:,iCh,iC) / subjCh(iCh,iC);
                    yAvg(:,iCh,iC) = grp1(:,iCh,iC) / subjCh(iCh,iC);
                end
            end
        end

    end
end


% Function to difference each column in a matrix
%
% Description
%  Function to difference each column in a matrix
%
%  This version is a slightly later one than that described in the
%  above published 2013 CSL paper [2]. The algorithm here rather than using binary
%  decision trees using artificial neural networks and combines the
%  features used in the CSL paper with those proposed in Ishi et al.
%  (2008). This updated version has been submitted to CSL for a special
%  issue on glottal source processing on April 14th 2013. It will have
%  reference [1].
%
% Inputs
%  mat  : [samples] [NxM] Feature matrix
%
% Outputs
%  delta_mat : [samples] [NxM] Differenced feature matrix
%
% Example
%  Please see the HOWTO_glottalsource.m example file.
%
% References
%  [1] Drugman, T., Kane, J., Gobl, C., `Automatic Analysis of Creaky
%       Excitation Patterns', Submitted to Computer Speech and
%       Language.
%  [2] Kane, J., Drugman, T., Gobl, C., (2013) `Improved automatic
%       detection of creak', Computer Speech and Language 27(4), pp.
%       1028-1047.
%  [3] Drugman, T., Kane, J., Gobl, C., (2012) `Resonator-based creaky
%       voice detection', Interspeech 2012, Portland, Oregon, USA.
%
% Copyright (c) 2013 University of Mons, FNRS & 2013 Trinity College Dublin
%
% License
%  This code is a part of the GLOAT toolbox with the following
%  licence:
%  This program is free software: you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation, either version 3 of the License, or
%  (at your option) any later version.
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Authors
%  Thomas Drugman <thomas.drugman@umons.ac.be> & John Kane <kanejo@tcd.ie>

function delta_mat = get_delta_mat(mat)

delta_mat=zeros(size(mat));
N=size(mat,2);

for n=1:N
    delta_mat(2:end,n)=diff(mat(:,n));
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright 2014 National Renewable Energy Laboratory and National
% Technology & Engineering Solutions of Sandia, LLC (NTESS).
% Under the terms of Contract DE-NA0003525 with NTESS,
% the U.S. Government retains certain rights in this software.
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

classdef mooringClass<handle
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % The ``mooringClass`` creates a ``mooring`` object saved to the MATLAB
    % workspace. The ``mooringClass`` includes properties and methods used
    % to define cable connections relative to other bodies.
    % It is suggested that the ``mooringClass`` be used for connections between
    % bodies and the global reference frame.
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % This class contains mooring parameters and settings
    properties (SetAccess = 'public', GetAccess = 'public')%input file
        initial                 = struct(...                               % (`structure`) Defines the initial displacement of the mooring.
            'displacement',         [0 0 0], ...                           %
            'axis',                 [0 1 0], ...                           %
            'angle',                0)                                     % (`structure`) Defines the initial displacement of the mooring. ``displacement`` (`3x1 float vector`) is defined as the initial displacement of the pto [m] in the following format [x y z], Default = [``0 0 0``].
        location                = [0 0 0]                                  % (`float 1 x 3`) Mooring Reference location. Default = ``[0 0 0]``
        matrix                  = struct(...                               % (`structure`) Defines the mooring parameters.
            'damping',              zeros(6,6), ...                        %
            'stiffness',            zeros(6,6), ...                        %
            'preTension',           [0 0 0 0 0 0])                         % (`structure`) Defines the mooring parameters. ``damping`` (`6x6 float matrix`) Matrix of damping coefficients, Default = ``zeros(6)``. ``stiffness`` (`6x6 float matrix`) Matrix of stiffness coefficients, Default = ``zeros(6)``. ``preTension`` (`6x6 float matrix`) Array of pretension force in each dof, Default = ``[0 0 0 0 0 0]``.
        moorDyn                 = 0                                        % (`integer`) Flag to indicate a MoorDyn block, 0 or 1. Default = ``0``
        moorDynLines            = 0                                        % (`integer`) Number of lines in MoorDyn. Default = ``0``
        moorDynNodes            = []                                       % (`integer`) number of nodes for each line. Default = ``'NOT DEFINED'``
        name                    = 'NOT DEFINED'                            % (`string`) Name of the mooring. Default = ``'NOT DEFINED'``
    end

    properties (SetAccess = 'private', GetAccess = 'public') %internal
        orientation             = []                                       % (`float 1 x 6`) Initial 6DOF location. Default = ``[0 0 0 0 0 0]``
        number                  = []                                       % (`integer`) Mooring number. Default = ``'NOT DEFINED'``
    end

    methods (Access = 'public')
        function obj = mooringClass(name)
            % This method initializes the mooringClass object
            if exist('name','var')
                obj.name = name;
            else
                error('The mooring class number(s) in the wecSimInputFile must be specified in ascending order starting from 1. The mooringClass() function should be called first to initialize each mooring line with a name.')
            end
        end

        function setInitDisp(obj, relCoord, axisAngleList, addLinDisp)
            % Function to set a mooring's initial displacement
            %
            % This function assumes that all rotations are about the same relative coordinate.
            % If not, the user should input a relative coordinate of 0,0,0 and
            % use the additional linear displacement parameter to set the cg or orientation
            % correctly.
            %
            % Parameters
            % ------------
            %    relCoord : [1 3] float vector
            %        Distance from x_rot to the body center of gravity or the constraint
            %        or pto location as defined by: relCoord = cg - x_rot. [m]
            %
            %    axisAngleList : [nAngle 4] float vector
            %        List of axes and angles of the rotations with the
            %        format: [n_x n_y n_z angle] (angle in rad)
            %        Rotations applied consecutively in order of dimension 1
            %
            %    addLinDisp : [1 3] float vector
            %        Initial linear displacement (in addition to the
            %        displacement caused by rotation) [m]
            %

            % initialize quantities before for loop
            axisList = axisAngleList(:,1:3);
            angleList = axisAngleList(:,4);
            nAngle = size(axisList,1);
            rotMat = eye(3);
            % Loop through all axes and angles.
            for i=1:nAngle
                rotMat = axisAngle2RotMat(axisList(i,:),angleList(i))*rotMat;
            end
            % calculate net axis-angle rotation
            [netAxis, netAngle] = rotMat2AxisAngle(rotMat);
            % calculate net displacement due to rotation
            rotatedRelCoord = relCoord*(rotMat');
            linDisp = rotatedRelCoord - relCoord;
            % apply rotation and displacement to object
            obj.initial.displacement = linDisp + addLinDisp;
            obj.initial.axis = netAxis;
            obj.initial.angle = netAngle;
        end

        function listInfo(obj)
            % Method to list mooring info
            fprintf('\n\t***** Mooring Name: %s *****\n',obj.name)
        end

        function obj = setLoc(obj)
            % This method sets mooring location
            obj.orientation = [obj.location + obj.initial.displacement 0 0 0];
        end

        function setNumber(obj,number)
            % Method to set the private number property
            obj.number = number;
        end
    end
end


function [h,s,v] = rgb2hsv_fast(r,g,b,opt_typ,opt_sel)
%RGB2HSV_FAST does the same as RGB2HSV
%but faster and less memory exhaustive,
%especially on images which are stored as integers.
%
%RGB2HSV_FAST(IMG,'single')
%You can specify the optional argument 'single'
%to use single precision.
%This saves memory and is sufficiently exact, anyhow.
%
%RGB2HSV_FAST(IMG,'','H')
%Optionally, you can specify which channels to calculate:
%'HSV' is default.
%'H' calculates hue only.
%'S' calculates saturation only.
%'V' calculates value only.
%'HS', 'HV', or 'SV' are also possible.

% How to make it efficient?
%  -  Don't cast integer images to floating point too soon.
%     Operate on integers as far as possible and
%     take advantage of functions like IMLINCOMB().
%  -  Avoid FIND(). Directly index via binary arrays instead.
%  -  Avoid RESHAPE().
%     http://blogs.mathworks.com/loren/?p=28

%
% Alexander Ihlow, Germany, Oct 2006
% Version 1.1
% 2006-11-02 added support for individual channel selection
%            version 1.0 saved to rgb2hsv_fast_10.m
%
%
% RGB2HSV_FAST has a high cyclomatic complexity
% due to lots of case checking.
%
% Please report bugs or suggestions to ml-user@web.de.

threeD = ndims(r) >= 3;

if (nargin < 4), opt_typ = ''; end
if (nargin < 5), opt_sel = ''; end
if (nargin > 1) && ~isnumeric(g), opt_typ = g; end
if (nargin > 2) && ~isnumeric(b), opt_sel = b; end

%disp(['threeD = ' num2str(threeD)])
%disp(['opt_typ = ' opt_typ])
%disp(['opt_sel = ' opt_sel])

vv = version; vv=str2double(vv(1));
% Check input class
switch (class(r))
  case 'uint8'
    immax = 255;
  case 'uint16'
    immax = 65535;
  case 'double'
    immax = 1;
  case 'single'
    if vv < 7
      error('Matlab version < 7 cannot perform calculations with single precision. Please cast to double first!')
    else
      immax = 1;
      % If input is single, output single per default.
      if isempty(opt_typ), opt_typ = 'single'; end
    end
  otherwise
    if vv < 7
      error('Only images of type uint8, uint16, and double are supported!')
    else
      error('Only images of type uint8, uint16, single, and double are supported!')
    end
end

% Default output is double.
if isempty(opt_typ), opt_typ = 'double'; end

% Use single precision if optionally specified.
% This saves 1/2 of memory and is exact enough
% for those simple colorspace transformations.
% single : out_typ = 1
% double : out_typ = 2
switch lower(opt_typ(1))
  case 's'
    out_typ = 1;
  otherwise
    out_typ = 2;
end

% For Matlab < version 7, no single precision is supported.
if (out_typ == 1) && (vv < 7)
  disp('Single precision is not available in this Matlab version. Using double.')
  out_typ = 2;
end

% Helper functions to map float either to single or double.
if out_typ == 1
  im2float = inline('im2single(x)');
  float = inline('single(x)');
  floatstr = 'single';
else
  im2float = inline('im2double(x)');
  float = inline('double(x)');
  floatstr = 'double';
end

immax = float(immax);

if threeD
  % Split RGB image into R G B channels and
  % thereby support arbitrary dimensional images.
  % R G B is assumed to be contained in the third dimension.
  sizc = num2cell(size(r));
  for k=1:numel(sizc), sizc{k} = ':'; end
  sizc{3} = 2;
  g = r(sizc{:});
  sizc{3} = 3;
  b = r(sizc{:});
  sizc{3} = 1;
  r = r(sizc{:});
elseif nargin==1
  % split N x 3 matrix into three vectors
  g = r(:,2); b = r(:,3); r = r(:,1);
end
siz = size(r);

if isempty(opt_sel), opt_sel = 'HSV'; else opt_sel = upper(opt_sel); end

if any( (opt_sel ~= 'H') & (opt_sel ~= 'S') & (opt_sel ~= 'V') )
  error('Invalid optional argument! Please use ''H'', ''S'', or ''V''')
end

if exist('imsubtract','file')
  % Image Processing Toolbox available
  % --> The calculation of HUE and SAT
  %     is performed without precasting R, G, and B to floats.
  v = max(max(r,g),b);
  if any(opt_sel == 'H') || any(opt_sel == 'S')
    s = imsubtract(v, min(min(r,g),b));
    z = ~s;
    s = im2float(s);
    s(z) = 1;

    if any(opt_sel == 'H')
      % Calculating HUE via IMLINCOMB() is highly efficient.
      sizc = num2cell(siz);
      h(sizc{:}) = float(0);
      k = (r == v);
      h(k) =     imlincomb(1,g(k),-1,b(k),floatstr)./(immax*s(k));
      k = (g == v);
      h(k) = 2 + imlincomb(1,b(k),-1,r(k),floatstr)./(immax*s(k));
      k = (b == v);
      h(k) = 4 + imlincomb(1,r(k),-1,g(k),floatstr)./(immax*s(k));

      h = (1/6) * h;
      k = (h < 0);
      h(k) = h(k) + 1;

      h(z) = 0;
    end

    if any(opt_sel == 'S') || any(opt_sel == 'V')
      k = (v ~= 0);
      v = im2float(v);
      if any(opt_sel == 'S')
        s(k) = (~z(k)).*s(k)./v(k);
        s(~k) = 0;
      end
    end
  else
    v = im2float(v);
  end

else
  % Image Processing Toolbox not available
  % --> Use suboptimal procedure.
  v = im2float(max(max(r,g),b));
  if any(opt_sel == 'H') || any(opt_sel == 'S')
    s = v - im2float(min(min(r,g),b));
    z = ~s;
    s(z) = 1;

    sizc = num2cell(siz);
    h(sizc{:}) = float(0);

    if any(opt_sel == 'H')
      k = (im2float(r) == v);
      h(k) =     (im2float(g(k))-im2float(b(k)))./s(k);
      k = (im2float(g) == v);
      h(k) = 2 + (im2float(b(k))-im2float(r(k)))./s(k);
      k = (im2float(b) == v);
      h(k) = 4 + (im2float(r(k))-im2float(g(k)))./s(k);

      h = (1/6) * h;
      k = (h < 0);
      h(k) = h(k) + 1;

      h(z) = 0;
    end

    if any(opt_sel == 'S')
      k = (v ~= 0);
      s(k) = (~z(k)).*s(k)./v(k);
      s(~k) = 0;
    end
  end

end

if ~any(opt_sel == 'H'), h = float([]); end
if ~any(opt_sel == 'S'), s = float([]); end
if ~any(opt_sel == 'V'), v = float([]); end

if nargout <= 1,
  if (threeD || nargin>=3),
    h = cat(3,h,s,v);
  else
    h = [h s v];
  end
else
  switch opt_sel
    case 'HSV'
      %
    case 'H'
      disp('There is more than one output variable given, but only HUE is assigned to the first one!')
    case 'S'
      h = s;
      disp('There is more than one output variable given, but only SAT is assigned to the first one!')
    case 'V'
      h = v;
      disp('There is more than one output variable given, but only VAL is assigned to the first one!')
    case 'HS'
      if nargout > 2
        disp('There are more than two output variables given, but only HUE and SAT are assigned to the first two!')
      end
    case 'HV'
      s = v;
      if nargout > 2
        disp('There are more than two output variables given, but only HUE and VAL are assigned to the first two!')
      end
    case 'SV'
      h = s;
      s = v;
      if nargout > 2
        disp('There are more than two output variables given, but only SAT and VAL are assigned to the first two!')
      end
    otherwise
      disp('Unrecognized output - please check what happened!')
  end
end


function [im] = prep_im_for_blob(im, im_means, target_size, max_size)
    im = single(im);

    if ~isa(im, 'gpuArray')
        try
            im = bsxfun(@minus, im, im_means);
        catch
            im_means = imresize(im_means, [size(im, 1), size(im, 2)], 'bilinear', 'antialiasing', false);
            im = bsxfun(@minus, im, im_means);
        end
        %im_scale = prep_im_for_blob_size(size(im), target_size, max_size);

        %target_size = round([size(im, 1), size(im, 2)] * im_scale);
        im = imresize(im, target_size, 'bilinear', 'antialiasing', false);
    else
        % for im as gpuArray
        try
            im = bsxfun(@minus, im, im_means);
        catch
            im_means_scale = max(double(size(im, 1)) / size(im_means, 1), double(size(im, 2)) / size(im_means, 2));
            im_means = imresize(im_means, im_means_scale);
            y_start = floor((size(im_means, 1) - size(im, 1)) / 2) + 1;
            x_start = floor((size(im_means, 2) - size(im, 2)) / 2) + 1;
            im_means = im_means(y_start:(y_start+size(im, 1)-1), x_start:(x_start+size(im, 2)-1));
            im = bsxfun(@minus, im, im_means);
        end

        %im_scale = prep_im_for_blob_size(size(im), target_size, max_size);
        %im = imresize(im, target_size);
    end
end


function d =  testing(a,d)

 Kt=get_x(a.Xsv)*get_x(d)';
 Yt=get_y(d);

 Yest=((a.alpha'* Kt)+a.b0)';
 if a.algorithm.use_signed_output
   Yest=sign(Yest);
 end

 d=set_x(d,Yest);
 d=set_name(d,[get_name(d) ' -> ' get_name(a)]);


function model = update_integer_bounds(model);

if ~isempty(model.integer_variables)
    % Clean up things like 0.00001 <= x <= 0.999999 to 0 <= x <= 1
    % however, don't kill equalities 1 <= x <= 1
    lbfixed = fix(model.lb(model.integer_variables));
    ubfixed = fix(model.ub(model.integer_variables));
    fixlb = find(model.lb(model.integer_variables) == lbfixed);
    fixub = find(model.ub(model.integer_variables) == ubfixed);
    model.lb(model.integer_variables) = ceil(model.lb(model.integer_variables)-1e-4);
    model.ub(model.integer_variables) = floor(model.ub(model.integer_variables)+1e-4);
    if ~isempty(fixlb)
        model.lb(model.integer_variables(fixlb)) = lbfixed(fixlb);
    end
    if ~isempty(fixub)
        model.ub(model.integer_variables(fixub)) = ubfixed(fixub);
    end
end
if ~isempty(model.binary_variables)
    lbfixed = fix(model.lb(model.binary_variables));
    ubfixed = fix(model.ub(model.binary_variables));
    fixlb = find(model.lb(model.binary_variables) == lbfixed);
    fixub = find(model.ub(model.binary_variables) == ubfixed);
    model.lb(model.binary_variables) = ceil(model.lb(model.binary_variables)-1e-4);
    model.ub(model.binary_variables) = floor(model.ub(model.binary_variables)+1e-4);
    if ~isempty(fixlb)
        model.lb(model.binary_variables(fixlb)) = lbfixed(fixlb);
    end
    if ~isempty(fixub)
        model.ub(model.binary_variables(fixub)) = ubfixed(fixub);
    end
end
if any(model.lb(model.binary_variables) > model.ub(model.binary_variables))
    model.feasible = 0;
end
if any(model.lb(model.integer_variables) > model.ub(model.integer_variables))
    model.feasible = 0;
end


function [DCM] = spm_dcm_ssr_results(DCM,Action)
% Results for ERP Dynamic Causal Modeling (DCM)
% FORMAT spm_dcm_erp_results(DCM,'spectral data');
% FORMAT spm_dcm_erp_results(DCM,'Coupling (A)');
% FORMAT spm_dcm_erp_results(DCM,'Coupling (B)');
% FORMAT spm_dcm_erp_results(DCM,'Coupling (C)');
% FORMAT spm_dcm_erp_results(DCM,'trial-specific effects');
% FORMAT spm_dcm_erp_results(DCM,'Input');
% FORMAT spm_dcm_erp_results(DCM,'Cross-spectral density');
% FORMAT spm_dcm_erp_results(DCM,'Dipoles');
%
%___________________________________________________________________________
%
% DCM is a causal modelling procedure for dynamical systems in which
% causality is inherent in the differential equations that specify the model.
% The basic idea is to treat the system of interest, in this case the brain,
% as an input-state-output system.  By perturbing the system with known
% inputs, measured responses are used to estimate various parameters that
% govern the evolution of brain states.  Although there are no restrictions
% on the parameterisation of the model, a bilinear approximation affords a
% simple re-parameterisation in terms of effective connectivity.  This
% effective connectivity can be latent or intrinsic or, through bilinear
% terms, model input-dependent changes in effective connectivity.  Parameter
% estimation proceeds using fairly standard approaches to system
% identification that rest upon Bayesian inference.
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_dcm_ssr_results.m 4096 2010-10-22 19:40:34Z karl $

% get figure handle
%--------------------------------------------------------------------------
Fgraph = spm_figure('GetWin','Graphics');
colormap(gray)
figure(Fgraph)
clf

% placespectral features in xY.y
%--------------------------------------------------------------------------
DCM.xY.y  = spm_cond_units(DCM.xY.csd,'csd');

% trial data
%--------------------------------------------------------------------------
xY  = DCM.xY;                   % data
nt  = length(xY.y);             % Nr trial types
nf  = size(xY.y{1},1);          % Nr frequency bins
nm  = size(xY.y{1},2);          % Nr spatial modes
Hz  = xY.Hz;                    % PST

% switch
%--------------------------------------------------------------------------
switch(lower(Action))

case{lower('spectral data')}

    % spm_dcm_ssr_results(DCM,'Data');
    %----------------------------------------------------------------------
    co = {'b', 'r', 'g', 'm', 'y', 'k', 'c'};
    Hz = xY.Hz;
    q  = max(spm_vec(xY.y));
    nm = min(nm,4);

    for k = 1:nt
        str{k} = sprintf('trial %i',k);
    end

    for i = 1:nm
        for j = i:nm

            % for each trial type
            %--------------------------------------------------------------
            subplot(nm,nm,(i - 1)*nm + j),cla
            for k = 1:nt
                plot(Hz,xY.y{k}(:,i,j),'color',co{k}), hold on
                set(gca,'YLim',[0 q])
            end
        end

        % spectral density
        %------------------------------------------------------------------
        subplot(2,2,3)
        for k = 1:nt
            plot(Hz,xY.y{k}(:,i,i),'color',co{i}), hold on
            set(gca,'YLim',[0 q])
        end
    end

    title('spectral density over modes')
    xlabel('Frequency (Hz)')
    ylabel('CSD')
    axis square
    return

end

% post inversion parameters
%--------------------------------------------------------------------------
nu  = length(DCM.B);          % Nr experimental inputs
ns  = size(DCM.A{1},2);       % Nr of sources

% switch
%--------------------------------------------------------------------------
switch(lower(Action))

case{lower('Coupling (A)')}

    % spm_dcm_ssr_results(DCM,'coupling (A)');
    %----------------------------------------------------------------------
    str = {'Forward','Backward','Lateral'};
    for  i = 1:3

        % images
        %------------------------------------------------------------------
        subplot(4,3,i)
        imagesc(exp(DCM.Ep.A{i}))
        title(str{i},'FontSize',10)
        set(gca,'YTick',[1:ns],'YTickLabel',DCM.Sname,'FontSize',8)
        set(gca,'XTick',[])
        xlabel('from','FontSize',8)
        ylabel('to','FontSize',8)
        axis square

        % table
        %------------------------------------------------------------------
        subplot(4,3,i + 3)
        text(0,1/2,num2str(full(exp(DCM.Ep.A{i})),' %.2f'),'FontSize',8)
        axis off,axis square

        % PPM
        %------------------------------------------------------------------
        subplot(4,3,i + 6)
        image(64*DCM.Pp.A{i})
        set(gca,'YTick',[1:ns],'YTickLabel',DCM.Sname,'FontSize',8)
        set(gca,'XTick',[])
        title('PPM')
        axis square

        % table
        %------------------------------------------------------------------
        subplot(4,3,i + 9)
        text(0,1/2,num2str(DCM.Pp.A{i},' %.2f'),'FontSize',8)
        axis off, axis square

    end

case{lower('Coupling (C)')}

    % spm_dcm_ssr_results(DCM,'coupling (C)');
    %----------------------------------------------------------------------

    % images
    %----------------------------------------------------------------------
    subplot(2,4,1)
    imagesc(exp(DCM.Ep.C))
    title('Factors','FontSize',10)
    set(gca,'XTick',[1:nu],'XTickLabel','Input','FontSize',8)
    set(gca,'YTick',[1:ns],'YTickLabel',DCM.Sname, 'FontSize',8)
    axis square

    % PPM
    %----------------------------------------------------------------------
    subplot(2,4,3)
    image(64*DCM.Pp.C)
    title('Factors','FontSize',10)
    set(gca,'XTick',[1:nu],'XTickLabel','Input','FontSize',8)
    set(gca,'YTick',[1:ns],'YTickLabel',DCM.Sname, 'FontSize',8)
    axis square
    title('PPM')

    % table
    %----------------------------------------------------------------------
    subplot(2,4,2)
    text(0,1/2,num2str(full(exp(DCM.Ep.C)),' %.2f'),'FontSize',8)
    axis off

    % table
    %----------------------------------------------------------------------
    subplot(2,4,4)
    text(0,1/2,num2str(DCM.Pp.C,' %.2f'),'FontSize',8)
    axis off

case{lower('Coupling (B)')}

    % spm_dcm_ssr_results(DCM,'coupling (B)');
    %----------------------------------------------------------------------
    for i = 1:nu

        % images
        %------------------------------------------------------------------
        subplot(4,nu,i)
        imagesc(exp(DCM.Ep.B{i}))
        title(DCM.xU.name{i},'FontSize',10)
        set(gca,'YTick',[1:ns],'YTickLabel',DCM.Sname,'FontSize',8)
        set(gca,'XTick',[])
        xlabel('from','FontSize',8)
        ylabel('to','FontSize',8)
        axis square

        % tables
        %------------------------------------------------------------------
        subplot(4,nu,i + nu)
        text(0,1/2,num2str(full(exp(DCM.Ep.B{i})),' %.2f'),'FontSize',8)
        axis off
        axis square

        % PPM
        %------------------------------------------------------------------
        subplot(4,nu,i + 2*nu)
        image(64*DCM.Pp.B{i})
        set(gca,'YTick',[1:ns],'YTickLabel',DCM.Sname,'FontSize',8)
        set(gca,'XTick',[])
        title('PPM')
        axis square

        % tables
        %------------------------------------------------------------------
        subplot(4,nu,i + 3*nu)
        text(0,1/2,num2str(DCM.Pp.B{i},' %.2f'),'FontSize',8)
        axis off
        axis square

    end

case{lower('trial-specific effects')}

    % spm_dcm_ssr_results(DCM,'trial-specific effects');
    %----------------------------------------------------------------------
    for i = 1:ns
        for j = 1:ns

            % ensure connection is enabled
            %--------------------------------------------------------------
            q     = 0;
            for k = 1:nu
                q = q | DCM.B{k}(i,j);
            end

            % plot trial-specific effects
            %--------------------------------------------------------------
            if q
                B     = zeros(nt,1);
                for k = 1:nu
                    B = B + DCM.xU.X(:,k)*DCM.Ep.B{k}(i,j);
                end

                subplot(ns,ns,(i - 1)*ns + j)
                bar(exp(B)*100,'c')
                title([DCM.Sname{j}, ' to ' DCM.Sname{i}],'FontSize',10)
                xlabel('trial',  'FontSize',8)
                ylabel('strength (%)','FontSize',8)
                set(gca,'XLim',[0 nt + 1])
                axis square

            end
        end
    end

case{lower('Input')}

    % spectrum of innovations or noise (Gu)
    %----------------------------------------------------------------------
    try
        Gu   = exp(DCM.Ep.a)*xY.Hz.^(-1)*2;    % spectral density of (AR) input
        Gu   = Gu + exp(DCM.Ep.b);             % spectral density of IID input
    catch
        Gu   = exp(DCM.Ep.a(1))*xY.Hz.^(-1);    % spectral density of (AR) input
        Gu   = Gu + exp(DCM.Ep.a(2));           % spectral density of IID input
    end

    % plot spectral density of innovations
    % ---------------------------------------------------------------------
    subplot(2,1,1)
    plot(xY.Hz,Gu)
    xlabel('frquency (Hz)')
    title('spectrum of innovations or noise')
    axis square, grid on

case{lower('Cross-spectral density')}

    % spm_dcm_ssr_results(DCM,'Cross-spectral density');
    %----------------------------------------------------------------------
    co = {'b', 'r', 'g', 'm', 'y', 'k', 'c'};
    Hz = xY.Hz;
    q  = max(spm_vec(DCM.Hc));
    nm = min(nm,4);

    tstr = {};
    mstr = {};
    for k = 1:nt
        tstr{end + 1} = sprintf('predicted: trial %i',k);
        tstr{end + 1} = sprintf('observed: trial %i',k);
    end
    for k = 1:nm
        mstr{end + 1} = sprintf('predicted: mode %i',k);
        mstr{end + 1} = sprintf('observed: mode %i',k);
    end

    for i = 1:nm
        for j = i:nm

            % for each trial type
            %--------------------------------------------------------------
            subplot(nm,nm,(i - 1)*nm + j),cla
            for k = 1:nt
                plot(Hz,DCM.Hc{k}(:,i,j),'color',co{k}), hold on
                plot(Hz,DCM.Hc{k}(:,i,j) + DCM.Rc{k}(:,i,j),':','color',co{k})
                set(gca,'YLim',[0 q])
            end
        end

        % legend
        %------------------------------------------------------------------
        if i == nm && j == nm
            legend(tstr)
        end

        % spectral density
        %------------------------------------------------------------------
        subplot(2,2,3)
        for k = 1:nt
            plot(Hz,DCM.Hc{k}(:,i,i),'color',co{i}), hold on
            plot(Hz,DCM.Hc{k}(:,i,i) + DCM.Rc{k}(:,i,i),':','color',co{i})
            set(gca,'YLim',[0 q])
        end
    end

    title({'Spectral density over modes';'(in channel-space)'},'FontSize',16)
    xlabel('Frequency (Hz)')
    ylabel('root CSD')
    axis square
    legend(mstr)

case{lower('Dipoles')}

    % return if LFP
    % ---------------------------------------------------------------------
    if strcmp(lower(DCM.xY.modality),'lfp')
        warndlg('There are no ECDs for these LFP data')
        return
    end

    % plot dipoles
    % ---------------------------------------------------------------------
    try
        P            = DCM.Ep;
        np           = size(P.L,2)/size(P.Lpos,2);
        sdip.n_seeds = 1;
        sdip.n_dip   = np*ns;
        sdip.Mtb     = 1;
        sdip.j{1}    = full(P.L);
        sdip.j{1}    = sdip.j{1}(:);
        sdip.loc{1}  = kron(ones(1,np),full(P.Lpos));
        spm_eeg_inv_ecd_DrawDip('Init', sdip)
    end

end


% run_simMegaExTEShaped.m
% Jamie Near, McGill University 2014.
%
% USAGE:
% This script is run simply by editing the input parameters and then
% clicking "Run".
%
% DESCRIPTION:
% This script simulates an ExTE-MEGA-PRESS experiment with fully shaped editing
% and refocusing pulses.  Phase cycling of both the editing and refocusing
% pulses is performed.  Simulations are run at various
% locations in space to account for the within-voxel spatial variation of
% the GABA signal.  Summation across phase cycles and spatial positions is
% performed.  As a result of the phase cycling and spatially resolved simulations,
% this code takes a long time to run.  Therefore, the MATLAB parallel computing
% toolbox (parfor loop) was used to accelerate the siumulations.  Accelration
% is currently performed in the direction of the slice selective pulse along
% the x-direction, but this can be changed.  Up to a factor of 12 acceleration
% can be achieved using this approach.  To enable the use of the MATLAB
% parallel computing toolbox, initialize the multiple worked nodes using
% "matlabpool size X" where "X" is the number of available processing
% nodes.  If the parallel processing toolbox is not available, then replace
% the "parfor" loop with a "for" loop.
%
% INPUTS:
% To run this script, edit the parameters below as desired and then click
% "run":
% refocWaveform     = name of refocusing pulse waveform.
% editWaveform      = name of editing pulse waveform.
% editOnFreq        = freqeucny of edit on pulse[ppm]
% editOffFreq       = frequency of edit off pulse[ppm]
% refTp             = duration of refocusing pulses[ms]
% editTp            = duration of editing pulses[ms]
% Bfield            = Magnetic field strength in [T]
% Npts              = number of spectral points
% sw                = spectral width [Hz]
% Bfield            = magnetic field strength [Tesla]
% lw                = linewidth of the output spectrum [Hz]
% thkX              = slice thickness of x refocusing pulse [cm]
% thkY              = slice thickness of y refocusing pulse [cm]
% x                 = vector of X positions to simulate [cm]
% y                 = vector of y positions to simulate [cm]
% taus              = vector of pulse sequence timings  [ms]
% spinSys           = spin system to simulate
% editPhCyc1        = vector of phase cycling steps for 1st editing pulse [degrees]
% editPhCyc2        = vector of phase cycling steps for 2nd editing pulse [degrees]
% refPhCyc1         = vector of phase cycling steps for 1st refocusing pulse [degrees]
% refPhCyc2         = vector of phase cycling steps for 2nd refocusing pulse [degrees]
%
% OUTPUTS:
% outON_posxy       = Simulated ExTE-MEGA-PRESS edit-ON spectrum, spatially resolved.
% outOFF_posxy      = Simulated ExTE-MEGA-PRESS edit-OFF spectrum, spatially resolved.
% outDIFF_posxy     = Simulated ExTE-MEGA-PRESS difference spectrum, spatially resolved.
% outON             = Simulated ExTE-MEGA-PRESS edit-ON spectrum, summed over
%                     all positions.
% outOFF            = Simulated ExTE-MEGA-PRESS edit-OFF spectrum, summed over
%                     all positions.
% outDIFF           = Simulated ExTE-MEGA-PRESS difference spectrum, summed over
%                     all positions.

% ************INPUT PARAMETERS**********************************
refocWaveform='sampleRefocPulse.pta'; %name of refocusing pulse waveform.
editWaveform='sampleEditPulse.pta'; %name of editing pulse waveform.
editOnFreq=1.88; %freqeucny of edit on pulse[ppm]
refTp=5.2; %duration of refocusing pulses[ms]
editTp=14; %duration of editing pulses[ms]
Npts=2048; %number of spectral points
sw=2000; %spectral width [Hz]
lw=2; %linewidth of the output spectrum [Hz]
Bfield=2.89; %Magnetic field strength in [T]
thkX=3.5; %slice thickness of x refocusing pulse [cm]
thkY=3.5; %slice thickness of y refocusing pulse [cm]
x=linspace(-2.0125,2.0125,12); %X positions to simulate [cm]
y=linspace(-2.0125,2.0125,12); %y positions to simulate [cm]
taus_inv=...  %Timing for J-Inverted scan
        [4.9,...    %time from excitation to 1st refoc pulse [ms]
        67.4885,... %time from 1st refoc pulse to 1st editing pulse [ms]
        33.5115,... %time from 1st editing pulse to 2nd refoc pulse [ms]
        33.4885,... %time from 2nd refoc pulse to 2nd editing pulse [ms]
        62.6115];   %time from 2nd editing pulse to ADC onset [ms]
taus_ref=... %Timing for J-refocused scan
        [4.9,...    %time from excitation to 1st refoc pulse [ms]
        50.4885,... %time from 1st refoc pulse to 1st editing pulse [ms]
        50.5115,... %time from 1st editing pulse to 2nd refoc pulse [ms]
        50.4885,... %time from 2nd refoc pulse to 2nd editing pulse [ms]
        45.6115];   %time from 2nd editing pulse to ADC onset [ms]
spinSys='GABA'; %spin system to simulate
centreFreq=3.0; %Centre frequency of MR spectrum [ppm]
editPhCyc1=[0 90]; %phase cycling steps for 1st editing pulse [degrees]
editPhCyc2=[0 90]; %phase cycling steps for 2nd editing pulse [degrees]
refPhCyc1=[0,90]; %phase cycling steps for 1st refocusing pulse [degrees]
refPhCyc2=[0,90]; %phase cycling steps for 2nd refocusing pulse [degrees]
% ************END OF INPUT PARAMETERS**********************************

%Load RF waveforms
refRF=io_loadRFwaveform(refocWaveform,'ref',0);
editRF=io_loadRFwaveform(editWaveform,'inv',0);

gamma=42577000; %gyromagnetic ratio

%Load spin systems
load spinSystems
if strcmp(spinSys,'MM');
    sys=sysGABA;
    sys.shifts(3)=1.7;
    sys.shifts(4)=1.7;
else
    sys=eval(['sys' spinSys]);
end

%Resample refocusing RF pulse from 400 pts to 100 pts to reduce
%computational workload
refRF=rf_resample(refRF,100);

%This is the step where the editing pulse waveform (initially a pulse with
%zero-frequency) is frequency shifted to produce and edit-on and an
%edit-off pulse;
editRFon=rf_freqshift(editRF,editTp,(centreFreq-editOnFreq)*Bfield*gamma/1e6);

Gx=(refRF.tbw/(refTp/1000))/(gamma*thkX/10000); %[G/cm]
Gy=(refRF.tbw/(refTp/1000))/(gamma*thkY/10000); %[G/cm]

[DX,DY]=meshgrid(x,y);

%n=1;
%totalIters=length(x)*length(y)*length(editPhCyc1)*length(editPhCyc2)*length(refPhCyc1)*length(refPhCyc2);

%Initialize structures:
outON_posxy_epc_rpc=cell(length(x),length(y),length(editPhCyc1),length(editPhCyc2),length(refPhCyc1),length(refPhCyc2));
outOFF_posxy_epc_rpc=cell(length(x),length(y),length(editPhCyc1),length(editPhCyc2),length(refPhCyc1),length(refPhCyc2));
outON_posxy_epc=cell(length(x),length(y),length(editPhCyc1),length(editPhCyc2));
outOFF_posxy_epc=cell(length(x),length(y),length(editPhCyc1),length(editPhCyc2));
outON_posxy=cell(length(x),length(y));
outOFF_posxy=cell(length(x),length(y));
outDIFF_posxy=cell(length(x),length(y));
outON=struct([]);
outOFF=struct([]);

%loop through space: Don't forget to initialize the parallel processing
%toolbox workers using 'matlabpool open N' (for N workers, 12 max).

for X=1:length(x);
%parfor X=1:length(x);
    for Y=1:length(y);
        for EP1=1:length(editPhCyc1)
            for EP2=1:length(editPhCyc2)
                for RP1=1:length(refPhCyc1)
                    for RP2=1:length(refPhCyc2)
                        disp(['Executing X-position ' num2str(X) ' of ' num2str(length(x)) ', '...
                            'Y-position ' num2str(Y) ' of ' num2str(length(y)) ', '...
                            'First Edit phase cycle ' num2str(EP1) ' of ' num2str(length(editPhCyc1)) ', '...
                            'Second Edit phase cycle ' num2str(EP2) ' of ' num2str(length(editPhCyc2)) ', '...
                            'First Refoc phase cycle ' num2str(RP1) ' of ' num2str(length(refPhCyc1)) ', '...
                            'Second Refoc phase cycle ' num2str(RP2) ' of ' num2str(length(refPhCyc2)) '!!!']);
                        outON_posxy_epc_rpc{X}{Y}{EP1}{EP2}{RP1}{RP2}=sim_megapress_shaped(Npts,sw,Bfield,lw,taus_ref,sys,...
                            editRFon,editTp,editPhCyc1(EP1),editPhCyc2(EP2),...
                            refRF,refTp,Gx,Gy,x(X),y(Y),refPhCyc1(RP1),refPhCyc2(RP2));
                        outOFF_posxy_epc_rpc{X}{Y}{EP1}{EP2}{RP1}{RP2}=sim_megapress_shaped(Npts,sw,Bfield,lw,taus_inv,sys,...
                            editRFon,editTp,editPhCyc1(EP1),editPhCyc2(EP2),...
                            refRF,refTp,Gx,Gy,x(X),y(Y),refPhCyc1(RP1),refPhCyc2(RP2));

                        if RP1==1 && RP2==1
                            outON_posxy_epc{X}{Y}{EP1}{EP2}=outON_posxy_epc_rpc{X}{Y}{EP1}{EP2}{RP1}{RP2};
                            outOFF_posxy_epc{X}{Y}{EP1}{EP2}=outOFF_posxy_epc_rpc{X}{Y}{EP1}{EP2}{RP1}{RP2};
                        else
                            outON_posxy_epc{X}{Y}{EP1}{EP2}=op_addScans(outON_posxy_epc{X}{Y}{EP1}{EP2},outON_posxy_epc_rpc{X}{Y}{EP1}{EP2}{RP1}{RP2},xor(RP1==length(refPhCyc1),RP2==length(refPhCyc2)));
                            outOFF_posxy_epc{X}{Y}{EP1}{EP2}=op_addScans(outOFF_posxy_epc{X}{Y}{EP1}{EP2},outOFF_posxy_epc_rpc{X}{Y}{EP1}{EP2}{RP1}{RP2},xor(RP1==length(refPhCyc1),RP2==length(refPhCyc2)));
                        end
                    end %end of 1st refocusing phase cycle loop
                end %end of 2nd refocusing phase cycle loop.

                if EP1==1 && EP2==1
                    outON_posxy{X}{Y}=outON_posxy_epc{X}{Y}{EP1}{EP2};
                    outOFF_posxy{X}{Y}=outOFF_posxy_epc{X}{Y}{EP1}{EP2};
                else
                    outON_posxy{X}{Y}=op_addScans(outON_posxy{X}{Y},outON_posxy_epc{X}{Y}{EP1}{EP2});
                    outOFF_posxy{X}{Y}=op_addScans(outOFF_posxy{X}{Y},outOFF_posxy_epc{X}{Y}{EP1}{EP2});
                end
                outDIFF_posxy{X}{Y}=op_subtractScans(outON_posxy{X}{Y},outOFF_posxy{X}{Y});
            end %end of 1st editing phase cycle loop.
        end %end of 2nd editing phase cycle loop.

        outON=op_addScans(outON,outON_posxy{X}{Y});
        outOFF=op_addScans(outOFF,outOFF_posxy{X}{Y});

    end %end of spatial loop (parfor) in y direction.
end %end of spatial loop (parfor) in x direction.

outDIFF=op_subtractScans(outON,outOFF);

figure
sim_make2DSimPlot(outON_posxy,2.75,3.25);
figure
sim_make2DSimPlot(outOFF_posxy,2.75,3.25);
figure
sim_make2DSimPlot(outDIFF_posxy,2.75,3.25);


function aux_parkfield(vResult, hParentFigure)

hSets = gui_result2('GetDatasetsHandle', hParentFigure, [], guidata(hParentFigure));
sList = get(hSets, 'String');
nLen = length(sList);
vResults = gui_result2('GetResults', hParentFigure, [], guidata(hParentFigure));

nCS=[[-154.01 60.88 -150.50 60.37];
    [-153.45 61.68 -149.81 61.21]];

for nCnt = 1:size(nCS,1)  % nLen

    vResults(nLen+nCnt)=aux_cs2(vResults(nCnt),nCS(nCnt,:));

    hPlot = gui_result2('GetFigureHandle', hParentFigure, [], guidata(hParentFigure));
    %   exportfig(hPlot, [num2str(nCnt) '.eps'], 'Color', 'cmyk');

end

save vResults_CS.mat vResults -mat

disp('Calc of CS finished: vResults_CS.mat')


% clc; clear all; close all;

%% hydro data
hydro = struct();
hydro = readAQWA(hydro, 'WEC3.AH1', 'WEC3.LIS');
hydro = radiationIRF(hydro,100,[],[],[],[]);
hydro = radiationIRFSS(hydro,[],[]);
hydro = excitationIRF(hydro,100,[],[],[],[]);
writeBEMIOH5(hydro)

%% Plot hydro data
% plotBEMIO(hydro)