function [uOutput] = import_Iceland_PT(nFunction, sFilename)

% Filter function switchyard
%%%%     CHANGE THESE LINES %%%%%%%%%%%
if nFunction == FilterOp.getDescription
    uOutput = 'Iceland (with P/T-axes)';
elseif nFunction == FilterOp.getWebpage
  uOutput = 'import_Iceland_PT_doc.html';
 %%%%    DO NOT CHANGE %%%%%%%%%%%

elseif nFunction == FilterOp.importCatalog
    % Read formated data
    mData = textread(sFilename, '%s', 'delimiter', '\n', 'whitespace', '');
    % Create empty catalog
    uOutput = zeros(length(mData), 12);
    % Loop through all lines of catalog and convert them
    mData = char(mData);
    l = find( mData == ' ' );
    mData(l) = '0';
    errc = 1;

        for i = 1:length(mData(:,1))
            if rem(i,100) == 0 ; disp([ num2str(i) ' of ' num2str(length(mData)) ' events processed ']); end
            try
                uOutput(i,:) = readvalues(mData,i,1);
            catch
                errc = errc + 1;
                if errc == 100
                    if stoploop
                        return
                    end
                end
                msg.dbfprintf('Import: Problem in line %d of %s. Line ignored.\n',i, sFilename);
                uOutput(i,:)=nan;
            end
        end

    l = isnan(uOutput(:,1));
    uOutput(l,:) = [];
end

%%%%%%%%%%%%%%%%%%%%%%
%%%%     CHANGE THESE LINES %%%%%%%%%%%

function [uOutput] = readvalues(mData,i,k)

uOutput(k,1) =-str2num(mData(i,29:30)) - (str2num(mData(i,31:35))/60); % Longitude
uOutput(k,2) = str2num(mData(i,20:21)) + (str2num(mData(i,22:26))/60); % Latitude
uOutput(k,3) = str2num(mData(i,2:3)) + 1900; % Year
uOutput(k,4) = str2num(mData(i,4:5));        % Month
uOutput(k,5) = str2num(mData(i,6:7));        % Day
uOutput(k,6) = str2num(mData(i,64:66));      % Magnitude
uOutput(k,7) = str2num(mData(i,37:41));      % Depth
uOutput(k,8) = str2num(mData(i,9:10));       % Hour
uOutput(k,9) = str2num(mData(i,11:12));      % Minute

fPTrend = str2double(mData(i,68:70));
fPDip = str2double(mData(i,72:73));
fTTrend = str2double(mData(i,75:77));
fTDip = str2double(mData(i,79:80));

% DipDirection, Dip, Rake
[uOutput(k,10), uOutput(k,11), uOutput(k,12)] = ex_pt2fm(fPTrend, fPDip, fTTrend, fTDip);

% Convert to decimal years
uOutput(k,3) = decyear([uOutput(k,3) uOutput(k,4) uOutput(k,5) uOutput(k,8) uOutput(k,9)]);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%    DO NOT CHANGE %%%%%%%%%%%

function [mystop] = stoploop()

ButtonName=questdlg('More than 100 lines could not be read. Continue?', ...
    'Interrupt?', ...
    'Yes','No','Nope');

switch ButtonName
case 'Yes'
    disp('going on');
    mystop = 0;
case 'No'
    mystop = 1;
end % switch


function [rgb] = bg_rgba2rgb(bg, rgba, varargin)

% BG_RGBA2RGB overlays a transparency masked colored image on a colored background,
% and represents the result as an RGB matrix.
%
% Use as:
%   rgb = bg_rgba2rgb(bg, rgba)
%
% or
%   rgb = bg_rgba2rgb(bg, rgba, cmap, clim, alpha, amap, alim);
%
% When 2 input arguments are supplied:
%   bg   = Nx3 matrix of background rgb-coded color-values, or MxNx3
%   rgba = Nx4 matrix of rgb + alpha values, or MxNx4
%
% When 7 input arguments are supplied:
%   bg   = Nx3 matrix, Nx1 vector, 1x3 vector, MxN, or MxNx3.
%   rgba = Nx1 vector with 'functional values', or MxN.
%   cmap = Mx3 colormap, or MATLAB-supported name of colormap
%   clim = 1x2 vector denoting the color limits
%   alpha = Nx1 vector with 'alpha values', or MxN
%   amap = Mx1 alphamap, or MATLAB -supported name of alphamap ('rampup/down', 'vup/down')
%   alim = 1x2 vector denoting the opacity limits

if numel(varargin)==0
  siz1 = size(bg);
  siz2 = size(rgba);
  assert(isequal(siz1(1:end-1),siz2(1:end-1)), 'number of data points should be the same');
  assert(siz1(end)==3 && siz2(end)==4,         'inconsistent input size');

  bg   = reshape(bg,   [], 3);
  rgba = reshape(rgba, [], 4);
  rgb  = do_conversion(bg, rgba);
  rgb  = reshape(rgb, siz1);
else
  % this requires the data to be converted into rgb values irst, and
  % needs a cmap + clim, and an alpha, alphamap and alim
  if numel(varargin)~=5
    error('if a vector of color data is supplied, more input arguments are required');
  end

  % colormap handling
  cmap = varargin{1};
  if ischar(cmap)
    cmap = colormap(cmap);
  elseif size(cmap,2)~=3
    error('invalid specification of colormap, should be nx3');
  end
  clim  = varargin{2}; if isempty(clim), clim(1) = min(rgba(:)); clim(2) = max(rgba(:)); end
  alpha = varargin{3};
  amap  = varargin{4};
  alim  = varargin{5}; if isempty(alim), alim(1) = min(alpha(:)); alim(2) = max(alpha(:)); end

  % deal with the color data
  dat     = rgba;
  siz     = size(dat);
  dat     = reshape(dat, [], 1);
  alpha   = reshape(alpha, [], 1); % assume to be same siza as input data!
  finvals = isfinite(dat);

  rgba              = zeros(size(dat,1),4);
  rgba(finvals,1:3) = dat2rgb(dat(finvals), cmap, clim);

  finvals          = isfinite(alpha);
  rgba(finvals,4)  = alpha2a(alpha(finvals), amap, alim);
  rgba(~finvals,4) = 0;

  % deal with the background: allow it to be 1x3, i.e. a single color per
  % pixel.
  if isequal(size(bg),[1 3])
    bg = permute(repmat(bg(:), [1 siz]), [1+(1:numel(siz)) 1]);
  else
    siz_bg = size(bg);
    if isequal(siz_bg, siz)
      % make bg rgb
      if all(bg(:)<=1) && all(bg(:)>=0)
        % don't scale
      else
        bg_min = min(bg(:));
        bg_max = max(bg(:));
        bg     = (bg-bg_min)./(bg_max-bg_min);
      end
      bg = repmat(bg, [ones(1,ndims(bg)) 3]);
    else
      %FIXME
    end
  end
  bg  = reshape(bg, [], 3);

  if numel(siz)==2 && siz(2)==1, siz = siz(1); end
  rgb = do_conversion(bg, rgba);
  rgb = reshape(rgb, [siz 3]);
end

function rgb = do_conversion(bg, rgba)

rgb = zeros(size(rgba,1),3);
a_  = 1-rgba(:,4);
a   = rgba(:,4);

for k = 1:3
    rgb(:,k) = bg(:,k).*a_  + rgba(:,k).*a;
end

function rgb = dat2rgb(dat, cmap, clim)

dat(end+1) = clim(1);
dat(end+1) = clim(2); % add the extremes to be sure that they are included

dat(dat<clim(1)) = clim(1);
dat(dat>clim(2)) = clim(2);

% scale between 0 and 1
dat = dat-min(dat);
dat = dat/max(dat);

ind = round(dat.*(size(cmap,1)-1))+1;
rgb = cmap(ind(1:end-2),:);

function a = alpha2a(alpha, amap, alim)

alpha(end+1) = alim(1);
alpha(end+1) = alim(2);

alpha(alpha<alim(1)) = alim(1);
alpha(alpha>alim(2)) = alim(2);

if ischar(amap)
    switch amap
        case 'rampup'
            a = alpha - min(alpha);
            a = a./max(a);
        case 'rampdown'
            a = alpha - min(alpha);
            a = a./max(a);
            a = 1-a;
        case 'vup'
            a = alpha - min(alpha);
            a = a./max(a);
            a = 1 - 2.*abs(a - 0.5);
        case 'vdown'
            a = alpha - min(alpha);
            a = a./max(a);
            a = 2.*abs(a - 0.5);
        otherwise
            error('unknown alphamap specified');
    end
else
    amap = amap(:);

    % assume it to be a vector that has M elements, scaled between 0 and 1
    a = alpha-min(alpha);
    a = a/max(a);
    ind = round(a.*(size(amap,1)-1))+1;
    a   = amap(ind(1:end),:);
end
a = a(1:end-2);


function model = addCOBRAConstraints(model, idList, d, varargin)
% Add a constraint to the model in the form c1 * v(id1) + c2 * v(id2) * ... cj * v(idj) dsense d
% where c is a vector with coefficients for each element in idList
% (default 1 for each reaction), dsense is one of lower than ('L', default), greater than
% ('G'), or equal ('E'), and d is a value.
% USAGE:
%    model = addCOBRAConstraints(model, idList, d, varargin)
%
% INPUTS:
%    model:         model structure
%    idList:        cell array of ids either from either the rxns, or the
%                   evars vectors. Can also be a a double vector of indices (in which
%                   case indices in evars have to be set off by
%                   numel(rxns).
%    d:             The right hand side of the C*v <= d constraint (or a
%                   vector, for multiple simultaneous addition;
%
%    varargin:
%                   * c:                the coefficients to use with one entry per
%                                       reaction of a constraint for multiple constraints, a matrix
%                                       (default: 1 for each element indicated in idList)
%                   * dsense:           the constraint sense ('L': <= ,
%                                       'G': >=, 'E': =), or a vector for multiple constraints
%                                       (default: ('L'))
%                   * ConstraintID:     the Name of the constraint. by
%                                       (default: 'ConstraintXYZ' with XYZ being the initial
%                                       position in the ctrs vector)
%                                       or a cell array of Strings for
%                                       multiple Constraints
%                   * checkDuplicates:  check whether the constraint already
%                                       exists, and if it does, don't add it (default: false)
%
% OUTPUT:
%    modelConstrained:      The constrained model containing the added
%                           constraints in the respective fields:
%                            * `.C` - The constraint matrix containing coefficients for reactions
%                            * `.ctrs` - The constraint IDs
%                            * `.dsense` - The constraint senses
%                            * `.d` the constraint right hand side values
%                            *  Optional: `D`, the matrix conatining coefficients for additional variables.
%
%
% EXAMPLE:
%    Add a constraint that leads to EX_glc and EX_fru not carrying a
%    combined flux higher than 5
%    model = addCOBRAConstraints(model, {'EX_glc','EX_fru'}, 5)
%    Assume Reaction 4 to be 2 A -> D and reaction 5 being A -> F. Create a
%    constraint that requires that the two reactions remove at least 4 units of A:
%    model = addCOBRAConstraints(model, model.rxns(4:5), 4, 'c', [2 1], 'dsense', 'G')
%
% NOTE:
%    This function will, if not present create the `C`, `ctrs`, `dsense`, `d` and,
%    if additional variables (i.e. the `E` matrix) is present, the `D`
%    field as defined in the model field definitions. The `C` field containts
%    the constraint coefficients referring to reactions, while the `D`
%    field contains the Constraint coefficients referring to additional
%    variables. `d` represents the right hand side of constraints and
%    `dsense` the sense (lower -'L' , equal - 'E' or greater than - 'G') of the constraint.
%    `ctrs` stores unique IDs for the constraints.
%
% Author: Thomas Pfau, Nov 2017

if ischar(idList) %This is an individual element.
    idList = {idList};
end

if iscell(idList)
    [pos,pres] = getIDPositions(model,idList,'rxns');
    if any(~pres)
        missingreactions = idList(~pres);
        error('The following ids were not found in the model:\n%s\nNo Constraint was added',strjoin(missingreactions,', '));
    end
    idList = pos;
end

multiAdd = false;
if ~all(size(idList) > 1) %if this is true, its multiple rows...
    if (length(d) > 1) %This should be a multiAdd
        dim = length(d) == size(idList);
        multiAdd = true;
        if ~all(dim)
            %make sure this is the right orientation
             cdim = find(dim);
             if cdim ~= 1
                 idList = idList';
             end
        else
            error('d has to be either a single value or a vector of doubles');
        end
    else
        %there is only one element in d and idList has a dimension of size
        %1. So we need to make sure, that idList is a row vector.
        if size(idList,1) > size(idList,2)
            idList = idList';
        end
        if ~(length(idList) == length(unique(idList)))
            error('There were duplicate reaction IDs or positions provided. No Constraint will be added.');
        end
    end
else
    multiAdd = true;
end

defaultcoefficients = ones(numel(d),numel(idList));

defaultcsense = repmat('L',numel(d),1);
if ~multiAdd
    defaultConstraintName = getConstraintName(model,1);
else
    defaultConstraintName = getConstraintName(model,length(d));
end

parser = inputParser();
parser.addRequired('model',@isstruct);
parser.addRequired('idList',@(x) isnumeric(x));
parser.addRequired('d',@isnumeric);
parser.addParamValue('c',defaultcoefficients,@(x) isnumeric(x) && (multiAdd || length(x) == length(idList)));
parser.addParamValue('dsense',defaultcsense, @ischar );
parser.addParamValue('ConstraintID',defaultConstraintName,@(x) ischar(x) || iscell(x) );
parser.addParamValue('checkDuplicates',false,@(x) islogical(x) || isnumeric(x) );

parser.parse(model,idList,d,varargin{:});

c = parser.Results.c;
d = columnVector(parser.Results.d);
dsense = columnVector(parser.Results.dsense);
ctrID = parser.Results.ConstraintID;
if ischar(ctrID)
    ctrID = {ctrID};
else
    ctrID = columnVector(ctrID);
end
checkDuplicate = parser.Results.checkDuplicates;

if ~isfield(model,'evars')
    varspresent = false;
    ConstraintFields = {'C','d','dsense','ctrs'};
else
    varspresent = true;
    ConstraintFields = {'C','D','d','dsense','ctrs'};
end
fieldsPresent = ismember(ConstraintFields,fieldnames(model));
if ~all(fieldsPresent)
    if any(fieldsPresent)
        for i = 1:numel(ConstraintFields)
            if ~isfield(model,ConstraintFields{i})
                model = createEmptyField(model,ConstraintFields{i});
            else
                if ~isempty(model.(ConstraintFields{i}))
                    error('Inconsistent Field sizes detected. Expected an empty field but %s was non empty',ConstraintFields{i})
                else
                    model = createEmptyField(model,ConstraintFields{i}); %Replace the existing to make sure the dimensions are correct.
                end
            end
        end
    else
        model = createEmptyFields(model,ConstraintFields);
    end
end

%Now, we have all fields.
%Check for duplicates:
if any(ismember(model.ctrs,ctrID))
    error('Constraints with the following IDs already exist.\n%s\n', strjoin(model.ctrs(ismember(model.ctrs,ctrID)),', '));
end
%And if multiAdd also check for duplicates in the input
if multiAdd && numel(ctrID) > numel(unique(ctrID))
    [unq,~,orig] = unique(ctrID);
    dupreacs = hist(orig,numel(unq)) > 1;
    error('Input contained the following duplicated IDs:\n %s ', strjoin(unq(dupreacs),', '));
end

if checkDuplicate && multiAdd
    %If we check for duplicates, and don't want to add them, we will first
    %filter them from the input, but only if we add multiple things.
    [sorted,order] = sort(idList,2);
    sortedC = c;
    sorted = repmat(sorted,size(c,1),1);
    for i = 1:size(idList,1)
        sortedC(i,:) = c(i,order(i,:));
    end
    %Now, concatenate all inputs (except names)
    toCompare = [sorted,sortedC,dsense]; %This will convert the dsense into doubles which is fine to get uniques.
    [~,pos] = unique(toCompare,'rows');
    %Now lets remove anything thats duplicated.
    d = d(pos,:);
    c = c(pos,:);
    dsense = dsense(pos,:);
    ctrID = ctrID(pos,:);
end

%In case nothing is left.
if isempty(ctrID)
    return
end

%Also check for duplicates in the C Matrix.
if varspresent
    mixrows = sparse(size(c,1),size(model.E,2));
end
constRow = sparse(size(c,1),size(model.C,2));
duppedRows = false(size(idList,1),1);
nRxns = numel(model.rxns);
rxnpos = idList <= nRxns;
varpos = idList > nRxns;

for i = 1:size(c,1)
    constRow(i,idList(rxnpos)) = c(i,rxnpos);
    if varspresent
         mixrows(i,idList(varpos)-nRxns) = c(i,varpos);
    end
    cRow = constRow(i,:);
    if checkDuplicate
        dupRows = all(model.C == cRow(ones(size(model.C,1),1),:),2);
    end
    if varspresent
        cmRow = mixrows(i,:);
        if checkDuplicate
            vdupRows = all(model.E == cmRow(ones(size(model.E,1),1),:),2);
            dupRows = dupRows & vdupRows;
        end
    end
    if checkDuplicate
        duppedRows(i) = any(dupRows) && (model.dsense(dupRows) == dsense(i)) && (model.d(dupRows) == d(i));
    end
end

if any(duppedRows) && checkDuplicate
    warning('Constraint(s) not added, because it already exists with ID: %s',strjoin(model.ctrs(dupRows)));
    if ~multiAdd
        return
    else
        ctrID(duppedRows) = [];
        d(duppedRows) = [];
        constRow(duppedRows,:) = [];
        dsense(duppedRows) = [];
    end
end

model.C = [model.C;constRow];
model.d = [model.d;d];
model.dsense = [model.dsense;dsense];
originalSize = numel(model.ctrs);
model.ctrs = [model.ctrs;ctrID];
if varspresent
    model.D = [model.D;mixrows];
end

model = extendModelFieldsForType(model,'ctrs','originalSize',originalSize);

end

function name = getConstraintName(model, count)
%Get a unique, not yet used constraint name.
if ~isfield(model,'ctrs')
    name = strcat('Constraint',cellfun(@num2str,num2cell(1:count)','UniformOutput',false));
    return
else
    name = cell(count,1);
    name(:) = {''}; %Need to initialize, otherwise we get a mismatch during ismember.
    constraintsCreated = 0;
    i = size(model.C,1) + 1;
    cname = ['Constraint' num2str(i)];
    while constraintsCreated < count
        while any(ismember(model.ctrs,cname)) || any(ismember(name,cname))
            i = i + 1;
            cname = ['Constraint' num2str(i)];
        end
        constraintsCreated = constraintsCreated + 1;
        name{constraintsCreated} = cname;
    end
end
end


function stInfo=convertMatToStruct(allData, gtMaxFrame)

numCols=size(allData,2);
numLines=size(allData,1);

% quickly check format
assert(numCols>=7,'FORMAT ERROR: Each line must have at least 6 values');
% assert(all(allData(:,1)>0),'FORMAT ERROR: Frame numbers must be positive.');
% assert(all(allData(:,2)>0),'FORMAT ERROR: IDs must be positive.');

IDMap = unique(allData(:,2))';
nIDs = length(IDMap);
% fprintf('%d unique targets IDs discovered\n',nIDs);
% pause

% do we have bbox coordinates?
imCoord=0;
if any(any(allData(:,3:6)~= -1))
    imCoord=1;
end

% do we have world coordinates?
worldCoord=0;

% ... we do if they exist and are not -1 (default)
if size(allData,2)>=9
    if any(any(allData(:,[8 9])~= -1))
        worldCoord=1;
    end
end

% at least one representation must be defined
assert(imCoord || worldCoord, ...
    'FORMAT ERROR: Neither bounding boxes nor world coorsinates defined.');

% go through all lines
for l=numLines:-1:1
    lineData=allData(l,:);

    fr = lineData(1);   % frame number
    id = lineData(2);   % target id

    % map id to 1..nIDs
    id = find(IDMap==id);

    %%%% sanity checks
    % ignore non-positive frames and IDs
    if fr<1,
        continue;
    end

    % bounding box
    stInfo.W(fr,id) = lineData(5);
    stInfo.H(fr,id) = lineData(6);
    stInfo.Xi(fr,id) = lineData(3) + stInfo.W(fr,id)/2;
    stInfo.Yi(fr,id) = lineData(4) + stInfo.H(fr,id);

    % values should not be exactly 0
    if ~stInfo.W(fr,id)
        stInfo.W(fr,id) = stInfo.W(fr,id) + 0.0001;
    end
    if ~stInfo.H(fr,id)
        stInfo.H(fr,id) = stInfo.H(fr,id) + 0.0001;
    end
    if ~stInfo.Xi(fr,id)
        stInfo.Xi(fr,id) = stInfo.Xi(fr,id) + 0.0001;
    end
    if ~stInfo.Yi(fr,id)
        stInfo.Yi(fr,id) = stInfo.Yi(fr,id) + 0.0001;
    end
    % consider 3D coordinates
    if worldCoord
        stInfo.Xgp(fr,id) = lineData(7);
        stInfo.Ygp(fr,id) = lineData(8);

        % position should not be exactly 0
        if ~stInfo.Xgp(fr,id)
            stInfo.Xgp(fr,id)=stInfo.Xgp(fr,id)+0.0001;
        end
        if ~stInfo.Ygp(fr,id)
            stInfo.Ygp(fr,id)=stInfo.Ygp(fr,id)+0.0001;
        end
    end
end

% append empty frames?
if gtMaxFrame ~= -1

    Fgt=gtMaxFrame;
    F=size(stInfo.W,1);
    % if stateInfo shorter, pad with zeros
    if F<Fgt
        missingFrames = F+1:Fgt;
        stInfo.Xi(missingFrames,:)=0;
        stInfo.Yi(missingFrames,:)=0;
        stInfo.W(missingFrames,:)=0;
        stInfo.H(missingFrames,:)=0;
        if worldCoord
            stInfo.Xgp(missingFrames,:)=0;
            stInfo.Ygp(missingFrames,:)=0;
        end
    end
end

% set X,Y
stInfo.X=stInfo.Xi;stInfo.Y=stInfo.Yi;
if ~imCoord
    stInfo.X=stInfo.Xgp;stInfo.Y=stInfo.Ygp;

    % reset image coordinates to -1
    te = find(stInfo.X(:));
    stInfo.W(te)=-1;stInfo.H(te)=-1;
    stInfo.Xi(te)=-1;stInfo.Yi(te)=-1;
end

% remove empty target IDs
nzc=~~sum(abs(stInfo.Xi),1);

if isfield(stInfo,'X')
    stInfo.X=stInfo.X(:,nzc);
    stInfo.Y=stInfo.Y(:,nzc);
end

% nzc
% stInfo.Xgp'
if isfield(stInfo,'Xgp')
    stInfo.Xgp=stInfo.Xgp(:,nzc);
    stInfo.Ygp=stInfo.Ygp(:,nzc);
end

if isfield(stInfo,'Xi')
    stInfo.Xi=stInfo.Xi(:,nzc);
    stInfo.Yi=stInfo.Yi(:,nzc);
    stInfo.W=stInfo.W(:,nzc);
    stInfo.H=stInfo.H(:,nzc);
end


function o = mean_CS(q,CS)
% fast mean of
%
% Syntax
%   m = mean(o)
%
% Input
%  o        - list of @orientation
%
% Output
%  m      - mean @orientation
%
% See also
% orientation/mean

if length(q) > 1
  q = project2FundamentalRegion(q,CS,q.subSet(1));
  q = mean(q);
end

o = orientation(q,CS);


function compareInterations

fCase{1}  = 'LatticeExperimentInputCantileverSymmetricMeshSuperEllipsePDE';
folder{1} = '/media/alex/My Passport/LatticeResults/CantileverSymmetricMeshSuperEllipsePDEGradientEpsilonH';

fCase{2} = 'LatticeExperimentInputCantileverSymmetricMeshSuperEllipsePDE';
folder{2} = '/media/alex/My Passport/LatticeResults/CantileverSymmetricMeshSuperEllipsePDEEpsilonEhGradient2000';

fCase{3} = 'LatticeExperimentInputCantileverSymmetricMeshSuperEllipsePDE';
folder{3} = '/media/alex/My Passport/LatticeResults/CantileverSymmetricMeshSuperEllipsePDE10000iteration';

f = figure();
hold on
it = 1;
for iPlot = 1:numel(fCase)
    fName = fullfile(folder{iPlot},fCase{iPlot});
    [xV,yV,cV] = getCostFunctions(fName);
    for iline = 1:size(yV,2)
        p{it} = plot(xV,yV(:,iline),'Color',cV(:,iline));
        it = it + 1;
    end
end
pr = plotPrinter(f,p);
pr.print(fullfile('/home/alex/Dropbox/GregMeeting30Octubre',['Iterations']));
end

function [xV,yV,cV] = getCostFunctions(fName)
fNameMon = fullfile([fName,'CostVsLinf.fig']);
h = openfig(fNameMon);
handles = findobj(h,'Type','line');
xV = get(handles(1),'Xdata');
for i = 1:numel(handles)
    yV(:,i) = get(handles(i),'Ydata');
    cV(:,i) = get(handles(i),'Color') ;
end
close(h)
end


function C = mtimes(A,B)
%MTIMES Multiplies two tenmat objects.
%
%  C = MTIMES(A,B) computes the product of A and B. The result is a
%  TENMAT object and can be transformed into a tensor.
%
%  C = MTIMES(A,B) is called for the syntax 'A * B' when A or B is a
%  TENMAT object.
%
%   See also TENMAT.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

% Handle scalar input
if ~isa(B,'tenmat') && numel(B) == 1
    C = A;
    C.data = C.data * B;
    return;
end
if ~isa(A,'tenmat') && numel(A) == 1
    C = B;
    C.data = C.data * A;
    return;
end

% Handle matrix input
if ~isa(A,'tenmat')
    A = tenmat(A,1);
end

if ~isa(B,'tenmat')
    B = tenmat(B,1);
end

% Error check
if size(A,2) ~= size(B,1)
    error(['Size mismatch: Number of columns in A is not equal to' ...
	   ' the number of rows in B']);
end

tsiz = [A.tsize(A.rindices) B.tsize(B.cindices)];

if ~isempty(tsiz)
    C = tenmat;
    C.tsize = tsiz;
    C.rindices = 1:length(A.rindices);
    C.cindices = (1:length(B.cindices)) + length(A.rindices);
    C.data = A.data * B.data;
else
    C = A.data * B.data;
end


function sizes = getVarSizes(obj, inputSizes)
%GETVARSIZES  Get the size of the variables
%   SIZES = GETVARSIZES(OBJ, INPUTSIZES) computes the SIZES of the
%   DagNN variables given the size of the inputs. `inputSizes` is
%   a cell array of the type `{'inputName', inputSize, ...}`
%   Returns a cell array with sizes of all network variables.
%
%   Example, compute the storage needed for a batch size of 256 for an
%   imagenet-like network:
%   ```
%   batch_size = 256; single_num_bytes = 4;
%   input_size = [net.meta.normalization.imageSize, batch_size];
%   var_sizes = net.getVarSizes({'data', input_size});
%   fprintf('Network activations will take %.2fMiB in single.\n', ...
%     sum(prod(cell2mat(var_sizes, 1))) * single_num_bytes ./ 1024^3);
%   ```

% Copyright (C) 2015 Andrea Vedaldi, Karel Lenc.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

nv = numel(obj.vars) ;
sizes = num2cell(NaN(nv, 4),2)' ;

for i = 1:2:numel(inputSizes)
  v = obj.getVarIndex(inputSizes{i}) ;
  sizes{v} = inputSizes{i+1}(:)' ;
end

for layer = obj.layers
  in = layer.inputIndexes ;
  out = layer.outputIndexes ;
  sizes(out) = layer.block.getOutputSizes(sizes(in)) ;
end


function [scoresAll, labelsAll, nGTall] = assignGTmulti(pred,annolist_gt,thresh)

nJoints = 14;
% LSP to MPII format map
jidxMap = [0:5 10:15 8:9];
assert(length(jidxMap) == nJoints);

% part detections scores
scoresAll = cell(nJoints,1);
% positive / negative labels
labelsAll = cell(nJoints,1);
% number of annotated GT joints per image
nGTall = zeros(nJoints,length(annolist_gt));

for i = 1:nJoints
    scoresAll{i} = cell(length(annolist_gt),1);
    labelsAll{i} = cell(length(annolist_gt),1);
end

for imgidx = 1:length(annolist_gt)
    % distance between predicted and GT joints
    dist = inf(length(pred(imgidx).annorect),length(annolist_gt(imgidx).annorect),nJoints);
    % score of the predicted joint
    score = nan(length(pred(imgidx).annorect),nJoints);
    % body joint prediction exist
    hasPred = false(length(pred(imgidx).annorect),nJoints);
    % body joint is annotated
    hasGT = false(length(annolist_gt(imgidx).annorect),nJoints);

    % iterate over predicted poses
    for ridxPred = 1:length(pred(imgidx).annorect)
        % predicted pose
        rectPred = pred(imgidx).annorect(ridxPred);
        pointsPred = rectPred.annopoints.point;
        % iterate over GT poses
        for ridxGT = 1:length(annolist_gt(imgidx).annorect) % GT
            % GT pose
            rectGT = annolist_gt(imgidx).annorect(ridxGT);
            % compute reference distance as head size
            refDist = util_get_head_size(rectGT);
            pointsGT = [];
            if (~isempty(rectGT.annopoints))
                pointsGT = rectGT.annopoints.point;
            end
            % iterate over all possible body joints
            for i = 1:nJoints
                % predicted joint in LSP format
                ppPred = util_get_annopoint_by_id(pointsPred, jidxMap(i));
                if (~isempty(ppPred))
                    score(ridxPred,i) = ppPred.score;
                    hasPred(ridxPred,i) = true;
                end
                % GT joint in LSP format
                ppGT = util_get_annopoint_by_id(pointsGT, jidxMap(i));
                if (~isempty(ppGT))
                    hasGT(ridxGT,i) = true;
                end
                % compute distance between predicted and GT joint locations
                if (hasPred(ridxPred,i) && hasGT(ridxGT,i))
                    dist(ridxPred,ridxGT,i) = norm([ppGT.x ppGT.y] - [ppPred.x ppPred.y])/refDist;
                end
            end % joints
        end % GT poses
    end % predicted poses

    % number of annotated joints
    nGT = repmat(sum(hasGT,2)',size(hasPred,1),1);
    % compute PCKh
    match = dist <= thresh;
    pck = sum(match,3)./nGT;
    % preserve best GT match only
    [val,idx] = max(pck,[],2);
    for ridxPred = 1:length(idx)
        pck(ridxPred,setdiff(1:size(pck,2),idx(ridxPred))) = 0;
    end
    [val,predToGT] = max(pck,[],1);
    predToGT(val == 0) = 0;

    % assign predicted poses to GT poses
    for ridxPred = 1:length(pred(imgidx).annorect)
        if (ismember(ridxPred,predToGT)) % pose matches to GT
            % GT pose that matches the predicted pose
            ridxGT = find(predToGT == ridxPred);
            s = score(ridxPred,:);
            m = squeeze(match(ridxPred,ridxGT,:));
            hp = hasPred(ridxPred,:);
            idxs = find(hp);
            for i = 1:length(idxs)
                scoresAll{idxs(i)}{imgidx} = [scoresAll{idxs(i)}{imgidx};s(idxs(i))];
                labelsAll{idxs(i)}{imgidx} = [labelsAll{idxs(i)}{imgidx};m(idxs(i))];
            end
        else % no matching to GT
            s = score(ridxPred,:);
            m = false(size(match,3),1);
            hp = hasPred(ridxPred,:);
            idxs = find(hp);
            for i = 1:length(idxs)
                scoresAll{idxs(i)}{imgidx} = [scoresAll{idxs(i)}{imgidx};s(idxs(i))];
                labelsAll{idxs(i)}{imgidx} = [labelsAll{idxs(i)}{imgidx};m(idxs(i))];
            end
        end
    end % prediction assignment

    % save number of GT joints
    for ridxGT = 1:length(annolist_gt(imgidx).annorect)
        hg = hasGT(ridxGT,:);
        nGTall(:,imgidx) = nGTall(:,imgidx) + hg';
    end
end
end


function plotSteeringComparison(files, laps, labels)
% Author:       Alexander Wischnewski
% Description:
%   function used to compare different controllers
% Inputs/parameters:
%   files:      Cell array with file names of logs
%   laps:       laps to evaluate (matrix with start and end lap for each datafile)
%   labels:     Cell array with abels for the datasets used for legends
%               (file names are used if not given)

% plotting parameters
LineWidth = 1;
DyLim = 1.0;
axLim = 25;
ayLim = 25;

% load all the relevant data files
for i = 1:1:length(files)
    data{i} = load(files{i});
end

% check if labels are given, if not use file names
if(nargin <= 2)
    labels = files;
end

% find start and end indices
for i = 1:1:length(files)
    idx_start{i} = find((data{i}.debug.debug_mvdc_path_matching_debug_ActualTrajPoint_LapCnt.Data == laps(i,1)), 1, 'first') + 50;
    idx_end{i} = find((data{i}.debug.debug_mvdc_path_matching_debug_ActualTrajPoint_LapCnt.Data == laps(i,2)), 1, 'last') - 50;
end

figure;
hold on; grid on;
colors = {'r', 'b'};
for i = 1:1:length(files)
    plot(data{i}.debug.debug_mvdc_path_matching_debug_ActualTrajPoint_s_glob_m.Data(idx_start{i}:idx_end{i}), ...
        data{i}.debug.debug_mvdc_actuator_debug_RequestSteeringAngle_rad.Data(idx_start{i}:idx_end{i}), ...
        'LineWidth', LineWidth, 'Color', colors{i}, 'DisplayName', [labels{i} ' Target']);
    plot(data{i}.debug.debug_mvdc_path_matching_debug_ActualTrajPoint_s_glob_m.Data(idx_start{i}:idx_end{i}), ...
        data{i}.debug.debug_VehicleSensorData_Delta_Wheel_rad.Data(idx_start{i}:idx_end{i}), '--',...
        'LineWidth', LineWidth, 'Color', colors{i}, 'DisplayName', [labels{i} ' Actual']);
end
xlabel('s in m'); ylabel({'Steering', 'in rad'}); ylim([-0.02, 0.02]);
legend();


function [xUpdate,LUpdate,PUpdate,innov,Pzz,W]=separatedCovUpdateWithPred(z,R,zPred,PzPred,otherInfo,LPred,c)
%%SEPARATEDCOVUPDATEWITHPRED Given the output of the measurement prediction
%           step from separatedCovMeasPred and a measurement, complete the
%           measurement update step of the separated covariance filter.
%           Separating the measurement prediction step from the rest of the
%           update step can make the creation of multiple measurement
%           association hypotheses from a single target prediction more
%           efficient. The full measurement update function is
%           separatedCovUpdate.
%
%INPUTS: z The zDimX1 vector measurement.
%        R The zDimXzDim measurement covariance matrix in the native
%          coordinate system of the measurement.
%    zPred The zDimXnumComp measurement predictions from the filter.
%   PzPred The zDimXzDimXnumComp covariance matrices associated with zPred.
% otherInfo The intermediate results returned in the otherInfo output of
%          the separatedCovMeasPred function.
%    LPred The xDimXzDimXnumComp predicted delay vectors (defined before
%          Equation 12 in [1]). The use of multiple columns represents a
%          choice in how the algorithm was generalized to multiple
%          dimensions.
%        c The confidence region under consideration by the filter. 0<c<1.
%          If this parameter is omitted or an empty matrix is passed, the
%          default value of c=0.99 is used.
%
%OUTPUTS: xUpdate The xDimXnumComp updated state vectors.
%         LUpdate The xDimXzDimXnumComp updated delay vectors.
%         PUpdate The xDimXxDimXnumComp covariance matrices of the state
%                 estimates. This is a combination of LUpdate and PUpdate.
%      innov, Pzz The zDimXnumComp innovations and a zDimXzDimXnumComp
%                 set of matrices Pzz that are akin to an innovation
%                 covariance matrices are returned in case one wishes to
%                 analyze the consistency of the estimator or use those
%                 values in gating or likelihood evaluation.
%               W The xDimXzDimXnumComp gains used in the update.
%
%See the comments to the function separatedCovMeasPred for an example of
%usage of this function. See the comments to separatedCovUpdate for more
%information on the algorithm.
%
%REFERENCES:
%[1] G. J. Portmann, J. R. Moore, and W. G. Bath, "Separated covariance
%    filtering," in Proceedings of the IEEE International Radar Conference,
%    Arlington, VA, 7-10 May 1990, pp. 456-460.
%
%June 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<7||isempty(c))
    c=0.99;
end

H=otherInfo.H;
TPred=otherInfo.TPred;
xPred=otherInfo.xPred;
Pxz=otherInfo.Pxz;

xDim=size(xPred,1);
numComp=size(xPred,2);
zDim=size(z,1);

xUpdate=zeros(xDim,numComp);
LUpdate=zeros(xDim,zDim,numComp);
PUpdate=zeros(xDim,xDim,numComp);
innov=zeros(zDim,numComp);
Pzz=zeros(zDim,zDim,numComp);
W=zeros(xDim,zDim,numComp);
for k=1:numComp
    Pzz(:,:,k)=PzPred(:,:,k)+c^2*R;
    W(:,:,k)=Pxz(:,:,k)/Pzz(:,:,k);%The gain

    innov(:,k)=z-zPred(:,k);%The innovation
    xUpdate(:,k)=xPred(:,k)+W(:,:,k)*innov(:,k);

    xDim=size(xPred,1);
    diff=eye(xDim,xDim)-W(:,:,k)*H;

    LUpdate(:,:,k)=diff*LPred(:,:,k);
    TUpdate=diff*TPred(:,:,k);

    PUpdate(:,:,k)=(TUpdate-LUpdate(:,:,k)*LUpdate(:,:,k)')/c^2;
end
end

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


function varargout = colorspace(Conversion,varargin)
%   COLORSPACE  Convert a color image between color representations.
%   B = COLORSPACE(S,A) converts the color representation of image A
%   where S is a string specifying the conversion.  S tells the
%   source and destination color spaces, S = 'dest<-src', or
%   alternatively, S = 'src->dest'.  Supported color spaces are
%
%     'RGB'              R'G'B' Red Green Blue (ITU-R BT.709 gamma-corrected)
%     'YPbPr'            Luma (ITU-R BT.601) + Chroma
%     'YCbCr'/'YCC'      Luma + Chroma ("digitized" version of Y'PbPr)
%     'YUV'              NTSC PAL Y'UV Luma + Chroma
%     'YIQ'              NTSC Y'IQ Luma + Chroma
%     'YDbDr'            SECAM Y'DbDr Luma + Chroma
%     'JPEGYCbCr'        JPEG-Y'CbCr Luma + Chroma
%     'HSV'/'HSB'        Hue Saturation Value/Brightness
%     'HSL'/'HLS'/'HSI'  Hue Saturation Luminance/Intensity
%     'XYZ'              CIE XYZ
%     'Lab'              CIE L*a*b* (CIELAB)
%     'Luv'              CIE L*u*v* (CIELUV)
%     'Lch'              CIE L*ch (CIELCH)
%
%  All conversions assume 2 degree observer and D65 illuminant.  Color
%  space names are case insensitive.  When R'G'B' is the source or
%  destination, it can be omitted. For example 'yuv<-' is short for
%  'yuv<-rgb'.
%
%  MATLAB uses two standard data formats for R'G'B': double data with
%  intensities in the range 0 to 1, and uint8 data with integer-valued
%  intensities from 0 to 255.  As MATLAB's native datatype, double data is
%  the natural choice, and the R'G'B' format used by colorspace.  However,
%  for memory and computational performance, some functions also operate
%  with uint8 R'G'B'.  Given uint8 R'G'B' color data, colorspace will
%  first cast it to double R'G'B' before processing.
%
%  If A is an Mx3 array, like a colormap, B will also have size Mx3.
%
%  [B1,B2,B3] = COLORSPACE(S,A) specifies separate output channels.
%  COLORSPACE(S,A1,A2,A3) specifies separate input channels.

%  Pascal Getreuer 2005-2006

%%% Input parsing %%%
if nargin < 2, error('Not enough input arguments.'); end
[SrcSpace,DestSpace] = parse(Conversion);

if nargin == 2
   Image = varargin{1};
elseif nargin >= 3
   Image = cat(3,varargin{:});
else
   error('Invalid number of input arguments.');
end

FlipDims = (size(Image,3) == 1);

if FlipDims, Image = permute(Image,[1,3,2]); end
if ~isa(Image,'double'), Image = double(Image)/255; end
if size(Image,3) ~= 3, error('Invalid input size.'); end

SrcT = gettransform(SrcSpace);
DestT = gettransform(DestSpace);

if ~ischar(SrcT) & ~ischar(DestT)
   % Both source and destination transforms are affine, so they
   % can be composed into one affine operation
   T = [DestT(:,1:3)*SrcT(:,1:3),DestT(:,1:3)*SrcT(:,4)+DestT(:,4)];
   Temp = zeros(size(Image));
   Temp(:,:,1) = T(1)*Image(:,:,1) + T(4)*Image(:,:,2) + T(7)*Image(:,:,3) + T(10);
   Temp(:,:,2) = T(2)*Image(:,:,1) + T(5)*Image(:,:,2) + T(8)*Image(:,:,3) + T(11);
   Temp(:,:,3) = T(3)*Image(:,:,1) + T(6)*Image(:,:,2) + T(9)*Image(:,:,3) + T(12);
   Image = Temp;
elseif ~ischar(DestT)
   Image = rgb(Image,SrcSpace);
   Temp = zeros(size(Image));
   Temp(:,:,1) = DestT(1)*Image(:,:,1) + DestT(4)*Image(:,:,2) + DestT(7)*Image(:,:,3) + DestT(10);
   Temp(:,:,2) = DestT(2)*Image(:,:,1) + DestT(5)*Image(:,:,2) + DestT(8)*Image(:,:,3) + DestT(11);
   Temp(:,:,3) = DestT(3)*Image(:,:,1) + DestT(6)*Image(:,:,2) + DestT(9)*Image(:,:,3) + DestT(12);
   Image = Temp;
else
   Image = feval(DestT,Image,SrcSpace);
end

%%% Output format %%%
if nargout > 1
   varargout = {Image(:,:,1),Image(:,:,2),Image(:,:,3)};
else
   if FlipDims, Image = permute(Image,[1,3,2]); end
   varargout = {Image};
end

return;

function [SrcSpace,DestSpace] = parse(Str)
% Parse conversion argument

if isstr(Str)
   Str = lower(strrep(strrep(Str,'-',''),' ',''));
   k = find(Str == '>');

   if length(k) == 1         % Interpret the form 'src->dest'
      SrcSpace = Str(1:k-1);
      DestSpace = Str(k+1:end);
   else
      k = find(Str == '<');

      if length(k) == 1      % Interpret the form 'dest<-src'
         DestSpace = Str(1:k-1);
         SrcSpace = Str(k+1:end);
      else
         error(['Invalid conversion, ''',Str,'''.']);
      end
   end

   SrcSpace = alias(SrcSpace);
   DestSpace = alias(DestSpace);
else
   SrcSpace = 1;             % No source pre-transform
   DestSpace = Conversion;
   if any(size(Conversion) ~= 3), error('Transformation matrix must be 3x3.'); end
end
return;

function Space = alias(Space)
Space = strrep(Space,'cie','');

if isempty(Space)
   Space = 'rgb';
end

switch Space
case {'ycbcr','ycc'}
   Space = 'ycbcr';
case {'hsv','hsb'}
   Space = 'hsv';
case {'hsl','hsi','hls'}
   Space = 'hsl';
case {'rgb','yuv','yiq','ydbdr','ycbcr','jpegycbcr','xyz','lab','luv','lch'}
   return;
end
return;

function T = gettransform(Space)
% Get a colorspace transform: either a matrix describing an affine transform,
% or a string referring to a conversion subroutine
switch Space
case 'ypbpr'
   T = [0.299,0.587,0.114,0;-0.1687367,-0.331264,0.5,0;0.5,-0.418688,-0.081312,0];
case 'yuv'
   % R'G'B' to NTSC/PAL YUV
   % Wikipedia: http://en.wikipedia.org/wiki/YUV
   T = [0.299,0.587,0.114,0;-0.147,-0.289,0.436,0;0.615,-0.515,-0.100,0];
case 'ydbdr'
   % R'G'B' to SECAM YDbDr
   % Wikipedia: http://en.wikipedia.org/wiki/YDbDr
   T = [0.299,0.587,0.114,0;-0.450,-0.883,1.333,0;-1.333,1.116,0.217,0];
case 'yiq'
   % R'G'B' in [0,1] to NTSC YIQ in [0,1];[-0.595716,0.595716];[-0.522591,0.522591];
   % Wikipedia: http://en.wikipedia.org/wiki/YIQ
   T = [0.299,0.587,0.114,0;0.595716,-0.274453,-0.321263,0;0.211456,-0.522591,0.311135,0];
case 'ycbcr'
   % R'G'B' (range [0,1]) to ITU-R BRT.601 (CCIR 601) Y'CbCr
   % Wikipedia: http://en.wikipedia.org/wiki/YCbCr
   % Poynton, Equation 3, scaling of R'G'B to Y'PbPr conversion
   T = [65.481,128.553,24.966,16;-37.797,-74.203,112.0,128;112.0,-93.786,-18.214,128];
case 'jpegycbcr'
   % Wikipedia: http://en.wikipedia.org/wiki/YCbCr
   T = [0.299,0.587,0.114,0;-0.168736,-0.331264,0.5,0.5;0.5,-0.418688,-0.081312,0.5]*255;
case {'rgb','xyz','hsv','hsl','lab','luv','lch'}
   T = Space;
otherwise
   error(['Unknown color space, ''',Space,'''.']);
end
return;

function Image = rgb(Image,SrcSpace)
% Convert to Rec. 709 R'G'B' from 'SrcSpace'
switch SrcSpace
case 'rgb'
   return;
case 'hsv'
   % Convert HSV to R'G'B'
   Image = huetorgb((1 - Image(:,:,2)).*Image(:,:,3),Image(:,:,3),Image(:,:,1));
case 'hsl'
   % Convert HSL to R'G'B'
   L = Image(:,:,3);
   Delta = Image(:,:,2).*min(L,1-L);
   Image = huetorgb(L-Delta,L+Delta,Image(:,:,1));
case {'xyz','lab','luv','lch'}
   % Convert to CIE XYZ
   Image = xyz(Image,SrcSpace);
   % Convert XYZ to RGB
   T = [3.240479,-1.53715,-0.498535;-0.969256,1.875992,0.041556;0.055648,-0.204043,1.057311];
   R = T(1)*Image(:,:,1) + T(4)*Image(:,:,2) + T(7)*Image(:,:,3);  % R
   G = T(2)*Image(:,:,1) + T(5)*Image(:,:,2) + T(8)*Image(:,:,3);  % G
   B = T(3)*Image(:,:,1) + T(6)*Image(:,:,2) + T(9)*Image(:,:,3);  % B
   % Desaturate and rescale to constrain resulting RGB values to [0,1]
   AddWhite = -min(min(min(R,G),B),0);
   Scale = max(max(max(R,G),B)+AddWhite,1);
   R = (R + AddWhite)./Scale;
   G = (G + AddWhite)./Scale;
   B = (B + AddWhite)./Scale;
   % Apply gamma correction to convert RGB to Rec. 709 R'G'B'
   Image(:,:,1) = gammacorrection(R);  % R'
   Image(:,:,2) = gammacorrection(G);  % G'
   Image(:,:,3) = gammacorrection(B);  % B'
otherwise  % Conversion is through an affine transform
   T = gettransform(SrcSpace);
   temp = inv(T(:,1:3));
   T = [temp,-temp*T(:,4)];
   R = T(1)*Image(:,:,1) + T(4)*Image(:,:,2) + T(7)*Image(:,:,3) + T(10);
   G = T(2)*Image(:,:,1) + T(5)*Image(:,:,2) + T(8)*Image(:,:,3) + T(11);
   B = T(3)*Image(:,:,1) + T(6)*Image(:,:,2) + T(9)*Image(:,:,3) + T(12);
   AddWhite = -min(min(min(R,G),B),0);
   Scale = max(max(max(R,G),B)+AddWhite,1);
   R = (R + AddWhite)./Scale;
   G = (G + AddWhite)./Scale;
   B = (B + AddWhite)./Scale;
   Image(:,:,1) = R;
   Image(:,:,2) = G;
   Image(:,:,3) = B;
end

% Clip to [0,1]
Image = min(max(Image,0),1);
return;

function Image = xyz(Image,SrcSpace)
% Convert to CIE XYZ from 'SrcSpace'
WhitePoint = [0.950456,1,1.088754];

switch SrcSpace
case 'xyz'
   return;
case 'luv'
   % Convert CIE L*uv to XYZ
   WhitePointU = (4*WhitePoint(1))./(WhitePoint(1) + 15*WhitePoint(2) + 3*WhitePoint(3));
   WhitePointV = (9*WhitePoint(2))./(WhitePoint(1) + 15*WhitePoint(2) + 3*WhitePoint(3));
   L = Image(:,:,1);
   Y = (L + 16)/116;
   Y = invf(Y)*WhitePoint(2);
   U = Image(:,:,2)./(13*L + 1e-6*(L==0)) + WhitePointU;
   V = Image(:,:,3)./(13*L + 1e-6*(L==0)) + WhitePointV;
   Image(:,:,1) = -(9*Y.*U)./((U-4).*V - U.*V);                  % X
   Image(:,:,2) = Y;                                             % Y
   Image(:,:,3) = (9*Y - (15*V.*Y) - (V.*Image(:,:,1)))./(3*V);  % Z
case {'lab','lch'}
   Image = lab(Image,SrcSpace);
   % Convert CIE L*ab to XYZ
   fY = (Image(:,:,1) + 16)/116;
   fX = fY + Image(:,:,2)/500;
   fZ = fY - Image(:,:,3)/200;
   Image(:,:,1) = WhitePoint(1)*invf(fX);  % X
   Image(:,:,2) = WhitePoint(2)*invf(fY);  % Y
   Image(:,:,3) = WhitePoint(3)*invf(fZ);  % Z
otherwise   % Convert from some gamma-corrected space
   % Convert to Rec. 701 R'G'B'
   Image = rgb(Image,SrcSpace);
   % Undo gamma correction
   R = invgammacorrection(Image(:,:,1));
   G = invgammacorrection(Image(:,:,2));
   B = invgammacorrection(Image(:,:,3));
   % Convert RGB to XYZ
   T = inv([3.240479,-1.53715,-0.498535;-0.969256,1.875992,0.041556;0.055648,-0.204043,1.057311]);
   Image(:,:,1) = T(1)*R + T(4)*G + T(7)*B;  % X
   Image(:,:,2) = T(2)*R + T(5)*G + T(8)*B;  % Y
   Image(:,:,3) = T(3)*R + T(6)*G + T(9)*B;  % Z
end
return;

function Image = hsv(Image,SrcSpace)
% Convert to HSV
Image = rgb(Image,SrcSpace);
V = max(Image,[],3);
S = (V - min(Image,[],3))./(V + (V == 0));
Image(:,:,1) = rgbtohue(Image);
Image(:,:,2) = S;
Image(:,:,3) = V;
return;

function Image = hsl(Image,SrcSpace)
% Convert to HSL
switch SrcSpace
case 'hsv'
   % Convert HSV to HSL
   MaxVal = Image(:,:,3);
   MinVal = (1 - Image(:,:,2)).*MaxVal;
   L = 0.5*(MaxVal + MinVal);
   temp = min(L,1-L);
   Image(:,:,2) = 0.5*(MaxVal - MinVal)./(temp + (temp == 0));
   Image(:,:,3) = L;
otherwise
   Image = rgb(Image,SrcSpace);  % Convert to Rec. 701 R'G'B'
   % Convert R'G'B' to HSL
   MinVal = min(Image,[],3);
   MaxVal = max(Image,[],3);
   L = 0.5*(MaxVal + MinVal);
   temp = min(L,1-L);
   S = 0.5*(MaxVal - MinVal)./(temp + (temp == 0));
   Image(:,:,1) = rgbtohue(Image);
   Image(:,:,2) = S;
   Image(:,:,3) = L;
end
return;

function Image = lab(Image,SrcSpace)
% Convert to CIE L*a*b* (CIELAB)
WhitePoint = [0.950456,1,1.088754];

switch SrcSpace
case 'lab'
   return;
case 'lch'
   % Convert CIE L*CH to CIE L*ab
   C = Image(:,:,2);
   Image(:,:,2) = cos(Image(:,:,3)*pi/180).*C;  % a*
   Image(:,:,3) = sin(Image(:,:,3)*pi/180).*C;  % b*
otherwise
   Image = xyz(Image,SrcSpace);  % Convert to XYZ
   % Convert XYZ to CIE L*a*b*
   X = Image(:,:,1)/WhitePoint(1);
   Y = Image(:,:,2)/WhitePoint(2);
   Z = Image(:,:,3)/WhitePoint(3);
   fX = f(X);
   fY = f(Y);
   fZ = f(Z);
   Image(:,:,1) = 116*fY - 16;    % L*
   Image(:,:,2) = 500*(fX - fY);  % a*
   Image(:,:,3) = 200*(fY - fZ);  % b*
end
return;

function Image = luv(Image,SrcSpace)
% Convert to CIE L*u*v* (CIELUV)
WhitePoint = [0.950456,1,1.088754];
WhitePointU = (4*WhitePoint(1))./(WhitePoint(1) + 15*WhitePoint(2) + 3*WhitePoint(3));
WhitePointV = (9*WhitePoint(2))./(WhitePoint(1) + 15*WhitePoint(2) + 3*WhitePoint(3));

Image = xyz(Image,SrcSpace); % Convert to XYZ
U = (4*Image(:,:,1))./(Image(:,:,1) + 15*Image(:,:,2) + 3*Image(:,:,3));
V = (9*Image(:,:,2))./(Image(:,:,1) + 15*Image(:,:,2) + 3*Image(:,:,3));
Y = Image(:,:,2)/WhitePoint(2);
L = 116*f(Y) - 16;
Image(:,:,1) = L;                        % L*
Image(:,:,2) = 13*L.*(U - WhitePointU);  % u*
Image(:,:,3) = 13*L.*(V - WhitePointV);  % v*
return;

function Image = lch(Image,SrcSpace)
% Convert to CIE L*ch
Image = lab(Image,SrcSpace);  % Convert to CIE L*ab
H = atan2(Image(:,:,3),Image(:,:,2));
H = H*180/pi + 360*(H < 0);
Image(:,:,2) = sqrt(Image(:,:,2).^2 + Image(:,:,3).^2);  % C
Image(:,:,3) = H;                                        % H
return;

function Image = huetorgb(m0,m2,H)
% Convert HSV or HSL hue to RGB
N = size(H);
H = min(max(H(:),0),360)/60;
m0 = m0(:);
m2 = m2(:);
F = H - round(H/2)*2;
M = [m0, m0 + (m2-m0).*abs(F), m2];
Num = length(m0);
j = [2 1 0;1 2 0;0 2 1;0 1 2;1 0 2;2 0 1;2 1 0]*Num;
k = floor(H) + 1;
Image = reshape([M(j(k,1)+(1:Num).'),M(j(k,2)+(1:Num).'),M(j(k,3)+(1:Num).')],[N,3]);
return;

function H = rgbtohue(Image)
% Convert RGB to HSV or HSL hue
[M,i] = sort(Image,3);
i = i(:,:,3);
Delta = M(:,:,3) - M(:,:,1);
Delta = Delta + (Delta == 0);
R = Image(:,:,1);
G = Image(:,:,2);
B = Image(:,:,3);
H = zeros(size(R));
k = (i == 1);
H(k) = (G(k) - B(k))./Delta(k);
k = (i == 2);
H(k) = 2 + (B(k) - R(k))./Delta(k);
k = (i == 3);
H(k) = 4 + (R(k) - G(k))./Delta(k);
H = 60*H + 360*(H < 0);
H(Delta == 0) = nan;
return;

function Rp = gammacorrection(R)
Rp = real(1.099*R.^0.45 - 0.099);
i = (R < 0.018);
Rp(i) = 4.5138*R(i);
return;

function R = invgammacorrection(Rp)
R = real(((Rp + 0.099)/1.099).^(1/0.45));
i = (R < 0.018);
R(i) = Rp(i)/4.5138;
return;

function fY = f(Y)
fY = real(Y.^(1/3));
i = (Y < 0.008856);
fY(i) = Y(i)*(841/108) + (4/29);
return;

function Y = invf(fY)
Y = fY.^3;
i = (Y < 0.008856);
Y(i) = (fY(i) - 4/29)*(108/841);
return;


function [lin_restr,nonlin_restr,tpl]=create_restrictions_and_markov_chains2(tpl)
% create_restrictions_and_markov_chains2 -- creates restrictions and
% markov chains for the SVAR model in which Coefficients and variances have
% different chains, different regimes, and different durations
%
% ::
%
%
%   [lin_restr,nonlin_restr,tpl]=create_restrictions_and_markov_chains2(tpl)
%
% Args:
%
%    - **tpl** [struct]: template created for SVAR objects
%
% Returns:
%    :
%
%    - **lin_restr** [cell]: two column-cell (see below). The first column
%    contains COEF objects or linear combinations of COEF objects, which are
%    themselves COEF objects.
%
%    - **nonlin_restr** [cell]: one column-cell containing inequality or
%    nonlinear restrictions
%
%    - **tpl** [struct]: modified template
%
% Note:
%
%    - The syntax to construct an advanced COEF object is
%    a=coef(eqtn,vname,lag,chain_name,state)
%      - **eqtn** [integer|char]: integer or variable name
%      - **vname** [integer|char]: integer or variable name
%      - **lag** [integer]: integer or variable name
%      - **chain_name** [char]: name of the markov chain
%      - **state** [integer]: state number
%
%    - RISE sorts the endogenous variables alphabetically and use this order
%    to tag each equation in SVAR and RFVAR models.
%
%    - The lag coefficients are labelled a0, a1, a2,...,ak, for a model with k
%    lags. Obviously, a0 denotes the contemporaneous coefficients.
%
%    - The constant terms labelled c_1_1, c_2_2,...,c_n_n, for a model with n
%    endogenous variables.
%
%    - The standard deviations labelled sig_1_1, sig_2_2,...,sig_n_n, for a
%    model with n endogenous variables.
%
% Example:
%    coef('pi','ygap',0,'policy',1)
%
%    coef(2,3,0,'policy',1)
%
%    coef(2,'ygap',0,'policy',1)
%
%    coef('pi',3,0,'policy',1)
%
%    See also:

% We borrow both the restrictions and the markov chains from the model in
% which all coefficients across all equations switch in lockstep.
%--------------------------------------------------------------------------
[lin_restr,nonlin_restr,tpl]=create_restrictions_and_markov_chains1(tpl);

% Then we add another chain controling all variances across all equations
%-------------------------------------------------------------------------
% We just make sure we do not change the restrictions
last=numel(tpl.markov_chains);
tpl.markov_chains(last+1)=struct('name','syncvol',...
    'states_expected_duration',[2+1i,2+1i,2+1i],...
    'controlled_parameters',{{'sig'}});

end


% RMART - Remove eye artifacts from EEG data using regression with
%           multiple time lags. Each channel is first made mean-zero.
%           After JL Kenemans et al., Psychophysiology 28:114-21, 1991.
%
%   Usage: >> rmart('datafile','outfile',nchans,chanlist,eogchan,[threshold])
% Example: >> rmart('noisy.floats','clean.floats',31,[2:31],7)
%
%   Input:   datafile - input float data file, multiplexed by channel
%            outfile  - name of output float data file
%            nchans   - number of channels in datafile
%            chanlist - indices of EEG channel(s) to process (1,...,nchans)
%            eogchan  - regressing channel indices(s) (1,...,nchans)
%            threshold- abs threshold value to trigger regression {def|0 -> 80}
%
% Output: Writes [length(chanlist),size(data,2)] floats to 'outfile'
%
% Note: Regression epoch length and number of lags are set in the script.
%       Some machines may require a new byte_order value in the script.
%       note that RUNICA -> ICAPROJ should give better results! See
%       Jung et al., Psychophysiology 111:1745-58, 2000.
%
% Author: Tzyy-Ping Jung, SCCN/INC/UCSD, La Jolla, 1997

% Copyright (C) 1997 Tzyy-Ping Jung, SCCN/INC/UCSD, scott@sccn.ucsd.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

% 2-22-97  Tzyy-Ping Jung  CNL/Salk Institute, La Jolla, CA
% 2-24-97  Formatted for ICA package release -Scott Makeig
% 12-10-97 Changed name from rmartifact to rmart for toolbox inclusion -sm
% 12-11-97 Adapted to read/write a float matrix -sm & sw
% 09-14-00 Added comments and help -sm
% 01-25-02 reformated help & license -ad

function rmart(datafile,outfile,nchans,chanlist,eogchan,threshold)

if nargin < 5
   help rmart
   return
end

%
% The following parameters may be fine-tuned for a data set
%
DEF_THRESHOLD = 80; % trigger regression on blocks exceeding this (default)
epoch         = 80; % remove artifacts in successive blocks of this length
nlags         = 40; % perform multiple regression filtering of this length

byte_order    = 'b';% (machine-dependent) byte order code for fopen();
MAKE_MEAN_ZERO = 1  % 1/0 flag removing mean offset from each channel

fprintf('Performing artifact regression on data in %s.\n',datafile);

if nargin<6
   threshold = 0;
end
if threshold == 0,
   threshold = DEF_THRESHOLD;
end
fprintf('Regression threshold %g.\n',threshold);

%
% Read the input data
%
[fid,msg]=fopen(datafile,'r',byte_order); % open datafile
if fid < 3,
  fprintf('rmart() - could not open data file: %s\n',msg);
  exit 1
end
data=(fread(fid,'float'))';
status=fclose('all');
if rem(length(data),nchans) == 0 % check length
   fprintf('rmart() - data length not divisible by %d chans.\n',nchans);
    return
end

data = reshape(data,nchans,length(data)/nchans);
[chans,frames] = size(data);
fprintf('Data of size [%d,%d] read.\n',chans,frames);
eog = data(eogchan,:);
data = data(chanlist,:);
procchans = length(chanlist);

fprintf('Regression epoch length %d frames.\n',epoch);
fprintf('Using %d regression lags.\n',nlags);
if length(eogchan)> 1
  fprintf('Processing %d of %d channels using %d EOG channels.\n',...
                        procchans,chans,length(eogchan));
else
  fprintf('Processing %d of %d channels using EOG channel %d.\n',...
                        procchans,chans,eogchan);
end

%
% Process the data
%
for i=1:procchans
  chan = chanlist(i);
  idx=[];
  frame=1+epoch/2+nlags/2;
  if MAKE_MEAN_ZERO
    data(chan,:) = data(chan,:) - mean(data(chan,:)); % make mean-zero
  end

  % Search the EOG & EEG records for values above threshold,
  % Selected frame numbers are registered in the variable "idx".
  % The entries in "idx" are at least epoch apart to avoid double
  % compensation (regression) on the same portion of the EEG data.

  while frame <= length(eog)-epoch/2-nlags/2,  % foreach epoch in channel
    stop = min(frame+epoch-1,eogframes);
    tmp= ...
        find( abs(eog(frame:stop)) >= threshold ...
             | abs(data(chan,frame:stop)) >= threshold);
                                           % find beyond-threshold values
    if length(tmp) ~= 0
      mark = tmp(1)+frame-1;
      if  length(idx) ~= 0
        if mark-idx(length(idx))  < epoch,
           idx=[idx idx(length(idx))+epoch]; % To guarantee idx(i) & idx(i-1)
                                             % are at least EPOCH points apart
           frame = idx(length(idx))+epoch/2;
        else
           idx=[idx mark];
           frame = mark + epoch/2;
        end
      else
        idx=[idx mark];
        frame = mark + epoch/2;
      end
    else
      frame=frame+epoch;
    end
  end % while

  % For each registered frame, take "epoch" points
  % surrounding it from the EEG, and "epoch + lag" points
  % from the EOG channel. Then perform multivariate
  % linear regression on EEG channel.

  for j=1:length(idx);
     art=ones(1,epoch);
     eogtmp=eog(idx(j)-epoch/2-nlags/2:idx(j)+epoch/2-1+nlags/2);

     % Collect EOG data from lag/2 points before to lag/2 points
     % after the regression window.
     for J=nlags:-1:1,
       art=[art ; eogtmp(J:J+epoch-1)];
     end
     eegtmp=data(chan,idx(j)-epoch/2:idx(j)+epoch/2-1);

     eegeog=eegtmp*art';        % perform the regression here
     eogeog=art*art';
     b=eegeog/eogeog;
     eegtmp=eegtmp-b*art;
     data(chan,idx(j)-epoch/2:idx(j)+epoch/2-1)=eegtmp;
   end % j
end % i

%
% Write output file
%
[fid,msg]=fopen(outfile,'w',byte_order);
if fid < 3
  fprintf('rmart() - could not open output file: %s\n',msg);
  return
end
count = fwrite(fid,data,'float');
if count == procchans*frames,
  fprintf('Output file "%s" written, size = [%d,%d] \n\n',...
             outfile,procchans,frames);
else
  fprintf('rmart(): Output file "%s" written, SIZE ONLY [%d,%g]\n',...
             outfile,procchans,count/procchans);
end
fclose('all');


% pop_erpparams() - Set plotting and statistics parameters for cluster ERP
%                   plotting
% Usage:
%   >> STUDY = pop_erpparams(STUDY, 'key', 'val');
%
% Inputs:
%   STUDY        - EEGLAB STUDY set
%
% Statistics options:
%   'groupstats  - ['on'|'off'] Compute (or not) statistics across groups.
%                  {default: 'off'}
%   'condstats'  - ['on'|'off'] Compute (or not) statistics across groups.
%                  {default: 'off'}
%   'topotime'   - [real] Plot ERP scalp maps at one specific latency (ms).
%                   A latency range [min max] may also be defined (the
%                   ERP is then averaged over the interval) {default: []}
%   'statistics' - ['param'|'perm'|'bootstrap'] Type of statistics to compute
%                  'param' for parametric (t-test/anova); 'perm' for
%                  permutation-based and 'bootstrap' for bootstrap
%                  {default: 'param'}
%   'naccu'      - [integer] Number of surrogate averages to accumulate for
%                  surrogate statistics. For example, to test whether
%                  p<0.01, use >=200. For p<0.001, use 'naccu' >=2000.
%                  If a threshold (not NaN) is set below, and 'naccu' is
%                  too low, it will be automatically reset. (This option
%                  is now available only from the command line).
%   'threshold'  - [NaN|float<<1] Significance probability threshold.
%                  NaN -> plot the p-values themselves on a different axis.
%                  When possible, the significant time regions are indicated
%                  below the data.
%   'mcorrect'   - ['fdr'|'none'] correction for multiple comparisons
%                  (threshold case only). 'fdr' uses false discovery rate.
%                  See the fdr function for more information. Defaut is
%                  'none'.
% Plot options:
%   'timerange'  - [min max] ERP plotting latency range in ms.
%                  {default: the whole epoch}
%   'ylim'       - [min max] ERP limits in microvolts {default: from data}
%   'plotgroups' - ['together'|'apart'] 'together' -> plot subject groups
%                  on the same axis in different colors, else ('apart')
%                  on different axes. {default: 'apart'}
%   'plotconditions' - ['together'|'apart'] 'together' -> plot conditions
%                  on the same axis in different colors, else ('apart')
%                  on different axes. Note: Keywords 'plotgroups' and
%                  'plotconditions' may not both be set to 'together'.
%                  {default: 'together'}
% See also: std_erpplot()
%
% Authors: Arnaud Delorme, CERCO, CNRS, 2006-

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

function [ STUDY, com ] = pop_erpparams(STUDY, varargin);

STUDY = default_params(STUDY);
STUDY.etc.erpparams = pop_statparams(STUDY.etc.erpparams, 'default');
TMPSTUDY = STUDY;
com = '';
if isempty(varargin)

    enablecond  = fastif(length(STUDY.design(STUDY.currentdesign).variable(1).value)>1, 'on', 'off');
    enablegroup = fastif(length(STUDY.design(STUDY.currentdesign).variable(2).value)>1, 'on', 'off');
    plotconditions    = fastif(strcmpi(STUDY.etc.erpparams.plotconditions, 'together'), 1, 0);
    plotgroups  = fastif(strcmpi(STUDY.etc.erpparams.plotgroups,'together'), 1, 0);
    vis = fastif(isnan(STUDY.etc.erpparams.topotime), 'off', 'on');

    uilist = { ...
        {'style' 'text'       'string' 'Time range in ms [low high]'} ...
        {'style' 'edit'       'string' num2str(STUDY.etc.erpparams.timerange) 'tag' 'timerange' } ...
        {'style' 'text'       'string' 'Plot limits in uV [low high]'} ...
        {'style' 'edit'       'string' num2str(STUDY.etc.erpparams.ylim) 'tag' 'ylim' } ...
        {'style' 'text'       'string' 'Plot scalp map at latency [ms]' 'enable' vis } ...
        {'style' 'edit'       'string' num2str(STUDY.etc.erpparams.topotime) 'tag' 'topotime' 'enable' vis } ...
        {'style' 'text'       'string' 'Display filter in Hz [high]' } ...
        {'style' 'edit'       'string' num2str(STUDY.etc.erpparams.filter) 'tag' 'filter' } ...
        {} {'style' 'checkbox'   'string' 'Plot first variable on the same panel' 'value' plotconditions 'enable' enablecond  'tag' 'plotconditions' } ...
        {} {'style' 'checkbox'   'string' 'Plot second variable on the same panel' 'value' plotgroups 'enable' enablegroup 'tag' 'plotgroups' } };

    cbline = [0.07 1.1];
    otherline = [ 0.7 .5 0.6 .5];
    geometry = { otherline otherline cbline cbline };

    [STUDY.etc.erpparams res options] = pop_statparams(STUDY.etc.erpparams, 'geometry' , geometry, 'uilist', uilist, ...
                                   'helpcom', 'pophelp(''std_erpparams'')', 'enablegroup', enablegroup, ...
                                   'enablecond', enablecond, ...
                                   'title', 'Set ERP plotting parameters -- pop_erpparams()');

    if isempty(res), return; end;

    % decode inputs
    % -------------
    %if res.plotgroups & res.plotconditions, warndlg2('Both conditions and group cannot be plotted on the same panel'); return; end;
    if res.plotgroups, res.plotgroups = 'together'; else res.plotgroups = 'apart'; end;
    if res.plotconditions , res.plotconditions  = 'together'; else res.plotconditions  = 'apart'; end;
    res.topotime  = str2num( res.topotime );
    res.timerange = str2num( res.timerange );
    res.ylim      = str2num( res.ylim );
    res.filter    = str2num( res.filter );

    % build command call
    % ------------------
    if ~strcmpi( char(res.filter), char(STUDY.etc.erpparams.filter)), options = { options{:} 'filter' res.filter }; end;
    if ~strcmpi( res.plotgroups, STUDY.etc.erpparams.plotgroups), options = { options{:} 'plotgroups' res.plotgroups }; end;
    if ~strcmpi( res.plotconditions , STUDY.etc.erpparams.plotconditions ), options = { options{:} 'plotconditions'  res.plotconditions  }; end;
    if ~isequal(res.ylim     , STUDY.etc.erpparams.ylim),      options = { options{:} 'ylim' res.ylim       }; end;
    if ~isequal(res.timerange, STUDY.etc.erpparams.timerange), options = { options{:} 'timerange' res.timerange }; end;
    if (all(isnan(res.topotime)) & all(~isnan(STUDY.etc.erpparams.topotime))) | ...
            (all(~isnan(res.topotime)) & all(isnan(STUDY.etc.erpparams.topotime))) | ...
                (all(~isnan(res.topotime)) & ~isequal(res.topotime, STUDY.etc.erpparams.topotime))
        options = { options{:} 'topotime' res.topotime };
    end;
    if ~isempty(options)
        STUDY = pop_erpparams(STUDY, options{:});
        com = sprintf('STUDY = pop_erpparams(STUDY, %s);', vararg2str( options ));
    end;
else
    if strcmpi(varargin{1}, 'default')
        STUDY = default_params(STUDY);
    else
        for index = 1:2:length(varargin)
            STUDY.etc.erpparams = setfield(STUDY.etc.erpparams, varargin{index}, varargin{index+1});
        end;
    end;
end;

% scan clusters and channels to remove erpdata info if timerange has changed
% ----------------------------------------------------------
if ~isequal(STUDY.etc.erpparams.timerange, TMPSTUDY.etc.erpparams.timerange)
    if isfield(STUDY.cluster, 'erpdata')
        for index = 1:length(STUDY.cluster)
            STUDY.cluster(index).erpdata  = [];
            STUDY.cluster(index).erptimes = [];
        end;
    end;
    if isfield(STUDY.changrp, 'erpdata')
        for index = 1:length(STUDY.changrp)
            STUDY.changrp(index).erpdata  = [];
            STUDY.changrp(index).erptimes = [];
        end;
    end;
end;

function STUDY = default_params(STUDY)
    if ~isfield(STUDY.etc, 'erpparams'), STUDY.etc.erpparams = []; end;
    if ~isfield(STUDY.etc.erpparams, 'topotime'),    STUDY.etc.erpparams.topotime = []; end;
    if ~isfield(STUDY.etc.erpparams, 'filter'),     STUDY.etc.erpparams.filter = []; end;
    if ~isfield(STUDY.etc.erpparams, 'timerange'),  STUDY.etc.erpparams.timerange = []; end;
    if ~isfield(STUDY.etc.erpparams, 'ylim'     ),  STUDY.etc.erpparams.ylim      = []; end;
    if ~isfield(STUDY.etc.erpparams, 'plotgroups') , STUDY.etc.erpparams.plotgroups = 'apart'; end;
    if ~isfield(STUDY.etc.erpparams, 'plotconditions') ,  STUDY.etc.erpparams.plotconditions  = 'apart'; end;


function [gx] = g_nl0(x,P,u,in)

try
    gx = P(1)*exp(P(2)*in.x);
catch
    gx = x(1)*exp(x(2)*P);
end


% -------------------------------------------------------------------------
clear all; close all;

%connection settings
number_of_retries = 1; % set to -1 for infinite
port=2057; % This code use for communication "port" and "port+1"
host='localhost';
samplingrate=1000; %in ms

while(true)
    data_to_send=['|',regexprep(num2str(randn(1),6),'\.',','),'|',regexprep(num2str(randn(1),6),'\.',',')];
    data_received=exchangeData(port,host,number_of_retries,samplingrate,data_to_send)
    if(numel(data_received)>0 )
        % Do your stuff with the data
    end;
end


function [state] = tapas_mcmc_meta_adaptive_ti(data, model, inference, ...
    state, states, si)
%%
%
% Input
%
% Output
%

% aponteeduardo@gmail.com
% copyright (C) 2016
%

if state.nsample > inference.nburnin || mod(si, inference.ndiag)
    return;
end

% Number of subjects and chains
[ns, nc] = size(states{6}.llh{1});

% No real adapation is possible
if nc <= 4
    return;
end

llh = zeros(nc, inference.ndiag);
g = [];
for i = 1:inference.ndiag
    llh(:, i) = sum(states{i}.llh{1}, 1);
    if any(isnan(llh(:, i))) || any(abs(llh(:, i)) == inf);
        g = [g i];
    end
end

% Remove nans if any
llh(:, g) = [];
t = state.T{1}(1, :)';

% Maybe something is not working with the first derivatives.
% Let's try to find a workable schedule
for i = 1:nc - 4
    try
        [~, ~, nt] = tapas_genpath(t, llh, i, 'hermite');
        % It worked
        break
    catch
        % Ok keep going
    end
end

% It is a mess and we could not estimate anything
if i == nc - 4
    return
else
    nt = [t(1:i - 1); nt];
end

% Update the temperature schedule
state.T{1} = repmat(nt', ns, 1);
hold on; plot(mean(llh, 2));
end


function output = brtTest( input, brtModel, varargin )

    if isempty(varargin)
        len = length(brtModel)-1;
    else
        len = varargin{1};
    end

    nu = brtModel{end};
    output = brtModel{1};

    for i=2:len
        output = output + nu * regressionTreeTest( input, brtModel{i} );
    end
end


function [data3d] = augmentPascal3Ddata(data,class)
%AUGMENTPASCAL3DDATA Summary of this function goes here
%   Detailed explanation goes here

N = length(data);
globals;
load(fullfile(datadir,'subtypeClusters'));
data3d = data;
cInd = pascalClassIndex(class);
notFound = 0;
for i=1:N
    bbox = data(i).bbox;
    if(data(i).flip)
        bbox(1) = data(i).imsize(2) + 1 - bbox(1) - bbox(3);
    end
    bbox(3:4) = bbox(1:2)+bbox(3:4)-1;
    pascal3Dfile = fullfile(PASCAL3Ddir,'Annotations',[class '_pascal'],[data(i).voc_image_id '.mat']);
    if(exist(pascal3Dfile,'file'))
      record = load(pascal3Dfile);record = record.record;
      bboxes = vertcat(record.objects(:).bbox);
      bboxes(~strcmp(class,{record.objects(:).class}),:) = 0;
      objectInd = (bboxOverlap(bbox,bboxes,0.9));
      if(objectInd)
          viewpoint = record.objects(objectInd).viewpoint;
          [rot,euler] = viewpointToRots(viewpoint);
          data3d(i).rotP3d=rot;
          data3d(i).euler=euler;
          data3d(i).subtype = record.objects(objectInd).cad_index;
          data3d(i).subtype = subtypeClusters{cInd}(data3d(i).subtype);
      end
      data3d(i).objectIndP3d = objectInd;
      if(data3d(i).flip)
          data3d(i).euler = data3d(i).euler.*[-1;1;-1];
          rotX = diag([1,-1,-1]);
          data3d(i).rotP3d = rotX*angle2dcm(data3d(i).euler(1), data3d(i).euler(2)-pi/2, -data3d(i).euler(3),'ZXZ')';
      end
      %disp('blah')
    else
        notFound = notFound+1;
        data3d(i).rotP3d = nan(3,3);
        data3d(i).euler = nan(3,1);
        data3d(i).subtype = nan;
        data3d(i).objectIndP3d = nan;
    end

end

if(notFound~=0)
    fprintf('PASCAL 3D annotations not found - %d\n',notFound);
end
end

function [R,euler] = viewpointToRots(vp)
        euler = [vp.azimuth vp.elevation vp.theta]' .* pi/180;
        rotX = diag([1,-1,-1]);
        R1 = angle2dcm(euler(3), euler(2)-pi/2, -euler(1),'ZXZ'); %took a lot of work to figure this formula out !!
        euler = euler([3 2 1]);
        R = rotX*R1';
end

function isSame = bboxOverlap(bbox1,bboxes,thresh)
    bboxes(:,3:4) = [bboxes(:,3)-bboxes(:,1) bboxes(:,4)-bboxes(:,2)];
    bbox1(3:4) = [bbox1(:,3)-bbox1(:,1) bbox1(:,4)-bbox1(:,2)];
    intersectionArea=rectint(bbox1,bboxes);
    x_g = bbox1(1); y_g = bbox1(2);
    x_p = bboxes(:,1); y_p = bboxes(:,2);
    width_g = bbox1(3); height_g = bbox1(4);
    width_p = bboxes(:,3); height_p = bboxes(:,4);
    unionCoords=[min(x_g,x_p),min(y_g,y_p),max(x_g+width_g-1,x_p+width_p-1),max(y_g+height_g-1,y_p+height_p-1)];
    unionArea=(unionCoords(:,3)-unionCoords(:,1)+1).*(unionCoords(:,4)-unionCoords(:,2)+1);
    overlapArea=intersectionArea(:)./unionArea(:);
    [~,isSame] = max(overlapArea);
end


function out = spm_run_dcm_bms_vis(job)
% Review BMS results
%__________________________________________________________________________
% Copyright (C) 2008-2014 Wellcome Trust Centre for Neuroimaging

% CC Chen and Maria Joao Rosa
% $Id: spm_run_dcm_bms_vis.m 6005 2014-05-21 16:46:26Z guillaume $

if ~nargin || isempty(job.bmsmat{1})
    [bmsmat, sts] = spm_select(1,'^BMS\.mat$','Select BMS.mat');
    if ~sts, out = []; return; end
else
    bmsmat = job.bmsmat{1};
end

try
    load(bmsmat);
catch
    error('Cannot load file: %s', bmsmat);
end

lab = {};
val = {};
if isfield(BMS.DCM,'ffx')
    lab = [lab 'Fixed'];
    val = [val 'ffx'];
end
if isfield(BMS.DCM,'rfx')
    lab = [lab 'Random'];
    val = [val 'rfx'];
end
if numel(val) == 2
    lab = [lab 'Bye'];
    val = [val {''}];
end

method = '?';

while ~isempty(method)

    method = spm_input('Inference method','0','b',lab,char(val),numel(val));

    switch method

        case 'ffx'

            N   = size(BMS.DCM.ffx.F,2);
            N   = 1:N;
            out = spm_api_bmc(BMS.DCM.ffx.SF,N);

            if ~isfield(BMS.DCM,'rfx'), method = ''; end

        case 'rfx'

            N   = size(BMS.DCM.rfx.F,2);
            N   = 1:N;
            if isfield(BMS.DCM.rfx,'model')
                out = spm_api_bmc(BMS.DCM.rfx.SF,...
                    N,BMS.DCM.rfx.model.exp_r,BMS.DCM.rfx.model.xp);
            else % Older version (prior to family level)
                out = spm_api_bmc(BMS.DCM.rfx.SF,...
                    N,BMS.DCM.rfx.exp_r,BMS.DCM.rfx.xp);
            end

            if ~isfield(BMS.DCM,'ffx'), method = ''; end

    end

    spm_input('Thank you',1,'d');

end


function [score alignment] = ScanMatch(seq1, seq2, ScanMatchInfo, varargin)
%SCANMATCH compares two sequences using the Needleman-Wunsch
% algorithm providing a GUI is needed to display the results.
%   SCORE = SCANMATCH(SEQ1, SEQ2, SCANMATCHINFO) where SEQ1 and SEQ2 are
%   two double strings (where a single fixation is represented by two
%   characters). SCANMATCHINFO is a structure containing all the parameters
%   needed to perform the comparison and must contain the following fields:
%
%           .Xres
%           .Yres
%           .Xbin
%           .Ybin
%     .RoiModulus
%      .Threshold
%       .GapValue
%        .TempBin
%      .SubMatrix
%           .mask
%
%   As an extra input parameter 'ShowViewer'm can be set to 1 to display the
%   GUI. If not set at all or set to zero the Gui will be not shown.
%
%   SCORE is the normalised result of the alignment. The closest SCORE is
%   to one the more related the two sequences are. Alignment output the
%   alignment of the two sequences. This is quite computationally expensive
%   hence if not needed call the function as follow:
%           score = ScanMatch(seq1, seq2, ScanMatchInfo)
%
%   Part of the ScanMatch toolbox
%   Written by Filipe Cristino
%   $Version: 1.00 $  $Date: 10/09/2009

% Check the input parameters
okargs = {'ShowViewer'};
if nargin == 3
    ShowViewer = 0; % if not specified then don't show
else
    if strcmp(varargin(1), okargs)
        ShowViewer = varargin{2};
    else
        error('ScanMatch:InvalidInput','Invalid parameter: %s', char(varargin(1)));
    end
end

% Check if the ScanMatchInfo structure is of the right form
Ok = ScanMatch_CheckStructure(ScanMatchInfo);

% use numerical arrays for easy indexing
if ischar(seq1)
    intseq1 = uint8(ScanMatch_DoubleStrToNum(seq1,ScanMatchInfo.RoiModulus));
else
    intseq1 = double(seq1);
    seq1 = ScanMatch_NumToDoubleStr(intseq1,ScanMatchInfo.RoiModulus);
end
if ischar(seq2)
    intseq2 = uint8(ScanMatch_DoubleStrToNum(seq2,ScanMatchInfo.RoiModulus));
else
    intseq2 = double(seq2);
    seq2 = ScanMatch_NumToDoubleStr(intseq2,ScanMatchInfo.RoiModulus);
end

% Check for the sequences lenghts >0 and that they are even

m = length(seq1);
n = length(seq2);

if  ~n||~m || mod(m,2)||mod(n,2)
    error('ScanMatch:InvalidLengthSequences','Length of input sequences must be greater than 0 and even');
end

m = length(intseq1);
n = length(intseq2);

% Perform the Needleman-Wunsch alogorithm
[score path step F] = ScanMatch_nwAlgo(intseq1,m,intseq2,n,ScanMatchInfo.SubMatrix,ScanMatchInfo.GapValue);

% Normalise output score
max_sub = max(ScanMatchInfo.SubMatrix(:));
scale = max_sub * max(m,n);
score = score / scale;

% if alignment output is not needed then exit now (faster)
if nargout<=1 && ~ShowViewer
    return
end

path(step:end,:) = []; % step-1 is the length of the alignment
path = flipud(path);

%double the path to take into account the double string
p1 = interp1(1:step-1,double(path(:,1)),fix(1:0.5:step-1+0.5),'nearest');
p2 = interp1(1:step-1,double(path(:,2)),fix(1:0.5:step-1+0.5),'nearest');
path = [p1' p2'];

% setting the size of the alignment
n_l = (step-1)*2;
alignment = repmat(('- -')',1,n_l);

% adding sequence to alignment
alignment(1,path(:,1)>0) = seq1;
alignment(3,path(:,2)>0) = seq2;

% find locations where there are no gaps
h=find(all(path>0,2));
noGaps1=ScanMatch_DoubleStrToNum(alignment(1,h),ScanMatchInfo.RoiModulus);
noGaps2=ScanMatch_DoubleStrToNum(alignment(3,h),ScanMatchInfo.RoiModulus);

% score pairs with no gap
value = ScanMatchInfo.SubMatrix(sub2ind(size(ScanMatchInfo.SubMatrix),double(noGaps1),double(noGaps2)));
value = interp1(1:length(value),value,fix(1:0.5:length(value)+0.5),'nearest');

% insert symbols of the match string into the alignment
alignment(2,h(value>=0)) = ':';
alignment(2,h(value==max(ScanMatchInfo.SubMatrix(:)))) = '|';

if ShowViewer == 1 % display the Gui viewer

    % Set some variable
    res_size = [800 380];

    % Create and setup figure
    fh = figure('Position',[200 200 res_size],'Toolbar','none', ...
                'name', 'String Alignment Viewer','NumberTitle', 'off',...
                'MenuBar', 'none', 'Color', [0.95,0.95,0.95],'wvisual','27');

    uicontrol('Style','text', ...
                    'String','Alignment Results',...
                    'Position', [res_size(1)/2 - 100 res_size(2)-25 200 25], 'Fontsize', 16);

    ah2 = axes('Parent',fh,'units','pixels',...
               'Position',[40 40 280 180 ],...
               'Visible', 'off',...
               'DataAspectRatioMode','auto'...
           );

    % Display the Score matrix and winning path
    F=scale.*max(F(2:end,2:end,:),[],3);
    clim=max(max(max(abs(F(~isinf(F))))),eps);
    imagesc(F,[-clim clim]);
    colormap(privateColorMap(1));
    set(colorbar,'YLim',[min([F(:);-eps]) max([F(:);eps])])
    title('Scoring Space and Winning Path')
    xlabel('Sequence 1')
    ylabel('Sequence 2')
    hold on
    plot(path(all(path>0,2),1),path(all(path>0,2),2),'k.')

    % Create display for the strings
    S_r = 20;
    y_p = 290;

    ah3 = axes('Parent',fh,'units','pixels',...
               'Position',[0 y_p res_size(1) 61 ],...
               'Visible', 'on',...
               'DataAspectRatioMode','auto'...
           );
    axis off
    set(ah3,'xlim',[0 800]);
    set(ah3,'ylim',[0 60]);

    [th,ws] = create_display_string(alignment,ah3,0, S_r, res_size);

    % Do slider for roling window
    SliderW = uicontrol('Parent', fh, 'Style', 'slider',...
                   'Position', [20 y_p-30 res_size(1)-40  20],...
                   'Min', 0, ...
                   'Max', ws - 800, ...
                   'Tag', 'SliderWindow', ...
                   'SliderStep', [0.05 0.2] ,...
                   'Callback',{@popup_menu_Callback} );

    % show scores
    uicontrol('Style','text', ...
                    'String','Score:',...
                    'Position', [330 120 160 40],'FontSize', 18);
    Scorea = uicontrol('Style','text', ...
                    'String',score,...
                    'Position', [330 40 160 60], 'ForegroundColor', [1 0 0], 'FontSize', 24);

    % Display ScanMatchInfo parameters
    ah1 = uipanel('units','pixels',...
               'Position',[520 0 279 239]...
           );

    uicontrol(ah1,'Style','text', ...
                    'String','Parameters',...
                    'Position', [0 210 270 25], 'FontSize', 16);

    uicontrol(ah1,'Style','text', ...
                    'String','Alignment algorithm:',...
                    'Position', [5 170 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String','Needleman-Wunsch',...
                    'Position', [145 170 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold', 'HorizontalAlignment', 'left');

    uicontrol(ah1,'Style','text', ...
                    'String','Gap value:',...
                    'Position', [5 150 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String',num2str(ScanMatchInfo.GapValue),...
                    'Position', [145 150 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold','HorizontalAlignment', 'left');

    uicontrol(ah1,'Style','text', ...
                    'String','Substitution threshold:',...
                    'Position', [5 130 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String',num2str(ScanMatchInfo.Threshold),...
                    'Position', [145 130 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold','HorizontalAlignment', 'left');

    uicontrol(ah1,'Style','text', ...
                    'String','RoI modulus:',...
                    'Position', [5 110 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String',num2str(ScanMatchInfo.RoiModulus),...
                    'Position', [145 110 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold','HorizontalAlignment', 'left');

    uicontrol(ah1,'Style','text', ...
                    'String','Temporal Bin size:',...
                    'Position', [5 90 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String',[num2str(ScanMatchInfo.TempBin) ' ms'],...
                    'Position', [145 90 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold','HorizontalAlignment', 'left');

    uicontrol(ah1,'Style','text', ...
                    'String','Stimuli Resolution:',...
                    'Position', [5 70 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String',[num2str(ScanMatchInfo.Xres) ' x ' num2str(ScanMatchInfo.Yres) ' pixels'],...
                    'Position', [145 70 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold','HorizontalAlignment', 'left');

    uicontrol(ah1,'Style','text', ...
                    'String','Number of bins:',...
                    'Position', [5 50 130 20], 'FontSize', 10, ...
                    'HorizontalAlignment', 'right');

    uicontrol(ah1,'Style','text', ...
                    'String',[num2str(ScanMatchInfo.Xbin) ' x ' num2str(ScanMatchInfo.Ybin) ],...
                    'Position', [145 50 130 20], 'FontSize', 10, ...
                    'FontWeight', 'bold','HorizontalAlignment', 'left');
end

function popup_menu_Callback(source,eventdata)
% This function is Nested hence all variables are globals.
      pop_menu = get(source,'Tag');
      switch pop_menu
          case 'SliderGap'
              set(fh,'CurrentAxes',ah2)
              GapValue = get(source,'Value');
              [score, data]=nwalignds(StringA, StringB,'ScoringMatrix',Transition_dist, 'GapOpen', GapValue,'SHOWSCORE', true);
              set(Scorea, 'string', num2str(score));
              set(Gapa, 'string', ['Gap value: ' num2str(GapValue)]);
              set(fh,'CurrentAxes',ah3)
              delete(th); % delete old display
              [th ws] = create_display_string(data,ah3,0, S_r,info); % Create new display for the strings
              set(SliderW, 'Value', 0);
              set(SliderW, 'Max', ws-800);
          case 'Transition_mat'

          case 'SliderWindow'
              dx = get(source,'Value');
              set(ah3,'xlim',[dx 800+dx]);

      end
end

end

function [th, ws] = create_display_string(data,ah3,y_p, S_r, res_size)

n_string = size(data,2)/2; % IF MORE THAN 30 YOU SHOULD SHOW A SCROOLING BAR!
if n_string > 25
   S_c = res_size(1)/25;
else
    S_c = res_size(1)/n_string-1;
end
ws = n_string * S_c;
th = zeros(3,n_string);
tic
for i=1:3
    x_p = S_c/2;
    ind=1;
    for j=1:n_string
    switch data(2,ind)
        case '|'
            col = [0 0 0];
        case ':'
            col = [1 0 0];
        case ' '
            col = [0 0 1];
    end

    th(i,j)=text('parent', ah3', 'Position', [x_p y_p], ...
            'string', data(i,ind:ind+1), 'color', col,'HorizontalAlignment', 'center' );
    x_p = x_p + S_c;
    ind = ind +2;
    end
    y_p = y_p + S_r;
end

toc
end

function pcmap = privateColorMap(selection)
%PRIVATECOLORMAP returns a custom color map
switch selection
    case 1, pts = [0 0 .3 20;
            0 .1 .8 25;
            0 .9 .5 15;
            .9 1 .9 8;
            1 1 0 26;
            1 0 0 26;
            .4 0 0 0];
    otherwise, pts = [0 0 0 128; 1 1 1 0];
end
xcl=1;
for i=1:size(pts,1)-1
    xcl=[xcl,i+1/pts(i,4):1/pts(i,4):i+1];
end
pcmap = interp1(pts(:,1:3),xcl);
end


% Add local code directories to Matlab path
% addpaths;

imdir='../Images_resized/'; % directory with original images

workspcdir='../tempworkspace/'; % directory to save intermediate results
if ~exist(workspcdir,'dir')
    mkdir(workspcdir);
end

resdir='../Results/'; % This is where we will save final results using this demo script.
if ~exist(resdir,'dir')
    mkdir(resdir);
end

% You can run it on a single image as follows
imagename='indoor_0268.jpg';
[ boxlayout,surface_labels ] = getspatiallayout(imdir,imagename,workspcdir);


clear; close all;
%% settings
folder = '291-aug/';  % 291 augment dataset
savepath = 'train_hdf5/train_x2.h5';  % save filename
size_input = 29; % 29 | 39
size_label = 57; % 57 | 77
scale = 2; % upsacling factor
stride = 29; % subimages sampling stride

%% initialization
data = zeros(size_input, size_input, 1, 1);
label = zeros(size_label, size_label, 1, 1);
bic = zeros(size_label, size_label, 1, 1);
count_input = 0;
count_label = 0;
count_bic = 0;

%% generate data
filepaths=dir(fullfile(folder,'*.bmp'));

for i = 1 :length(filepaths)

    image = imread(fullfile(folder, filepaths(i).name));
    if size(image,3) == 1
        continue;
    end

    image = rgb2ycbcr(image);
    image = im2double(image(:, :, 1)); % uint8 to double, ranges from [16/255, 235/255]

    im_label = modcrop(image, scale); % high resolution subimage
    im_input = imresize(im_label, 1/scale, 'bicubic'); % low resolution subimage
    im_bic=imresize(im_input,scale,'bicubic'); % interpolated low resolution subimage

    [hei,wid] = size(im_input); % LR subimage size
    [hei_label,wid_label]=size(im_label);% HR subimage size
    stride_label=stride*scale;
    % two-step cut
    % data
    for x = 1 : stride : hei - size_input + 1
        for y = 1 : stride : wid - size_input + 1
            subim_input = im_input(x : size_input + x - 1, y : size_input + y - 1);
            count_input = count_input + 1;
            data(:, :, 1, count_input) = subim_input;
        end

    end

    % label
    for x = 1 : stride_label : hei_label -size_label + 1
        for y = 1 : stride_label : wid_label -size_label +1
            locx=x+scale-1;
            locy=y+scale-1;
            subim_label=im_label(locx:size_label+locx-1,locy:size_label+locy-1);
            count_label=count_label+1;
            label(:, :, 1, count_label)=subim_label;
        end
    end

    % bicubic
    for x = 1 : stride_label : hei_label -size_label + 1
        for y = 1 : stride_label : wid_label -size_label +1
            locx=x+scale-1;
            locy=y+scale-1;
            subim_bic=im_bic(locx:size_label+locx-1,locy:size_label+locy-1);
            count_bic=count_bic+1;
            bic(:,:,1,count_bic)=subim_bic;
        end
    end

end

assert(count_label==count_input, 'Number of samples should be matched between data and labels');
count=count_label;

order = randperm(count);
data = data(:, :, 1, order);
label = label(:, :, 1, order);
bic = bic(:, :, 1, order);

%% writing to HDF5
chunksz = 64; % chunksize
created_flag = false;
totalct = 0;

for batchno = 1:floor(count/chunksz)
    last_read = (batchno-1)*chunksz;
    batchdata = data(:,:,1,last_read+1:last_read+chunksz);
    batchlabs = label(:,:,1,last_read+1:last_read+chunksz);
    batchbic = bic(:,:,1,last_read+1:last_read+chunksz);

    startloc = struct('dat',[1,1,1,totalct+1], 'lab', [1,1,1,totalct+1], 'bic', [1,1,1,totalct+1]);
    curr_dat_sz = store2hdf5(savepath, batchdata, batchlabs, batchbic, ~created_flag, startloc, chunksz);
    created_flag = true;
    totalct = curr_dat_sz(end);
end
h5disp(savepath);


function test_bug2508

% MEM 1gb
% WALLTIME 00:10:00
% DEPENDENCY ft_selectdata ft_selectdata_new

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% check the averaging over dimensions for a simple timelock structure

timelock = [];
timelock.label = {'1', '2', '3'};
timelock.time = 1:5;
timelock.avg = randn(3,5);
timelock.dimord = 'chan_time';

cfg = [];
cfg.avgoverchan = 'no';
cfg.avgovertime = 'no';
output = ft_selectdata(cfg, timelock);

assert(length(output.label)==3, 'error in output labels');
assert(length(output.time)==5,  'error in output time');

cfg = [];
cfg.avgoverchan = 'yes';
cfg.avgovertime = 'no';
output = ft_selectdata(cfg, timelock);

assert(length(output.label)==1, 'error in output labels');
assert(length(output.time)==5,  'error in output time');

cfg = [];
cfg.avgoverchan = 'no';
cfg.avgovertime = 'yes';
output = ft_selectdata(cfg, timelock);

assert(length(output.label)==3, 'error in output labels');
assert(length(output.time)==1,  'error in output time');

cfg = [];
cfg.avgoverchan = 'yes';
cfg.avgovertime = 'yes';
output = ft_selectdata(cfg, timelock);

assert(length(output.label)==1, 'error in output labels');
assert(length(output.time)==1,  'error in output time');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% continue with timelock, now with repetitions

timelock = [];
timelock.label = {'1', '2', '3'};
timelock.time = 1:5;
timelock.trial = randn(2,3,5);
timelock.dimord = 'rpt_chan_time';

cfg = [];
cfg.avgoverchan = 'no';
cfg.avgovertime = 'no';
cfg.avgoverrpt = 'no';
output = ft_selectdata(cfg, timelock);

assert(isequal(size(output.trial), [2 3 5]), 'error in output data size');
assert(length(output.label)==3, 'error in output labels');
assert(length(output.time)==5,  'error in output time');

cfg = [];
cfg.avgoverchan = 'no';
cfg.avgovertime = 'no';
cfg.avgoverrpt = 'yes';
output = ft_selectdata(cfg, timelock);

assert(isequal(size(output.trial), [3 5]), 'error in output data size'); % note the confusing average field name output.trial
assert(length(output.label)==3, 'error in output labels');
assert(length(output.time)==5,  'error in output time');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% now see what happens when some fields are not kept

cfg = [];
cfg.avgoverchan = 'yes';
cfg.avgovertime = 'yes';
cfg.avgoverrpt  = 'yes';
cfg.keeprptdim  = 'yes';
cfg.keeptimedim = 'yes';
cfg.keepchandim = 'yes';
output = ft_selectdata(cfg, timelock);

assert(strcmp(output.dimord, 'rpt_chan_time'), 'incorrect dimord');
assert(numel(output.trial)==1, 'error in output data size'); % note the confusing average field name output.trial
assert(length(output.label)==1, 'error in output labels');
assert(length(output.time)==1,  'error in output time');

cfg = [];
cfg.avgoverchan = 'yes';
cfg.avgovertime = 'yes';
cfg.avgoverrpt  = 'yes';
cfg.keeprptdim  = 'no';
cfg.keeptimedim = 'yes';
cfg.keepchandim = 'yes';
output = ft_selectdata(cfg, timelock);

assert(strcmp(output.dimord, 'chan_time'), 'incorrect dimord');
assert(numel(output.trial)==1, 'error in output data size'); % note the confusing average field name output.trial
assert(length(output.label)==1, 'error in output labels');
assert(length(output.time)==1,  'error in output time');

cfg = [];
cfg.avgoverchan = 'yes';
cfg.avgovertime = 'yes';
cfg.avgoverrpt  = 'yes';
cfg.keeprptdim  = 'no';
cfg.keeptimedim = 'no';
cfg.keepchandim = 'yes';
output = ft_selectdata(cfg, timelock);

assert(strcmp(output.dimord, 'chan'), 'incorrect dimord');
assert(numel(output.trial)==1, 'error in output data size'); % note the confusing average field name output.trial
assert(~isfield(output, 'time'),  'output should not have time field');
assert( isfield(output, 'label'), 'output should have time field');

cfg = [];
cfg.avgoverchan = 'yes';
cfg.avgovertime = 'yes';
cfg.avgoverrpt  = 'yes';
cfg.keeprptdim  = 'no';
cfg.keeptimedim = 'yes';
cfg.keepchandim = 'no';
output = ft_selectdata(cfg, timelock);

assert(strcmp(output.dimord, 'time'), 'incorrect dimord');
assert(numel(output.trial)==1, 'error in output data size'); % note the confusing average field name output.trial
assert( isfield(output, 'time'),  'output should have time field');
assert(~isfield(output, 'label'), 'output should not have time field');