function []=strsdispols(decimaldates1,stringdates1,strshocks_estimates,endo,pref,IRFt,strctident)

if IRFt==1||IRFt==2||IRFt==3
    identified=size(endo,1); % fully identified
    labels=endo; % simply use the name of the endogenous variables as labels
elseif IRFt==4 || IRFt==6 %if the model is identified by sign restrictions or sign restrictions (+ IV)
    identified=size(strctident.signreslabels_shocks,1); % count the labels provided in the sign res sheet (+ IV)
    labels=strctident.signreslabels_shocks; % signreslabels, only identified shocks
elseif IRFt==5
    identified=1; % one IV shock
    labels{identified,1}=strcat('IV Shock (',strctident.Instrument,')'); % one label for the IV shock
end

if pref.plot==1
% create shock figure
strshocks=figure('Tag','BEARresults');
set(strshocks,'Color',[0.9 0.9 0.9]);
set(strshocks,'name','structural shocks');
ncolumns=ceil(identified^0.5);
nrows=ceil(identified/ncolumns);
for ii=1:identified
subplot(nrows,ncolumns,ii);
hold on
plot(decimaldates1,strshocks_estimates(ii,:),'Color',[0.4 0.4 1],'LineWidth',2);
plot([decimaldates1(1,1),decimaldates1(end,1)],[0 0],'k--');
hold off
minband=min(strshocks_estimates(ii,:));
maxband=max(strshocks_estimates(ii,:));
space=maxband-minband;
Ymin=minband-0.2*space;
Ymax=maxband+0.2*space;
set(gca,'XLim',[decimaldates1(1,1) decimaldates1(end,1)],'YLim',[Ymin,Ymax],'FontName','Times New Roman');
title(labels{ii,1},'FontName','Times New Roman','FontSize',10,'FontWeight','normal','interpreter','none');
end
end

if pref.results==1
% finally, save in excel
% create the cell that will be saved on excel
horzspace=repmat({''},1,identified);
strshockcell=[{'structural shocks'} horzspace;{''} horzspace;{''} labels';stringdates1 num2cell(strshocks_estimates')];

% write in excel
    bear.xlswritegeneral(fullfile(pref.results_path, [pref.results_sub '.xlsx']),strshockcell,'structshocks','B2');
end


function setRavenSolver(solver)
% setRavenSolver
%   Sets the solver for RAVEN and optionally saves a default value
%	to MATLAB startup.
%
%   solver  string with solver name. The following options are available:
%           glpk    uses RAVEN-provided binaries
%           gurobi  requires a working Gurobi installation
%           cobra   requires a working COBRA Toolbox installation. RAVEN
%                   parses the problem to COBRA and uses the solver that is
%                   set by changeCobraSolver.
%
%   Usage: setRavenSolver(solver)
solver=char(solver);
switch solver
    case 'cobra'
        global CBT_LP_SOLVER;
        if isempty(CBT_LP_SOLVER)
            error('COBRA toolbox is not initialized, run ''initCobraToolbox()''')
        else
            setpref('RAVEN','solver','cobra');
        end
    case 'mosek'
        error('MOSEK support has been discontinued since RAVEN 2.3.0.')
    case {'glpk','gurobi','soplex'}
        setpref('RAVEN','solver',solver)
    otherwise
        error('Invalid solver defined')
end
global RAVENSOLVER
RAVENSOLVER = solver;
end


function [success,msg] = ConvertCtrax2JAABA(varargin)

success = false;
msg = {};

[inmoviefile,intrxfile,annfile,...
  expdir,moviefilestr,trxfilestr,perframedirstr,...
  arenatype,arenacenterx,arenacentery,...
  arenaradius,arenawidth,arenaheight,roi2,...
  pxpermm,fps,overridefps,overridearena,...
  dosoftlink,...
  dofliplr,doflipud,dotransposeimage,...
  inperframedir,frameinterval] = myparse(varargin,...
  'inmoviefile','','intrxfile','','annfile','',...
  'expdir','','moviefilestr','movie.ufmf','trxfilestr','trx.mat','perframedirstr','perframe',...
  'arenatype','None','arenacenterx',0,'arenacentery',0,...
  'arenaradius',123,'arenawidth',123,'arenaheight',123,'roi2',[],...
  'pxpermm',1,'fps',30,...
  'overridefps',false,'overridearena',false,...
  'dosoftlink',false,...
  'fliplr',false,...
  'flipud',false,...
  'dotransposeimage',false,...
  'inperframedir','',...
  'frameinterval',[]);

wingunits = struct(...
  'nwingsdetected',parseunits('unit'),...
  'wing_areal',parseunits('px^2'),...
  'wing_arear',parseunits('px^2'),...
  'wing_trough_angle',parseunits('rad'));

%% check that required inputs are given
if isempty(inmoviefile),
  msg = 'Input movie file is empty';
  return;
end
if isempty(intrxfile),
  msg = 'Input trx mat file is empty';
  return;
end
% if isempty(annfile),
%   msg = 'Input ann file is empty';
%   return;
% end

% output file locations
moviefile = fullfile(expdir,moviefilestr);
trxfile = fullfile(expdir,trxfilestr);
perframedir = fullfile(expdir,perframedirstr);

%% load in the trx
try
  [trx,~,success1,timestamps] = load_tracks(intrxfile,moviefile,...
    'dosave',false,'annname',annfile,'verbose',false);
  if ~success1,
    msg = sprintf('Could not load trx from file %s',intrxfile);
    return;
  end
catch ME,
  msg = sprintf('Could not load trx from file %s: %s',intrxfile,getReport(ME));
  return;
end

iswings = isfield(trx,'xwingl');

if iswings,
  if isempty(inperframedir),
    msg = 'Per-frame directory containing wing data is not set';
    return;
  end
  fns = fieldnames(wingunits);
  for i = 1:numel(fns),
    fn = fns{i};
    filename = fullfile(inperframedir,[fn,'.mat']);
    if ~exist(filename,'file'),
      msg = sprintf('Wing feature file %s does not exist.',filename);
      return;
    end
  end
end

if dofliplr || doflipud,
  try
    % get image size
    [readframe,~,fid] = get_readframe_fcn(inmoviefile);
    im = readframe(1);
    [imheight,imwidth,~] = size(im);
    if fid > 1,
      fclose(fid);
    end
  catch ME,
    msg = getReport(ME);
    return;
  end
end

% flip if necessary
if dofliplr,
  for i = 1:numel(trx),
    trx(i).x = imwidth-trx(i).x+1;
    trx(i).theta = modrange(pi - trx(i).theta,-pi,pi);
    if iswings,
      trx(i).xwingl = imwidth-trx(i).xwingl+1;
      trx(i).xwingr = imwidth-trx(i).xwingr+1;
    end
  end
  msg{end+1} = 'Flipped the trajectories left-right.';
end
if doflipud,
  for i = 1:numel(trx),
    trx(i).y = imheight-trx(i).y+1;
    trx(i).theta = modrange(-trx(i).theta,-pi,pi);
    if iswings,
      trx(i).ywingl = imheight-trx(i).xwingl+1;
      trx(i).ywingr = imheight-trx(i).xwingr+1;
    end
  end
  msg{end+1} = 'Flipped the trajectories up-down.';
end
if dotransposeimage,
  for i = 1:numel(trx),
    tmp = trx(i).x;
    trx(i).x = trx(i).y;
    trx(i).y = tmp;
    c = cos(trx(i).theta);
    s = sin(trx(i).theta);
    trx(i).theta = atan2(c,s);
    if iswings,
      tmp = trx(i).xwingl;
      trx(i).xwingl = trx(i).ywingl;
      trx(i).ywingl = tmp;
      tmp = trx(i).xwingr;
      trx(i).xwingr = trx(i).ywingr;
      trx(i).ywingr = tmp;
    end
  end
  msg{end+1} = 'Switched x and y in trajectories.';
end

% Clip the tracks if necessary
outofrange = [];
clipranges = zeros(length(trx),2);
if (frameinterval(1)>1) || ~isinf(frameinterval(end)),
  fields2clip = {'x','y','a','b','theta','timestamps',...
                 'wing_anglel','wing_angler',...
                 'xwingl','ywingl','xwingr','ywingr'};
  for fly = 1:length(trx),
    if trx(fly).endframe<frameinterval(1) || ...
        trx(fly).firstframe>frameinterval(2),
      outofrange(end+1) = fly;  %#ok<AGROW>
      continue;
    end
    tstart = max(1,frameinterval(1)-trx(fly).firstframe+1);
    tend = min(trx(fly).nframes,frameinterval(2)-trx(fly).endframe+trx(fly).nframes);
    clipranges(fly,1) = tstart;
    clipranges(fly,2) = tend;
    trx(fly).firstframe = max(frameinterval(1),trx(fly).firstframe);
    trx(fly).endframe = min(frameinterval(2),trx(fly).endframe);
    trx(fly).nframes = trx(fly).endframe-trx(fly).firstframe+1;
    for fieldndx = 1:numel(fields2clip)
      if isfield(trx(fly),fields2clip{fieldndx});
        trx(fly).(fields2clip{fieldndx}) = trx(fly).(fields2clip{fieldndx})(tstart:tend);
      end
    end
  end

end
trx(outofrange) = [];

% compute frame rate if not overriding and possible
if ~overridefps && ~isempty(timestamps),
  fps = 1/nanmedian(diff(timestamps));
  msg{end+1} = sprintf('Computed frame rate = %f fps from timestamps.',fps);
else
  msg{end+1} = sprintf('Using input frame rate %f fps to set timestamps',fps);
end

if ~overridearena && isfield(trx,'pxpermm'),
  tmp = nanmean([trx.pxpermm]);
  if ~isnan(tmp),
    pxpermm = tmp;
    msg{end+1} = sprintf('Read pxpermm = %f from trxfile.',pxpermm);
  end
else
  msg{end+1} = sprintf('Using input pixels-per-mm scaling = %f.',pxpermm);
end

if ~overridearena && isfield(trx,'arena') && all(isfield(trx(1).arena,{'x','y','r'})) && ...
  ~isempty(trx(1).arena.r) && ~isempty(trx(1).arena.x) && ~isempty(trx(1).arena.y),
  arenaradius = trx(1).arena.r;
  arenacenterx = trx(1).arena.x;
  arenacentery = trx(1).arena.y;
  arenatype = 'Circle';
  msg{end+1} = sprintf('Read circle arena parameters from trxfile. Center = (%.1f, %.1f) px, radius = %.1f px.',arenacenterx,arenacentery,arenaradius);
elseif strcmpi(arenatype,'None'),
  arenacenterx = 0;
  arenacentery = 0;
end

if ~isempty(roi2)
  roi2(:,1) = (roi2(:,1)-arenacenterx) / pxpermm;
  roi2(:,2) = (roi2(:,2)-arenacentery) / pxpermm;
  roi2(:,3) = roi2(:,3) / pxpermm;
  roi2(:,4) = roi2(:,4) / pxpermm;
end

% apply to trajectories
for fly = 1:length(trx),

  % scale and translate position
  trx(fly).x_mm = (trx(fly).x - arenacenterx) / pxpermm;
  trx(fly).y_mm = (trx(fly).y - arenacentery) / pxpermm;
  trx(fly).a_mm = trx(fly).a / pxpermm;
  trx(fly).b_mm = trx(fly).b / pxpermm;
  trx(fly).theta_mm = trx(fly).theta;

  % add in dt
  if overridefps || isempty(timestamps),
    trx(fly).dt = repmat(1/fps,[1,trx(fly).nframes-1]);
  else
    trx(fly).dt = diff(timestamps(trx(fly).firstframe:trx(fly).endframe));
    trx(fly).dt(isnan(trx(fly).dt)) = 1/fps;
  end

  trx(fly).fps = 1/median(trx(fly).dt);
  trx(fly).pxpermm = pxpermm;

end

msg{end+1} = sprintf('Read trx for %d flies, frame range [%d,%d]',numel(trx),min([trx.firstframe]),max([trx.endframe]));

if isempty(timestamps) || overridefps,
  timestamps = (0:max([trx.endframe]))*1/fps; %#ok<NASGU>
end

% set landmark parameters
arenaradius_mm = arenaradius / pxpermm;
arenawidth_mm = arenawidth / pxpermm;
arenaheight_mm = arenaheight / pxpermm;
arenacenterx_mm = 0;
arenacentery_mm = 0;
trx = SetLandmarkParameters(trx,arenatype,arenacenterx_mm,arenacentery_mm,...
  arenaradius_mm,arenawidth_mm,arenaheight_mm,roi2);

if strcmpi(arenatype,'Circle')
  msg{end+1} = sprintf('Set circular arena parameters. Center = (0,0) mm, radius = %.1f mm.',arenaradius_mm);
elseif strcmpi(arenatype,'Rectangle'),
  msg{end+1} = sprintf('Set rectangular arena parameters. Center = (0,0) mm, width= %.1f mm, height = %.1f mm',arenawidth_mm,arenaheight_mm);
end
msg{end+1} = sprintf('x_mm ranges within [%.1f,%.1f], y_mm ranges within [%.1f,%.1f]',...
  min([trx.x_mm]),max([trx.x_mm]),min([trx.y_mm]),max([trx.y_mm]));

% create the experiment directory
if ~exist(expdir,'dir'),
  [success1,msg1] = mkdir(expdir);
  if ~success1,
    msg = msg1;
    return;
  end
  msg{end+1} = sprintf('Created experiment directory %s.',expdir);
end

% save the trx file
try
  save(trxfile,'trx','timestamps');
catch ME,
  msg = sprintf('Could not save to file %s: %s',trxfile,getReport(ME));
  return;
end
if ~exist(trxfile,'file'),
  msg = sprintf('Failed to save trx to file %s',trxfile);
  return;
end
msg{end+1} = sprintf('Saved trx to file %s.',trxfile);

% copy/soft-link movie
if strcmp(fullfile(inmoviefile),fullfile(moviefile)),
  msg{end+1} = 'Input and out movie files are the same, not copying/linking.';
else

  if dosoftlink,
    if exist(moviefile,'file'),
      delete(moviefile);
    end
    if isunix,
      cmd = sprintf('ln -s %s %s',inmoviefile,moviefile);
      unix(cmd);
      % test to make sure it worked
      [status,result] = unix(sprintf('readlink %s',moviefile));
      result = strtrim(result);
      if status ~= 0 || ~strcmp(result,inmoviefile),
        res = questdlg(sprintf('Failed to make soft link. Copy %s to %s instead?',inmoviefile,moviefile));
        if ~strcmpi(res,'Yes'),
          msg = sprintf('Failed to make soft link from %s to %s.',inmoviefile,moviefile);
          return;
        end
        dosoftlink = false;
      end
    elseif ispc,
      if exist([moviefile,'.lnk'],'file'),
        delete([moviefile,'.lnk']);
      end
      cmd = sprintf('mkshortcut.vbs /target:"%s" /shortcut:"%s"',inmoviefile,moviefile);
      fprintf('Making a Windows shortcut file at "%s" with target "%s"\n',inmoviefile,moviefile);
      system(cmd);
      % test to make sure that worked
      [equalmoviefile,didfind] = GetPCShortcutFileActualPath(moviefile);
      if ~didfind || ~strcmp(equalmoviefile,inmoviefile),
        res = questdlg(sprintf('Failed to make shortcut. Copy %s to %s instead?',inmoviefile,moviefile));
        if ~strcmpi(res,'Yes'),
          msg = sprintf('Failed to make shortcut from %s to %s.',inmoviefile,moviefile);
          return;
        end
        dosoftlink = false;
      end
    else
      res = questdlg(sprintf('Unknown OS, cannot soft-link movie file %s. Copy instead?',inmoviefile));
      if ~strcmpi(res,'Yes'),
        msg = sprintf('Failed to make softlink from %s to %s.',inmoviefile,moviefile);
        return;
      end
      dosoftlink = false;
    end
    if dosoftlink,
      msg{end+1} = sprintf('Made a link to movie file %s at %s',inmoviefile,moviefile);
    end
  end

  if ~dosoftlink,
    if ispc,
      if exist([moviefile,'.lnk'],'file'),
        delete([moviefile,'.lnk']);
      end
    end
    if exist(moviefile,'file'),
      delete(moviefile);
    end
    [success1,msg1] = copyfile(inmoviefile,moviefile);
    if ~success1,
      msg = msg1;
      success = false;
      return;
    end
    msg{end+1} = sprintf('Copied movie file %s to %s',inmoviefile,moviefile);
  end

end

% make per-frame directory
if ~exist(perframedir,'dir'),
  [success1,msg1] = mkdir(perframedir);
  if ~success1,
    msg = msg1;
    return;
  end
end

% copy over wing features
if iswings,
  fns = fieldnames(wingunits);

  doclip = false;
  docopy = false;
  fn = fns{1};
  filenamein = fullfile(inperframedir,[fn,'.mat']);
  filenameout = fullfile(perframedir,[fn,'.mat']);
  if (frameinterval(1)>1) || ~isinf(frameinterval(end)),
    if strcmp(filenamein,filenameout),
      qstr = sprintf('Input and output file locations for %s/%s.mat (and possibly others) are the same. The original file will be overwritten with newer version with fewer frames. Overwrite?',...
        perframedir,fn);
      res = questdlg(qstr,'Overwrite perframe file','Yes','No','No');
      if strcmpi(res,'Yes'),doclip = true; end
    else
      doclip = true;
    end
  else
    if strcmp(filenamein,filenameout),
      msg{end+1} = fprintf('%s/%s.mat input and output file locations are the same, not copying.',perframedir,fn);
    else
      docopy = true;
    end
  end

  for i = 1:numel(fns),
    fn = fns{i};
    filenamein = fullfile(inperframedir,[fn,'.mat']);
    filenameout = fullfile(perframedir,[fn,'.mat']);

    if docopy
      if exist(filenameout,'file'),
        delete(filenameout);
      end
      [success1,msg1] = copyfile(filenamein,filenameout);
      if ~success1,
        msg = msg1;
        return;
      end
    end

    if doclip
      Q = load(filenamein);
      for fly = 1:numel(Q.data)
        if ismember(fly,outofrange),
          continue;
        end
        Q.data{fly} = Q.data{fly}(clipranges(fly,1):clipranges(fly,2));
      end
      Q.data(outofrange) = [];

      save(filenameout,'-struct','Q');

    end

  end
end

success = true;


function str = scn_get_datetime(varargin)
% :Usage:
% ::
%
%     str = scn_get_datetime
%
% pass in 'ymd' to get the string in yyyy_mm_dd-HH_MM format, so that
% alphanumeric order will correspond to chronological order
%
% Returns a string with the date and time
% Useful for annotating data and output

if strmatch('ymd', varargin)
    datestring=datestr(date, 'yyyy-mm-dd');

else
    datestring=date;
end

    cval = fix(clock);

    str = sprintf('%s_%02d:%02d', datestring, cval(4),  cval(5));

    str(str == ':') = '_';
end


classdef LineSearch_Backtracking < LineSearch

    properties (Access = private)
       rate
    end

    methods (Access = public)

        function obj = LineSearch_Backtracking(cParams)
            obj.init(cParams);
            obj.rate = cParams.rate;
        end

        function update(obj)
            obj.value = obj.value*obj.rate;
            obj.nTrials = obj.nTrials + 1;
        end

    end

end


function D = spm_eeg_inv_vbecd_gui(D,val)
% GUI function for Bayesian ECD inversion
% - load the necessary data, if not provided
% - fill in all the necessary bits for the VB-ECD inversion routine,
% - launch the B_ECD routine, aka. spm_eeg_inv_vbecd
% - displays the results.
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
%
% $Id: spm_eeg_inv_vbecd_gui.m 7702 2019-11-22 11:32:26Z guillaume $

%%
% Load data, if necessary
%==========
if nargin<1
    D = spm_eeg_load;
end

DISTTHRESH=120; %% mm distance from centre of brain classified as inside the head

%%
% Check if the forward model was prepared & handle the other info bits
%========================================
if ~isfield(D,'inv')
    error('Data must have been prepared for inversion procedure...')
end
if nargin==2
    % check index provided
    if val>length(D.inv)
        val = length(D.inv);
        D.val = val;
    end
else
    if isfield(D,'val')
        val = D.val;
    else
        % use last one
        val = length(D.inv);
        D.val = val;
    end
end

% Use val to define which is the "current" inv{} to use
% If no inverse solution already calculated (field 'inverse' doesn't exist)
% use that inv{}. Otherwise create a new one by copying the previous
% inv{} structure
if isfield(D.inv{val},'inverse')
    % create an extra inv{}
    Ninv = length(D.inv);
    D.inv{Ninv+1} = D.inv{val};
    if isfield(D.inv{Ninv+1},'contrast')
        % no contrast field used here !
        D.inv{Ninv+1} = rmfield(D.inv{Ninv+1},'contrast');
    end
    val = Ninv+1;
    D.val = val;
end

if ~isfield(D.inv{val}, 'date')
    % Set time , date, comments & modality
    clck = fix(clock);
    if clck(5) < 10
        clck = [num2str(clck(4)) ':0' num2str(clck(5))];
    else
        clck = [num2str(clck(4)) ':' num2str(clck(5))];
    end
    D.inv{val}.date = strvcat(date,clck);
end

if ~isfield(D.inv{val}, 'comment'),
   D.inv{val}.comment = {spm_input('Comment/Label for this analysis', '+1', 's')};
end

D.inv{val}.method = 'vbecd';

%% Struct that collects the inputs for vbecd code
P = [];

P.modality = spm_eeg_modality_ui(D, 1, 1);

for m = 1:numel(D.inv{val}.datareg)
    if strncmp(D.inv{val}.datareg(m).modality, P.modality, 3)
        modind = m;
    end
end

data = spm_eeg_inv_get_vol_sens(D, val, [], 'inv', P.modality);

P.forward.vol     = data.(P.modality(1:3)).vol;
if ischar(P.forward.vol)
    P.forward.vol = ft_read_headmodel(P.forward.vol);
end

P.forward.sens    = data.(P.modality(1:3)).sens;
P.forward.siunits = data.siunits;
M1 = data.transforms.toMNI;
[U, L, V] = svd(M1(1:3, 1:3));
orM1(1:3,1:3) =U*V'; %% for switching orientation between meg and mni space

P.Ic = indchantype(D, P.modality, 'GOOD');

if isempty(P.Ic)
    error(['The specified modality (' P.modality ') is missing from file ' D.fname]);
else
    P.channels = D.chanlabels(P.Ic);
end

P.forward.chanunits = D.units(P.Ic);

[P.forward.vol, P.forward.sens] =  ft_prepare_vol_sens( ...
    P.forward.vol, P.forward.sens, 'channel', P.channels);

P.forward.sens.prj = D.coor2D(P.Ic);

%%
% Deal with data
%===============

% time bin or time window
msg_tb = ['time_bin or average_win [',num2str(round(min(D.time)*1e3)), ...
            ' ',num2str(round(max(D.time)*1e3)),'] ms'];
ask_tb = 1;
while ask_tb
    tb = spm_input(msg_tb,1,'r');   % ! in msec
    if length(tb)==1
        if tb>=min(D.time([], 'ms')) && tb<=max(D.time([], 'ms'))
            ask_tb = 0;
        end
    elseif length(tb)==2
        if all(tb>=floor(min(D.time([], 'ms')))) && all(tb<=ceil(max(D.time([], 'ms')))) && tb(1)<=tb(2)
            ask_tb = 0;
        end
    end
end
if length(tb)==1
    [kk,ltb] = min(abs(D.time([], 'ms')-tb)); % round to nearest time bin
else
    [kk,ltb(1)] = min(abs(D.time([], 'ms')-tb(1)));  % round to nearest time bin
    [kk,ltb(2)] = min(abs(D.time([], 'ms')-tb(2)));
    ltb = ltb(1):ltb(2); % list of time bins 'tb' to use
end

% trial type
if D.ntrials>1
    msg_tr = ['Trial type number [1 ',num2str(D.ntrials),']'];
    ltr = spm_input(msg_tr,2,'i',num2str(1:D.ntrials));
    tr_q = 1;
else
    tr_q = 0;
    ltr = 1;
end

% data, averaged over time window considered

EEGscale=1;

%% SORT OUT EEG UNITS AND CONVERT VALUES TO VOLTS
if strcmpi(P.modality,'EEG')
    allunits  = strvcat('uV','mV','V');
    allscales = [1, 1e3, 1e6]; %%
    EEGscale  = 0;
    eegunits  = unique(D.units(D.indchantype('EEG')));
    Neegchans = numel(D.units(D.indchantype('EEG')));
    for j=1:length(allunits)
        if strcmp(deblank(allunits(j,:)),deblank(eegunits))
            EEGscale=allscales(j);
        end % if
    end % for j

    if EEGscale==0
        warning('units unspecified');
        if mean(std(D(P.Ic,ltb,ltr)))>1e-2
            guess_ind=[1 2 3];
        else
            guess_ind=[3 2 1];
        end
        msg_str = sprintf('Units of EEG are %s ? (rms=%3.2e)',allunits(guess_ind(1),:),mean(std(D(P.Ic,ltb,ltr))));
        dip_ch  = sprintf('%s|%s|%s',allunits(guess_ind(1),:),allunits(guess_ind(2),:),allunits(guess_ind(3),:));
        dip_val = [1,2,3];
        def_opt = 1;
        unitind = spm_input(msg_str,2,'b',dip_ch,dip_val,def_opt);
        %ans=spm_input(msg_str,1,'s','yes');
        allunits(guess_ind(unitind),:)
        D = units(D, 1:Neegchans, allunits(guess_ind(unitind),:));
        EEGscale = allscales(guess_ind(unitind));
        D.save; %% Save the new units
    end %if EEGscale==0

end % if eeg data

dat_y = squeeze(mean(D(P.Ic,ltb,ltr)*EEGscale,2));

%%
% Other bits of the P structure, apart for priors and #dipoles
%==============================

P.ltr          = ltr;
P.Nc           = length(P.Ic);

% Deal with dipoles number and priors
%====================================
dip_q = 0; % number of dipole 'elements' added (single or pair)
dip_c = 0; % total number of dipoles in the model
adding_dips = 1;
clear dip_pr

priorlocvardefault=[100, 100, 100]; %% location variance default in mm
nopriorlocvardefault=[80*80, 80*80, 80*80];
nopriormomvardefault=[10, 10, 10]*100; %% moment variance in nAM
priormomvardefault=[1, 1, 1]; %%

while adding_dips
    if dip_q>0,
        msg_dip =['Add dipoles to ',num2str(dip_c),' or stop?'];
        dip_ch = 'Single|Symmetric Pair|Stop';
        dip_val = [1,2,0];
        def_opt=3;
    else
        msg_dip =['Add dipoles to model'];
        def_opt=1;
        dip_ch = 'Single|Symmetric Pair';
        dip_val = [1,2];
    end
    a_dip = spm_input(msg_dip,2+tr_q+dip_q,'b',dip_ch,dip_val,def_opt);
    if a_dip == 0
        adding_dips = 0;
    elseif a_dip == 1
    % add a single dipole to the model
        dip_q = dip_q+1;
        dip_pr(dip_q) = struct( 'a_dip',a_dip, ...
            'mu_w0',[],'mu_s0',[],'S_s0',eye(3),'S_w0',eye(3));
          %%  'ab20',[],'ab30',[]); %% ,'Tw', [],'Ts', []);
        % Location prior
        spr_q = spm_input('Location prior ?',1+tr_q+dip_q+1,'b', ...
                    'Informative|Non-info',[1,0],2);
        if spr_q
            % informative location prior
            str = 'Location prior';
            while 1
                s0mni = spm_input(str, 1+tr_q+dip_q+2,'e',[0 0 0])';

                %outside = ~ft_inside_headmodel(s0mni',mnivol);

                distcentre=sqrt(dot(s0mni'-mean(D.inv{D.val}.mesh.tess_mni.vert),s0mni'-mean(D.inv{D.val}.mesh.tess_mni.vert))); %%
                outside=(distcentre>DISTTHRESH);

                s0=D.inv{val}.datareg(modind).fromMNI*[s0mni' 1]';
                s0=s0(1:3);

                str2='Prior location variance (mm2)';
                diags_s0_mni = spm_input(str2, 1+tr_q+dip_q+2,'e',priorlocvardefault)';

                S_s0_ctf=orM1*diag(diags_s0_mni)*orM1'; %% transform covariance

                %% need to leave diags(S0) free

                if all(~outside), break, end
                    str = 'Prior location must be inside head';
                  end
            dip_pr(dip_q).mu_s0 = s0;
           else
            % no location  prior
            dip_pr(dip_q).mu_s0 = zeros(3,1);
            diags_s0_mni= nopriorlocvardefault';
            S_s0_ctf=diag(diags_s0_mni);
            end

        dip_pr(dip_q).S_s0=S_s0_ctf; %

        % Moment prior
        wpr_q = spm_input('Moment prior ?',1+tr_q+dip_q+spr_q+2,'b', ...
                    'Informative|Non-info',[1,0],2);
        if wpr_q
            % informative moment prior
            w0_mni= spm_input('Moment prior', ...
                                        1+tr_q+dip_q+spr_q+3,'e',[0 0 0])';
            str2='Prior moment variance (nAm2)';
            diags_w0_mni = spm_input(str2, 1+tr_q+dip_q+2,'e',priormomvardefault)';
            dip_pr(dip_q).mu_w0 =orM1*w0_mni;
            S_w0_ctf=orM1*diag(diags_w0_mni)*orM1';

        else
            % no location  prior
            dip_pr(dip_q).mu_w0 = zeros(3,1);
            S_w0_ctf= diag(nopriormomvardefault);
        end
        %% set up covariance matrix for orientation with no crosstalk terms (for single
        %% dip)
        dip_pr(dip_q).S_w0=S_w0_ctf;
        dip_c = dip_c+1;
    else
    % add a pair of symmetric dipoles to the model
        dip_q = dip_q+1;
        dip_pr(dip_q) = struct( 'a_dip',a_dip, ...
            'mu_w0',[],'mu_s0',[],'S_s0',eye(6),'S_w0',eye(6));
        %%...
          %  'ab20',[],'ab30',[]); %%,'Tw',eye(6),'Ts',eye(6));
        % Location prior
        spr_q = spm_input('Location prior ?',1+tr_q+dip_q+1,'b', ...
                    'Informative|Non-info',[1,0],2);
        if spr_q
            % informative location prior
             str = 'Location prior (one side only)';
            while 1
                s0mni = spm_input(str, 1+tr_q+dip_q+2,'e',[0 0 0])';
                syms0mni=s0mni;
                syms0mni(1)=-syms0mni(1);

                distcentre=sqrt(dot(s0mni'-mean(D.inv{D.val}.mesh.tess_mni.vert),s0mni'-mean(D.inv{D.val}.mesh.tess_mni.vert))); %%
                outside=(distcentre>DISTTHRESH);

                s0=D.inv{val}.datareg(modind).fromMNI*[s0mni' 1]';

                s0sym=D.inv{val}.datareg(modind).fromMNI*[syms0mni' 1]';

                str2='Prior location variance (mm2)';
                tmp_diags_s0_mni = spm_input(str2, 1+tr_q+dip_q+2,'e',priorlocvardefault)';
                tmp_diags_s0_mni= [tmp_diags_s0_mni ; tmp_diags_s0_mni ];

                if all(~outside), break, end
                    str = 'Prior location must be inside head';
                  end

            dip_pr(dip_q).mu_s0 = [s0(1:3);s0sym(1:3)];
        else
            % no location  prior
            dip_pr(dip_q).mu_s0 = zeros(6,1);
            tmp_diags_s0 = [nopriorlocvardefault';nopriorlocvardefault'];
            tmp_diags_s0_mni=[nopriorlocvardefault';nopriorlocvardefault'];
        end %% end of if informative prior
        %% setting up a covariance matrix where there is covariance between
        %% the x parameters negatively coupled, y,z positively.
         mni_dip_pr(dip_q).S_s0 = eye(length(tmp_diags_s0_mni)).*repmat(tmp_diags_s0_mni,1,length(tmp_diags_s0_mni));
         mni_dip_pr(dip_q).S_s0(4,1)=-mni_dip_pr(dip_q).S_s0(4,4); % reflect in x
         mni_dip_pr(dip_q).S_s0(5,2)=mni_dip_pr(dip_q).S_s0(5,5); % maintain y and z
         mni_dip_pr(dip_q).S_s0(6,3)=mni_dip_pr(dip_q).S_s0(6,6);

         mni_dip_pr(dip_q).S_s0(1,4)=mni_dip_pr(dip_q).S_s0(4,1);
         mni_dip_pr(dip_q).S_s0(2,5)=mni_dip_pr(dip_q).S_s0(5,2);
         mni_dip_pr(dip_q).S_s0(3,6)=mni_dip_pr(dip_q).S_s0(6,3);
         %% transform to MEG space

         %dip_pr(dip_q).S_s0(:,1:3)=orM1*mni_dip_pr(dip_q).S_s0(:,1:3)*orM1'; %% NEED TO LOOK AT THIS
         %dip_pr(dip_q).S_s0(:,4:6)=orM1*mni_dip_pr(dip_q).S_s0(:,4:6)*orM1';
         tmp1=orM1*mni_dip_pr(dip_q).S_s0(1:3,1:3)*orM1'; %% NEED TO LOOK AT THIS
         tmp2=orM1*mni_dip_pr(dip_q).S_s0(1:3,4:6)*orM1';
         tmp3=orM1*mni_dip_pr(dip_q).S_s0(4:6,4:6)*orM1';
         tmp4=orM1*mni_dip_pr(dip_q).S_s0(4:6,1:3)*orM1';
         dip_pr(dip_q).S_s0(1:3,1:3)=tmp1;
         dip_pr(dip_q).S_s0(1:3,4:6)=tmp2;
         dip_pr(dip_q).S_s0(4:6,4:6)=tmp3;
         dip_pr(dip_q).S_s0(4:6,1:3)=tmp4;

        % Moment prior
        wpr_q = spm_input('Moment prior ?',1+tr_q+dip_q+spr_q+2,'b', ...
                                           'Informative|Non-info',[1,0],2);
        if wpr_q
            % informative moment prior
            tmp= spm_input('Moment prior (right only)', ...
                                      1+tr_q+dip_q+spr_q+3,'e',[1 1 1])';
            tmp = [tmp ; tmp] ; tmp(4) = tmp(4);
            dip_pr(dip_q).mu_w0 = tmp;

            str2='Prior moment variance (nAm2)';
            diags_w0 = spm_input(str2, 1+tr_q+dip_q+spr_q+3,'e',priormomvardefault)';
            tmp_diags_w0=[diags_w0; diags_w0];

        else
            % no moment  prior
            dip_pr(dip_q).mu_w0 = zeros(6,1);
            tmp_diags_w0 = [nopriormomvardefault'; nopriormomvardefault'];
        end
        %dip_pr(dip_q).S_w0=eye(length(diags_w0)).*repmat(diags_w0,1,length(diags_w0));
        %% couple all orientations, except x, positively or leave for now...

                mni_dip_pr(dip_q).S_w0 = eye(length(tmp_diags_w0)).*repmat(tmp_diags_w0,1,length(tmp_diags_w0));

            mni_dip_pr(dip_q).S_w0(4,1)=-mni_dip_pr(dip_q).S_w0(4,4); % reflect x orientation
            mni_dip_pr(dip_q).S_w0(5,2)=mni_dip_pr(dip_q).S_w0(5,5); %
            mni_dip_pr(dip_q).S_w0(6,3)=mni_dip_pr(dip_q).S_w0(6,6); %
            mni_dip_pr(dip_q).S_w0(1,4)=-mni_dip_pr(dip_q).S_w0(4,1); %
            mni_dip_pr(dip_q).S_w0(2,5)=mni_dip_pr(dip_q).S_w0(5,2); %
            mni_dip_pr(dip_q).S_w0(3,6)=mni_dip_pr(dip_q).S_w0(6,3); %
            tmp1=orM1*mni_dip_pr(dip_q).S_w0(1:3,1:3)*orM1';
            tmp2=orM1*mni_dip_pr(dip_q).S_w0(1:3,4:6)*orM1';
            tmp3=orM1*mni_dip_pr(dip_q).S_w0(4:6,4:6)*orM1';
            tmp4=orM1*mni_dip_pr(dip_q).S_w0(4:6,1:3)*orM1';
            dip_pr(dip_q).S_w0(1:3,1:3)=tmp1;
            dip_pr(dip_q).S_w0(1:3,4:6)=tmp2;
            dip_pr(dip_q).S_w0(4:6,4:6)=tmp3;
            dip_pr(dip_q).S_w0(4:6,1:3)=tmp4;

        dip_c = dip_c+2;
    end
end

%str2='Data SNR (amp)';
% SNRamp = spm_input(str2, 1+tr_q+dip_q+2+1,'e',5)';
%SNRamp=3;
SNRamp=3;
 hE=log(SNRamp^2); %% expected log precision of data
 hC=1; % variability of the above precision

str2='Number of iterations';
 Niter = spm_input(str2, 1+tr_q+dip_q+2+2,'e',10)';

%%
% Get all the priors together and build structure to pass to inv_becd

%============================

priors = struct('mu_w0',cat(1,dip_pr(:).mu_w0), ...
                'mu_s0',cat(1,dip_pr(:).mu_s0), ...
                'S_w0',blkdiag(dip_pr(:).S_w0),'S_s0',blkdiag(dip_pr(:).S_s0),'hE',hE,'hC',hC);

P.priors = priors;

%%
% Launch inversion !
%===================

% Initialise inverse field
inverse = struct( ...
    'F',[], ... % free energy
    'pst',D.time, ... % all time points in data epoch
    'tb',tb, ... % time window/bin used
    'ltb',ltb, ... % list of time points used
    'ltr',ltr, ... % list of trial types used
    'n_seeds',length(ltr), ... % using this field for multiple reconstruction
    'n_dip',dip_c, ... % number of dipoles used
    'loc',[], ... % loc of dip (3 x n_dip)
    'j',[], ... % dipole(s) orient/ampl, in 1 column
    'cov_loc',[], ... % cov matrix of source location
    'cov_j',[], ...   % cov matrix of source orient/ampl
    'Mtb',1, ... % ind of max EEG power in time series, 1 as only 1 tb.
    'exitflag',[], ... % Converged (1) or not (0)
    'P',[]);             % save all kaboodle too.

for ii=1:length(ltr)
    P.y = dat_y(:,ii);
    P.ii = ii;

 %% set up figures
    P.handles.hfig  = spm_figure('GetWin','Graphics');
    spm_clf(P.handles.hfig)
    P.handles.SPMdefaults.col = get(P.handles.hfig,'colormap');
    P.handles.SPMdefaults.renderer = get(P.handles.hfig,'renderer');
    set(P.handles.hfig,'userdata',P)
    dip_amp=[];
    for j=1:Niter,

     Pout(j) = spm_eeg_inv_vbecd(P);
     close(gcf);
     varresids(j)=var(Pout(j).y-Pout(j).ypost);
     pov(j)=100*(1-varresids(j)/var(Pout(j).y)); %% percent variance explained
     allF(j)=Pout(j).F;
     dip_mom=reshape(Pout(j).post_mu_w,3,length(Pout(j).post_mu_w)/3);
     dip_amp(j,:)=sqrt(dot(dip_mom,dip_mom));
    % display
     megloc=reshape(Pout(j).post_mu_s,3,length(Pout(j).post_mu_s)/3); % loc of dip (3 x n_dip)
     mniloc=D.inv{val}.datareg(modind).toMNI*[megloc;ones(1,size(megloc,2))]; %% actual MNI location (with scaling)
     megmom=reshape(Pout(j).post_mu_w,3,length(Pout(j).post_mu_w)/3); % moments of dip (3 x n_dip)
     megposvar=reshape(diag(Pout(j).post_S_s),3,length(Pout(j).post_mu_s)/3); %% estimate of positional uncertainty in three principal axes
     mnimom=orM1*megmom; %% convert moments into mni coordinates through a rotation (no scaling or translation)
     mniposvar=(orM1*sqrt(megposvar)).^2; %% convert pos variance into approx mni space by switching axes

     displayVBupdate2(Pout(j).y,pov,allF,Niter,dip_amp,mnimom,mniloc(1:3,:),mniposvar,P,j,[],Pout(j).F,Pout(j).ypost,[]);

    end; % for  j
    allF=[Pout.F];
    [maxFvals,maxind]=max(allF);

    P=Pout(maxind); %% take best F
    % Get the results out.
    inverse.pst = tb*1e3;
    inverse.F(ii) = P.F; % free energy

     megloc=reshape(P.post_mu_s,3,length(P.post_mu_s)/3); % loc of dip (3 x n_dip)
     meg_w=reshape(P.post_mu_w,3,length(P.post_mu_w)/3); % moments of dip (3 x n_dip)
     mni_w=orM1*meg_w; %% orientation in mni space
     mniloc=D.inv{val}.datareg(modind).toMNI*[megloc;ones(1,size(megloc,2))]; %% actual MNI location (with scaling)
     inverse.mniloc{ii}=mniloc(1:3,:);
    inverse.loc{ii} = megloc;

    inverse.j{ii} = P.post_mu_w; % dipole(s) orient/ampl, in 1 column in meg space
    inverse.jmni{ii} = reshape(mni_w,1,prod(size(mni_w)))'; % dipole(s) orient/ampl in mni space
    inverse.cov_loc{ii} = P.post_S_s; % cov matrix of source location
    inverse.cov_j{ii} = P.post_S_w; % cov matrix of source orient/ampl
    inverse.exitflag(ii) = 1; % Converged (1) or not (0)
    inverse.P{ii} = P; % save all kaboodle too.
    %% show final result
    pause(1);

    spm_clf(P.handles.hfig)

     megmom=reshape(Pout(maxind).post_mu_w,3,length(Pout(maxind).post_mu_w)/3); % moments of dip (3 x n_dip)
     %megposvar=reshape(diag(Pout(maxind).post_S_s),3,length(Pout(maxind).post_mu_s)/3); %% estimate of positional uncertainty in three principal axes
     mnimom=orM1*megmom; %% convert moments into mni coordinates through a rotation (no scaling or translation)

     longorM1=zeros(size(Pout(maxind).post_S_s,1));
     for k1=1:length(Pout(maxind).post_S_s)/3;
        longorM1((k1-1)*3+1:k1*3,(k1-1)*3+1:k1*3)=orM1;
     end; % for k1
     S0_mni=longorM1*Pout(maxind).post_S_s*longorM1';
     mniposvar=diag(S0_mni); %% convert pos variance into approx mni space by switching axes
     mniposvar=reshape(mniposvar,3,length(Pout(maxind).post_S_s)/3);

     displayVBupdate2(Pout(maxind).y,pov,allF,Niter,dip_amp,mnimom,mniloc(1:3,:),mniposvar,P,j,[],Pout(maxind).F,Pout(maxind).ypost,maxind);

    %displayVBupdate2(Pout(maxind).y,pov,allF,Niter,dip_amp,mniloc,Pout(maxind).post_mu_s,Pout(maxind).post_S_s,P,j,[],Pout(maxind).F,Pout(maxind).ypost,maxind,D);
  %
end

%  [tmp] = ft_compute_leadfield([-42 15 48], P.forward.sens, P.forward.vol,'reducerank',2);
%  estfield=tmp*[-21 -8 -45]';
%  plot(P.y,estfield./1000,'x')
%  axis equal

D.inv{val}.inverse = inverse;

%%
% Save results and display
%-------------------------
save(D)

return

function [P] = displayVBupdate2(y,pov_iter,F_iter,maxit,dipamp_iter,mu_w,mu_s,diagS_s,P,it,flag,F,yHat,maxind)

%% yHat is estimate of y based on dipole position
if ~exist('flag','var')
    flag = [];
end
if ~exist('maxind','var')
    maxind = [];
end

if isempty(flag) || isequal(flag,'ecd')
    % plot dipoles
    try
        opt.ParentAxes = P.handles.axesECD;
        opt.hfig = P.handles.hfig;
        opt.handles.hp = P.handles.hp;
        opt.handles.hq = P.handles.hq;
        opt.handles.hs = P.handles.hs;
        opt.handles.ht = P.handles.ht;
        opt.query = 'replace';
    catch
        P.handles.axesECD = axes(...
            'parent',P.handles.hfig,...
            'Position',[0.13 0.55 0.775 0.4],...
            'hittest','off',...
            'visible','off',...
            'deleteFcn',@back2defaults);
        opt.ParentAxes = P.handles.axesECD;
        opt.hfig = P.handles.hfig;
    end
    w = reshape(mu_w,3,[]);
    s = reshape(mu_s, 3, []);
%     mesh.faces=D.inv{D.val}.forward.mesh.face; %% in ctf space
%     mesh.vertices=D.inv{D.val}.forward.mesh.vert; %% in ctf space
%     [out] = spm_eeg_displayECD_ctf(...
%         s,w,reshape(diag(S_s),3,[]),[],mesh,opt);
       [out] = spm_eeg_displayECD(...
         s,w,diagS_s,[],opt);

        P.handles.hp = out.handles.hp;
        P.handles.hq = out.handles.hq;
        P.handles.hs = out.handles.hs;
        P.handles.ht = out.handles.ht;

end

% plot data and predicted data
pos = P.forward.sens.prj;
ChanLabel = P.channels;
in.f = P.handles.hfig;
in.noButtons = 1;
try
    P.handles.axesY;
catch
    figure(P.handles.hfig)
    P.handles.axesY = axes(...
        'Position',[0.02 0.3 0.3 0.2],...
        'hittest','off');
    in.ParentAxes = P.handles.axesY;
    spm_eeg_plotScalpData(y,pos,ChanLabel,in);
    title(P.handles.axesY,'measured data')
end
if isempty(flag) || isequal(flag,'data') || isequal(flag,'ecd')
    %yHat = P.gmn*mu_w;
    miY = min([yHat;y]);
    maY = max([yHat;y]);
    try
        P.handles.axesYhat;
        d = get(P.handles.axesYhat,'userdata');
        yHat = yHat(d.goodChannels);
        clim = [min(yHat(:))-( max(yHat(:))-min(yHat(:)) )/63,...
            max(yHat(:))];
        ZI = griddata(...
            d.interp.pos(1,:),d.interp.pos(2,:),full(double(yHat)),...
            d.interp.XI,d.interp.YI);
        set(d.hi,'Cdata',flipud(ZI));
        caxis(P.handles.axesYhat,clim);
        delete(d.hc)
        [C,d.hc] = contour(P.handles.axesYhat,flipud(ZI),...
            'linecolor',0.5.*ones(3,1));
        set(P.handles.axesYhat,...
            'userdata',d);
    catch
        figure(P.handles.hfig)
        P.handles.axesYhat = axes(...
            'Position',[0.37 0.3 0.3 0.2],...
            'hittest','off');
        in.ParentAxes = P.handles.axesYhat;
        spm_eeg_plotScalpData(yHat,pos,ChanLabel,in);
        title(P.handles.axesYhat,'predicted data')
    end
    try
        P.handles.axesYhatY;
    catch
        figure(P.handles.hfig)
        P.handles.axesYhatY = axes(...
            'Position',[0.72 0.3 0.25 0.2],...
            'NextPlot','replace',...
            'box','on');
    end
    plot(P.handles.axesYhatY,y,yHat,'.')
    set(P.handles.axesYhatY,...
        'nextplot','add')
    plot(P.handles.axesYhatY,[miY;maY],[miY;maY],'r')
    set(P.handles.axesYhatY,...
        'nextplot','replace')
    title(P.handles.axesYhatY,'predicted vs measured data')
    axis(P.handles.axesYhatY,'square','tight')
    grid(P.handles.axesYhatY,'on')

end

if isempty(flag) || isequal(flag,'var')
    % plot precision hyperparameters
    try
        P.handles.axesVar1;
    catch
        figure(P.handles.hfig)
        P.handles.axesVar1 = axes(...
            'Position',[0.05 0.05 0.25 0.2],...
            'NextPlot','replace',...
            'box','on');
    end
    plot(P.handles.axesVar1,F_iter,'o-');
    if ~isempty(maxind),
        hold on;
        h=plot(P.handles.axesVar1,maxind,F_iter(maxind),'rd');
        set(h,'linewidth',4);
        end;
    set(P.handles.axesVar1,'Xlimmode','manual');
    set(P.handles.axesVar1,'Xlim',[1 maxit]);
    set(P.handles.axesVar1,'Xtick',1:maxit);
    set(P.handles.axesVar1,'Xticklabel',num2str([1:maxit]'));
    set(P.handles.axesVar1,'Yticklabel','');
    title(P.handles.axesVar1,'Free energy ')
    axis(P.handles.axesVar1,'square');
    set(P.handles.axesVar1,'Ylimmode','auto'); %,'tight')

    grid(P.handles.axesVar1,'on')

    try
        P.handles.axesVar2;
    catch
        figure(P.handles.hfig)
        P.handles.axesVar2 = axes(...
            'Position',[0.37 0.05 0.25 0.2],...
            'NextPlot','replace',...
            'box','on');
    end

    plot(P.handles.axesVar2,pov_iter,'*-')
    if ~isempty(maxind),
        hold on;
        h=plot(P.handles.axesVar2,maxind,pov_iter(maxind),'rd');
        set(h,'linewidth',4);
        end;
    set(P.handles.axesVar2,'Xlimmode','manual');
    set(P.handles.axesVar2,'Xlim',[1 maxit]);
    set(P.handles.axesVar2,'Xtick',1:maxit);
    set(P.handles.axesVar2,'Xticklabel',num2str([1:maxit]'));
    set(P.handles.axesVar2,'Ylimmode','manual'); %,'tight')
     set(P.handles.axesVar2,'Ylim',[0 100]);
    set(P.handles.axesVar2,'Ytick',[0:20:100]);
    set(P.handles.axesVar2,'Yticklabel',num2str([0:20:100]'));

    %set(P.handles.axesVar2,'Yticklabel','');
    title(P.handles.axesVar2,'Percent variance explained');
    axis(P.handles.axesVar2,'square');

    grid(P.handles.axesVar2,'on')

    try
        P.handles.axesVar3;
    catch
        figure(P.handles.hfig)
        P.handles.axesVar3 = axes(...
            'Position',[0.72 0.05 0.25 0.2],...
            'NextPlot','replace',...
            'box','on');
    end
    plot(P.handles.axesVar3,1:it,dipamp_iter','o-');
      if ~isempty(maxind),
        hold on;
        h=plot(P.handles.axesVar3,maxind,dipamp_iter(maxind,:)','rd');
        set(h,'linewidth',4);
        end;

    set(P.handles.axesVar3,'Xlimmode','manual');
    set(P.handles.axesVar3,'Xlim',[1 maxit]);
    set(P.handles.axesVar3,'Xtick',1:maxit);
    set(P.handles.axesVar3,'Xticklabel',num2str([1:maxit]'));
    set(P.handles.axesVar3,'Yticklabel','');
    title(P.handles.axesVar3,'Dipole amp (nAm) ')
    axis(P.handles.axesVar3,'square');
    set(P.handles.axesVar3,'Ylimmode','auto'); %,'tight')
    grid(P.handles.axesVar3,'on')

end

if ~isempty(flag) && (isequal(flag,'ecd') || isequal(flag,'mGN') )
    try
        P.handles.hte(2);
    catch
        figure(P.handles.hfig)
        P.handles.hte(2) = uicontrol('style','text',...
            'units','normalized',...
            'position',[0.2,0.91,0.6,0.02],...
            'backgroundcolor',[1,1,1]);
    end
    set(P.handles.hte(2),'string',...
        ['ECD locations: Modified Gauss-Newton scheme... ',num2str(floor(P.pc)),'%'])
else
    try
        set(P.handles.hte(2),'string','VB updates on hyperparameters')
    end
end

try
    P.handles.hte(1);
catch
    figure(P.handles.hfig)
    P.handles.hte(1) = uicontrol('style','text',...
        'units','normalized',...
        'position',[0.2,0.94,0.6,0.02],...
        'backgroundcolor',[1,1,1]);
end
try
    set(P.handles.hte(1),'string',...
        ['Model evidence: p(y|m) >= ',num2str(F(end),'%10.3e\n')])
end

try
    P.handles.hti;
catch
    figure(P.handles.hfig)
    P.handles.hti = uicontrol('style','text',...
        'units','normalized',...
        'position',[0.3,0.97,0.4,0.02],...
        'backgroundcolor',[1,1,1],...
        'string',['VB ECD inversion: trial #',num2str(P.ltr(P.ii))]);
end
drawnow

function back2defaults(e1,e2)
hf = spm_figure('FindWin','Graphics');
P = get(hf,'userdata');
try
    set(hf,'colormap',P.handles.SPMdefaults.col);
    set(hf,'renderer',P.handles.SPMdefaults.renderer);
end


function [V,F] = load_mesh(filename,varargin)
  % read in vertices and faces from a .off or .obj file
  %
  % [V,F] = load_mesh(filename)
  % [V,F] = load_mesh(filename,'ParameterName',ParameterValue, ...)
  %
  % Input:
  %   filename  file holding mesh
  %   Optional:
  %     'Quiet' followed by whether to be quiet {false}
  % Output:
  %   V (vertex list)
  %   F (face list) fields
  %
  % Copyright 2011, Alec Jacobson (jacobson@inf.ethz.ch)
  %
  % See also: readOBJ, readOBJfast, readOFF
  %

  % parse any optional input
  v = 1;
  quiet = false;
  while(v <= numel(varargin))
    switch varargin{v}
    case 'Quiet'
      v = v+1;
      assert(v<=nargin);
      quiet = varargin{v};
      quiet = quiet * 1;
    otherwise
      error(['Unsupported parameter: ' varargin{v}]);
    end
    v = v + 1;
  end

  % if mex libigl reader exists use that (up to 25x faster for .obj)
  if exist('read_triangle_mesh','file')==3
    try
      [V,F] = read_triangle_mesh(GetFullPath(filename));
      if ~isempty(V) && ~isempty(F)
        return;
      end
      % else keep trying below
    catch e
      warning(e.message);
      % else keep trying below
    end
  end

  [~,~,ext] = fileparts(filename);
  ext = lower(ext);
  switch ext
  case '.3ds'
    [V,F] = read3DS(filename);
  case '.obj'
    try
      [V,F] = readOBJfast(filename);
    catch exception
      if ~quiet
        fprintf('Fast reader failed, retrying with more robust, slower reader\n');
      end
      [V,F] = readOBJ(filename);
    end
  case '.off'
    [V,F] = readOFF(filename);
  case '.ply'
    [V,F] = readPLY(filename);
  case '.stl'
    [V,F] = readSTL(filename);
  case '.wrl'
    [V,F] = readWRL(filename);
  case '.xml'
    [V,F] = read_mesh_from_xml(filename);
  otherwise
    error('Unknown mesh format: %s',ext);
  end
end


function [eq,dict] = exp_match(exp,form,dict)
% Check whether an expression is matched by a pattern.
% [Equals,Assignment] = exp_match(Expression, Pattern)
%
% The pattern may contain blanks, named sub-patterns and conditional expressions. Assignment is an
% optional output which contains sub-expressions matched by named parts of the pattern.
%
% See also:
%   exp_same
%
%                                Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                2010-04-19

if ~exp_beginfun('symbolic') return; end

if ~exist('dict','var')
    dict = struct(); end

[eq,dict] = utl_match(exp,form,dict);

exp_endfun;


%
% Input
%  I: binary image (black = true)
%
function plot_image_only(I)
    assert(size(I,1)==105);
    assert(size(I,2)==105);
    newI = 1-I;
    newI(isinf(I)) = 0.5;
    image([1 105],[1 105],repmat(newI,[1 1 3]));
    set(gca,'YDir','reverse','XTick',[],'YTick',[]);
    xlim([1 105]);
    ylim([1 105]);
end


classdef prtOptionsComputation

    properties

        largestMatrixSize = 9e6; % Total number of elements in the matrix (3000 x 3000)
        verboseStorage = true;   % Save's the training dataset within each
                                 % action. True enables easier plotting
                                 % and data exploration.
        showProgressBar = true;
    end

    methods
        function obj = prtOptionsComputation(varargin)
            obj = prtUtilAssignStringValuePairs(obj,varargin{:});
        end
    end

    methods
        function obj = set.largestMatrixSize(obj,val)
            assert(prtUtilIsPositiveInteger(val),'largestMatrixSize must be a positive integer');

            if val < 1e3
                warning('prt:prtOptionsComputation','Although valid, this value for largestMatrixSize is small. Consider using a larger value.')
            end

            obj.largestMatrixSize = val;
        end
    end
end


function disp_lines(rectimg, lines, label, showimage)

if ~exist('showimage','var') || showimage==1
	figure; imshow(rectimg); hold on;
else
	hold on;
end

if nargin<3
    for k = 1:length(lines)
        xy = [lines(k).point1; lines(k).point2];
%         col = [0 0 1];
        col = rand(1,3);
        plot(xy(:,1),xy(:,2), 'LineWidth',2, 'Color', col);
        plot(xy(1,1), xy(1,2), 'x', 'LineWidth',2, 'Color', col);
        text(mean(xy(:,1)),mean(xy(:,2)), num2str(k), 'Color', col);
    end
else
    for k = 1:length(lines)
        xy = [lines(k).point1; lines(k).point2];
text(xy(1,1), xy(1,2), sprintf('%d',k));
        if label(k) == 1
            plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','red');
        elseif label(k) == -1
            plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','blue');
        elseif label(k) == 0
            plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
        end
    end
end


% Ryan Steindl based on Robotics Toolbox for MATLAB (v6 and v9)
%
% Copyright (C) 1993-2011, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com
function [v, a, b] = subsref(r, s)

	if s(1).type  ~= '.'
		%error('only .field supported')
	end

	% NOTE WELL:  the following code can't use getfield() since
	% getfield()  uses this, and Matlab will crash!!

	el = char(s(1).subs);
	switch el,
%-------------------------------------------------------------------------------------
% External Functions
	case 'fkine',
		q = s(2).subs;
		v = fkine(r,q{:});

	case 'ikine6s',
		q = s(2).subs;
		v = ikine6s(r,q{:});

	case 'ikine',
		q = s(2).subs;
		v = ikine(r,q{:});

	case 'maniplty',
		q = s(2).subs;
		[v, a] = maniplty(r,q{:});

	case 'rne'
		q = s(2).subs;
		[v, a] = rne(r,q{:});

	case 'isspherical',
		v = isspherical(r);

	case 'gravload'
		q = s(2).subs;
		v = gravload(r,q{:});

	case 'inertia'
		q = s(2).subs;
		v = inertia(r,q{:});

	case 'cinertia',
		q = s(2).subs;
		v = cinertia(r,q{:});

	case 'coriolis'
		q = s(2).subs;
		v = coriolis(r,q{:});

	case 'friction'
		q = s(2).subs;
		v = friction(r,q{:});

	case 'nofriction'
		if numel(s(2).subs) < 1
		v = nofriction(r);
		else
		q = s(2).subs;
		v = nofriction(r,q{:});
		end

	case 'islimit',
		q = s(2).subs;
		v = islimit(r,q{:});

	case 'payload',
		q = s(2).subs;
		l = r.links;
		l(r.n).m = q{1};
		l(r.n).r = q{2};
		r.links = l;
		v = SerialLink(r);

	case 'jacob0',
		q = s(2).subs;
		v = jacob0(r,q{:});

	case 'accel',
		q = s(2).subs;
		v = accel(r,q{:});

	case 'plot',
		q = s(2).subs;
		plot(r,q{:})

	case 'fdyn',
		q = s(2).subs;
		[v, a, b] = fdyn(r,q{:});

	case 'jacobn',
		q = s(2).subs;
		v = jacobn(r,q{:});

	case 'jtraj',
		q = s(2).subs;
		v = jtraj(r,q{:});

	case 'perturb',
		q = s(2).subs;
		v = perturb(r,q{:});

	case 'itorque',
		q = s(2).subs;
		v = itorque(r,q{:});

	case 'jacob_dot',
		q = s(2).subs;
		v = jacob_dot(r,q{:});

	case 'dyn',
		q = s(2).subs;
		v = dyn(r,q{:});

	case 'showlink',
		q = s(2).subs;
		v = showlink(r,q{:});

%-------------------------------------------------------------------------------------
	case 'links',

		if length(s) == 1,
			v = r.links;

		elseif length(s) == 2,
			if s(2).type == '()'
				j = s(2).subs;
				j = j{:};
				if (j < 1) | (j > r.n)
					error('link index out of bounds')
				end
			end
			v = r.links(j);

		elseif length(s) >= 3,
			if s(2).type == '()'
				j = s(2).subs;
				j = j{:};
				if (j < 1) | (j > r.n)
					error('link index out of bounds')
				end
			end
			if s(3).subs = 'dyn',
				link = r.links(j);
				v = link.dyn();
			end
		end
	case 'offset',
		L = r.links;
		v = [];
		for i=1:r.n,
			v = [v; L(i).offset];
		end
	case 'qlim',
		L = r.links;
		v = [];
		for i=1:r.n,
			v = [v; L(i).qlim];
		end

	case 'n',
		v = r.n;
	case 'name',
		v = r.name;
	case 'dh',
		v = rdh(r);
	case 'dyn'
		v = rdyn(r);
	case 'gravity'
		v = r.gravity;
	case 'tool'
		v = r.tool;
	case 'base'
		v = r.base;
	case 'mdh',
		v = r.mdh;
	case 'q',
		v = r.q;
	case 'plotopt',
		v = r.plotopt;
	case 'lineopt'
		v = r.lineopt;
	case 'shadowopt'
		v = r.shadowopt;
	case {'show', 'handle'}
		v = r.handle';
	otherwise, error('Unknown method in subsref')
	end


%% (Internal) Guess ECG signals indexes in a multimodal recording
%
%   [ECG_idx, ECG_header ]= get_ECG_idx_from_header(ECG_header)
%
% Arguments:
%
%      + ECG_header: header info
%
% Output:
%
%      + ECG_idx: indexes of the ECG signals in the multimodal matrix
%
%      + ECG_header: header of a ECG only recording
%
% Example:
%
%
% See also get_PPG_ABP_idx_from_header, ECGwrapper
%
% Author: Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar
% Version: 0.1 beta
% Last update: 14/5/2014
% Birthdate  : 21/4/2015
% Copyright 2008-2015
%
function [ECG_idx, ECG_header ]= get_ECG_idx_from_header(ECG_header)

    ECG_idx = [];

    str_12_leads_desc = {'I' 'II' 'III' 'AVR' 'AVL' 'AVF' 'V1' 'V2' 'V3' 'V4' 'V5' 'V6' ... %Standard leads.
                         'MLII' 'MLI' 'MLIII' 'MV1' 'MV2' 'MV3' 'MV4' 'MV5' 'MV6' ... % Modifyied leads.
                         'X' 'Y' 'Z' 'VX' 'VY' 'VZ' ... % Orthogonal leads
                         'E-S' 'A-S' 'A-I' ... % Easy leads
                         };

    % add ECG patterns to be matched in ECG_header.desc
    ECG_pattern_desc = {'ECG' 'BIPOLAR' 'LEAD'};

    if( isfield(ECG_header, 'desc') )
        [~, ~, aux_idx ] = intersect(str_12_leads_desc, upper(strtrim(cellstr(ECG_header.desc))) );
    else
        aux_idx = [];
    end

    if( ECG_header.nsig ~= length(aux_idx) )

        ECG_idx = colvec(aux_idx);

        if( isfield(ECG_header, 'desc') )
            aux_idx = find(any(cell2mat(cellfun(@(b)(cell2mat(cellfun(@(a)(~isempty(strfind(a, b))), rowvec(upper(cellstr(ECG_header.desc))), 'UniformOutput', false))), colvec(ECG_pattern_desc), 'UniformOutput', false)),1));
        else
            aux_idx = [];
        end

        if( ~(isempty(aux_idx) && isempty(ECG_idx)) )
            ECG_idx = [ECG_idx; colvec(aux_idx)];
            Not_ECG_idx = setdiff(1:ECG_header.nsig, ECG_idx);
            if( ~isempty(Not_ECG_idx) )
%                 warning('get_ECG_idx_from_header:SignalsDiscarded', disp_option_enumeration('Some signal/s present are not ECG:', cellstr(ECG_header.desc(Not_ECG_idx,:)) ))
            end
        end

        ECG_idx = sort(ECG_idx);

    else
        % all leads are standard ECG leads
        ECG_idx = 1:ECG_header.nsig;
    end

    if(length(ECG_idx) ~= ECG_header.nsig && nargout > 1)
       %trim the heasig if needed
        ECG_header = trim_ECG_header(ECG_header, ECG_idx);
    end


function tetris(action)

% TETRIS for MATLAB
%
%	To begin, simply type: tetris
%
%	Only one game can be run at a time.
%	UN-PAUSE (I know that's not a word) the game by hitting RETURN
%	in the Matlab command window.
%
%	Please feel free to modify, improve, rewrite, cleanup the code etc.
%	Written and tested on a SUN running Matlab 4.2c, but should work with
%	Matlab 4.0, if not you can debug/modify it.
%	This is FREEWARE, enjoy!   -  Peace & Love

%
%	Author: Maurice Smith, 1/19/95 (msmith@bme.jhu.edu)

global CENTER_X CENTER_Y POS STUCK USED_SPACE H;
global WIDTH1 HEIGHT1 LEVEL TIME_DELAY SQ_X SQ_Y;
global H_SLIDER_LEVEL H_SLIDER_WIDTH H_SLIDER_HEIGHT;
global H_TEXT_LEVEL H_TEXT_WIDTH H_TEXT_HEIGHT H_TEXT_SCORE;
global START_HANDLE STOP_HANDLE STOP_GAME EXIT_HANDLE;
global H_A H_B BOX H_LINE MIN_DELAY MAX_DELAY;

if nargin < 1, action = 'initialize'; end;

if strcmp(action,'initialize'),

default_width = 10;		% default width of tetris play-field
default_height = 25;		% default hieght of tetris play-field
default_level = 5;		% default skill level
default_box = 1;		% default play field outline (on=1, off=0)

WIDTH1 = default_width;
HEIGHT1 = default_height;
LEVEL = default_level;
BOX = default_box;

MIN_DELAY = 0.1;		% delay corresponding to skill level 9
MAX_DELAY = 1;			% delay corresponding to skill level 0
TIME_DELAY = MAX_DELAY*exp((LEVEL/9)*log(MIN_DELAY/MAX_DELAY));
fig=figure( ...
        'Name','Tetris for Matlab', 'NumberTitle','off', ...
        'Visible','off', 'BackingStore','off');

SQ_X = [0 -1 -1 0]';	% vertex coordinates of unit square (for "patch" command)
SQ_Y = [0 0 -1 -1]';

on = 'set(go_handle,''back'',''cyan''), ';
off = 'set(go_handle,''back'',''default''), ';

figure(fig);
H_A = axes( ...
        'Units','normalized', 'Position', [.1 .18 .4 .8], ...
        'Visible','off', 'DrawMode','fast', ...
        'NextPlot','replace', 'XLim',[1 WIDTH1+1],'YLim',[0 HEIGHT1]);
H_B = axes( ...
        'Units','normalized', 'Position', [.1 .18 .4 .8],...
        'Visible','off', 'DrawMode','fast', ...
        'NextPlot','replace', 'XLim',[1 WIDTH1+1],'YLim',[0 HEIGHT1]);

if BOX == 1,			% draw outline box initially
	BOX = ~BOX;
	tetris('box');
end

pause_handle = uicontrol('units','normalized',...
	'position', [.7 .04 .1 .05],'string','pause', ...
	'callback','disp(''press RETURN to continue''); pause;', ...
	'interruptible','no');

box_handle = uicontrol('units','normalized',...
	'position', [.7 .15 .1 .05],'string','box', ...
	'callback','tetris(''box'');', ...
	'interruptible','yes');

STOP_HANDLE = uicontrol('units','normalized',...
	'position', [.55 .04 .1 .05],'string','stop', ...
	'callback','tetris(''stop'')', ...
	'interruptible','yes','visible','off');

EXIT_HANDLE = uicontrol('units','normalized',...
	'position', [.85 .04 .1 .05],'string','exit', ...
	'callback','delete(gcf)', ...
	'interruptible','no');

START_HANDLE = uicontrol('units','normalized',...
	'position', [.55 .04 .1 .05],'string','start', ...
	'callback','tetris(''start'')', ...
	'interruptible','yes','visible','on');

left_handle = uicontrol('units','normalized',...
	'position', [.18 .07 .1 .05 ],'string','<---', ...
	'callback','tetris(''left'')', ...
	'interruptible','yes');

right_handle = uicontrol('units','normalized',...
	'position', [.32 .07 .1  .05 ],'string','--->', ...
	'callback','tetris(''right'')', ...
	'interruptible','yes');

drop_handle = uicontrol('units','normalized',...
	'position',[.25 .01 .1 .05 ],'string','drop', ...
	'callback','tetris(''drop'')');

rotate_handle = uicontrol('units','normalized',...
	'position',[.25 .13 .1 .05],'string','rotate', ...
	'callback','tetris(''rotate'')');

H_TEXT_SCORE = uicontrol(...
		'ForegroundColor',[ 1 1 1 ],...
		'Position',[ 0.65 0.85 0.2 0.07 ],...
		'String','Score: xxxxx',...
		'Units','normalized');

v = version;
if str2num(v(1:3)) >= 4.2,	% if Matlab 4.2 or later, create slider controls

H_SLIDER_LEVEL = uicontrol(...
		'CallBack', 'tetris(''level''); ', 'Max',[ 9 ], 'Min',[ 0 ],...
		'val', LEVEL, 'Position', [ 0.6 0.3 0.04 0.4 ],...
		'Style', 'slider', 'Units', 'normalized');

H_SLIDER_HEIGHT = uicontrol(...
		'CallBack', 'tetris(''height''); ', 'Max', [ 50 ], 'Min', [ 10 ],...
		'val', HEIGHT1, 'Position', [ 0.78 0.3 0.04 0.4 ],...
		'Style', 'slider', 'Units', 'normalized');

H_SLIDER_WIDTH = uicontrol(...
		'CallBack','tetris(''width''); ','Max',[ 20 ],'Min',[ 6 ],...
		'val',WIDTH1,'Position',[ 0.9 0.3 0.04 0.4 ],...
		'Style','slider','Units','normalized');

H_label_width = uicontrol(...
		'ForegroundColor',[ 0 1 1 ], 'Position',[0.87 .72 .1 .06],...
		'String','Width', 'Style','text', 'Units','normalized');

H_label_Height = uicontrol(...
		'ForegroundColor',[ 1 1 0 ], 'Position',[ 0.75 0.72 0.1 0.06 ],...
		'String','Height', 'Style','text', 'Units','normalized');

H_label_level = uicontrol(...
		'ForegroundColor',[ 1 0 0 ], 'Position',[ 0.57 0.72 0.1 0.06 ],...
		'String','Level', 'Style','text', 'Units','normalized');

H_TEXT_WIDTH = uicontrol(...
		'ForegroundColor',[ 0 1 1 ], 'Position',[0.87 .22 .1 .06],...
		'String',num2str(WIDTH1), 'Style','text', 'Units','normalized');

H_TEXT_HEIGHT = uicontrol(...
		'ForegroundColor',[ 1 1 0 ], 'Position',[ 0.75 0.22 0.1 0.06 ],...
		'String',num2str(HEIGHT1), 'Style','text', 'Units','normalized');

H_TEXT_LEVEL = uicontrol(...
		'ForegroundColor',[ 1 0 0 ], 'Position',[ 0.57 0.22 0.1 0.06 ],...
		'String',num2str(LEVEL), 'Style','text', 'Units','normalized');

end;    % end version 4.2 extras (slider controls & labels)

end; 	% end initialization routine

if strcmp(action,'level'),				% set skill level
	LEVEL = round(get(H_SLIDER_LEVEL,'val'));
	set(H_TEXT_LEVEL,'string',LEVEL);
	TIME_DELAY = MAX_DELAY*exp((LEVEL/9)*log(MIN_DELAY/MAX_DELAY));
end;

if strcmp(action,'height'),			% set play-field height
	HEIGHT1 = round(get(H_SLIDER_HEIGHT,'val'));
	set(H_TEXT_HEIGHT,'string',HEIGHT1);
end;

if strcmp(action,'width'),			% set play-field width
	WIDTH1 = round(get(H_SLIDER_WIDTH,'val'));
	set(H_TEXT_WIDTH,'string',WIDTH1);
end;

if strcmp(action,'box'),		% toggle display of play-field outline
	BOX = ~BOX;
	if BOX == 1,
		H_LINE = line ([1 WIDTH1+1 WIDTH1+1 1 1], [1 1 HEIGHT1 HEIGHT1 1]);
	else, delete(H_LINE);
	end
end;

if strcmp(action,'left'),		% Move Left
	stopped = 0;
	for i=1:4, if USED_SPACE(POS(i,1)-1,POS(i,2)) == 1, stopped=1; end; end;
	if stopped == 0,
		POS(:,1) = POS(:,1) - 1;
		CENTER_X = CENTER_X - 1;
		for i=1:4, set(H(i),'XData',SQ_X+POS(i,1),'YData',SQ_Y+POS(i,2)); end;
		drawnow;
	end;
end;

if strcmp(action,'right'),		% Move Right
	stopped = 0;
	for i=1:4, if USED_SPACE(POS(i,1)+1,POS(i,2)) == 1, stopped=1; end; end;

	if stopped == 0,
		POS(:,1) = POS(:,1) + 1;
		CENTER_X = CENTER_X + 1;
		for i=1:4, set(H(i),'XData',SQ_X+POS(i,1),'YData',SQ_Y+POS(i,2)); end;
		drawnow;
	end;
end;

if strcmp(action,'drop'),		% Drop Piece Down
	while STUCK==0,
		for i=1:4, if USED_SPACE(POS(i,1),POS(i,2)-1) == 1, STUCK=1; end; end;
		if STUCK == 0, POS(:,2) = POS(:,2) -1; end;
	end;
	for i=1:4, set(H(i),'XData',SQ_X+POS(i,1),'YData',SQ_Y+POS(i,2)); end;
	drawnow;

end;

if strcmp(action,'rotate'),			% Rotate
	new_x = -(POS(:,2) - CENTER_Y) + CENTER_X;
	new_y = (POS(:,1) - CENTER_X) + CENTER_Y;
	stopped = 0;
	for i=1:4,
		if ((new_x>1) & (new_x<(WIDTH1+2)) & (new_y>1)),
			if USED_SPACE(new_x(i), new_y(i)) == 1, stopped=1; end;
		else, stopped=1;
		end;
	end;
	if stopped == 0,			% space not occupied
		POS = [new_x new_y];
		for i=1:4, set(H(i),'XData',SQ_X+POS(i,1),'YData',SQ_Y+POS(i,2)); end;
		drawnow;
	end;
end;

if strcmp(action,'stop'),             % stop game
	STOP_GAME = 1;
end;

% start tetris game

if strcmp(action,'start'),             % start game

STOP_GAME = 0;
score = 0;
set(START_HANDLE, 'visible', 'off');
set(STOP_HANDLE, 'visible', 'on');
set(EXIT_HANDLE, 'visible', 'off');
set(H_TEXT_SCORE, 'string', ['Score: ' num2str(score)]);

h_matb = zeros(WIDTH1+2,HEIGHT1);
USED_SPACE = zeros(WIDTH1+2,HEIGHT1);
USED_SPACE(:,1) = ones(WIDTH1+2,1);
USED_SPACE ([1 WIDTH1+2],:) = ones(2,HEIGHT1);
%USED_SPACE
drawnow;
axes(H_A);

% shape definitions

a_shape = [-1 0 1 2; 0 0 0 0]';		% rectangle 1x4
b_shape = [-1 0 0 1; 0 0 1 0]';		% Z mirror
c_shape = [-1 0 0 1; 0 0 1 1]';		% Z normal
d_shape = [-1 0 0 1; 1 1 0 0]';		% truncated T
e_shape = [0 0 1 1; 0 1 0 1]';		% square 2x2
f_shape = [-1 0 1 1; 0 0 0 1]';		% L normal
g_shape = [-1 -1 0 1; 1 0 0 0]';	% L mirror

shape_matrix = [a_shape b_shape c_shape d_shape e_shape f_shape g_shape];
s = size(shape_matrix);
num_shapes = s(2) / 2;

color_matrix = [ 0 0 1; 0 1 0; 0 1 1; 1 0 0; 1 0 1; 1 1 0; 1 1 1];
home_pos = ones(4,1) * [(WIDTH1/2) (HEIGHT1-2)];
POS = a_shape + home_pos;
for i=1:4, H(i) = patch(SQ_X+POS(i,1),SQ_Y+POS(i,2),'r'); end;

while ((sum(USED_SPACE(2:WIDTH1+1,HEIGHT1-4)) == 0) & (STOP_GAME == 0)),

	shape_index = ceil(num_shapes*rand(1)); 	% choose random shape
	current_color = color_matrix(shape_index,:);	% associated color
	POS = shape_matrix(:,(2*shape_index - 1):(2*shape_index)) + home_pos;	% set initial postion of shape
	CENTER_X = home_pos(1,1);			% set origin of rotation
	CENTER_Y = home_pos(1,2);
	for i = 1:4,
		set(H(i),'XData',SQ_X+POS(i,1), 'YData',SQ_Y+POS(i,2), ...
			'FaceColor', current_color, 'Visible', 'on');
	end;
	drawnow;
	STUCK = 0;
	t0 = clock;
	while ((STUCK == 0) & (STOP_GAME == 0)),
		drawnow;
		if etime(clock,t0) > TIME_DELAY,	% move piece down one unit
			%etime(clock,t0)
			for i=1:4,
				if USED_SPACE(POS(i,1),POS(i,2)-1) == 1, STUCK=1; end;
			end;

			if STUCK == 0,
				t0 = clock;
				POS(:,2) = POS(:,2) - 1;
				CENTER_Y = CENTER_Y - 1;
				for i = 1:4,
					set(H(i),'YData',SQ_Y+POS(i,2));
				end;
				drawnow;
				%etime(clock,t0)

			end
		end;
		drawnow;
	end
	for i=1:4, USED_SPACE(POS(i,1),POS(i,2)) = 1; end;	% retire piece
	for i = 1:4, set(H(i),'Visible', 'off'); end;		% hide active piece
	axes(H_B);
	for i=1:4, h_matb(POS(i,1),POS(i,2)) = patch(SQ_X+POS(i,1),SQ_Y+POS(i,2),current_color); end;

	i=2;
	while i < HEIGHT1,  				% check if any lines are complete
		if sum(USED_SPACE(2:WIDTH1+1,i)) == WIDTH1,
			score = score + 10*(LEVEL+1);	% add score for completing line
			set(H_TEXT_SCORE, 'string', ['Score: ' num2str(score)]);
			for k1=2:WIDTH1+1, delete(h_matb(k1,i)); end;
			for k2=(i+1):HEIGHT1,
				for k1=2:WIDTH1+1,
					if h_matb(k1,k2) ~= 0,
						%disp([k1 k2 h_matb(k1,k2)]);
						set(h_matb(k1,k2),'YData',k2-1+SQ_Y);
					end;
				end;
			end;
			h_matb(2:WIDTH1+1,i:(HEIGHT1-1)) = h_matb(2:WIDTH1+1,(i+1):HEIGHT1);
			h_matb(2:WIDTH1+1,HEIGHT1) = zeros(WIDTH1,1);
			USED_SPACE(2:WIDTH1+1,i:(HEIGHT1-1)) = USED_SPACE(2:WIDTH1+1,(i+1):HEIGHT1);
			USED_SPACE(2:WIDTH1+1,HEIGHT1) = zeros(WIDTH1,1);
		else i = i+1;
		end

	end
	axes(H_A);

end  % end while loop

for k2=2:HEIGHT1,		% delete objects and clear play-field
	for k1=2:WIDTH1+1,
		if h_matb(k1,k2) ~= 0,
			delete(h_matb(k1,k2));
		end;
	end;
end;
set(START_HANDLE, 'visible', 'on');
set(STOP_HANDLE, 'visible', 'off');
set(EXIT_HANDLE, 'visible', 'on');

end  	% end 'start' command (end game)


%% FEM2D_FSU uses the fsuClusterMatlab command to run the FEM2D computation.
%
%  Discussion:
%
%    The arguments to fsuClusterMatlab mean:
%
%    [] allows us to specify an output directory;
%    [] allows us to specify switches to the MOAB queue handler, such as more time.
%    'm" indicates this is an "MPI-like" job;
%    'w' indicates that the MATLAB session should wait for completion;
%    4 is the number of processors requested;
%    @fem2d_fun indicates the function we want to execute;
%    { param } contains input arguments.
%
%    The function "fem2d_fun" must correspond to a MATLAB M-file "fem2d_fun.m"
%    and that file must be in MATLAB's path.
%
%    The easiest way to ensure that the file is in MATLAB's path is to
%    create a subdirectory called "matlab" immediately below your home directory,
%    and place the function file there (as well as any other files needed by the job).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 March 2010
%
%  Author:
%
%    John Burkardt
%
  param = p_data ( );

  fsuClusterMatlab ( [], [], 'm', 'w', 4, @fem2d_fun, { param } )


% create_study_fv() - creates a STUDY structure using ALL sets stored in a folder specified by the parameter "pathin".
%
% Usage:
%             >> [STUDY, ALLEEG] = create_study_fv(pathin,pathout,studyname,badcomps);
% Inputs:
%   pathin     - [string] path to the folder containing datasets
%   pathout    - [string] path where STUDY is going to be saved
%   studyname  - [string] name used to save STUDY
%   badcomps   - [0 1] badcomps=1 -> EEG.badcomps is created for each
%                single dataset as an empty field; badcomps=0 -> EEG.badcomps is not created
%
% Outputs:
%   STUDY      - a new STUDY set containing ALL datasets stored in the folder
%   ALLEEG     - a vector of EEG datasets included in the STUDY structure
%
%  See also:  pop_createstudy()
%
% Authors: Filipa Campos Viola, 24/01/2008, MRC-IHR, Southampton, UK
% (f.viola@soton.ac.uk)

%123456789012345678901234567890123456789012345678901234567890123456789012

% Copyright (C) F. Campos Viola, MRC-IHR
%
% 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

% revised by F Campos-Viola - corrmap1.01 (30/01/2009)

% revised by F Campos-Viola - adding option to created EEG.badcomps as an empty field for each dataset (30/01/2009)

function [STUDY,ALLEEG]=create_study_fv(pathin, pathout,studyname,badcomps)

cd(pathin) %points to a path
list=dir('*.set'); %reads all .set files in that path

%[ALLEEG EEG CURRENTSET ALLCOM] = eeglab;

STUDY=[];
ALLEEG=[];

n=length(list); %number of datasets that are going to be included in STUDY

if badcomps==1
for j=1:n

    EEG = pop_loadset(list(j).name, pathin);

    EEG.badcomps=[];

    EEG = eeg_checkset(EEG);
    [ALLEEG EEG] = eeg_store(ALLEEG, EEG);

    EEG = pop_saveset(EEG, list(j).name, pathin);

end
end

for i= 1:n

    %creating the study
    [STUDY ALLEEG]= std_editset(STUDY, ALLEEG,'name', studyname, 'commands', {...
        {'index', i,'load', [pathin,list(i).name],'subject',num2str(i)}
    });
end

%saving the STUDY and not changing datasets
[STUDY ALLEEG]= std_editset(STUDY,ALLEEG,'filename',[pathout studyname '.study'], 'updatedat', 'off');

%CURRENTSTUDY = 1; EEG = ALLEEG; CURRENTSET = [1:length(EEG)];

[STUDY, ALLEEG] = std_checkset(STUDY, ALLEEG);


function u = mldivide(L, f, varargin)
%\         Solve a linear system (same as LINOP.LINSOLVE).
%   Important: A CHEBOPPREF object PREFS has to be passed. When this method
%   is called via CHEBOP/MLDIVIDE, PREFS is inherited from the CHEBOP level.
%
%  Copyright 2017 by The University of Oxford and The Chebfun Developers.
%  See http://www.chebfun.org/ for Chebfun information.
u = linsolve(L, f, varargin{:});

end


function [ sout, slist ] = cvx_solver( sname )

%CVX_SOLVER    CVX solver selection.
%   CVX_SOLVER <solver_name> or CVX_SOLVER('<solver_name>')
%   selects the named solver the CVX uses to solve models. The solver name
%   is case-insensitive; so, for example, both 'SeDuMi' and 'sedumi' will
%   select the same solver.
%
%   When CVX is first installed, the solver SDPT3 is selected as the
%   default. For most problems, this will be a good choice; nevertheless,
%   no solver is perfect, so if you encounter issues you may wish to
%   experiment with other solvers.
%
%   There are two ways to use the CVX_SOLVER command. If you use it within
%   a model---that is, between the statements CVX_BEGIN and CVX_END---then
%   the new solver selection will apply only to that particular model. For
%   instance, if the default solver is SDPT3, then the following structure
%   will solve a single model using SeDuMi instead:
%       cvx_begin
%           cvx_solver sedumi
%           variables ...
%           ...
%       cvx_end
%   On the other hand, if CVX_SOLVER is called *outside* of a model, then
%   the change will apply for all subsequent models, or until you call
%   CVX_SOLVER once again.
%
%   [ SOLVER, SOLVER_LIST ] = CVX_SOLVER returns the name of the current
%   solver, and a cell array containing the names of all available choices.
%
%   Calling CVX_SOLVER with no input or output arguments produces a listing
%   of the solvers that CVX currently recognized, and an indication of the
%   current solver selection and/or the default.

global cvx___
cvx_global
if nargin,
    if isempty( sname ),
        sname = 'default';
    elseif ~ischar( sname ) || size( sname, 1 ) ~= 1,
        cvx_throw( 'Argument must be a string.' );
    end
    try
        snumber = cvx___.solvers.map.(lower(sname));
    catch
        cvx_throw( 'Unknown, unusable, or missing solver: %s', sname );
    end
    if ~isempty( cvx___.solvers.list(snumber).error ),
        cvx_throw( 'Solver unusable due to prior errors: %s', sname );
    end
    if isempty( cvx___.problems ),
        cvx___.solvers.selected = snumber;
    elseif ~isa( evalin( 'caller', 'cvx_problem', '[]' ), 'cvxprob' ),
        cvx_throw( 'The global CVX solver selection cannot be changed while a model is being constructed.' );
    elseif cvx___.problems(end).solver ~= snumber,
        cvx___.problems(end).solver = snumber;
        cvx___.problems(end).settings = cvx___.solvers.list.settings;
    end
    if cvx___.solvers.active,
        cvx_setspath;
    end
elseif nargout == 0,
    solvers = cvx___.solvers;
    snames = solvers.names;
    statvec = [ 0, solvers.map.default, solvers.active ];
    statstr = { 'selected', 'default', 'active' };
    if ~isempty( cvx___.problems ),
        statvec(1) = cvx___.problems(end).solver;
    else
        statvec(1) = solvers.selected;
    end
    fprintf( '\n' );
    dash = '-';
    solvers = solvers.list;
    nsolv = length( solvers );
    lens = [4,6,7,8];
    for k = 1 : nsolv,
        if isempty( solvers(k).error ),
            nstat = statstr(k==statvec);
            if ~isempty(nstat),
                nstat = sprintf( '%s,', nstat{:} );
                nstat = nstat(1:end-1);
            end
        else
            nstat = 'disabled';
        end
        lens = max( lens, [ length(snames{k}), length(nstat), length(solvers(k).version), length(solvers(k).location) ] );
    end
    fmt = sprintf( '   %%-%ds   %%-%ds   %%-%ds   %%s\\n', lens(1), lens(2), lens(3) );
    fprintf( fmt, 'Name', 'Status', 'Version', 'Location' ); %#ok
    fprintf( '%s\n', dash(ones(1,sum(lens)+15)) );
    for k = 1 : nsolv,
        if isempty( solvers(k).error ),
            nstat = statstr(k==statvec);
            if ~isempty(nstat),
                nstat = sprintf( '%s,', nstat{:} );
                nstat = nstat(1:end-1);
            else
                nstat = '';
            end
        else
            nstat = 'disabled';
        end
        fprintf( fmt, snames{k}, nstat, solvers(k).version, solvers(k).location );
    end
    fprintf( '\n' );
end
if nargout > 0,
    sout = cvx___.solvers.list(cvx___.solvers.selected).name;
    slist = cvx___.solvers.names;
end

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


%% Facemark LBF training demo
%
% The user should provides the list of training images accompanied by their
% corresponding landmarks location in separate files.
%
% See below for a description of file formats.
%
% Examples of datasets are available at
% <https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/>.
%
% Sources:
%
% * <https://github.com/opencv/opencv_contrib/blob/3.4.0/modules/face/samples/facemark_demo_lbf.cpp>
% * <https://github.com/opencv/opencv_contrib/blob/3.4.0/modules/face/tutorials/facemark_usage/facemark_usage.markdown>
%

%% Preparation
%
% Before you continue with this tutorial, you should download a training
% dataset of facial landmarks detection.
%
% We suggest you to download the IBUG dataset which can be retrieved at
% <https://ibug.doc.ic.ac.uk/download/annotations/ibug.zip>
%
% First thing to do is to make two text files containing the list of image
% files and annotation files respectively. Make sure that the order of images
% and annotations in both files are matched. Furthermore, it is advised to use
% absolute paths instead of relative paths.
%
% Example to make the file list in Linux machine:
%
%  ls /data/ibug/*.jpg > images.txt
%  ls /data/ibug/*.pts > annotations.txt
%
% Example of content in the |images.txt| file:
%
%  /data/ibug/image_003_1.jpg
%  /data/ibug/image_004_1.jpg
%  /data/ibug/image_005_1.jpg
%  ...
%
% Example of content in the |annotations.txt| file:
%
%  /data/ibug/image_003_1.pts
%  /data/ibug/image_004_1.pts
%  /data/ibug/image_005_1.pts
%  ...
%
% where a |.pts| file contains the position of each face landmark.
% Make sure that the annotation format is supported by the API, where the
% contents should look like the following snippet:
%
%  version: 1
%  n_points:  68
%  {
%  212.716603 499.771793
%  230.232816 566.290071
%  ...
%  }
%
% Once trained, we show how to use the model to detect face landmarks in a
% test image.
%
% You can also download a pre-trained model in this link
% <https://raw.githubusercontent.com/kurnianggoro/GSOC2017/master/data/lbfmodel.yaml>
% (that way you can skip training and simply load the model).
%

%% Options

% [INPUT] path of a text file contains the list of paths to all training images
imgList = fullfile(mexopencv.root(),'test','facemark','ibug','images.lst');
assert(exist(imgList, 'file') == 2, 'missing images list file');

% [INPUT] path of a text file contains the list of paths to all annotations files
ptsList = fullfile(mexopencv.root(),'test','facemark','ibug','annotations.lst');
assert(exist(ptsList, 'file') == 2, 'missing annotations list file');

% [OUTPUT] path for saving the trained model
modelFile = fullfile(tempdir(), 'model_lbf.yaml');

% [INPUT] path to the cascade xml file for the face detector
xmlFace = fullfile(mexopencv.root(),'test','lbpcascade_frontalface.xml');
download_classifier_xml(xmlFace);

% name of user-defined face detector function
faceDetectFcn = 'myFaceDetector';
assert(exist([faceDetectFcn '.m'], 'file') == 2, 'missing face detect function');

% path to test image
testImg = fullfile(mexopencv.root(),'test','lena.jpg');

%% Init
% create the facemark instance
obj = cv.Facemark('LBF', 'NLandmarks',68, 'CascadeFace',xmlFace, ...
    'ModelFilename',modelFile, 'SaveModel',true, 'Verbose',true);

%%
% set user-defined face detector
obj.setFaceDetector(faceDetectFcn);

%% Data
% load the dataset, and add training samples one-by-one
disp('Loading data...')
[imgFiles, ptsFiles] = cv.Facemark.loadDatasetList(imgList, ptsList);
for i=1:numel(imgFiles)
    % load image and its corresponding annotation data, then add pair
    img = cv.imread(imgFiles{i});
    pts = cv.Facemark.loadFacePoints(ptsFiles{i});
    obj.addTrainingSample(img, pts);
end

%% Train
% train the algorithm, model will be saved to specified file
disp('Training...')
tic
obj.training();
toc

%% Test
% run on some test image
img = cv.imread(testImg);
faces = obj.getFaces(img);
landmarks = obj.fit(img, faces);
for i=1:numel(faces)
    img = cv.rectangle(img, faces{i}, 'Color',[255 0 255]);
    img = cv.Facemark.drawFacemarks(img, landmarks{i}, 'Color',[0 0 255]);
end
imshow(img)

%% Helper functions

function download_classifier_xml(fname)
    if exist(fname, 'file') ~= 2
        % attempt to download trained Haar/LBP/HOG classifier from Github
        url = 'https://cdn.rawgit.com/opencv/opencv/3.4.0/data/';
        [~, f, ext] = fileparts(fname);
        if strncmpi(f, 'haarcascade_', length('haarcascade_'))
            url = [url, 'haarcascades/'];
        elseif strncmpi(f, 'lbpcascade_', length('lbpcascade_'))
            url = [url, 'lbpcascades/'];
        elseif strncmpi(f, 'hogcascade_', length('hogcascade_'))
            url = [url, 'hogcascades/'];
        else
            error('File not found');
        end
        urlwrite([url f ext], fname);
    end
end

% The facemark API provides the functionality to the user to use their own
% face detector. The code below implements a sample face detector. This
% function must be saved in its own M-function to be used by the facemark API.
function faces = myFaceDetector(img)
    persistent obj
    if isempty(obj)
        obj = cv.CascadeClassifier();
        obj.load(xmlFace);
    end

    if size(img,3) > 1
        gray = cv.cvtColor(img, 'RGB2GRAY');
    else
        gray = img;
    end
    gray = cv.equalizeHist(gray);
    faces = obj.detect(gray, 'ScaleFactor',1.4, 'MinNeighbors',2, ...
        'ScaleImage',true, 'MinSize',[30 30]);
end


%kWaveletSpots 'localizes spots based on wavelet analysis '
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros WaveletSpots.pane file
%
% Parameters:
% InputFile: i 'Input ', required: 'First Input data object'
% Integer: nw 'Wavelet Levels', default: 3: 'number of wavelet levels to account for'
% Integer: mw 'First Wavelet', default: 1: 'number of first wavelet that counts for thresholding (starting with 0)'
% Double: krel 'Relative k', default: 3: 'this factor defines the threshold for the wavelet images prior to multiplication'
% OutputFile: o1 'Filtered', optional: 'Filtered images'
% OutputFile: o2 'Wavelet', optional: 'Wavelet decomposition (a trous)'
% OutputFile: o3 'Output', required: 'Multiplication of the wavelets to be thresholded'
%
% Example: [o1, o2, o3] = kWaveletSpots(i, {'i','';'nw',3;'mw',1;'krel',3;'o1','';'o2','';'o3',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% WaveletSpots - localizes spots based on wavelet analysis
%
%  DESCRIPTION
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1996-2003, Rainer Heintzmann,  All rights reserved.
%

function varargout = kWaveletSpots(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kWaveletSpots(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'nw', 3;'mw', 1;'krel', 3;'o1', '__output';'o2', '__output';'o3', '__output'};
maxval={0,2,1,0,1,1,0};
minval={0,2,1,0,1,1,0};
istoggle=[0,0,0,1,1,1,0];
was_set=istoggle * 0;
paramtype={'InputFile','Integer','Integer','Double','OutputFile','OutputFile','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'waveletspots"  -k'],Inputs,narglist);