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

%%
clear; close all; clc;

%% Syntax
% |cVoigt=voigtMap(c);|

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


function mfprintf(fid, varargin)
% mfprintf(fid, varargin)
% As fprintf but allows fid to be a vector.
% For example:
% fid = fopen('foo.txt','a');
% mfprintf([fid 1], 'Hello %s\m','world')
% fclose(fid);
% prints 'Hello world' into file foo.txt and on the screen at the same
% time.

arrayfun(@(fid) fprintf(fid, varargin{:}), fid,'UniformOutput',0);


function result = query(BIDS,query,varargin)
% Query a directory structure formated according to the BIDS standard
% FORMAT result = bids.query(BIDS,query,...)
% BIDS   - BIDS directory name or BIDS structure (from bids.layout)
% query  - type of query: {'data', 'metadata', 'sessions', 'subjects',
%          'runs', 'tasks', 'runs', 'types', 'modalities'}
% result - outcome of query
%__________________________________________________________________________
%
% BIDS (Brain Imaging Data Structure): https://bids.neuroimaging.io/
%   The brain imaging data structure, a format for organizing and
%   describing outputs of neuroimaging experiments.
%   K. J. Gorgolewski et al, Scientific Data, 2016.
%__________________________________________________________________________

% Copyright (C) 2016-2018, Guillaume Flandin, Wellcome Centre for Human Neuroimaging
% Copyright (C) 2018--, BIDS-MATLAB developers

if nargin < 2
    error('Not enough input arguments.');
end

BIDS = bids.layout(BIDS);

opts = parse_query(varargin);

switch query
%   case 'subjects'
%       result = regexprep(unique({BIDS.subjects.name}),'^[a-zA-Z0-9]+-','');
    case 'modalities'
        hasmod = arrayfun(@(y) structfun(@(x) isstruct(x) & ~isempty(x),y),...
            BIDS.subjects,'UniformOutput',false);
        hasmod = any([hasmod{:}],2);
        mods   = fieldnames(BIDS.subjects)';
        result = mods(hasmod);
    case {'sessions','subjects', 'tasks', 'runs', 'types', 'data', 'metadata'}
        %-Initialise output variable
        result = {};
        %-Filter according to subjects
        if any(ismember(opts(:,1),'sub'))
            subs = opts{ismember(opts(:,1),'sub'),2};
            opts(ismember(opts(:,1),'sub'),:) = [];
        else
            subs = unique({BIDS.subjects.name});
            subs = regexprep(subs,'^[a-zA-Z0-9]+-','');
        end
        %-Filter according to modality
        if any(ismember(opts(:,1),'modality'))
            mods = opts{ismember(opts(:,1),'modality'),2};
            opts(ismember(opts(:,1),'modality'),:) = [];
        else
            mods = bids.query(BIDS,'modalities');
        end
        %-Get optional target option for metadata query
        if strcmp(query,'metadata') && any(ismember(opts(:,1),'target'))
            target = opts{ismember(opts(:,1),'target'),2};
            opts(ismember(opts(:,1),'target'),:) = [];
            if iscellstr(target)
                target = substruct('.',target{1});
            end
        else
            target = [];
        end
        %-Perform query
        for i=1:numel(BIDS.subjects)
            if ~ismember(BIDS.subjects(i).name(5:end),subs), continue; end
            for j=1:numel(mods)
                d = BIDS.subjects(i).(mods{j});
                for k=1:numel(d)
                    sts = true;
                    for l=1:size(opts,1)
                        if ~isfield(d(k),opts{l,1}) || ~ismember(d(k).(opts{l,1}),opts{l,2})
                            sts = false;
                        end
                    end
                    switch query
                        case 'subjects'
                            if sts
                                result{end+1} = BIDS.subjects(i).name;
                            end
                        case 'sessions'
                            if sts
                                result{end+1} = BIDS.subjects(i).session;
                            end
                        case 'data'
                            if sts && isfield(d(k),'filename')
                                if strcmp(mods{j},'other')
                                    result{end+1} = fullfile(BIDS.subjects(i).path,d(k).filename);
                                else
                                    result{end+1} = fullfile(BIDS.subjects(i).path,mods{j},d(k).filename);
                                end
                            end
                        case 'metadata'
                            if sts && isfield(d(k),'filename')
                                f = fullfile(BIDS.subjects(i).path,mods{j},d(k).filename);
                                result{end+1} = get_metadata(f);
                                if ~isempty(target)
                                    try
                                        result{end} = subsref(result{end},target);
                                    catch
                                        warning('Non-existent field for metadata.');
                                        result{end} = [];
                                    end
                                end
                            end
%                             if sts && isfield(d(k),'meta')
%                                 result{end+1} = d(k).meta;
%                             end
                        case 'runs'
                            if sts && isfield(d(k),'run')
                                result{end+1} = d(k).run;
                            end
                        case 'tasks'
                            if sts && isfield(d(k),'task')
                                result{end+1} = d(k).task;
                            end
                        case 'types'
                            if sts && isfield(d(k),'type')
                                result{end+1} = d(k).type;
                            end
                    end
                end
            end
        end
        %-Postprocessing output variable
        switch query
            case 'subjects'
                result = unique(result);
                result = regexprep(result,'^[a-zA-Z0-9]+-','');
            case 'sessions'
                result = unique(result);
                result = regexprep(result,'^[a-zA-Z0-9]+-','');
                result(cellfun('isempty',result)) = [];
            case 'data'
                result = result';
            case 'metadata'
                if numel(result) == 1
                    result = result{1};
                end
            case {'tasks','runs','types'}
                result = unique(result);
                result(cellfun('isempty',result)) = [];
        end
    otherwise
        error('Unable to perform BIDS query.');
end

%==========================================================================
%-Parse BIDS query
%==========================================================================
function query = parse_query(query)
if numel(query) == 1 && isstruct(query{1})
    query = [fieldnames(query{1}), struct2cell(query{1})];
else
    if mod(numel(query),2)
        error('Invalid input syntax.');
    end
    query = reshape(query,2,[])';
end
for i=1:size(query,1)
    if ischar(query{i,2})
        query{i,2} = cellstr(query{i,2});
    end
    for j=1:numel(query{i,2})
        if iscellstr(query{i,2})
            query{i,2}{j} = regexprep(query{i,2}{j},sprintf('^%s-',query{i,1}),'');
        end
    end
end


function formats = supported_wc_extensions()
    % Return a cell of arrays with the formats supported. Automatically updated
    formats ={};
    raw_readers_folder = fileparts(mfilename('fullpath'));
    files = dir(raw_readers_folder);
    for i = 1: length(files)
        fname = files(i).name;
        fend = regexp(fname,'_wc_reader.m');
        if ~isempty (fend)
             formats = [formats,{fname(1:fend-1)}];
        end
    end
end


% -*- INTERNAL UNDOCUMENTED FUNCTION -*-
function sp = sp_nurbs_2d (varargin)

warning ('geopdes:obsolete', 'The class SP_NURBS_2D is obsolete. Using SP_NURBS instead')

sp = sp_nurbs (varargin{:});


function [ source_directory, list_of_images ] = createListOfImagesFromVOCOpts( path_to_voc_devkit, set_name )

addpath([path_to_voc_devkit,'/VOCcode']);
VOCopts = VOCInitFrom( path_to_voc_devkit );

image_ids      = textread(sprintf(VOCopts.imgsetpath,set_name),'%s');
list_of_images = cell(numel(image_ids),1);

for i = 1:numel(image_ids)
    list_of_images{i} = sprintf(VOCopts.imgpath,image_ids{i});
end

end


function str = printstruct(name, val, varargin)

% PRINTSTRUCT converts a MATLAB structure into a multiple-line string that, when
% evaluated by MATLAB, results in the original structure. It also works for most
% other standard MATLAB classes, such as numbers, vectors, matrices, and cell-arrays.
%
% Use as
%   str = printstruct(val)
% or
%   str = printstruct(name, val)
% where "val" is any MATLAB variable, e.g. a scalar, vector, matrix, structure, or
% cell-array. If you pass the name of the variable, the output is a piece of MATLAB code
% that you can execute, i.e. an ASCII serialized representation of the variable.
%
% Example
%   a.field1 = 1;
%   a.field2 = 2;
%   s = printstruct(a)
%
%   b = rand(3);
%   s = printstruct(b)
%
%   s = printstruct('c', randn(10)>0.5)
%
% See also DISP

% Copyright (C) 2006-2018, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip 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 FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

if nargin==1
  val  = name;
  name = inputname(1);
end

% get the options and set defaults
transposed    = ft_getopt(varargin, 'transposed', false);     % print a column as a transposed row, or a row as a transposed column
linebreaks    = ft_getopt(varargin, 'linebreaks', true);      % print with or without linebreaks
lastnewline   = ft_getopt(varargin, 'lastnewline', false);    % end with a newline
lastsemicolon = ft_getopt(varargin, 'lastsemicolon', true);   % end with a semicolon

% when called recursively, it should keep the last newline and semicolon intact
varargin = ft_setopt(varargin, 'lastnewline', true);
varargin = ft_setopt(varargin, 'lastsemicolon', true);

% Note that because we don't know the final size of the string, iteratively appending
% is actually faster than creating a cell-array and subsequently doing a cat(2,
% strings{:}). Note also that sprintf() is slow.
str = '';

% Note further that in the string concatenations I use the numerical value
% of a newline (\n), which is 10.

if numel(val) == 0
  if iscell(val)
    str = [name ' = {};' 10];
  elseif isstruct(val)
    str = [name ' = [];' 10];
  elseif isnumeric(val)
    str = [name ' = [];' 10];
  end

elseif isstruct(val)
  if numel(val)>1
    % print it as a struct-array
    str = cell(size(val));
    for i=1:numel(val)
      str{i} = printstruct(sprintf('%s(%d)', name, i), val(i), varargin{:});
    end
    str = cat(2, str{:});
  elseif numel(val)==1
    % print it as a named structure
    fn = fieldnames(val);
    for i=1:length(fn)
      fv = val.(fn{i});
      switch class(fv)
        case {'char' 'string'}
          line = printstr([name '.' fn{i}], fv, linebreaks, transposed);
        case {'single' 'double' 'int8' 'int16' 'int32' 'int64' 'uint8' 'uint16' 'uint32' 'uint64' 'logical'}
          if ismatrix(fv)
            line = printmat([name '.' fn{i}], fv, linebreaks, transposed);
          else
            line = '''ERROR: multidimensional arrays are not supported''';
          end
        case 'cell'
          line = printcell([name '.' fn{i}], fv, linebreaks, transposed);
        case 'struct'
          line = [printstruct([name '.' fn{i}], fv, varargin{:}) 10];
        case 'function_handle'
          line = printstr([name '.' fn{i}], func2str(fv), linebreaks, transposed);
        otherwise
          ft_error('unsupported');
      end
      str = [str line newline];
    end % for fieldnames
    if isempty(fn)
      % print it as an empty structure
      str = [name ' = struct();'];
    end
  end

elseif ~isstruct(val)
  % print it as a named variable
  switch class(val)
    case {'char' 'string'}
      str = printstr(name, val, linebreaks, transposed);
    case {'double' 'single' 'int8' 'int16' 'int32' 'int64' 'uint8' 'uint16' 'uint32' 'uint64' 'logical'}
      str = printmat(name, val, linebreaks, transposed);
    case 'cell'
      str = printcell(name, val, linebreaks, transposed);
    otherwise
      ft_error('unsupported');
  end
end

% replace double newlines with a single one
str = strrep(str, [newline newline], newline);

if isempty(name)
  % remove the ' = ' part from the string
  str = str(4:end);
end

if str(end)==newline && ~lastnewline
  % remove the last newline
  str = str(1:end-1);
end

if str(end)==';' && ~lastsemicolon
  % remove the last semicolon
  str = str(1:end-1);
end

if ~nargout
  disp(str)
  clear str
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function str = printstr(name, val, linebreaks, transposed)
siz = size(val);
if siz(1)>1
  str = sprintf('%s = \n', name);
  for i=1:siz(1)
    str = [str sprintf('  %s\n', printval(val(i,:), linebreaks, transposed))];
  end
elseif siz(1)==1
  str = sprintf('%s = %s;\n', name, printval(val, linebreaks, transposed));
else
  str = sprintf('%s = '''';\n', name);
end
if ~linebreaks
  str(str==10) = [];
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function str = printcell(name, val, linebreaks, transposed)
siz = size(val);
if isempty(val)
  str = sprintf('%s = {};\n', name);
elseif numel(siz) == 2 && siz(2) == 1 && transposed
  % print column vector as (non-conjugate) transposed row
  str = printcell(name, transpose(val), linebreaks, false);
  str = sprintf('%s'';\n', str(1:end-2));
elseif numel(siz) == 2 && siz(1) == 1 && transposed
  % print row vector as (non-conjugate) transposed column
  str = printcell(name, transpose(val), linebreaks, false);
  str = sprintf('%s'';\n', str(1:end-2));
else
  str = sprintf('%s = {\n', name);
  for i=1:siz(1)
    for j=1:(siz(2)-1)
      dum = printval(val{i,j}, linebreaks, transposed);
      if endsWith(dum, ';')
        dum = dum(1:end-1);
      elseif endsWith(dum, [';' newline])
        dum = dum(1:end-2);
      end
      str = [str ' ' dum ',']; % add the element with a comma
    end
    dum = printval(val{i,siz(2)}, linebreaks, transposed);
    if endsWith(dum, ';')
      dum = dum(1:end-1);
    elseif endsWith(dum, [';' newline])
      dum = dum(1:end-2);
    end
    str = [str ' ' dum 10];  % add the last element of each row with a linebreak
  end
  if siz(1)==1
    str(str==10) = [];
  end
  str = sprintf('%s };\n', str);
end
if ~linebreaks
  str(str==10) = [];
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function str = printmat(name, val, linebreaks, transposed)
siz = size(val);
if numel(val) == 0
  str = sprintf('%s = [];\n', name);
elseif numel(val) == 1
  % an integer will never get trailing decimals when using %g
  str = sprintf('%s = %g;', name, val);
elseif numel(siz) == 2 && siz(2) == 1 && transposed
  % print column vector as (non-conjugate) transposed row
  str = printmat(name, transpose(val), linebreaks, false);
  str = sprintf('%s''', str);
elseif numel(siz) == 2 && siz(1) == 1 && transposed
  % print row vector as (non-conjugate) transposed column
  str = printmat(name, transpose(val), linebreaks, false);
  str = sprintf('%s''', str);
elseif ismatrix(val)
  if isa(val, 'double')
    str = sprintf('%s = %s;', name, mat2str(val));
  else
    % add class information for non-double numeric matrices
    str = sprintf('%s = %s;', name, mat2str(val, 'class'));
  end
  % add a newline after each semicolon
  str = strrep(str, ';', [';' newline]);
else
  ft_warning('multidimensional arrays are not supported');
  str = '''ERROR: multidimensional arrays are not supported''';
end
if ~linebreaks
  str(str==10) = [];
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function str = printval(val, linebreaks, transposed)

switch class(val)
  case 'char'
    str = ['''' val ''''];

  case 'string'
    % these use " in the declaration rather than '
    str = ['"' char(val) '";'];

  case {'single' 'double' 'int8' 'int16' 'int32' 'int64' 'uint8' 'uint16' 'uint32' 'uint64' 'logical'}
    str = printmat('', val, linebreaks, transposed);
    str = str(4:end);
    if endsWith(str, ';')
      str = str(1:end-1);
    end

  case 'function_handle'
    str = ['@' func2str(val)];

  case 'struct'
    % print it as an anonymous structure
    str = 'struct(';
    fn = fieldnames(val);
    for i=1:numel(fn)
      str = [str '''' fn{i} '''' ', ' printval(val.(fn{i}), linebreaks, transposed)];
    end
    str = [str ')'];

  otherwise
    ft_warning('cannot print unknown object at this level');
    str = '''ERROR: cannot print unknown object at this level''';
end
if ~linebreaks
  str(str==10) = [];
end


% to the value of the slider.
   function slider1_callback(hObject,eventdata)
   global fh slider1_data
      % Get 'slider' appdata.
      slider1_data = getappdata(fh,'slider');
      slider1_data.previous_val = slider1_data.val;
      slider1_data.val = get(hObject,'Value');
%      set(eth,'String',num2str(slider_data.val));
      sprintf('You changed the slider value--> %6.3f',...
              slider1_data.val)
      % Save 'slider' appdata before returning.
      setappdata(fh,'slider',slider1_data)
end


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

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

% Last Modified by GUIDE v2.5 29-Aug-2008 11:01:33

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

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

% AUTHOR: MARK FRANKOSKY (MFRANKOSKY@GMAIL.COM)

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

% Choose default command line output for piano2
handles.output      = hObject;
handles.SampleRate  = 1/20000;
handles.SoundVector = 0;
handles.TimeValue   = 0.3488;

% Update handles structure
guidata(hObject, handles);

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

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

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

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

freq = 207.65;
PlayNote(handles,freq);

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

freq = 233.08;
PlayNote(handles,freq);

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

freq = 739.99;
PlayNote(handles,freq);

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

freq = 185.00;
PlayNote(handles,freq);

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

freq = 466.16;
PlayNote(handles,freq);

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

freq = 622.25;
PlayNote(handles,freq);

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

freq = 554.37;
PlayNote(handles,freq);

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

freq = 415.3;
PlayNote(handles,freq);

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

freq = 277.18;
PlayNote(handles,freq);

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

freq = 196;
PlayNote(handles,freq);

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

freq = 220;
PlayNote(handles,freq);

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

freq = 246.94;
PlayNote(handles,freq);

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

freq = 261.625;
PlayNote(handles,freq);

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

freq = 293.66;
PlayNote(handles,freq);

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

freq = 329.63;
PlayNote(handles,freq);

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

freq = 349.23;
PlayNote(handles,freq);

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

freq = 392;
PlayNote(handles,freq);

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

freq = 440;
PlayNote(handles,freq);

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

freq = 493.88;
PlayNote(handles,freq);

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

freq = 523.25;
PlayNote(handles,freq);

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

freq = 587.33;
PlayNote(handles,freq);

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

freq = 659.26;
PlayNote(handles,freq);

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

freq = 698.46;
PlayNote(handles,freq);

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

freq = 369.99;
PlayNote(handles,freq);

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

freq = 311.13;
PlayNote(handles,freq);

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

freq = 783.99;
PlayNote(handles,freq);

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

freq = 174.61;
PlayNote(handles,freq);

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

freq = 164.81;
PlayNote(handles,freq);

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

freq = 146.83;
PlayNote(handles,freq);

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

freq = 880;
PlayNote(handles,freq);

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

freq = 130.81;
PlayNote(handles,freq);

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

freq = 987.77;
PlayNote(handles,freq);

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

freq = 830.61;
PlayNote(handles,freq);

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

freq = 932.33;
PlayNote(handles,freq);

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

freq = 155.56;
PlayNote(handles,freq);

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

freq = 138.59;
PlayNote(handles,freq);

function PlayNote(handles,freq)
% plays the note that was pressed for 1 second
% also sets the frequency value on GUI for last played note.

strFreq = num2str(freq);
set(handles.STFreqValue, 'String', strFreq);

SampleRate  = handles.SampleRate;
TimeValue   = handles.TimeValue;
Samples     = 0:SampleRate:TimeValue;
SinOn       = get(handles.SinWave, 'Value');
SquareOn    = get(handles.SquareWave, 'Value');
SawtoothOn  = get(handles.SawtoothWave, 'Value');

if SinOn == 1
  soundVector = sin(2*pi*freq*Samples);
elseif SquareOn == 1
  soundVector = square(2*pi*freq*Samples);
elseif SawtoothOn == 1
  soundVector = sawtooth(2*pi*freq*Samples);
end

sound(soundVector, 1/SampleRate)

RecordOn = get(handles.Record, 'Value');

if RecordOn == 1
  SoundVectorLong = handles.SoundVector;
  if SoundVectorLong == 0
    SoundVectorLong = soundVector;
  else
    SoundVectorLong = cat(2, SoundVectorLong, soundVector);
  end
  handles.SoundVector = SoundVectorLong;
  guidata(handles.figure1, handles);
end

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

SoundVector   = handles.SoundVector;
SampleRate    = handles.SampleRate;

sound(SoundVector, 1/SampleRate)

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

handles.SoundVector = 0;
guidata(handles.figure1, handles);

function Time_Callback(hObject, eventdata, handles)
% hObject    handle to Time (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of Time as text
%        str2double(get(hObject,'String')) returns contents of Time as a double

Value     = str2double(get(hObject, 'String'));
TimeValue = 60/Value;

half    = get(handles.HalfNote, 'Value');
Whole   = get(handles.WholeNote, 'Value');
Eighth  = get(handles.EighthNote, 'Value');

if half == 1
    TimeValue = TimeValue * 2;
elseif Whole == 1
    TimeValue = TimeValue * 4;
elseif Eighth == 1
    TimeValue = TimeValue / 2;
end

handles.TimeValue = TimeValue;
guidata(handles.figure1, handles);

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

set(handles.QuarterNote, 'Value', 1);
set(handles.HalfNote, 'Value', 0);
set(handles.EighthNote, 'Value', 0);
set(handles.WholeNote, 'Value', 0);

Value     = str2double(get(handles.Time, 'String'));
TimeValue = 60/Value;

handles.TimeValue = TimeValue;
guidata(handles.figure1, handles);

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

set(handles.QuarterNote, 'Value', 0);
set(handles.HalfNote, 'Value', 1);
set(handles.EighthNote, 'Value', 0);
set(handles.WholeNote, 'Value', 0);

Value     = str2double(get(handles.Time, 'String'));
TimeValue = 60/Value * 2;

handles.TimeValue = TimeValue;
guidata(handles.figure1, handles);

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

set(handles.QuarterNote, 'Value', 0);
set(handles.HalfNote, 'Value', 0);
set(handles.EighthNote, 'Value', 1);
set(handles.WholeNote, 'Value', 0);

Value     = str2double(get(handles.Time, 'String'));
TimeValue = (60/Value) / 2;

handles.TimeValue = TimeValue;
guidata(handles.figure1, handles);

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

set(handles.QuarterNote, 'Value', 0);
set(handles.HalfNote, 'Value', 0);
set(handles.EighthNote, 'Value', 0);
set(handles.WholeNote, 'Value', 1);

Value     = str2double(get(handles.Time, 'String'));
TimeValue = 60/Value * 4;

handles.TimeValue = TimeValue;
guidata(handles.figure1, handles);

% --- Executes during object creation, after setting all properties.
function QuarterNote_CreateFcn(hObject, eventdata, handles)
% hObject    handle to QuarterNote (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

set(hObject, 'Value', 1);

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

SoundVector     = handles.SoundVector;
SampleRate      = handles.SampleRate;

if SoundVector == 0
    return;
else
  Filename = get(handles.Filename, 'String');
  wavwrite(SoundVector, 1/SampleRate, 32, Filename);
end

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

% Hint: get(hObject,'Value') returns toggle state of SinWave

set(handles.SinWave, 'Value', 1);
set(handles.SquareWave, 'Value', 0);
set(handles.SawtoothWave, 'Value', 0);

% --- Executes during object creation, after setting all properties.
function SinWave_CreateFcn(hObject, eventdata, handles)
% hObject    handle to SinWave (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

set(hObject, 'Value', 1);

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

% Hint: get(hObject,'Value') returns toggle state of SquareWave

set(handles.SinWave, 'Value', 0);
set(handles.SquareWave, 'Value', 1);
set(handles.SawtoothWave, 'Value', 0);

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

% Hint: get(hObject,'Value') returns toggle state of SawtoothWave

set(handles.SinWave, 'Value', 0);
set(handles.SquareWave, 'Value', 0);
set(handles.SawtoothWave, 'Value', 1);


function m = getmem
% return total system memory in kb

try
  m = memory;
  m = m.MemAvailableAllArrays / 1024;
catch %#ok<CTCH>
  [r,s] = system('free');
  m = sscanf(s(strfind(s,'Mem:')+5:end),'%d',3);
  if isempty(m)
    m = sscanf(s(strfind(s,'Speicher:')+9:end),'%d',3);
  end
  if isempty(m)
    m = 300 * 1024;
  else
    m = m(3);
  end
  % reset error
  lasterr('');
end
end


classdef SetSteeringModelAction < AbstractEventAction
    %SetSteeringModelAction Summary of this class goes here
    %   Detailed explanation goes here

    properties
        steeringModels SteeringModelsSet
    end

    %deprecated
    properties(Access=private)
        steeringModel(1,1) AbstractSteeringModel = RollPitchYawPolySteeringModel.getDefaultSteeringModel()
    end

    properties(Constant)
        emptyVarArr = AbstractOptimizationVariable.empty(0,1);
    end

    methods
        function obj = SetSteeringModelAction(steeringModel)
            obj.steeringModels = SteeringModelsSet();

            if(nargin > 0)
                obj.steeringModels.selectedModel = steeringModel;
            else
                obj.steeringModels.selectedModel = RollPitchYawPolySteeringModel.getDefaultSteeringModel();
            end

            obj.id = rand();
        end

%         function sm = get.steeringModel(obj)
%             sm = obj.steeringModel;
%             warning('Calling SetSteeringModelAction.steeringModel is deprecated.');
%         end
%
%         function set.steeringModel(obj,sm)
%             obj.steeringModel = sm;
%             warning('Calling SetThrottleModelAction.steeringModel is deprecated.');
%         end

        function newStateLogEntry = executeAction(obj, stateLogEntry)
            newStateLogEntry = stateLogEntry;
            newStateLogEntry.steeringModel = obj.steeringModels.selectedModel;
        end

        function initAction(obj, initialStateLogEntry)
            t0 = initialStateLogEntry.time;
            obj.steeringModels.selectedModel.setT0(t0);

            dcm = initialStateLogEntry.attitude.dcm;
            rVect = initialStateLogEntry.position;
            vVect = initialStateLogEntry.velocity;
            bodyInfo = initialStateLogEntry.centralBody;
            obj.steeringModels.selectedModel.setConstsFromDcmAndContinuitySettings(dcm, t0, rVect, vVect, bodyInfo);
        end

        function name = getName(obj)
            name = sprintf('Set Steering Model (%s)', obj.steeringModels.selectedModel.getTypeNameStr());
        end

        function tf = usesStage(obj, stage)
            tf = false;
        end

        function tf = usesEngine(obj, engine)
            tf = false;
        end

        function tf = usesTank(obj, tank)
            tf = false;
        end

        function tf = usesEngineToTankConn(obj, engineToTank)
            tf = false;
        end

        function tf = usesStopwatch(obj, stopwatch)
            tf = false;
        end

        function tf = usesExtremum(obj, extremum)
            tf = false;
        end

        function tf = usesTankToTankConn(obj, tankToTank)
            tf = false;
        end

        function [tf, vars] = hasActiveOptimVar(obj)
            tf = false;
            vars = obj.emptyVarArr;

            optVar = obj.steeringModels.selectedModel.getExistingOptVar();
            if(not(isempty(optVar)))
                tf = any(optVar.getUseTfForVariable());
                vars(end+1) = optVar;
            end
        end
    end

    methods(Static)
        function addActionTf = openEditActionUI(action, lv)
            arguments
                action SetSteeringModelAction
                lv LaunchVehicle
            end

            addActionTf = action.steeringModels.openEditDialog(lv.lvdData, true);
        end

        function obj = loadobj(obj)
            arguments
                obj SetSteeringModelAction
            end

            if(isempty(obj.steeringModels))
                obj.steeringModels = SteeringModelsSet();
%                 obj.steeringModels.selectedModel = obj.steeringModel;

%             elseif(obj.steeringModels.selectedModel ~= obj.steeringModel)
%                 obj.steeringModels.selectedModel = obj.steeringModel;
            end
        end
    end
end


function plot_setPrmAndPlot(hFig, idxPC, varargin)

% Actual parameter
p = hFig.UserData.PC{idxPC}.U.p;

for i = 1:2:numel(varargin)

    prm = varargin{i};
    val = varargin{i+1};

    % Color --------------------------------------------------------------------

    if strcmpi(prm, 'Color')
        if ischar(val)
            % Convert color defined as char to RGB value
            % Note: this is necessary, as:
            %       - Unicolor:  colors have to be defined as RGB values
            %       - Attribute: attributes have to be defined as char
            [row, ~] = find(strcmp(hFig.UserData.colors, val));
            if ~isempty(row) % a color name was selected
                p.Color = hFig.UserData.colors{row,1};
            % Temp !!!!! - start
            elseif strcmpi(val(1:2), 'A.')
                p.Color = val;
                if ~any(strcmp(varargin, 'CAxisLim'))
                    p.CAxisLim = [];
                end
            % Temp !!!!! - end
            else % 'RGB' or 'by PC'
                p.Color = val;
            end
        elseif numel(val) == 3
            p.Color = val;
        else
            plot_throwError(prm); return;
        end
    end

    % MarkerSize ---------------------------------------------------------------

    if strcmpi(prm, 'MarkerSize')
        if isnumeric(val) && isscalar(val) && val>0
            p.MarkerSize = val;
        else
            plot_throwError(prm); return;
        end
    end

    % MaxPoints ----------------------------------------------------------------

    if strcmpi(prm, 'MaxPoints')
        if isnumeric(val) && isscalar(val) && val>0
            p.MaxPoints = val;
        else
            plot_throwError(prm); return;
        end
    end

    % ColormapName -------------------------------------------------------------

    if strcmpi(prm, 'ColormapName')
        if ischar(val)
            p.ColormapName = val;
        else
            plot_throwError(prm); return;
        end
    end

    % CAxisLim -----------------------------------------------------------------

    if strcmpi(prm, 'CAxisLim')
        if isnumeric(val) && numel(val)==2
            p.CAxisLim = val;
        else
            plot_throwError(prm); return;
        end
    end

    % ToDo: error if non-valid prm name is defined

end

hFig.UserData.PC{idxPC}.U.p = p;

% Update figure and axes -------------------------------------------------------

% Axes color
hAxes = findobj('Parent', hFig, 'Type', 'Axes');
row = strcmpi(hFig.UserData.options.AxesColor, hFig.UserData.colors(:,3));
if any(row), hAxes.Color = hFig.UserData.colors{row,1}; end

% Figure color
row = strcmpi(hFig.UserData.options.FigureColor, hFig.UserData.colors(:,3));
if any(row), hFig.Color = hFig.UserData.colors{row,1}; end

% Help text
hFig.UserData.hHelptext.BackgroundColor = hFig.UserData.options.FigureColor;

% Plot! ------------------------------------------------------------------------

plot_updatePlot(hFig, idxPC);

end


classdef ExposureCompensator < handle
    %EXPOSURECOMPENSATOR  Class for all exposure compensators
    %
    % See also: cv.Stitcher
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    methods
        function this = ExposureCompensator(compensatorType, varargin)
            %EXPOSURECOMPENSATOR  Constructor
            %
            %     obj = cv.ExposureCompensator(compensatorType)
            %     obj = cv.ExposureCompensator(compensatorType, 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __compensatorType__ exposure compensator type. One of:
            %   * __NoExposureCompensator__ Stub exposure compensator which
            %     does nothing.
            %   * __GainCompensator__ Exposure compensator which tries to
            %     remove exposure related artifacts by adjusting image
            %     intensities, see [BL07] and [WJ10] for details.
            %   * __BlocksGainCompensator__ Exposure compensator which tries
            %     to remove exposure related artifacts by adjusting image
            %     block intensities, see [UES01] for details.
            %
            % ## Options
            % The following are options for the various algorithms:
            %
            % ### `BlocksGainCompensator`
            % * __Width__ Block width. default 32
            % * __Heigth__ Block height. default 32
            %
            % ## References
            % [BL07]:
            % > Matthew Brown and David G Lowe.
            % > "Automatic panoramic image stitching using invariant features".
            % > International journal of computer vision, 74(1):59-73, 2007.
            %
            % [WJ10]:
            % > Wei Xu and Jane Mulligan. "Performance evaluation of color
            % > correction approaches for automatic multi-view image and video
            % > stitching". In Computer Vision and Pattern Recognition (CVPR),
            % > 2010 IEEE Conference on, pages 263-270. IEEE, 2010.
            %
            % [UES01]:
            % > Matthew Uyttendaele, Ashley Eden, and R Skeliski.
            % > "Eliminating ghosting and exposure artifacts in image mosaics".
            % > In Computer Vision and Pattern Recognition, 2001. CVPR 2001.
            % > Proceedings of the 2001 IEEE Computer Society Conference on,
            % > volume 2, pages II-509. IEEE, 2001.
            %
            % See also: cv.ExposureCompensator.apply
            %
            this.id = ExposureCompensator_(0, 'new', compensatorType, varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.ExposureCompensator
            %
            if isempty(this.id), return; end
            ExposureCompensator_(this.id, 'delete');
        end

        function typename = typeid(this)
            %TYPEID  Name of the C++ type (RTTI)
            %
            %     typename = obj.typeid()
            %
            % ## Output
            % * __typename__ Name of C++ type
            %
            typename = ExposureCompensator_(this.id, 'typeid');
        end
    end

    %% ExposureCompensator
    methods
        function feed(this, corners, images, masks)
            %FEED  Processes the images
            %
            %     obj.feed(corners, images, masks)
            %
            % ## Input
            % * __corners__ Source image top-left corners. Cell-array of 2D
            %   points `{[x,y], ...}`.
            % * __images__ Source cell-array of images.
            % * __masks__ Cell-array of image masks to update (the value 255
            %   is used to detect where image is).
            %
            % See also: cv.ExposureCompensator.apply
            %
            ExposureCompensator_(this.id, 'feed', corners, images, masks);
        end

        function image = apply(this, index, corner, image, mask)
            %APPLY  Compensate exposure in the specified image
            %
            %     image = obj.apply(index, corner, image, mask)
            %
            % ## Input
            % * __index__ Image index.
            % * __corner__ Image top-left corner `[x,y]`.
            % * __image__ Image to process.
            % * __mask__ Image 8-bit mask.
            %
            % ## Output
            % * __image__ processed image.
            %
            % See also: cv.ExposureCompensator.feed
            %
            image = ExposureCompensator_(this.id, 'apply', index, corner, image, mask);
        end
    end

    %% GainCompensator
    methods
        function g = gains(this)
            %GAINS  Gains
            %
            %     g = obj.gains()
            %
            % ## Output
            % * __g__ double vector of gains.
            %
            g = ExposureCompensator_(this.id, 'gains');
        end
    end

end


function setOptsDoubleValueStrInGUI(handles, options, optPropName, handlesFieldName)
    value = options.(optPropName);

    if(isnan(value))
        str = '';
    else
        str = fullAccNum2Str(double(value));
    end

    handles.(handlesFieldName).String = str;


function chrpak_test1225 ( )

%*****************************************************************************80
%
%% TEST1225 tests S_S_SUBANAGRAM.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 June 2007
%
%  Author:
%
%    John Burkardt
%
  test_num = 4;

  s1_test(1,1:13) = 'Get a priest!';
  s1_test(2,1:13) = 'Get a priest!';
  s1_test(3,1:13) = 'Get a priest!';
  s1_test(4,1:13) = 'Get a priest!';

  s2_test(1,1:6) = 'stripe';
  s2_test(2,1:6) = 'pastor';
  s2_test(3,1:6) = 'a sip ';
  s2_test(4,1:6) = 'tag!  ';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST1225\n' );
  fprintf ( 1, '  S_S_SUBANAGRAM is TRUE if S2 is a "subanagram"\n' );
  fprintf ( 1, '  of S1.\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num

    s1 = s1_test(test,1:13);
    s2 = s2_test(test,1:6);
    s2_length = s_len_trim ( s2 );

    value = s_s_subanagram ( s1, s2(1:s2_length) );

    fprintf ( 1, '  "%s"  "%s"  %d\n', s1, s2, value );

  end

  return
end


classdef (Abstract) MetricGeneratorX < BaseX
% MetricGeneratorX Abstract class
%
% Summary of MetricGeneratorX:
% This is the base class for all TrackingX metric generators.
% Any custom defined metric generator should be derived from this MetricGeneratorX
% base class.
%
% MetricGeneratorX Properties:
%   None
%
% MetricGeneratorX Methods:
%   + MetricGeneratorX - Constructor method
%   ~ evaluate - Evaluates and returns a given metric
%
% (+) denotes puplic properties/methods
%
% February 2018 Lyudmil Vladimirov, University of Liverpool.

    properties
    end

    methods (Abstract)
        % evaluate Evaluate the correctness of a set of tracks compared to
        % the groundtrouth.
        %   METRIC = EVALUATE(THIS, TRACKLIST, GROUNDTRUTH) evaluates the
        %   correctness of the TRACKLIST compared to the GROUNDTRUTH.
        %   TRACKLIST and GROUNDTRUTH can be structured based on the needs
        %   of the respective metric generator.

        metric = evaluate(~,TrackList,GroundTruth);
    end
end


classdef FreeFemInputPrinter < FreeFemFilePrinter

    properties (Access = private)
        inputLines
        beforeInputLines
        afterInputLines

        startingLines
        endingLines
        inputData
    end

    methods (Access = public)

        function setInputData(obj,d)
            obj.inputData = d;
        end
    end

    methods (Access = protected)

        function printingLines(obj)
            obj.obtainBeforeAfterAndInputLines();
            obj.printBeforeInputLines();
            obj.printInputLines();
            obj.printAfterInputLines();
        end

    end

    methods (Access = private)

        function obtainBeforeAfterAndInputLines(obj)
            nlines = numel(obj.linesToPrint);
            [sL,eL] = obj.obtainStartingEndingInputLines();
            obj.beforeInputLines = (1:sL-1);
            obj.inputLines = (sL:eL);
            obj.afterInputLines = (eL+1:nlines);
        end

        function [sL,eL] = obtainStartingEndingInputLines(obj)
            nlines = numel(obj.linesToPrint);
            obj.startingLines = false(nlines,1);
            obj.endingLines   = false(nlines,1);
            for iline = 1:nlines
                line = obj.linesToPrint{iline};
                obj.startingLines(iline) = obj.isInputStarting(line);
                obj.endingLines(iline)   = obj.isInputEnding(line);
            end
            sL = obj.obtainStartingLine();
            eL = obj.obtainEndingLine();
        end

        function sL = obtainStartingLine(obj)
            sLines = obj.startingLines;
            sLines = obj.booleanIndex2integerIndex(sLines);
            firstSL = sLines(1);
            sL = firstSL + 1;
        end

        function eL = obtainEndingLine(obj)
            eLines = obj.endingLines;
            eLines = obj.booleanIndex2integerIndex(eLines);
            firstEL = eLines(1);
            eL = firstEL(1) - 1;
        end

        function printBeforeInputLines(obj)
            lines = obj.beforeInputLines;
            obj.printNonInputLines(lines)
        end

        function printAfterInputLines(obj)
            lines = obj.afterInputLines;
            obj.printNonInputLines(lines)
        end

        function printNonInputLines(obj,nonInputLines)
            nLines = length(nonInputLines);
            for iline = 1:nLines
                lineNumber = nonInputLines(iline);
                line = obj.linesToPrint{lineNumber};
                obj.printLine(line);
            end
        end

        function printInputLines(obj)
            obj.printRealInputData();
            obj.printStringInputData();
        end

        function printRealInputData(obj)
            inVar = obj.inputData.reals;
            for iData = 1:numel(inVar)
                varName  = inVar{iData}{1,1};
                varValue = num2str(inVar{iData}{1,2});
                line = ['real ',varName,' = ',varValue,';'];
                obj.printLine(line);
            end
        end

        function printStringInputData(obj)
            inVar = obj.inputData.strings;
            for iData = 1:numel(inVar)
                varName  = inVar{iData}{1,1};
                varValue = ['"',inVar{iData}{1,2},'"'];
                line = ['string ',varName,' = ',varValue,';'];
                obj.printLine(line);
            end
        end

        function printInputData(obj)
            inVar = obj.inputData.reals;
            for iData = 1:numel(inVar)
                varName  = inVar{iData}{1,1};
                varValue = num2str(inVar{iData}{1,2});
                line = ['real ',varName,' = ',varValue,';'];
                obj.printLine(line);
            end
        end

        function printInputLine(obj)
            fprintf(obj.fileID,'%s\r\n',obj.line);
        end

        function printLine(obj,line)
            fprintf(obj.fileID,'%s\r\n',line);
        end

    end

    methods (Access = private, Static)

        function itIs = isInputStarting(line)
            itIs = strcmp(line,'// --- Input ---');
        end

        function itIs = isInputEnding(line)
            itIs = strcmp(line,'// --- End Input ---');
        end

        function index = booleanIndex2integerIndex(index)
            allValues = 1:length(index);
            index = allValues(index);
        end

    end

end


classdef MimCineTool < MimTool
    % MimCineTool. A tool for interactively moving through slices
    %
    %     MimCineTool is a tool class used with GemCinePanel to allow the user
    %     to cine through an image using mouse controls.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, 2013.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    properties
        ButtonText = 'Cine'
        Cursor = 'arrow'
        ToolTip = 'Cine tool. Drag mouse to cine through slices.'
        Tag = 'Cine'
        ShortcutKey = 'n'
    end

    properties (Access = private)
        Callback
        ImageParameters
        StartCoords
        StartKPosition
    end

    methods
        function obj = MimCineTool(image_parameters, callback)
            obj.Callback = callback;
            obj.ImageParameters = image_parameters;
        end

        function MouseDragged(obj, screen_coords, last_coords)
            if ~isempty(obj.StartCoords)
                [min_coords, max_coords] = obj.Callback.GetImageLimits;
                coords_offset = screen_coords -  obj.StartCoords;

                y_range = max_coords(2) - min_coords(1);
                y_relative_movement = coords_offset(2)/y_range;
                direction = sign(y_relative_movement);
                y_relative_movement = abs(y_relative_movement);
                y_relative_movement = 100*y_relative_movement;
                y_relative_movement = ceil(y_relative_movement);

                k_position = obj.StartKPosition - direction*y_relative_movement;
                obj.ImageParameters.SliceNumber(obj.ImageParameters.Orientation) = k_position;
            end
        end

        function MouseDown(obj, screen_coords)
            obj.StartCoords = screen_coords;
            obj.StartKPosition = obj.ImageParameters.SliceNumber(obj.ImageParameters.Orientation);
        end

        function NewOrientation(obj)
            obj.StartCoords = [];
            obj.StartKPosition = [];
        end

        function ImageChanged(obj)
            obj.StartCoords = [];
            obj.StartKPosition = [];
        end

        function Enter(obj)
            obj.StartCoords = [];
            obj.StartKPosition = [];
        end
    end
end


function badChannels = getBadChannelStructure()
  badChannels = struct( ...
    'all', [], ...
    'badChannelsFromNaNs', [], ...
    'badChannelsFromNoData', [], ...
    'badChannelsFromLowSNR', [], ...
    'badChannelsFromHFNoise', [], ...
    'badChannelsFromCorrelation', [], ...
    'badChannelsFromDeviation', [], ...
    'badChannelsFromRansac', [], ...
    'badChannelsFromDropOuts', []);


function GenerateFunctionMFile(ask)
%GENERATEFUNCTIONMFILE Generates an m-file suitable for a function,
% with header text.
%
% GENERATEFUNCTIONMFILE() generates an m-file suitable for a function,
% with header text, saves it in your current directory, and opens it in
% the editor.
%
% GENERATEFUNCTIONMFILE(ASK) works as above, but prompts for the name of
% the function.

% $Author: rcotton $  $Date: 2010/04/12 10:36:31 $ $Revision: 1.2 $
% Copyright: Health and Safety Laboratory 2010

persistent fileNameCount

if nargin > 0 && ask
   fnName = input('Enter the name of your function >> ', 's');
   if ~isvarname(fnName)
      error('GenerateFunctionMFile:InvalidFunctionName', ...
         [fnName ' is not a valid function name']);
   end
else
   if isempty(fileNameCount)
      fileNameCount = 1;
   else
      fileNameCount = fileNameCount + 1;
   end
   while exist(['Untitled' num2str(fileNameCount)], 'file') >= 2
      fileNameCount = fileNameCount + 1;
   end
   fnName = ['Untitled' num2str(fileNameCount)];
end

fileName = fullfile(cd, [fnName '.m']);

if exist(fnName, 'file')
   error('GenerateFunctionMFile:FileAlreadyExists', ...
      [fnName '.m already exists in the current directory']);
end

WriteFile(fnName, fileName)
edit(fileName);

end

function WriteFile(fnName, fileName)
% Engine for writing the file.

now = clock;
nl = char(10);

   function PrintCommentLine(fid)
   fprintf(fid, '%% %s', nl);
   end

   function PrintBlankLine(fid)
   fprintf(fid, '%s', nl);
   end

fid = fopen0(fileName, 'w');
c = onCleanup(@() fclose(fid));

fprintf(fid, 'function [outputArgs] = %s(inputArgs)%s', ...
   fnName, nl);
fprintf(fid, '%%%s Summary of this function goes here%s', ...
   upper(fnName), nl);
PrintCommentLine(fid);
fprintf(fid, '%% [OUTPUTARGS] = %s(INPUTARGS) Explain usage here%s', ...
   upper(fnName), nl);
PrintCommentLine(fid);
fprintf(fid, '%% Examples: %s', nl);
PrintCommentLine(fid);
fprintf(fid, '%% Provide sample usage code here%s', nl);
PrintCommentLine(fid);
fprintf(fid, '%% See also: List related files here%s', nl);
fprintf(fid, nl);
% Need to keep $ separate in next line, so CVS doesn't replace values
% Also, this line will not work with GIT, since it messes with the SHA-1
fprintf(fid, '%% %sAuthor: %s $\t%sDate: %s $\t%sRevision: 0.1 $%s', ...
   '$', GetUserLoginName(), '$', ...
   datestr(now, 'yyyy/mm/dd HH:MM:SS'), '$', nl);
fprintf(fid, '%% Copyright: Health and Safety Laboratory %s%s', ...
   datestr(now, 'yyyy'), nl);
PrintBlankLine(fid);
PrintBlankLine(fid);
PrintBlankLine(fid);
fprintf(fid, 'end%s', nl);
end


function [l, sh] = TellAfni_Commands (f, fpart )
%
%   [l, sh] = TellAfni_Commands (f, field)
%
%Purpose:
%   Extract, all the commands from README.driver
%   No guarantee that you'll get all the commands extracted,
%   Use this as a guide but read the entire README.driver for the full picture
%
%Input Parameters:
%   f: Full path and name of README.driver file
%      pass no parameters if you want the function to try and
%      locate the file automatically.
%      Use '' if you want to look for the file interactively.
%   field: Particular command of interest.
%          If specified, the help section from README.driver
%          is returned in sh.
%
%Output Parameters:
%   l a cell string of the possible parameters
%   sh: help string corresponding to field
%
%
%Key Terms:
%
%More Info :
%    TellAfni
%    TellAfni_Commands
%    Test_TellAfni
%    AFNI's README.driver
%    NewCs
%
%     Author : Ziad Saad
%     Date : Wed Dec 7 15:34:57 EST 2005
%     SSCC/NIMH/ National Institutes of Health, Bethesda Maryland

%Define the function name for easy referencing
FuncName = 'TellAfni_Commands';

%Debug Flag
DBG = 1;

%initailize return variables
err = 1;

if (nargin == 0), %try to find README.driver
   f = '';
   fpart = '';
elseif (nargin == 1),
   fpart = '';
end

if (isempty(f)),
   [s,w] = unix('locate README.driver');
   if (~isempty(w)), %got a hit
      i = find(isspace(w));
      f = w(1:i(1)-1);
   end
end

if (~isempty(f)),
   if (exist(f,'file') == 2),
      fprintf(1,'Using file %s for info.\n', f);
   else
      fprintf(2,'Failed to find README file %s\n', f);
      return;
   end
else
   f = '';
end

if (isempty(f)),
   [f, p] = uigetfile('README.driver', 'Pick a README.driver');
   if (f == 0),
      return;
   end
   f = sprintf('%s%c%s',p,filesep,f);
end

fid = fopen(f, 'r');
if (fid < 0),
   fprintf(2,'Failed to read %s\n', f);
   return;
end

s = fscanf(fid,'%c');
ns = length(s);
fclose(fid);

[err,inl] = FindChar(s,'NewLine');
ninl = length(inl);

ncm = 50;
cnt = 1;
S = char(zeros(ninl, ncm));
sl = [];
if (ninl),
   for (i=1:1:ninl-1),
      [err,w] = GetWord(s(inl(i):min(inl(i)+ncm, ns)),1);
      w = zdeblank(w);
      nw = length(w);
      if (nw > 1),
         if ( (sum(abs(double(upper(w))-double(w))) == 0) & sum(isletter(w)) > nw/2),
            % fprintf(2,'>%s<\t',w); pause
            S(cnt,1:nw) = w;
            %store location in s
            sl(cnt) = inl(i);
            cnt = cnt + 1;
         end
      end
   end
else
   fprintf(2,'Failed to understand file.\n');
   return;
end

if (cnt < 2),
   fprintf(2,'Failed to understand file, found nothing.\n');
   return;
end

[l, ilu] = unique(cellstr (S(1:cnt-1,:)));
ils = sl(ilu);

%do they want particular info ?
sh = '';
if (~isempty(fpart)),
   fpart = upper(zdeblank(fpart));
   cnt = 1;
   fnd = 0;
   while (cnt <= length(l)),
      if (~isempty(findstr(char(l(cnt)),fpart))), %(strncmp(char(l(cnt)),fpart,length(fpart))),
         fnd = cnt;
         %find location of next command
         dils = (ils - ils(cnt)); dils(find(dils<=0)) = max(dils + 1); [jj,imin] = min(dils);
         %here is the string
         sh = [sh s(ils(cnt)+1:min(ils(imin), length(s)))];
      end
      cnt = cnt + 1;
   end
   if (~fnd),
      fprintf(2,'Failed to find help for %s.\n', fpart);
      return;
   end
end

return;


classdef ImageRatio < Algorithms.CDAlg
    methods
        function obj = ImageRatio()
            obj@Algorithms.CDAlg('Image Ratioing', '')
        end
        DI = detectChange(obj, ~, ~);
    end
end


function obj = create(obj, varargin)
% Create an object from an empty obj structure, assigning fieldname/value
% pairs as optional arguments.
%
% :Usage:
% ::
%
%     [obj = create(obj, varargin)
%
% Used in fmri_data.m class constructor.

			  % if 'noverbose' is entered, suppress output
  verbose = isempty(strmatch('noverbose', varargin(cellfun(@ischar, varargin))));

  N = fieldnames(obj);

  for i = 1:length(varargin)
    if ischar(varargin{i})

      % Look for a field (attribute) with the input name
      wh = strmatch(varargin{i}, N, 'exact');

      if ~isempty(wh)

	obj.(varargin{i}) = varargin{i + 1};

	% special methods for specific fields
	switch varargin{i}
          case 'dat'
            xx = isnan(obj.(varargin{i}));
            if any(xx(:))
              if verbose
		fprintf('fmri_data.create: Converting %3.0f NaNs to 0s.', sum(xx(:)));
	      end
              obj.dat(xx) = 0;
            end
	end %Switch
      end % ~isempty
    end
  end
end % function


function varargout = process_evt_remove_simult( varargin )
% PROCESS_EVT_REMOVE_SIMULT: Remove occurences of an event A occurring at the same time as an event B.
%
% USAGE:  OutputFiles = process_evt_remove_simult('Run', sProcess, sInputs)

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2014-2019

eval(macro_method);
end

%% ===== GET DESCRIPTION =====
function sProcess = GetDescription() %#ok<DEFNU>
    % Description the process
    sProcess.Comment     = 'Remove simultaneous';
    sProcess.Category    = 'Custom';
    sProcess.SubGroup    = 'Events';
    sProcess.Index       = 49;
    sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/ArtifactsDetect#Remove_simultaneous_blinks.2Fheartbeats';
    % Definition of the input accepted by this process
    sProcess.InputTypes  = {'data', 'raw'};
    sProcess.OutputTypes = {'data', 'raw'};
    sProcess.nInputs     = 1;
    sProcess.nMinFiles   = 1;
    % Event name: to remove
    sProcess.options.remove.Comment = 'Remove events named: ';
    sProcess.options.remove.Type    = 'text';
    sProcess.options.remove.Value   = 'cardiac';
    % Event name: target
    sProcess.options.target.Comment = 'When too close to events: ';
    sProcess.options.target.Type    = 'text';
    sProcess.options.target.Value   = 'blink';
    % Maximum duration events
    sProcess.options.dt.Comment = 'Minimum delay between events: ';
    sProcess.options.dt.Type    = 'value';
    sProcess.options.dt.Value   = {0.250, 'ms', 0};
    % Delete original events
    sProcess.options.rename.Comment = 'Rename the events instead of deleting them';
    sProcess.options.rename.Type    = 'checkbox';
    sProcess.options.rename.Value   = 0;
end

%% ===== FORMAT COMMENT =====
function Comment = FormatComment(sProcess) %#ok<DEFNU>
    Comment = sProcess.Comment;
end

%% ===== RUN =====
function OutputFiles = Run(sProcess, sInputs) %#ok<DEFNU>
    % Return all the input files
    OutputFiles = {};

    % ===== GET OPTIONS =====
    % Get the options
    isDelete = ~sProcess.options.rename.Value;
    dt = sProcess.options.dt.Value{1};
    evtA = strtrim(sProcess.options.remove.Value);
    evtB = strtrim(sProcess.options.target.Value);
    % Check that the user gave one event in each box
    if isempty(evtA) || isempty(evtB)
        bst_report('Error', sProcess, [], 'Event name is empty.');
        return;
    elseif any(evtA == ',') || any(evtA == ';')  || any(evtB == ',') || any(evtB == ';')
        bst_report('Error', sProcess, [], 'This event can be used to process only one event type at a time.');
        return;
    end

    % ===== PROCESS ALL FILES =====
    % For each file
    for iFile = 1:length(sInputs)
        % ===== GET FILE DESCRIPTOR =====
        % Load the raw file descriptor
        isRaw = strcmpi(sInputs(iFile).FileType, 'raw');
        if isRaw
            DataMat = in_bst_data(sInputs(iFile).FileName, 'F');
            sEvents = DataMat.F.events;
        else
            DataMat = in_bst_data(sInputs(iFile).FileName, 'Events');
            sEvents = DataMat.Events;
        end
        % If no markers are present in this file
        if isempty(sEvents)
            bst_report('Error', sProcess, sInputs(iFile), 'This file does not contain any event. Skipping File...');
            continue;
        end
        % Call the detection function
        [sEvents, isModified] = Compute(sInputs(iFile), sEvents, evtA, evtB, dt, isDelete);

        % ===== SAVE RESULT =====
        % Only save changes if something was change
        if isModified
            % Report changes in .mat structure
            if isRaw
                DataMat.F.events = sEvents;
            else
                DataMat.Events = sEvents;
            end
            % Save file definition
            bst_save(file_fullpath(sInputs(iFile).FileName), DataMat, 'v6', 1);
        end
        % Return all the input files
        OutputFiles{end+1} = sInputs(iFile).FileName;
    end
end

%% ===== RENAME SIMULTANEOUS EVENTS =====
function [eventsNew, isModified] = Compute(sInput, events, evtA, evtB, dt, isDelete)
    % Initialize returned variables
    isModified = 0;
    eventsNew = events;
    % Get events names
    iEvtA = find(strcmpi({events.label}, evtA));
    iEvtB = find(strcmpi({events.label}, evtB));
    if isempty(iEvtA)
        bst_report('Error', 'process_evt_remove_simult', sInput, ['Event "' evtA '" does not exist.']);
        return;
    elseif isempty(iEvtB)
        bst_report('Error', 'process_evt_remove_simult', sInput, ['Event "' evtB '" does not exist.']);
        return;
    end
    % If events are extended events: error
    if (size(events(iEvtA).times,1) > 1) || (size(events(iEvtB).times,1) > 1)
        bst_report('Error', 'process_evt_remove_simult', sInput, 'Cannot process extended events.');
        return;
    end
    % Look of all the events A that are too close to event B
    iRemoveA = [];
    for iOcc = 1:size(events(iEvtA).times,2)
        if any(abs(events(iEvtA).times(iOcc) - events(iEvtB).times) <= dt)
            iRemoveA(end+1) = iOcc;
        end
    end
    % No events to remove
    if isempty(iRemoveA)
        return;
    end
    % Display info message with the number of events removed
    bst_report('Info', 'process_evt_remove_simult', sInput, sprintf('Removed %d events "%s" that were less than %d ms away from an event "%s".', length(iRemoveA), evtA, round(dt*1000), evtB));
    % If we need to rename the events to a new category
    if ~isDelete
        % Create new event name for the removed occurrences
        newLabel = file_unique([evtA '_rm'], {events.label});
        % Create new event
        iEvtRm = length(eventsNew) + 1;
        eventsNew(iEvtRm) = db_template('event');
        eventsNew(iEvtRm).label    = newLabel;
        eventsNew(iEvtRm).color    = [1 0 0];
        eventsNew(iEvtRm).times    = eventsNew(iEvtA).times(:,iRemoveA);
        eventsNew(iEvtRm).epochs   = eventsNew(iEvtA).epochs(iRemoveA);
        if ~isempty(eventsNew(iEvtA).channels)
            eventsNew(iEvtRm).channels = eventsNew(iEvtA).channels(iRemoveA);
        end
        if ~isempty(eventsNew(iEvtA).notes)
            eventsNew(iEvtRm).notes = eventsNew(iEvtA).notes(iRemoveA);
        end
    end
    % Remove occurrences / remove event
    if isequal(iRemoveA, 1:size(eventsNew(iEvtA).times,2))
        eventsNew(iEvtA) = [];
    else
        eventsNew(iEvtA).times(:,iRemoveA)  = [];
        eventsNew(iEvtA).epochs(iRemoveA)   = [];
        if ~isempty(eventsNew(iEvtA).channels)
            eventsNew(iEvtA).channels(iRemoveA) = [];
        end
        if ~isempty(eventsNew(iEvtA).notes)
            eventsNew(iEvtA).notes(iRemoveA) = [];
        end
    end
    isModified = 1;
end


function [molCollectionReport, newMolFilesDir] = obtainMetStructures(model, metList, outputDir, sources)
% Obtain MDL MOL files from various databases, including KEGG, HMDB, ChEBI,
% and PubChem. Alternatively, openBabel can be used to convert InChI
% strings or SMILES in MDL MOL files.
%
% USAGE:
%
% molCollectionReport = obtainMetStructures(model, mets, sources, standardisationApproach)
%
% INPUTS:
%    model: COBRA model with following fields:
%
%        * .S - The m x n stoichiometric matrix for the metabolic network.
%        * .mets - An m x 1 array of metabolite identifiers.
%        * .metInChIString - An m x 1 array of metabolite identifiers.
%        * .metSmiles - An m x 1 array of metabolite identifiers.
%        * .metVMHID - An m x 1 array of metabolite identifiers.
%        * .metCHEBIID - An m x 1 array of metabolite identifiers.
%        * .metKEGGID - An m x 1 array of metabolite identifiers.
%        * .metPubChemID - An m x 1 array of metabolite identifiers.
%        * .metHMDBID - An m x 1 array of metabolite identifiers.
%        * .metDrugbankID - An m x 1 array of metabolite identifiers.
%        * .metLipidmassID - An m x 1 array of metabolite identifiers.
%
% OPTIONAL INPUTS:
%    mets: List of metabolites to be download (Default: All)
%    outputDir: Directory that will contain the obtained metabolite structures.
%    sources: Sources where the MOL files will be obtained (Default: all).
%             The sources supported are:
%
%        1.- 'inchi' (requires openBabel)
%        2.- 'smiles' (requires openBabel)
%        3.- 'kegg' (https://www.genome.jp/)
%        4.- 'hmdb' (https://hmdb.ca/)
%        5.- 'pubchem' (https://pubchem.ncbi.nlm.nih.gov/)
%        6.- 'chebi' (https://www.ebi.ac.uk/)
%        7.- 'drugbank' (https://go.drugbank.com/)
%        8.- 'lipidmass' (https://www.lipidmaps.org/)
%
% OUTPUTS:
%    molCollectionReport: Report of the obtained MDL MOL files
%
%        * .metList - List of metabolites to be download
%        * .sources -list of sources of metabolite structures
%        * .structuresObtained -Total of metabolite structures obtained.
%        * .structuresObtainedPerSource -Boolean table with the metabolite
%               structures obtained by source.
%        * .databaseCoverage -Table indicating the coverage of metabolites
%               obtained by each of the sources.
%        * .idsToCheck -Id source from which no molecular structures could
%               be obtained due to a webTimeout, conversion error, or
%               inconsistent id.
%    newMolFilesDir: directory where new mol files were written, subdirectories for each source.

if nargin < 2 || isempty(metList)
    metList = unique(regexprep(model.mets, '(\[\w\])', ''));
else
    metList = unique(regexprep(metList, '(\[\w\])', ''));
end
if nargin < 3 || isempty(outputDir)
    outputDir = [pwd filesep];
else
    % Make sure input path ends with directory separator
    outputDir = [regexprep(outputDir,'(/|\\)$',''), filesep];
end

% Set directory
newMolFilesDir  = [outputDir 'metStructures' filesep];
if exist(newMolFilesDir, 'dir') == 0
    mkdir(newMolFilesDir)
end

if nargin < 4 || isempty(sources)
    sources = {'chebi'; 'drugbank'; 'hmdb'; 'inchi'; 'kegg'; 'lipidmaps'; 'pubchem'; 'smiles'};
else
    sources = sort(sources);
end
allSources = {'chebi'; 'drugbank'; 'hmdb'; 'inchi'; 'kegg'; 'lipidmaps'; 'pubchem'; 'smiles'};

% Check openbabel installation
if isunix || ispc
    obabelCommand = 'obabel';
else
    obabelCommand = 'openbabel.obabel';
end
[oBabelInstalled, ~] = system(obabelCommand);
if oBabelInstalled ~= 1
    oBabelInstalled = false;
    disp('obabel is not installed, two features cannot be used: ')
    disp('1 - Generation of SMILES, InChI and InChIkey')
    disp('2 - MOL file standardisation')
end

% if ismac || ispc
%     [oBabelInstalled, results] = system('obabel');
%     if find(contains(results,'Usage:')) % it is actually installed but input file is missing
%         oBabelInstalled = 1;
%     end
% else
%     [oBabelInstalled, ~] = system('openbabel.obabel');
% end
% if oBabelInstalled == 127
%     oBabelInstalled = 0;
% end

webTimeout = weboptions('Timeout', 60);

%% Obtain met data

% Obtain ID's
fields = fieldnames(model);

% chebi
chebiFieldBool = ~cellfun(@isempty, regexpi(fields, 'chebi'));
if any(chebiFieldBool)
    chebiIDs = model.(fields{chebiFieldBool});
else
    chebiIDs = cell(size(model.mets));
end

% drugbank
drugbankFieldBool = ~cellfun(@isempty, regexpi(fields, 'drugbank'));
if any(drugbankFieldBool)
    drugbankIDs = model.(fields{drugbankFieldBool});
else
    drugbankIDs = cell(size(model.mets));
end

% HMDB
hmdbFieldBool = ~cellfun(@isempty, regexpi(fields, 'hmdb'));
if any(hmdbFieldBool)
    hmdbIDs = model.(fields{hmdbFieldBool});
end

% inchi
inchiFieldBool = ~cellfun(@isempty, regexpi(fields, 'inchi'));
if any(inchiFieldBool) && isstruct(model.(fields{ismember(fields, 'inchi')}))
    inchis = model.(fields{ismember(fields, 'inchi')}).standardWithStereoAndCharge;
elseif any(inchiFieldBool) && ~isstruct(model.(fields{ismember(fields, 'inchi')}))
    inchis = model.(fields{ismember(fields, 'inchi')});
else
    inchis = cell(size(model.mets));
end

% KEGG
keggFieldBool = ~cellfun(@isempty, regexpi(fields, 'kegg'));
if any(keggFieldBool)
    if sum(keggFieldBool) > 1
        metFieldBool = ~cellfun(@isempty, regexpi(fields, 'met'));
        keggFieldBool = keggFieldBool & metFieldBool;
    end
    keggIDs = model.(fields{keggFieldBool});
else
    keggIDs = cell(size(model.mets));
end

% lipidmaps
lipidmapsFieldBool = ~cellfun(@isempty, regexpi(fields, 'lipidmaps'));
if any(lipidmapsFieldBool)
    lipidmapsIDs = model.(fields{lipidmapsFieldBool});
else
    lipidmapsIDs = cell(size(model.mets));
end

% PubChem
PubChemFieldBool = ~cellfun(@isempty, regexpi(fields, 'PubChem'));
if any(PubChemFieldBool)
    PubChemIDs = model.(fields{PubChemFieldBool});
else
    PubChemIDs = cell(size(model.mets));
end

% SMILES
smilesFieldBool = ~cellfun(@isempty, regexpi(fields, 'smiles'));
if any(smilesFieldBool)
    smiles = model.(fields{smilesFieldBool});
else
    smiles = cell(size(model.mets));
end

%% Obtain met structures

% Unique metabolites idexes
mets = regexprep(model.mets, '(\[\w\])', '');

% Obtain MDL MOL files
idsToCheck = {};
[inchiMsg, smilesMsg] = deal(true);
idMatrix = false(length(metList), length(allSources));
for i = 1:length(metList)

    % identify met in model and start matrix counter
    idx = find(ismember(mets, metList{i}));
    matrixCounter = 0;

    % ChEBI
    if ~isempty(chebiIDs{idx(1)})  && ismember({'chebi'}, sources)
        saveFileDir = [newMolFilesDir 'chebi' filesep];
        try
            molFile = webread(['https://www.ebi.ac.uk/chebi/saveStructure.do?defaultImage=true&chebiId=' num2str(chebiIDs{idx(1)}) '&imageId=0'], webTimeout);
            if ~isempty(regexp(molFile, 'M  END'))
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                fid2 = fopen([newMolFilesDir 'chebi' filesep metList{i} '.mol'], 'w');
                fprintf(fid2, '%s\n', molFile);
                fclose(fid2);
                idMatrix(i, 1) = true;
            end
        catch ME
            disp(ME.message)
            idsToCheck{end + 1, 1} = ['chebi - ' chebiIDs{idx(1)}];
        end
    end

    % drugbank
    if ~isempty(drugbankIDs{idx(1)})  && ismember({'drugbank'}, sources)
        saveFileDir = [newMolFilesDir 'drugbank' filesep];
        try
            if contains(drugbankIDs{idx(1)}, 'MET')
                molFile = webread(['https://go.drugbank.com/structures/metabolites/' num2str(drugbankIDs{idx(1)}) '.mol'], webTimeout);
            else
                molFile = webread(['https://go.drugbank.com/structures/small_molecule_drugs/' num2str(drugbankIDs{idx(1)}) '.mol'], webTimeout);
            end
            if ~isempty(regexp(molFile, 'M  END'))
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                fid2 = fopen([newMolFilesDir 'drugbank' filesep metList{i} '.mol'], 'w');
                fprintf(fid2, '%s\n', molFile);
                fclose(fid2);
                idMatrix(i, 2) = true;
            end
        catch ME
            disp(ME.message)
            idsToCheck{end + 1, 1} = ['drugbank - ' drugbankIDs{idx(1)}];
        end
    end

    % HMDB
    if ~isempty(hmdbIDs{idx(1)})  && ismember({'hmdb'}, sources)
        saveFileDir = [newMolFilesDir 'hmdb' filesep];
        try
            numbersID = hmdbIDs{idx(1)}(5:end);
            if size(numbersID, 2) < 7
                numbersID = [repelem('0', 7 - size(numbersID, 2)) numbersID];
            end
            molFile = webread(['https://hmdb.ca/structures/metabolites/HMDB' numbersID '.mol'], webTimeout);
            if ~isempty(regexp(molFile, 'M  END'))
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                fid2 = fopen([newMolFilesDir 'hmdb' filesep metList{i} '.mol'], 'w');
                fprintf(fid2, '%s\n', molFile);
                fclose(fid2);
                idMatrix(i, 3) = true;
            end
        catch ME
            disp(ME.message)
            idsToCheck{end + 1, 1} = ['hmdb - ' hmdbIDs{idx(1)}];
        end
    end

    % InChI
    if ~isempty(inchis{idx(1)}) && ismember({'inchi'}, sources)
        if oBabelInstalled
            try
                saveFileDir = [newMolFilesDir 'inchi' filesep];
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                newFormat = openBabelConverter(inchis{idx(1)}, 'mol', [saveFileDir ...
                    metList{i} '.mol']);
                idMatrix(i, 4) = true;
            catch ME
                disp(ME.message)
                idsToCheck{end + 1, 1} = ['inchi - ' keggIDs{idx(1)}];
            end
        elseif inchiMsg && ~oBabelInstalled
            inchiMsg = false;
            display('OpenBabel is not installed to convert InChIs')
        end
    end

    % KEGG
    if ~isempty(keggIDs{idx(1)})  && ismember({'kegg'}, sources)
        saveFileDir = [newMolFilesDir 'kegg' filesep];
        try
            switch keggIDs{idx(1)}(1)
                case 'C'
                    molFile = webread(['https://www.genome.jp/dbget-bin/www_bget?-f+m+compound+' keggIDs{idx(1)}], webTimeout);
                case 'D'
                    molFile = webread(['https://www.kegg.jp/dbget-bin/www_bget?-f+m+drug+' keggIDs{idx(1)}], webTimeout);
            end
            if ~isempty(regexp(molFile, 'M  END'))
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                fid2 = fopen([newMolFilesDir 'kegg' filesep metList{i} '.mol'], 'w');
                fprintf(fid2, '%s\n', molFile);
                fclose(fid2);
                idMatrix(i, 5) = true;
            end
        catch ME
            disp(ME.message)
            idsToCheck{end + 1, 1} = ['kegg - ' keggIDs{idx(1)}];
        end
    end

    % lipidmaps
    if ~isempty(lipidmapsIDs{idx(1)})  && ismember({'lipidmaps'}, sources)
        saveFileDir = [newMolFilesDir 'lipidmaps' filesep];
        try
            molFile = webread(['https://www.lipidmaps.org/databases/lmsd/' num2str(lipidmapsIDs{idx(1)}) '?format=mdlmol'], webTimeout);
            if ~isempty(regexp(molFile, 'M  END'))
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                fid2 = fopen([newMolFilesDir 'lipidmaps' filesep metList{i} '.mol'], 'w');
                fprintf(fid2, '%s\n', molFile);
                fclose(fid2);
                idMatrix(i, 6) = true;
            end
        catch ME
            disp(ME.message)
            idsToCheck{end + 1, 1} = ['lipidmaps - ' lipidmapsIDs{idx(1)}];
        end
    end

    % PubChem
    if ~isempty(PubChemIDs{idx(1)})  && ismember({'pubchem'}, sources)
        saveFileDir = [newMolFilesDir 'pubchem' filesep];
        try
            molFile = webread(['https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/CID/'...
                num2str(PubChemIDs{idx(1)}) ...
                '/record/SDF/?record_type=2d&response_type=display'], webTimeout);
            if ~isempty(regexp(molFile, 'M  END'))
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                molFile(regexp(molFile, 'M  END') + 6:end) = [];
                fid2 = fopen([newMolFilesDir 'pubchem' filesep metList{i} '.mol'], 'w');
                fprintf(fid2, '%s\n', molFile);
                fclose(fid2);
                idMatrix(i, 7) = true;
            end
        catch ME
            disp(ME.message)
            idsToCheck{end + 1, 1} = ['pubchem - ' PubChemIDs{idx(1)}];
        end
    end

    % SMILES
    if ~isempty(inchis{idx(1)}) && ismember({'smiles'}, sources)
        if oBabelInstalled
            try
                saveFileDir = [newMolFilesDir 'smiles' filesep];
                if exist(saveFileDir, 'dir') == 0
                    mkdir(saveFileDir)
                end
                newFormat = openBabelConverter(smiles{idx(1)}, 'mol', [saveFileDir ...
                    metList{i} '.mol']);
                idMatrix(i, 8) = true;
            catch ME
                disp(ME.message)
                idsToCheck{end + 1, 1} = ['inchi - ' keggIDs{idx(1)}];
            end
        elseif smilesMsg && ~oBabelInstalled
            smilesMsg = false;
            display('OpenBabel is not isntalled to convert SMILES')
        end
    end
end

%% Report

% Delete databases not included
idMatrix(:, ~ismember(allSources, sources)) = [];

% molCollectionReport
molCollectionReport.metList = metList;
molCollectionReport.sources = sources;
molCollectionReport.structuresObtained = sum(any(idMatrix'));

% Structures obtained
nRows = size(idMatrix, 1);
varTypes = ['string', repmat({'logical'}, 1, size(idMatrix, 2))];
varNames = ['mets'; sources];
structuresObtainedPerSource = table('Size', [nRows length(varTypes)], 'VariableTypes', varTypes, 'VariableNames', varNames);
structuresObtainedPerSource.mets = metList;
for i = 1:length(sources)
    structuresObtainedPerSource.(sources{i}) = idMatrix(:, i);
end
molCollectionReport.structuresObtainedPerSource = structuresObtainedPerSource;

% Database coverage table
[nCols nRows] = size(idMatrix);
varTypes = {'string', 'double', 'double', 'double'};
varNames = {'sources', 'coverage', 'metsWithStructure', 'metsWithoutStructure'};
databaseCoverage = table('Size', [nRows length(varTypes)], 'VariableTypes', varTypes, 'VariableNames', varNames);
databaseCoverage.sources = sources;

%if size(idMatrix, 2)> 0
%    databaseCoverage.metsWithStructure = sum(idMatrix)';
%    databaseCoverage.metsWithoutStructure = sum(~idMatrix)';
%    databaseCoverage.coverage = round((databaseCoverage.metsWithStructure * 100) / size(idMatrix, 1), 2);
%    molCollectionReport.databaseCoverage = databaseCoverage;
%end

if nCols > 1
    databaseCoverage.metsWithStructure = sum(idMatrix)';
    databaseCoverage.metsWithoutStructure = sum(~idMatrix)';
else
    databaseCoverage.metsWithStructure = double(idMatrix)';
    databaseCoverage.metsWithoutStructure = double(~idMatrix)';
end
databaseCoverage.coverage = round((databaseCoverage.metsWithStructure * 100) / size(idMatrix, 1), 2);
molCollectionReport.databaseCoverage = databaseCoverage;

molCollectionReport.idsToCheck = idsToCheck;
if ~isempty(idsToCheck)
    disp('The following structures could not be obtained')
    disp(idsToCheck)
end
end


function varargout = gui_loadset(varargin)
% load a dataset via the GUI
% [Dataset,Action] = gui_loadset()
% [Dataset,Action] = gui_loadset('Initialpath',Initialpath)
%
% Out:
%   Dataset     : the dataset, an expression (or [], if the user pressed Cancel)
%   Action      : either 'OK' or 'Cancel'
%
%                           Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                           2010-10-27

% Last Modified by GUIDE v2.5 05-Jan-2012 07:14:18

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

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

% --- Executes just before gui_loadset is made visible.
function gui_loadset_OpeningFcn(hObject, eventdata, handles, varargin)
if length(varargin) < 2
    initialpath = env_translatepath('data:/');
else
    initialpath = env_translatepath(varargin{2});
end

% run file dialog...
[handles.filename,handles.filepath] = uigetfile({'*.*', 'any supported file'; '*.set', 'EEGLAB dataset'; '*.vhdr', 'BrainProducts Vision Recorder file'; ...
    '*.bdf', 'BioSEMI BDF file'; '*.cnt', 'Neuroscan CNT / ANT EEProbe CNT file'; '*.avr', 'ANT EEProbe average / Megis/BESA file'; '*.mat', 'MATLAB file'; ...
    '*.raw', 'Electrical Geodesics / ERPSS / Yokogawa raw data file '; '*.sna', 'Snapmaster SNA file'; '*.eeg', 'Neuroscan EEG / ANT EEProbe / BrainVision data file'; ...
    '*.edf', 'European data format file'; '*.ds', 'CTF folder'; '*.rdf', 'ERPSS data file'; '*.asc', 'INStep ASC file'; '*.m4d', '4D pdf file'; ...
    '*.smr', 'Cambridge Electronic Design file'; '*.egis', 'Electrical Geodesics file'; '*.ave', 'Yokogawa / Electrical Geodesics file'; ...
    '*.gave', 'Electrical Geodesics file'; '*.ses', 'Electrical Geodesics file '; '*.swf', 'Megis/BESA file'; '*.avg', 'NeuroScan file'; '*.nxe', 'Nexstim file'; ...
    '*.dat', 'BrainVision data file'; '*.seg', 'BrainVision data file'; '*.res4', 'VSM MedTech file'; '*.meg4', 'VSM MedTech file'; ...
    '*.m4d', 'Neuromag Elektra / 4D Neuroimaging file'; '*.pdf', 'Neuromag Elektra / 4D Neuroimaging file'; '*.xyz', 'Neuromag Elektra / 4D Neuroimaging file'},'Select dataset(s) to load',initialpath);

% Choose default command line output for gui_loadset
handles.output = {[],'Cancel'};
% Update handles structure
guidata(hObject, handles);

if ~isnumeric(handles.filename)
    % UIWAIT makes gui_loadset wait for user response (see UIRESUME)
    uiwait(handles.figure1);
else
    % otherwise we directly close the figure again...
    close(handles.figure1);
end

% --- Outputs from this function are returned to the command line.
function varargout = gui_loadset_OutputFcn(hObject, eventdata, handles)
try
    varargout = handles.output;
    close(handles.figure1);
catch
    varargout = {[],'Cancel'};
end

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% construct optional arguments
args = {};
channels = str2num(get(handles.edit2,'String'));
if ~isempty(channels)
    args = [args {'channels' channels}]; end
timerange = str2num(get(handles.edit5,'String'));
if ~isempty(timerange)
    args = [args {'timerange' timerange}]; end
samplerange = str2num(get(handles.edit4,'String'));
if ~isempty(samplerange)
    args = [args {'samplerange' samplerange}]; end
types = get(handles.edit8,'String');
if ~isempty(types)
    % neither quoted nor a cell array --> put in quotes
    if types(1) ~= '''' && types(1) ~= '{'
        types = ['''' types '''']; end
    % evaluate & make a cell if necessary
    types = eval(types);
    if ~iscell(types)
        types = {types}; end
    args = [args {'types' types}];
end
miscopts = get(handles.edit6,'String');
if ~isempty(miscopts)
    args = [args evalin('base',['{' miscopts '}'])]; end
if isfield(handles,'markerchannel')
    args = [args {'markerchannel', {handles.markerchannel}}]; end
if ~isfield(handles,'insert_params')
    handles.insert_params = {}; end

% construct the loader expression
if iscell(handles.filename)
    for c=1:length(handles.filename)
        dataset{c} = io_loadset([handles.filepath,handles.filename{c}],args{:});
        for p=1:length(handles.insert_params)
            dataset{c} = set_insert_markers(dataset{c},handles.insert_params{p}); end

    end
    dataset = set_concat(dataset{:});
else
    dataset = io_loadset([handles.filepath,handles.filename],args{:});
    for p=1:length(handles.insert_params)
        dataset = set_insert_markers(dataset,handles.insert_params{p}); end
end

% optionally check if the dataset is loadable
if get(handles.checkbox1,'Value') == get(handles.checkbox1,'Max')
    tmp = exp_eval(dataset); end

% assign in workspace
assignin('base',get(handles.edit1,'String'),dataset);
handles.output = {dataset,'OK'};
guidata(hObject,handles);
uiresume(handles.figure1);

function pushbutton2_Callback(hObject, eventdata, handles)
handles.output = {[],'Cancel'};
guidata(hObject,handles);
uiresume(handles.figure1);

function pushbutton3_Callback(hObject, eventdata, handles)
handles.insert_params = gui_eventinsertion();
guidata(hObject,handles);

function pushbutton6_Callback(hObject, eventdata, handles)
tmp = arg_guidialog(@set_infer_markers,'Invoke',false);
if ~isempty(tmp)
    handles.markerchannel = tmp; end
guidata(hObject,handles);

function edit1_Callback(hObject, eventdata, handles)
gui_check_varname(hObject,'lastdata');

function edit2_Callback(hObject, eventdata, handles)
gui_check_vector(hObject);

function edit3_Callback(hObject, eventdata, handles)
gui_check_scalar(hObject);

function edit4_Callback(hObject, eventdata, handles)
gui_check_range(hObject);

function edit5_Callback(hObject, eventdata, handles)
gui_check_range(hObject);

function edit8_Callback(hObject, eventdata, handles)

function pushbutton5_Callback(hObject, eventdata, handles)
% help button
env_doc io_loadset

function figure1_KeyPressFcn(hObject, eventdata, handles)
if strcmp(eventdata.Key,'return')
    pushbutton1_Callback(handles.pushbutton1, eventdata, handles); end
if strcmp(eventdata.Key,'escape')
    pushbutton2_Callback(handles.pushbutton2, eventdata, handles); end

% --- auto-generated trash ---

% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
function edit2_CreateFcn(hObject, eventdata, handles)
function edit3_CreateFcn(hObject, eventdata, handles)
function edit4_CreateFcn(hObject, eventdata, handles)
function edit5_CreateFcn(hObject, eventdata, handles)
function edit6_Callback(hObject, eventdata, handles)
function edit6_CreateFcn(hObject, eventdata, handles)
function checkbox1_Callback(hObject, eventdata, handles)
function edit8_CreateFcn(hObject, eventdata, handles)
function figure1_CreateFcn(hObject, eventdata, handles)