function [cfg] = ft_definetrial(cfg)

% FT_DEFINETRIAL defines the trials or segments of data that will be used for further
% processing and analysis, i.e. the pieces of data that will be read in by
% FT_PREPROCESSING. Trials are defined by their begin and end sample in the data file
% and each trial has an offset that defines where the relative t=0 point (usually the
% sample at which the trigger is detected) is for that trial or segment.
%
% Use as
%   [cfg] = ft_definetrial(cfg)
% where the configuration structure should contain
%   cfg.trialdef       = structure with the details of trial definition, see below
%   cfg.trialfun       = string with the function name, see below (default = 'ft_trialfun_general')
%   cfg.representation = 'numeric' or 'table', determines how the trial definition is returned (default is automatic)
% and furthermore
%   cfg.dataset        = string with the filename
% or
%   cfg.headerfile     = string with the filename
%   cfg.datafile       = string with the filename
% and optionally
%   cfg.headerformat   = string, see FT_FILETYPE (default is automatic)
%   cfg.dataformat     = string, see FT_FILETYPE (default is automatic)
%   cfg.eventformat    = string, see FT_FILETYPE (default is automatic)
%
% In general, a call to FT_DEFINETRIAL results in the trial definition "trl" being
% added to the output configuration. The trials are defined on the basis of events or
% triggers by a user-specified MATLAB function that is subsequently referred to as
% the trial function. The user can specify their own custom function tailored to the
% experimental paradigm, or use one of the default trial functions (see below).
%
% Simple trial definitions (for example based on a single trigger) are supported by
% FT_TRIALFUN_GENERAL, which is specified as the default. It supports the following
% options
%   cfg.trialdef.eventtype  = string, or cell-array with strings
%   cfg.trialdef.eventvalue = number, string, or list with numbers or strings
%   cfg.trialdef.prestim    = number, latency in seconds (optional)
%   cfg.trialdef.poststim   = number, latency in seconds (optional)
%
% To read all data from a continuous file in a single or in multiple segments,
% FT_TRIALFUN_GENERAL understands the following options
%    cfg.trialdef.triallength = duration in seconds (can also be 1 or Inf)
%    cfg.trialdef.ntrials     = number of trials (can also be 1 or Inf)
%    cfg.trialdef.overlap     = number between 0 and 1 (exclusive) specifying the fraction of overlap between snippets (0 = no overlap)
%
% To display a list with the events in your data on screen, you can use
% FT_TRIALFUN_SHOW. This is useful for diagnostics; no actual trials will be defined.
%
% To display a graphical user interface dialog that allows you to select events of
% interest, you can use FT_TRIALFUN_GUI.
%
% The trial definition "trl" is an Nx3 matrix or table, where N is the number of
% trials. The first column contains the sample-indices of the start of each trial
% relative to the start of the raw data, the second column contains the sample
% indices of the end of each trial, and the third column contains the offset of the
% trigger with respect to the trial. An offset of 0 means that the first sample of
% the trial corresponds to the trigger. A positive offset indicates that the first
% sample is later than the trigger, and a negative offset indicates that the trial
% begins before the trigger.
%
% Besides the required three columns in the trial definition "trl" that represent
% start, end and offset, it can have contain additional columns . These additional
% columns can be used by a custom trialfun to provide  information about each trial,
% such as trigger codes, response latencies, trial type and response correctness.
% After FT_PREPROCESSING these additional columns of the "trl" matrix will be
% represented in the "trialinfo" field.
%
% If FT_TRIALFUN_GENERAL or FT_TRIALFUN_GUI has been used to generate the "trl"
% matrix or table, the function may return a fourth column that refers to the
% event-code for the corresponding trial. Whether or not this column is returned
% depends on the acquisition system. In general, this fourth column is generated by
% default if the event codes are represented numerically, or as a string starting
% with 'S' or 'R' (for BrainVision data).
%
% If you need to define the segments of interest on the basis of a conditional
% sequence of events (e.g. stimulus trigger followed by a correct response) or on
% basis of some signal feature that needs to be detected in the data, you should
% supply in cfg.trialfun the name of a function that you wrote yourself and that
% FT_DEFINETRIAL will call. The function receives the cfg structure as input and
% should return a NxM matrix in the same format as "trl" as the output. You can add
% extra custom fields to cfg.trialdef to pass to your own trialfun. See below for
% pointers to some examples.
%
% See also FT_PREPROCESSING, FT_READ_HEADER, FT_READ_EVENT, FT_TRIALFUN_GENERAL,
% FT_TRIALFUN_GUI, FT_TRIALFUN_SHOW, FT_TRIALFUN_BIDS, FT_TRIALFUN_EXAMPLE1,
% FT_TRIALFUN_EXAMPLE2

% Undocumented local options:
% cfg.datafile
% cfg.dataset
% cfg.event
% cfg.trl
% cfg.version

% Copyright (C) 2003-2021, Robert Oostenveld, FCDC
%
% 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$

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble provenance

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% check if the input cfg is valid for this function
cfg = ft_checkconfig(cfg, 'dataset2files', 'yes');

% this is deprecated as of 26 Sept 2021, it can be removed in a few years
if issubfield(cfg, 'trialdef.eventtype')
  if isequal(cfg.trialdef.eventtype, '?')
    ft_warning('cfg.trialdef.eventtype=''?'' is deprecated, please specify cfg.trialfun=''ft_trialfun_show''');
    cfg.trialfun = 'ft_trialfun_show';
    cfg.trialdef = rmfield(cfg.trialdef, 'eventtype');
  elseif isequal(cfg.trialdef.eventtype, 'gui')
    ft_warning('cfg.trialdef.eventtype=''gui'' is deprecated, please specify cfg.trialfun=''ft_trialfun_gui''');
    cfg.trialfun = 'ft_trialfun_gui';
    cfg.trialdef = rmfield(cfg.trialdef, 'eventtype');
  end
end % default based on eventtype

if issubfield(cfg, 'trialdef.eventvalue')
  if isequal(cfg.trialdef.eventvalue, '?')
    ft_warning('cfg.trialdef.eventvalue=''?'' is deprecated, please specify cfg.trialfun=''ft_trialfun_show''');
    cfg.trialfun = 'ft_trialfun_show';
    cfg.trialdef = rmfield(cfg.trialdef, 'eventvalue');
  elseif isequal(cfg.trialdef.eventvalue, 'gui')
    ft_warning('cfg.trialdef.eventvalue=''gui'' is deprecated, please specify cfg.trialfun=''ft_trialfun_gui''');
    cfg.trialfun = 'ft_trialfun_gui';
    cfg.trialdef = rmfield(cfg.trialdef, 'eventvalue');
  end
end % default based on eventvalue

% set the default options
cfg.trialfun        = ft_getopt(cfg, 'trialfun', 'ft_trialfun_general'); % the default might already be set above
cfg.representation  = ft_getopt(cfg, 'representation'); % this can 'numeric' or 'table'

if isfield(cfg, 'trl')
  % the trial definition is already part of the configuration
  ft_info('retaining existing trial definition\n');
  trl = cfg.trl;
  if isfield(cfg, 'event')
    ft_info('retaining existing event information\n');
    event = cfg.event;
  else
    event = [];
  end

else
  % try to locate the trialfun
  trialfunSpecified = cfg.trialfun;
  cfg.trialfun = ft_getuserfun(cfg.trialfun, 'trialfun');

  if isempty(cfg.trialfun)
    ft_error('the specified trialfun ''%s'' was not found', trialfunSpecified);
  else
    ft_info('evaluating trial function ''%s''\n', func2str(cfg.trialfun));
  end

  % determine the number of outpout arguments of the user-supplied trial function
  try
    % the nargout function in MATLAB 6.5 and older does not work on function handles
    num = nargout(cfg.trialfun);
  catch
    num = 1;
  end
  if num==1
    % the user-defined function only gives back the trial definition
    trl   = feval(cfg.trialfun, cfg);
    event = [];
  else
    % the user-defined function also gives back detailed information about
    % conditions, reaction time or any other information
    [trl, event] = feval(cfg.trialfun, cfg);
  end

end % if trl is present or trialfun specified

if size(trl,1)<1
  if isequal(cfg.trialfun, 'ft_trialfun_show') || isequal(cfg.trialfun, str2func('ft_trialfun_show'))
    % give a gentle message instead of an error
    ft_notice('no trials have been defined yet, see FT_DEFINETRIAL for further help\n');
  else
    % give an error in all other cases
    ft_error('no trials were defined, see FT_DEFINETRIAL for help');
  end
elseif size(trl,2) < 3
  ft_error('trl must have at least 3 columns, see FT_DEFINETRIAL for help');
end

% set trl to requested type
if isempty(cfg.representation)
  % keep the format as is
elseif strcmp(cfg.representation, 'numeric') && istable(trl)
  % convert from table to numeric
  trl = table2array(trl);
elseif strcmp(cfg.representation, 'table') && isnumeric(trl)
  % convert the numeric array to a table
  trl = array2table(trl);
  % the 3 first columns are named begsample, endsample and offset, and the rest get default names
  trl.Properties.VariableNames(1:3) = {'begsample', 'endsample', 'offset'};
end

% add the events to the output configuration
if isstruct(event)
  ft_info('found %d events\n', length(event));
  cfg.event = event;
elseif istable(event)
  ft_info('found %d events\n', size(event, 1));
  cfg.event = event;
end

% add the trial definition to the output configuration
if size(trl,1)>0
  ft_info('created %d trials\n', size(trl,1));
  cfg.trl = trl;
end

% do the general cleanup and bookkeeping at the end of the function
ft_postamble provenance
ft_postamble debug


function str = info(i, game)

data = get(game.Players(i), 'UserData');
str = {game.names{i}; ...
       ['Troops: ' num2str(data(1))]; ...
       ['Conquered: ' num2str(data(2))]};


function varargout = lvd_EditFixedInFrameVectorGUI(varargin)
% LVD_EDITFIXEDINFRAMEVECTORGUI MATLAB code for lvd_EditFixedInFrameVectorGUI.fig
%      LVD_EDITFIXEDINFRAMEVECTORGUI, by itself, creates a new LVD_EDITFIXEDINFRAMEVECTORGUI or raises the existing
%      singleton*.
%
%      H = LVD_EDITFIXEDINFRAMEVECTORGUI returns the handle to a new LVD_EDITFIXEDINFRAMEVECTORGUI or the handle to
%      the existing singleton*.
%
%      LVD_EDITFIXEDINFRAMEVECTORGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in LVD_EDITFIXEDINFRAMEVECTORGUI.M with the given input arguments.
%
%      LVD_EDITFIXEDINFRAMEVECTORGUI('Property','Value',...) creates a new LVD_EDITFIXEDINFRAMEVECTORGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before lvd_EditFixedInFrameVectorGUI_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to lvd_EditFixedInFrameVectorGUI_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 lvd_EditFixedInFrameVectorGUI

% Last Modified by GUIDE v2.5 12-Jan-2021 12:32:12

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @lvd_EditFixedInFrameVectorGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @lvd_EditFixedInFrameVectorGUI_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 lvd_EditFixedInFrameVectorGUI is made visible.
function lvd_EditFixedInFrameVectorGUI_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 lvd_EditFixedInFrameVectorGUI (see VARARGIN)

    % Choose default command line output for lvd_EditFixedInFrameVectorGUI
    handles.output = hObject;

    centerUIFigure(hObject);

    vector = varargin{1};
    setappdata(hObject, 'vector', vector);

    lvdData = varargin{2};
    setappdata(hObject, 'lvdData', lvdData);

	populateGUI(handles, vector);

    % Update handles structure
    guidata(hObject, handles);

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

function populateGUI(handles, vector)
    set(handles.vectorNameText,'String',vector.getName());
    setappdata(handles.lvd_EditFixedInFrameVectorGUI,'frame',vector.frame);

    frame = vector.getFrame();
    handles.refFrameTypeCombo.String = ReferenceFrameEnum.getListBoxStr();
    handles.refFrameTypeCombo.Value = ReferenceFrameEnum.getIndForName(frame.typeEnum.name);
    handles.setFrameOptionsButton.TooltipString = sprintf('Current Frame: %s', frame.getNameStr());

    rVect = vector.getRVect();
    set(handles.xCoordText,'String',fullAccNum2Str(rVect(1)));
    set(handles.yCoordText,'String',fullAccNum2Str(rVect(2)));
    set(handles.zCoordText,'String',fullAccNum2Str(rVect(3)));

    handles.vectorLineColorCombo.String = ColorSpecEnum.getListboxStr();
    handles.vectorLineColorCombo.Value = ColorSpecEnum.getIndForName(vector.lineColor.name);

    handles.vectorLineSpecCombo.String = LineSpecEnum.getListboxStr();
    handles.vectorLineSpecCombo.Value = LineSpecEnum.getIndForName(vector.lineSpec.name);

% --- Outputs from this function are returned to the command line.
function varargout = lvd_EditFixedInFrameVectorGUI_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
    if(isempty(handles))
        varargout{1} = false;
    else
        vector = getappdata(hObject, 'vector');

        vector.setName(handles.vectorNameText.String);

        x = str2double(get(handles.xCoordText,'String'));
        y = str2double(get(handles.yCoordText,'String'));
        z = str2double(get(handles.zCoordText,'String'));
        vector.setRVect([x;y;z]);

        vector.frame = getappdata(hObject,'frame');

        str = handles.vectorLineColorCombo.String{handles.vectorLineColorCombo.Value};
        vector.lineColor = ColorSpecEnum.getEnumForListboxStr(str);

        str = handles.vectorLineSpecCombo.String{handles.vectorLineSpecCombo.Value};
        vector.lineSpec = LineSpecEnum.getEnumForListboxStr(str);

        varargout{1} = true;
        close(handles.lvd_EditFixedInFrameVectorGUI);
    end

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

    if(isempty(errMsg))
        uiresume(handles.lvd_EditFixedInFrameVectorGUI);
    else
        msgbox(errMsg,'Invalid Vector Inputs','error');
    end

function errMsg = validateInputs(handles)
    errMsg = {};

    xval = str2double(get(handles.xCoordText,'String'));
    enteredStr = get(handles.xCoordText,'String');
    numberName = 'X Coordinate';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(xval, numberName, lb, ub, isInt, errMsg, enteredStr);

    yval = str2double(get(handles.yCoordText,'String'));
    enteredStr = get(handles.yCoordText,'String');
    numberName = 'Y Coordinate';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(yval, numberName, lb, ub, isInt, errMsg, enteredStr);

    zval = str2double(get(handles.zCoordText,'String'));
    enteredStr = get(handles.zCoordText,'String');
    numberName = 'Z Coordinate';
    lb = -Inf;
    ub = Inf;
    isInt = false;
    errMsg = validateNumber(zval, numberName, lb, ub, isInt, errMsg, enteredStr);

    if(normVector([xval, yval, zval]) == 0)
        errMsg{end+1} = 'The magnitude of the vector must be greater than 0.';
    end

    if(isempty(strtrim(handles.vectorNameText.String)))
        errMsg{end+1} = 'Vector name must contain more than white space and must not be empty.';
    end

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

function vectorNameText_Callback(hObject, eventdata, handles)
% hObject    handle to vectorNameText (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 vectorNameText as text
%        str2double(get(hObject,'String')) returns contents of vectorNameText as a double

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function xCoordText_Callback(hObject, eventdata, handles)
% hObject    handle to xCoordText (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 xCoordText as text
%        str2double(get(hObject,'String')) returns contents of xCoordText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on key press with focus on lvd_EditFixedInFrameVectorGUI or any of its controls.
function lvd_EditFixedInFrameVectorGUI_WindowKeyPressFcn(hObject, eventdata, handles)
% hObject    handle to lvd_EditFixedInFrameVectorGUI (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.FIGURE)
%	Key: name of the key that was pressed, in lower case
%	Character: character interpretation of the key(s) that was pressed
%	Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)
    switch(eventdata.Key)
        case 'return'
            saveAndCloseButton_Callback(handles.saveAndCloseButton, [], handles);
        case 'enter'
            saveAndCloseButton_Callback(handles.saveAndCloseButton, [], handles);
        case 'escape'
            close(handles.lvd_EditFixedInFrameVectorGUI);
    end

function yCoordText_Callback(hObject, eventdata, handles)
% hObject    handle to yCoordText (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 yCoordText as text
%        str2double(get(hObject,'String')) returns contents of yCoordText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function zCoordText_Callback(hObject, eventdata, handles)
% hObject    handle to zCoordText (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 zCoordText as text
%        str2double(get(hObject,'String')) returns contents of zCoordText as a double
    newInput = get(hObject,'String');
    newInput = attemptStrEval(newInput);
    set(hObject,'String', newInput);

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

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in vectorLineSpecCombo.
function vectorLineSpecCombo_Callback(hObject, eventdata, handles)
% hObject    handle to vectorLineSpecCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns vectorLineSpecCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from vectorLineSpecCombo

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

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in vectorLineColorCombo.
function vectorLineColorCombo_Callback(hObject, eventdata, handles)
% hObject    handle to vectorLineColorCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns vectorLineColorCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from vectorLineColorCombo

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

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in refFrameTypeCombo.
function refFrameTypeCombo_Callback(hObject, eventdata, handles)
% hObject    handle to refFrameTypeCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns refFrameTypeCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from refFrameTypeCombo
    frameUpdated(handles);

function frameUpdated(handles)
    lvdData = getappdata(handles.lvd_EditFixedInFrameVectorGUI, 'lvdData');

    frame = getappdata(handles.lvd_EditFixedInFrameVectorGUI,'frame'); %curElemSet
    bodyInfo = frame.getOriginBody();

    if(isempty(bodyInfo))
        bodyInfo = LvdData.getDefaultInitialBodyInfo(lvdData.celBodyData);
    end

    contents = cellstr(get(handles.refFrameTypeCombo,'String'));
    selFrameType = contents{get(handles.refFrameTypeCombo,'Value')};
    refFrameEnum = ReferenceFrameEnum.getEnumForListboxStr(selFrameType);

    switch refFrameEnum
        case ReferenceFrameEnum.BodyCenteredInertial
            newFrame = bodyInfo.getBodyCenteredInertialFrame();

        case ReferenceFrameEnum.BodyFixedRotating
            newFrame = bodyInfo.getBodyFixedFrame();

        case ReferenceFrameEnum.TwoBodyRotating
            if(frame.typeEnum == ReferenceFrameEnum.TwoBodyRotating)
                newFrame = frame;
            else
                if(not(isempty(bodyInfo.childrenBodyInfo)))
                    primaryBody = bodyInfo;
                    secondaryBody = bodyInfo.childrenBodyInfo(1);
                else
                    primaryBody = bodyInfo.getParBodyInfo();
                    secondaryBody = bodyInfo;
                end

                originPt = TwoBodyRotatingFrameOriginEnum.Primary;

                newFrame = TwoBodyRotatingFrame(primaryBody, secondaryBody, originPt, bodyInfo.celBodyData);
            end

        case ReferenceFrameEnum.UserDefined
            numFrames = lvdData.geometry.refFrames.getNumRefFrames();
            if(numFrames >= 1)
                geometricFrame = lvdData.geometry.refFrames.getRefFrameAtInd(1);
                newFrame = UserDefinedGeometricFrame(geometricFrame, lvdData);
            else
                newFrame = bodyInfo.getBodyCenteredInertialFrame();
                warndlg('There are no geometric frames available.  A body-centered inertial frame will be selected instead.');
            end

        otherwise
            error('Unknown reference frame type: %s', string(refFrameEnum));
    end

    if(not(isempty(newFrame)) && newFrame.typeEnum ~= refFrameEnum)
        refFrameEnum = newFrame.typeEnum;
        handles.refFrameTypeCombo.Value = ReferenceFrameEnum.getIndForName(refFrameEnum.name);
    end

    setappdata(handles.lvd_EditFixedInFrameVectorGUI,'frame',newFrame);
    handles.setFrameOptionsButton.TooltipString = sprintf('Current Frame: %s', newFrame.getNameStr());

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

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in setFrameOptionsButton.
function setFrameOptionsButton_Callback(hObject, eventdata, handles)
% hObject    handle to setFrameOptionsButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    frame = getappdata(handles.lvd_EditFixedInFrameVectorGUI,'frame');

    newFrame = frame.editFrameDialogUI(EditReferenceFrameContextEnum.ForGeometry);

    setappdata(handles.lvd_EditFixedInFrameVectorGUI,'frame',newFrame);

    frameUpdated(handles);


function centerGUI(h)

OldUnits = get(h,'Units');
set(h,'Units','pixels');
OldPos = get(h,'Position');
FigWidth = OldPos(3);
FigHeight = OldPos(4);

ScreenUnits = get(0,'Units');
set(0,'Units','pixels');
ScreenSize = get(0,'MonitorPosition'); % MonitorPosition works better than ScreenSize for multiheaded comps
ScreenSize = ScreenSize(1,:);
set(0,'Units',ScreenUnits);

FigPos(1)=1/2*(ScreenSize(3)-FigWidth);
FigPos(2)=2/3*(ScreenSize(4)-FigHeight);
FigPos(3:4)=[FigWidth FigHeight];
set(h,'Position',FigPos);
set(h,'Units',OldUnits);

end


%kputpixel 'Display Pixel Values Associated with Region of Image'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros putpixel.pane file
%
% Parameters:
% InputFile: i 'Input File', required: 'File containing pixels to display'
% Integer: valuewidth 'Width of Pixel Value Display ', default: 7: 'Specifies the number of pixel values along width'
% Integer: valueheight 'Height of Pixel Value Display', default: 7: 'Specifies the number of pixel values along height'
% Integer: x 'X Placement', default: -1: 'X location for GUI autoplacement'
% Integer: width 'Window Width ', default: 256: 'Window width'
% Integer: y 'Y Placement', default: -1: 'Y location for GUI autoplacement'
% Integer: height 'Window Height', default: 256: 'Window height'
% Double: update 'Update time', default: 2: 'How often to check input file for modification'
%
% Example: kputpixel(i, {'i','';'valuewidth',7;'valueheight',7;'x',-1;'width',256;'y',-1;'height',256;'update',2})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% putpixel - Display Pixel Values Associated with Region of Image
%
%  DESCRIPTION
% Putpixel is a visualization program that displays value data as
% a grid of values.  These value data points may be pixels in an image.
%
% The number of map pixel values that are displayed along width and height
% can be specified using the [-valuewidth] and [-valueheight] arguments.  These
% options control the number of pixel values that are displayed in
% the horizontal and vertical directions of the display.
%
% It is possible to specify the map pixel background color using the
% [-showcolormap] argument.  When set to "TRUE", the pixel under the
% pointer will be displayed as the background color for the label object in
% which the map values are displayed.  When set to "FALSE", the background
% color is displayed as black.
%
% By default, the visualization display will share its colormap will all
% other applications running at the same time; that is, it does not not use a
% .I "private colormap",
% but rather makes use of the
% .I "default colormap".
% It is possible to specify that the visualization display allocate its
% own private colormap or "grab" all available colors for its own use.
% This is done using the [-priv] argument.  When [-priv] is specified,
% moving the mouse pointer into the display window will cause the display
% to have its private colormap installed; moving the pointer out of the
% display window will cause the private colormap to be de-installed.  This
% results in the "technoflashing" phenomenon characteristic of private
% colormap installation.
%
% Color allocation can also be controlled and set to either
% .I "read-only"
% or
% .I "read/write"
% using the [-alloc] argument.  When set to
% .I "read-only",
% once a color cell has been allocated, it can have its color set only once;
% from then on, the color cell can be shared by multiple applications, but
% not changed.  If the visualization display requires the color displayed
% to change, it must re-allocate the color cell, forcing a re-display of
% data.  This can be an expensive procedure.  In contrast, after a
% .I "read/write"
% color cell is allocated, it can have its color changed at any time
% without re-allocation; the data being displayed does not need to be
% redisplayed, and the color update process is much more efficient.
% However, the colors used in the visualization display cannot be shared by
% other applications.
%
% The input file containing the data values to be displayed is monitored
% by default; the file is checked every 2 seconds for change, and if it
% has been modified, the displayed values are updated accordingly.  The
% interval at which the input file is checked for modification may be
% specified using the [-update] argument.
%
% On creation, the window which displays the value data may be placed
% manually (the default method), or placed automatically.  For automatic
% placement of the window which displays the value data, specify the
% desired location in device (screen) coordinates using the [-x] and
% [-y] arguments.
%
% While the display window should be created with a default size that is
% appropriate to display the data, a width and height for the window can
% be specified explicitly using the [-width] and [-height] arguments.
% Alternatively, you may allow the display window to size itself initially,
% and then use the window manager to interactively modify its size as desired.
%
%
%
%  EXAMPLES
% % putpixel -i image:mandril
% % putpixel -i image:ball
%
%  "SEE ALSO"
% putdata(1)
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

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

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


function data=readbin(fname,nrow,type)
%Open the file
fid=fopen(fname,'rb');
if (fid==-1)
    disp('file not found');
    data=[];
    return;
end

%Determine the type
if (nargin==3)
    if (isempty(type))
        type='double';
    end
else
    type='double';
end

%Read the Data
data=fread(fid,[nrow inf],type);

%Check the last data to see if the nrow is true
sr_a=zeros(1,type);
sr_b=whos('sr_a');
nbyte=sr_b.bytes;

fseek(fid,-nbyte, 'cof');
sr_a=fread(fid,1,type);
if (sr_a~=data(end))
    disp('Achtung: (readbin) "nrow" is probably wrong!');
end

fclose(fid);


% Used for printing and displaying image
%
% @authors:     Ahmad Humayun
% @contact:     ahumayun@cc.gatech.edu
% @affiliation: Georgia Institute of Technology
% @date:        Fall 2013 - Summer 2014

function [ varargout ] = drawFigFrames( varargin )
% evaluate function according to the number of inputs and outputs

    if nargout(varargin{1}) > 0
        [varargout{1:nargout(varargin{1})}] = feval(varargin{:});
    else
        feval(varargin{:});
    end
end

function [fig_info] = init_fig(frame_sz, varargin)
    addpath_export_fig();

    screen_sz = get(0,'ScreenSize');
    fig_info.fg_h = figure('units', 'pixels', 'position', ...
        [screen_sz([3 4])-frame_sz([2 1])-40 frame_sz([2 1])], ...
        'paperpositionmode', 'auto', varargin{:});
    fig_info.ax_h = axes('Parent',fig_info.fg_h);
end

function h = imshow_fig(frame, fig_info, varargin)
    h = imshow(frame, 'Parent',fig_info.ax_h, ...
        'InitialMagnification','fit', 'Border','tight', varargin{:});
%     truesize;
end

function h = imagesc_fig(frame, fig_info, varargin)
    h = imagesc(frame, 'Parent',fig_info.ax_h, varargin{:});
    adjust_ax(fig_info);
end

function h = image_fig(frame, fig_info, varargin)
    h = image(frame, 'Parent', fig_info.ax_h, varargin{:});
    adjust_ax(fig_info);
end

function holdonoff(on_off, fig_info)
    hold(fig_info.ax_h, on_off);
end

function fg_h = get_fig_h(fig_info)
    fg_h = fig_info.fg_h;
end

function ax_h = get_ax_h(fig_info)
    ax_h = fig_info.ax_h;
end

function export_fig_only(im_filepath, fig_info)
    adjust_ax(fig_info);
%     set(fig_info.ax_h, 'Units','pixels','Position',[200 200 c r]);
    export_fig(im_filepath, '-a1', fig_info.fg_h);
%     set(gca,'Position',[0 0 1 1]);  %# Modify axes size
end

function export_fig_and_clear(im_filepath, fig_info)
    export_fig_only(im_filepath, fig_info);
    delete(get(fig_info.ax_h, 'children'));
end

function adjust_ax(fig_info)
    set(fig_info.ax_h, 'Units','normalized', ...
        'position', [0 0 1 1], 'visible', 'off');
end

function close_fig(fig_info)
    delete(fig_info.ax_h);
    close(fig_info.fg_h);
end

function addpath_export_fig(extern_dir)
    % get export_fig in the path
    if exist('extern_dir', 'var') == 0
        extern_dir = 'C:\Users\Administrator\Documents\MATLAB\Rigor_untouched\extern_src';
    end
    addpath(fullfile(extern_dir, 'utils', 'export_fig'));
end


function compatibleStatus = isCompatible(solverName, printLevel, specificSolverVersion)
% determine the compatibility status of a solver based on the file compatMatrix.rst
%
% USAGE:
%    compatibleStatus = isCompatible(solverName, printLevel, specificSolverVersion)
%
% INPUT:
%    solverName:            Name of the solver
%    printLevel:            verbose level (default: 0)
%    specificSolverVersion: string with specific solver version (example: '12.7.1' or '6.5.1')
%
% OUTPUT:
%    compatibleStatus:      compatibility status
%
%                             * 0: not compatible with the COBRA Toolbox (tested)
%                             * 1: compatible with the COBRA Toolbox (tested)
%                             * 2: unverified compatibility with the COBRA Toolbox (not tested)
%
% .. Author: - Laurent Heirendt, Ronan Fleming
%

    global CBTDIR

    % define a default printLevel
    if nargin < 2
        printLevel = 1;
    end

    % determine specific version
    if nargin < 3
        specificSolverVersion = '';
    end

    % define the same interface for tomlab and quadMinos
    if strcmp(solverName, 'tomlab_snopt')
        solverName = 'tomlab_cplex';
    end

    if strcmp(solverName, 'quadMinos')
        solverName = 'dqqMinos';
    end

    if strcmp(solverName, 'lindo_old')
        solverName = 'lindo_legacy';
    end

    % default compatibility status (untested)
    compatibleStatus = 2;

    % check if the solver and the matlab version are compatible
    compatMatrixFile = [CBTDIR filesep 'docs' filesep 'source' filesep 'installation' filesep 'compatMatrix.rst'];

    % read in the file with the compatibility matrix
    persistent C;
    persistent compatMatrix;
    persistent testedOS;

    untestedFlag = false;
    if isempty(compatMatrix)
        C = {};
        compatMatrix = {};
        testedOS = {};
        fid = fopen(compatMatrixFile);
        lineCount = 0;
        while 1

            % save the previous line
            if lineCount > 0
                tline_prev = tline;
            end

            % read in a new line
            tline = fgetl(fid);

            if ~ischar(tline), break; end

            % skip a table line
            if ~isempty(strfind(tline, '+-------------------+')) || ~isempty(strfind(tline, '+====================+'))
                tline = '';
            end

            % if the line is not empty, read it in
            if length(tline) > 1
                if printLevel > 1
                    disp(tline);
                end

                % replace the markers
                tline = strrep(tline, '|x|', ':x:');
                tline = strrep(tline, '|white_check_mark|', ':white_check_mark:');
                tline = strrep(tline, '|warning|', ':warning:');

                if strcmp(tline(1), '|')
                    % split the line at the vertical bar
                    Cpart = strsplit(tline, '|');
                    Cpart = Cpart(2:end-1);

                    % convert incompatible flag
                    Cpart = strrep(Cpart, ':x:', '0');

                    % convert compatible flag
                    Cpart = strrep(Cpart, ':white_check_mark:', '1');

                    % convert untested flag
                    Cpart = strrep(Cpart, ':warning:', '2');

                    C{end+1} = strtrim(Cpart);
                else
                    if ~isempty(C)
                        compatMatrix{end+1} = C;
                        C = {};
                    end
                    if strcmp(tline(1:2), '~~')
                        testedOS{end+1} = strtrim(tline_prev);
                    end
                end
            end
            lineCount = lineCount + 1;
        end
        compatMatrix{end+1} = C;
    end
    % select the compatibility matrix based on the OS
    if isunix && ~ismac % linux
        tableNb = 1;
        % help system_dependent
        % system_dependent is an undocumented builtin function.
        resultVERS = system_dependent('getos');
        tmp = strsplit(testedOS{tableNb});
        if contains(lower(resultVERS), lower(tmp{2}))
            cMatrix = compatMatrix{tableNb};
        else
            untestedFlag = true;
            if printLevel > 0
                fprintf([' > isCompatible: The compatibility can only be verified on Linux ', tmp{2}, '.\n']);
            end
        end
    elseif ismac % macOS
        macpos = find(strncmp(testedOS,'macOS',5));
        macOSFound = false;
        [~, resultVERS] = unix('sw_vers');
        for tableNb = macpos %
            tmp = strsplit(testedOS{tableNb});
            if ~isempty(strfind(resultVERS, tmp{2}))
                cMatrix = compatMatrix{tableNb};
                macOSFound = true;
            end
        end
        if ~macOSFound
            untestedFlag = true;
            if printLevel > 0
                fprintf([' > isCompatible: The compatibility can only be verified on the following mac OS versions: ', strjoin(testedOS(macpos),', '), '.\n']);
            end
        end
    else % Windows
        resultVERS = system_dependent('getos');
        for tableNb = length(testedOS)-1:length(testedOS) % loop through the last 2 tables
            tmp = strsplit(testedOS{tableNb});
            if ~isempty(strfind(resultVERS, tmp{2}))
                cMatrix = compatMatrix{tableNb};
                break;
            else
                untestedFlag = true;
                if printLevel > 0 && tableNb == length(testedOS)
                    fprintf([' > isCompatible: The compatibility can only be verified on Windows 7 and Windows 10.\n']);
                end
            end
        end
    end

    if untestedFlag
        cMatrix = {};
    end

    % determine the version of MATLAB and the corresponding column
    versionMatlab = ['R' version('-release')];
    if ~isempty(cMatrix)
        compatMatlabVersions = cMatrix{1}(2:end);
        colIndexVersion = strmatch(versionMatlab, compatMatlabVersions);
    else
        colIndexVersion = [];
    end

    % any MATLAB version that is not explicitly supported yields a compatibility status of 2
    if isempty(colIndexVersion)
        compatibleStatus = 2;
        if printLevel > 0
            fprintf([' > isCompatible: The solver compatibility cannot be verified with MATLAB ', versionMatlab, '.\n']);
        end
    else
        % replace any underscores in the solvername
        solverNameAlias = strrep(upper(solverName), '_', '');

        % set the solver version to be checked
        if exist('specificSolverVersion', 'var') && ~isempty(specificSolverVersion)
            solverVersion = strrep(specificSolverVersion, '.', '');
        else
            solverVersion = getCobraSolverVersion(solverName, 0);
        end

        % check compatibility of solver
        for i = 1:length(cMatrix)
            % save the row of the compatibilitx matrix
            row = cMatrix{i};

            % determine the name of the solver
            solverNameRow = row{1};
            solverNameRow = upper(solverNameRow);
            solverNameRow = regexprep(solverNameRow, {'\ ', '\.'}, '');

            % find the correct row
            if strcmpi([solverNameAlias, solverVersion], solverNameRow)
                % retrieve the compatibility status from the table
                compatibilityBoolean = row{colIndexVersion + 1};

                % define output of solverVersion
                if ~isempty(solverVersion),
                    txtSolverVersion = [' (version ', solverVersion, ')'];
                else
                    txtSolverVersion = '';
                end

                % determine the compatibility status
                if strcmpi(compatibilityBoolean, '1')
                    compatibleStatus = 1;
                    if printLevel > 0
                        fprintf([' > isCompatible: ', lower(solverName), txtSolverVersion, ' is compatible and fully tested with MATLAB ', versionMatlab, ' on your type of operating system.\n']);
                    end
                elseif strcmpi(compatibilityBoolean, '0')
                    compatibleStatus = 0;
                    if printLevel > 0
                        fprintf([' > isCompatible: ', lower(solverName), txtSolverVersion, ' is NOT compatible with MATLAB ', versionMatlab, ' on your  type of operating system.\n']);
                    end
                else
                    compatibleStatus = 2;
                    if printLevel > 0
                        fprintf([' > isCompatible: The compatibility of ', upper(solverName), txtSolverVersion, ' is not fully tested and might not be compatible with MATLAB ', versionMatlab, ' on your  type of operating system.\n']);
                    end
                end
            end
        end
    end

    matver = split(version, '.');
    matver = str2double(strcat(char(matver(1)), '.', char(matver(2))));

    % special case: cplex_direct
    if strcmp(solverName, 'cplex_direct') && matver < 8.4
        compatibleStatus = 0;
        if printLevel > 0
            fprintf([' > ', 'cplex_direct is NOT compatible with MATLAB ', versionMatlab, ' on your  type of operating system. Try using the tomlab_cplex interface.\n']);
        end
    end
end


function [sens] = ft_appendsens(cfg, varargin)

% FT_APPENDSENS concatenates multiple sensor definitions that have been processed
% separately.
%
% Use as
%   combined = ft_appendsens(cfg, sens1, sens2, ...)
%
% A call to FT_APPENDSENS results in the label, pos and ori fields to be
% concatenated, and the tra matrix to be merged. Any duplicate electrodes
% will be removed. The labelold and chanposold fields are kept under the
% condition that they are identical across the inputs.
%
% See also FT_ELECTRODEPLACEMENT, FT_ELECTRODEREALIGN, FT_DATAYPE_SENS,
% FT_APPENDDATA, FT_APPENDTIMELOCK, FT_APPENDFREQ, FT_APPENDSOURCE

% Copyright (C) 2017-2018, Arjen Stolk
%
% 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$

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble loadvar    varargin
ft_preamble provenance varargin

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% check if the input data is valid for this function
% and ensure it is up to the latest standards
for i=1:length(varargin)
  assert(ft_datatype(varargin{i}, 'sens'), 'incorrect input, should be a grad/elec/opto structure');
  varargin{i} = ft_datatype_sens(varargin{i});
end

% do a basic check whether the senstype, units, and coordinate systems match
senstype = cell(1,length(varargin));
for i=1:length(varargin)
  senstype{i} = ft_senstype(varargin{i});
end
typematch = all(strcmp(senstype{1}, senstype));

unitmatch = 1;
if isfield(varargin{1}, 'unit')
  unit = cell(1,length(varargin));
  for i=1:length(varargin)
    unit{i} = varargin{i}.unit;
  end
  unitmatch = all(strcmp(unit{1}, unit));
end

coordsysmatch = 1;
if isfield(varargin{1}, 'coordsys')
  coordsys = cell(1,length(varargin));
  for i=1:length(varargin)
    coordsys{i} = varargin{i}.coordsys;
  end
  coordsysmatch = all(strcmp(coordsys{1}, coordsys));
end

if ~typematch || ~unitmatch || ~coordsysmatch
  ft_error('the senstype, units, or coordinate systems of the inputs do not match');
end

% keep these fields (when present) in the output
sens = keepfields(varargin{1}, {'type', 'unit', 'coordsys'});

% make inventory
haselecpos = 0;
hascoilpos = 0;
hascoilori = 0;
haschanori = 0;
hasoptopos = 0;
hastra     = 0;
haslabelold = 0;
haschanposold = 0;
for i=1:length(varargin)
  % the following fields should be present in any sens structure
  if isfield(varargin{i}, 'label')
    label{i} = varargin{i}.label(:); % ensure column orientation
  end
  if isfield(varargin{i}, 'chanpos')
    chanpos{i} = varargin{i}.chanpos;
  end

  % some the following fields are likely present in a sens structure
  if isfield(varargin{i}, 'elecpos') % EEG
    elecpos{i} = varargin{i}.elecpos;
    haselecpos = 1;
  end
  if isfield(varargin{i}, 'coilpos') % MEG
    coilpos{i} = varargin{i}.coilpos;
    hascoilpos = 1;
  end
  if isfield(varargin{i}, 'coilori') % MEG
    coilori{i} = varargin{i}.coilori;
    hascoilori = 1;
  end
  if isfield(varargin{i}, 'chanori') % MEG
    chanori{i} = varargin{i}.chanori;
    haschanori = 1;
  end
  if isfield(varargin{i}, 'optopos') % NIRS
    optopos{i} = varargin{i}.optopos;
    hasoptopos = 1;
  end
  if isfield(varargin{i}, 'tra') % tra
    tra{i} = varargin{i}.tra;
    hastra = 1;
  end

  % the following fields might be present in a sens structure
  if isfield(varargin{i}, 'labelold')
    labelold{i} = varargin{i}.labelold(:); % ensure column orientation
    haslabelold = 1;
  end
  if isfield(varargin{i}, 'chanposold')
    chanposold{i} = varargin{i}.chanposold;
    haschanposold = 1;
  end
end

% concatenate the main fields and remove duplicates
sens.label = cat(1,label{:});
[dum, labidx] = unique(sens.label, 'stable');
if ~isequal(numel(labidx), numel(sens.label))
  fprintf('removing duplicate labels\n')
  sens.label = sens.label(labidx);
end

sens.chanpos = cat(1,chanpos{:});
[dum, chanidx] = unique(sens.chanpos, 'rows', 'stable');
if ~isequal(numel(chanidx), size(sens.chanpos,1))
  fprintf('removing duplicate channels\n')
  sens.chanpos = sens.chanpos(chanidx,:);
  if ~isequal(labidx, chanidx) % check for matching order
    ft_error('inconsistent order or number of channel labels and positions')
  end
end
if ~isequal(numel(sens.label), size(sens.chanpos,1)) % check for matching number
  ft_error('inconsistent number of channel labels and positions')
end
if haschanori
  sens.chanori = cat(1,chanori{:});
  if ~isequal(numel(chanidx), size(sens.chanpos,1))
    sens.chanori = sens.chanori(chanidx,:); % chanori should match chanpos
  end
end

if hastra && ~any(cellfun(@isempty, tra))
  sens.tra = [];
  for t = 1:numel(tra)
    trarow = [1:size(tra{t},1)]+size(sens.tra,1);
    tracol = [1:size(tra{t},2)]+size(sens.tra,2);
    sens.tra(trarow, tracol) = tra{t};
  end
end

if haselecpos
  sens.elecpos = cat(1,elecpos{:});
  [dum, elecidx, elecidx2] = unique(sens.elecpos, 'rows', 'stable');
  if ~isequal(numel(elecidx), size(sens.elecpos,1))
    fprintf('removing duplicate electrodes\n')
    sens.elecpos = sens.elecpos(elecidx,:);
  end
  if isfield(sens, 'tra')
    % shape duplicates into a single column, if necessary
    for idx = 1:numel(elecidx)
      tmp(:, idx) = sum(sens.tra(chanidx, find(idx==elecidx2)),2); % find and take sum over duplicates
    end
    sens.tra = tmp;
    % check for expected size and non-empty rows
    if ~isequal(size(sens.tra,1), size(sens.chanpos,1)) || ~isequal(size(sens.tra,2), size(sens.elecpos,1)) ...
        || any(any(sens.tra,2)==0) % all channels need to be linked to their origins
      fprintf('removing inconsistent tra matrix\n')
      sens = rmfield(sens, 'tra');
    end
  end
end

if hasoptopos
  sens.optopos = cat(1,optopos{:});
  [dum, optoidx, optoidx2] = unique(sens.optopos, 'rows', 'stable');
  if ~isequal(numel(optoidx), size(sens.optopos,1))
    fprintf('removing duplicate optodes\n')
    sens.optopos = sens.optopos(optoidx,:);
  end
  if isfield(sens, 'tra')
    % shape duplicates into a single column, if necessary
    for idx = 1:numel(optoidx)
      tmp(:, idx) = sum(sens.tra(chanidx, find(idx==optoidx2)),2); % find and take sum over duplicates
    end
    sens.tra = tmp;
    % check for expected size and non-empty rows
    if ~isequal(size(sens.tra,1), size(sens.chanpos,1)) || ~isequal(size(sens.tra,2), size(sens.optopos,1)) ...
        || any(any(sens.tra,2)==0) % all channels need to be linked to their origins
      fprintf('removing inconsistent tra matrix\n')
      sens = rmfield(sens, 'tra');
    end
  end
end

if hascoilpos
  sens.coilpos = cat(1,coilpos{:});
  [dum, coilidx, coilidx2] = unique(sens.coilpos, 'rows', 'stable');
  if ~isequal(numel(coilidx), size(sens.coilpos,1))
    fprintf('removing duplicate coils\n')
    sens.coilpos = sens.coilpos(coilidx,:);
  end
  if isfield(sens, 'tra')
    % shape duplicates into a single column, if necessary
    for idx = 1:numel(coilidx)
      tmp(:, idx) = sum(sens.tra(chanidx, find(idx==coilidx2)),2); % find and take sum over duplicates
    end
    sens.tra = tmp;
    % check for expected size and non-empty rows
    if ~isequal(size(sens.tra,1), size(sens.chanpos,1)) || ~isequal(size(sens.tra,2), size(sens.coilpos,1)) ...
        || any(any(sens.tra,2)==0) % all channels need to be linked to their origins
      fprintf('removing inconsistent tra matrix\n')
      sens = rmfield(sens, 'tra');
    end
  end
end
if hascoilori
  sens.coilori = cat(1,coilori{:});
  if ~isequal(numel(coilidx), size(sens.coilori,1))
    sens.coilori = sens.coilori(coilidx,:); % coilori should match coilpos
  end
end

% keep the following fields only when identical across inputs
if haslabelold && all(isequal(labelold{1}, labelold{:})) % labeloldmatch
  sens.labelold = labelold{1};
end
if haschanposold && all(isequal(chanposold{1}, chanposold{:})) % chanposoldmatch
  sens.chanposold = chanposold{1};
end

% ensure up-to-date and consistent output sensor description
sens = ft_datatype_sens(sens);

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble previous varargin
ft_postamble provenance sens
ft_postamble history sens
ft_postamble savevar sens


classdef FemTestsSuite < handle

    methods

        function obj = FemTestsSuite()
            path = './tests/Source/FemTests/FemTests.m';
            suite = matlab.unittest.TestSuite.fromFile(path, 'Tag','FEM');
            results = suite.run;
            table(results)
        end

    end
end


function favar_excelrecord6fcn(identified, IRFperiods, favar, labels, favar_fevd_estimates, pref)

% create the cell that will be saved on excel
fevdcell={};

% build preliminary elements: space between the tables
horzspace=repmat({''},2,5*(identified+1));
vertspace=repmat({''},IRFperiods+3,1);

%subsample
informationvariablestrings=favar.informationvariablestrings(1,favar.plotX_index);

% loop over variables (vertical dimension)
for ii=1:favar.npltX
    tempcell={};
    % loop over shocks (horizontal dimension)
    for jj=1:identified+1
        % create cell of fevd record for variable ii in response to shock jj
        temp=['part of ' informationvariablestrings{1,ii} ' fluctuation due to ' labels{jj,1} ' shocks'];
        fevd_ij=[temp {''} {''} {''};{''} {''} {''} {''};{''} {'lw. bound'} {'median'} {'up. bound'};[num2cell((1:IRFperiods)') num2cell((favar_fevd_estimates{ii,jj})')]];
        tempcell=[tempcell fevd_ij vertspace];
    end
    fevdcell=[fevdcell;horzspace;tempcell];
end
% trim
fevdcell=fevdcell(3:end,1:end-1);
% write in excel
warning off MATLAB:xlswrite:AddSheet
xlswrite(fullfile(pref.results_path, [pref.results_sub '.xlsx']),fevdcell,'favar_FEVD','B2');
warning on MATLAB:xlswrite:AddSheet


classdef VehicleState < Simulink.IntEnumType
    % MATLAB enumeration class definition generated from template
    %   to track the active leaf state of FMS/FMS State Machine/Vehicle.

    enumeration
        None(0),
		Disarm(1),
		Standby(2),
		Offboard(3),
		Mission(4),
		InvalidAutoMode(5),
		Hold(6),
		Acro(7),
		Stabilize(8),
		Altitude(9),
		Position(10),
		InvalidAssistMode(11),
		Manual(12),
		InValidManualMode(13),
		InvalidArmMode(14),
		Land(15),
		Return(16),
		Takeoff(17)
    end

    methods (Static)

        function defaultValue = getDefaultValue()
            % GETDEFAULTVALUE  Returns the default enumerated value.
            %   If this method is not defined, the first enumeration is used.
            defaultValue = VehicleState.None;
        end

        function dScope = getDataScope()
            % GETDATASCOPE  Specifies whether the data type definition should be imported from,
            %               or exported to, a header file during code generation.
            dScope = 'Auto';
        end

        function desc = getDescription()
            % GETDESCRIPTION  Returns a description of the enumeration.
            desc = 'enumeration to track active leaf state of FMS/FMS State Machine/Vehicle';
        end

        function fileName = getHeaderFile()
            % GETHEADERFILE  Returns path to header file if non-empty.
            fileName = '';
        end

        function flag = addClassNameToEnumNames()
            % ADDCLASSNAMETOENUMNAMES  Indicate whether code generator applies the class name as a prefix
            %                          to the enumeration.
            flag = true;
        end

    end

end


% submitWeb Creates files from your code and output for web submission.
%
%   If the submit function does not work for you, use the web-submission mechanism.
%   Call this function to produce a file for the part you wish to submit. Then,
%   submit the file to the class servers using the "Web Submission" button on the
%   Programming Assignments page on the course website.
%
% Copyright (C) Daphne Koller, Stanford University, 2012

function submitWeb(partId)
  if ~exist('partId', 'var') || isempty(partId)
    partId = [];
  end

  submit(partId, 1);
end


% READEGILOCS - look up locations for EGI EEG dataset.
%
% Usage:
%   >> EEG = readegilocs(EEG);
%   >> EEG = readegilocs(EEG, fileloc);
%
% Inputs:
%   EEG        - EEGLAB data structure
%
% Optional input:
%   fileloc    - EGI channel location file
%
% Outputs:
%   EEG        - EEGLAB data structure with channel location structure
%
% Author: Arnaud Delorme, SCCN/UCSD
%
% See also: POP_READEGI, READEGI

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

function EEG = readegilocs(EEG, fileloc);

if nargin < 1
    help readegilocs;
    return;
end

% importing channel locations
% ---------------------------
found = 1;
if nargin < 2
    switch EEG.nbchan
        case { 32 33 }, fileloc = 'GSN-HydroCel-32.sfp';
        case { 64 65 }, fileloc = 'GSN65v2_0.sfp';
        case { 128 129 }, fileloc = 'GSN129.sfp';
        case { 256 257 }, fileloc = 'GSN-HydroCel-257.sfp';
        otherwise, found = 0;
    end
end
if found
    fprintf('EGI channel location automatically detected %s ********* WARNING please check that this the proper file\n', fileloc);
    if EEG.nbchan == 64 || EEG.nbchan == 65 || EEG.nbchan == 256 || EEG.nbchan == 257
        fprintf( [ 'Warning: this function assumes you have a 64-channel system Version 2\n' ...
                   '         if this is not the case, update the channel location with the proper file' ]);
    end
    % remove the last channel for 33 channels

    peeglab = fileparts(which('eeglab.m'));
    fileloc = fullfile(peeglab, 'sample_locs', fileloc);
    locs = readlocs(fileloc);
    locs(1).type = 'FID';
    locs(2).type = 'FID';
    locs(3).type = 'FID';
    locs(end).type = 'REF';
    if EEG.nbchan == 256 || EEG.nbchan == 257
        if EEG.nbchan == 256
            chaninfo.nodatchans = locs([end]);
            locs([end]) = [];
        end
    elseif mod(EEG.nbchan,2) == 0,
        chaninfo.nodatchans = locs([1 2 3 end]);
        locs([1 2 3 end]) = [];
    else
        chaninfo.nodatchans = locs([1 2 3]);
        locs([1 2 3]) = [];
    end; % remove reference
    chaninfo.filename = fileloc;
    EEG.chanlocs   = locs;
    EEG.urchanlocs = locs;
    EEG.chaninfo   = chaninfo;
end


function options = bonminset(varargin)
%BONMINSET  Create or alter the options for Optimization with BONMIN
%
% options = bonminset('param1',value1,'param2',value2,...) creates an IPOPT
% options structure with the parameters 'param' set to their corresponding
% values in 'value'. Parameters not specified will be set to the IPOPT
% default.
%
% options = bonminset(oldopts,'param1',value1,...) creates a copy of the old
% options 'oldopts' and then fills in (or writes over) the parameters
% specified by 'param' and 'value'.
%
% options = bonminset() creates an options structure with all fields set to
% bonminset defaults.
%
% bonminset() prints a list of all possible fields and their function.
%
% See supplied BONMIN and IPOPT Documentation for further details of these options.

%   Copyright (C) 2011 Jonathan Currie (IPL)

% Print out possible values of properties.
if((nargin == 0) && (nargout == 0))
    printfields();
    return
end

%Names and Defaults
Names = {'algorithm','var_lin','cons_lin','allowable_fraction_gap','allowable_gap','cutoff','cutoff_decr','enable_dynamic_nlp','iteration_limit',...
         'nlp_failure_behavior','node_comparison','num_cut_passes','num_cut_passes_at_root',...
         'number_before_trust','number_strong_branch','solution_limit','sos_constraints','tree_search_strategy',...
         'variable_selection','feasibility_pump_objective_norm','heuristic_RINS','heuristic_dive_MIP_fractional',...
         'heuristic_dive_MIP_vectorLength','heuristic_dive_fractional','heuristic_dive_vectorLength',...
         'heuristic_feasibility_pump','pump_for_minlp','candidate_sort_criterion','maxmin_crit_have_sol',...
         'maxmin_crit_no_sol','min_number_strong_branch','number_before_trust_list','number_look_ahead',...
         'number_strong_branch_root','setup_pseudo_frac','coeff_var_threshold','dynamic_def_cutoff_decr','first_perc_for_cutoff_decr',...
         'max_consecutive_infeasible','num_resolve_at_infeasibles',...
         'num_resolve_at_node','num_resolve_at_root','second_perc_for_cutoff_decr','milp_solver','milp_strategy','bb_log_interval',...
         'bb_log_level','lp_log_level','milp_log_level','nlp_log_level','nlp_log_at_root','oa_log_frequency','oa_log_level',...
         'max_consecutive_failures','max_random_point_radius','num_retry_unsolved_random_point','random_point_perturbation_interval',...
         'random_point_type','warm_start'}';
Defaults = {'B-BB',[],[],0,0,1e100,1e-5,'no',2^31-1,'stop','best-bound',1,20,8,20,2^31-1,'enable','probed-dive','osi-strong',1,'no',...
            'yes','no','no','no','no','no','best-ps-cost',0.1,0.7,0,0,0,2^31-1,0.5,0.1,'no',-0.02,0,0,0,0,-0.05,'Cbc_D','find_good_sol',...
            100,1,0,0,0,0,100,1,10,100000,0,1,'Jon','none'}';
%Get IPOPT Defaults if required
if(nargin == 2 && strcmpi(varargin{2},'noipopt'))
    varargin = varargin(1);
else
    iset = ipoptset('bonmin');
    Names = [Names;fieldnames(iset)];
    Defaults = [Defaults;struct2cell(iset)];
end

%Enter and check user args
try
    options = opticheckset(Names,Defaults,@checkfield,varargin{:});
catch ME
    throw(ME);
end

function checkfield(field,value)
%Check a field contains correct data type
switch lower(field)
    %Scalar double
    case {'first_perc_for_cutoff_decr','second_perc_for_cutoff_decr'}
        err = opticheckval.checkScalarDbl(value,field);
    %Scalar non negative double
    case {'min_number_strong_branch','number_look_ahead','number_strong_branch_root','coeff_var_threshold'}
        err = opticheckval.checkScalarNonNeg(value,field);
    %Scalar non zero double
    case {'oa_log_frequency','max_random_point_radius','random_point_perturbation_interval'}
        err = opticheckval.checkScalarGrtZ(value,field);
    %Scalar non negative integer
    case {'iteration_limit','num_cut_passes','num_cut_passes_at_root','number_before_trust','number_strong_branch',...
          'solution_limit','max_consecutive_infeasible','num_resolve_at_infeasibles','num_resolve_at_node',...
          'num_resolve_at_root','bb_log_interval','max_consecutive_failures','num_retry_unsolved_random_point'}
        err = opticheckval.checkScalarIntNonNeg(value,field);
    %Scalar double with bounds
    case 'cutoff_decr'
        err = opticheckval.checkScalarBoundLELE(value,field,-1e10,1e10);
    case {'allowable_fraction_gap','allowable_gap'}
        err = opticheckval.checkScalarBoundLELE(value,field,-1e20,1e20);
    case 'cutoff'
        err = opticheckval.checkScalarBoundLELE(value,field,-1e100,1e100);
    case {'maxmin_crit_have_sol','maxmin_crit_no_sol','setup_pseudo_frac'}
        err = opticheckval.checkScalarBoundLELE(value,field,0,1);
    case 'number_before_trust_list'
        err = opticheckval.checkScalarBoundLEL(value,field,-1,inf);
    %Scalar integer with bounds
    case 'feasibility_pump_objective_norm'
        err = opticheckval.checkScalarIntBoundLELE(value,field,1,2);
    case 'bb_log_level'
        err = opticheckval.checkScalarIntBoundLELE(value,field,0,5);
    case {'lp_log_level','milp_log_level'}
        err = opticheckval.checkScalarIntBoundLELE(value,field,0,4);
    case {'nlp_log_level','oa_log_level'}
        err = opticheckval.checkScalarIntBoundLELE(value,field,0,2);
    case 'nlp_log_at_root'
        err = opticheckval.checkScalarIntBoundLELE(value,field,0,12);
    %Vector integer 0/1
    case {'var_lin','cons_lin'}
        err = opticheckval.checkVector01(value,field);
    %Yes / No
    case {'heuristic_rins','heuristic_dive_mip_fractional','heuristic_dive_mip_vectorlength','heuristic_dive_fractional',...
          'heuristic_dive_vectorlength','heuristic_feasibility_pump','pump_for_minlp','dynamic_def_cutoff_decr'}
        err = opticheckval.checkYesNo(value,field);
    %Yes / No with Yes Crash
    case 'enable_dynamic_nlp'
        err = opticheckval.checkYesCrashNo(value,field);
    %Enable / Disable
    case 'sos_constraints'
        err = opticheckval.checkEnDis(value,field);
    %Misc String methods
    case 'algorithm'
        err = opticheckval.checkValidString(value,field,{'B-BB','B-OA','B-QG','B-Hyb','B-Ecp','B-iFP'});
    case 'nlp_failure_behavior'
        err = opticheckval.checkValidString(value,field,{'stop','fathom'});
    case 'node_comparison'
        err = opticheckval.checkValidString(value,field,{'best-bound','depth-first','breadth-first','dynamic','best-guess'});
    case 'tree_search_strategy'
        err = opticheckval.checkValidString(value,field,{'top-node','dive','probed-dive','dfs-dive','dfs-dive-dynamic'});
    case 'variable_selection'
        err = opticheckval.checkValidString(value,field,{'most-fractional','strong-branching','reliability-branching','qp-strong-branching',...
                                                         'lp-strong-branching','nlp-strong-branching','osi-simple','osi-strong','random'});
    case 'candidate_sort_criterion'
        err = opticheckval.checkValidString(value,field,{'best-ps-cost','worst-ps-cost','most-fractional','least-fractional'});
    case 'milp_solver'
        err = opticheckval.checkValidString(value,field,{'cbc_d','cplex'});
    case 'milp_strategy'
        err = opticheckval.checkValidString(value,field,{'find_good_sol','solve_to_optimality'});
    case 'random_point_type'
        err = opticheckval.checkValidString(value,field,{'jon','andreas','claudia'});
    case 'warm_start'
        err = opticheckval.checkValidString(value,field,{'none','fake_basis','optimum','interior_point'});

    %IPOPT or Unknown Parameter
    otherwise
        err = [];
        try
            %try for ipoptset arg
            iset = ipoptset(field,value);
        catch ME
            throw(ME);
        end
        if(isempty(iset))
            err = MException('OPTI:SetFieldError','Unrecognized parameter name ''%s''.', field);
        end
end
if(~isempty(err)), throw(err); end

function printfields()
%Print out fields with defaults
fprintf(' ----- BONMIN (MIP SOLVER) SETTINGS ----- \n');
fprintf('  BONMIN GENERAL SETTINGS:\n');
fprintf('                          algorithm: [ MIP Algorithm {''B-BB''}, ''B-OA'', ''B-QG'', ''B-Hyb'', ''B-Ecp'', ''B-iFP'' ] \n');
fprintf('                            var_lin: [ Decision Variable Linearity (0 - Nonlinear, 1 - Linear) {zeros(n,1)} ] \n');
fprintf('                           cons_lin: [ Constraint Linearity (0 - Nonlinear, 1 - Linear) {zeros(m,1)} ] \n');

fprintf('\n  BONMIN BRANCH & BOUND SETTINGS:\n');
fprintf('             allowable_fraction_gap: [ Value of Relative Gap when algorithm stops {0} ] \n');
fprintf('                      allowable_gap: [ Value of Absolute Gap when algorithm stops {0} ] \n');
fprintf('                             cutoff: [ The algorithm will only look for values better than cutoff {1e100} ] \n');
fprintf('                        cutoff_decr: [ Amount by which cutoff is decremented below a new best upper bound {1e-5} ] \n');
fprintf('                 enable_dynamic_nlp: [ Enable dynamic linear and quadratic rows addition in NLP ''yes'', {''no''} ] \n');
fprintf('                    iteration_limit: [ Cumulated maximum number of iterations in the algorithm to process continuous relaxations {2^31-1} ] \n');
fprintf('               nlp_failure_behavior: [ Action to take when an NLP is unsolved by IPOPT {''stop''}, ''fathom'' ] \n');
fprintf('                    node_comparison: [ Node selection strategy {''best-bound''}, ''depth-first'', ''breadth-first'', ''dynamic'', ''best-guess'' ] \n');
fprintf('                     num_cut_passes: [ Maximum number of cut passes at regular nodes {1} ] \n');
fprintf('             num_cut_passes_at_root: [ Maximum number of cut passes at root node {20} ] \n');
fprintf('                number_before_trust: [ Number of branches on a variable before its pseudo costs are to be believed in dynamic strong branching {8} ] \n');
fprintf('               number_strong_branch: [ Maximum number of variables considered for strong branching {20} ] \n');
fprintf('                     solution_limit: [ Abort after this many integer feasible solutions have been found (or 0 to deactivate) {2^31-1} ] \n');
fprintf('                    sos_constraints: [ Activate SOS Type 1 constraints {''enable''}, ''disable'' ] \n');
fprintf('               tree_search_strategy: [ Tree traversing strategy {''probed-dive''}, ''top-node'', ''dive'', ''dfs-dive'', ''dfs-dive-dynamic'' ] \n');
fprintf('                 variable_selection: [ Variable selection strategy {''osi-strong''}, ''most-fractional'', ''reliability-branching'', ''qp-strong-branching'', ''lp-strong-branching'', ''nlp-strong-branching'', ''osi-simple'', ''strong-branching'', ''random'' ] \n');

fprintf('\n  BONMIN MINLP HEURISTIC SETTINGS:\n');
fprintf('    feasibility_pump_objective_norm: [ Norm of feasibility pump objective norm {1}, 2 ] \n');
fprintf('                     heuristic_RINS: [ Use RINS heuristic {''no''}, ''yes'' ] \n');
fprintf('      heuristic_dive_MIP_fractional: [ Use Dive MIP fractional heuristic {''no''}, ''yes'' ] \n');
fprintf('    heuristic_dive_MIP_vectorLength: [ Use Dive MIP vectorLength heuristic {''no''}, ''yes'' ] \n');
fprintf('          heuristic_dive_fractional: [ Use Dive fractional heuristic ''no'', {''yes''} ] \n');
fprintf('        heuristic_dive_vectorLength: [ Use Dive vectorLength heuristic ''no'', {''yes''} ] \n');
fprintf('         heuristic_feasibility_pump: [ Use feasibility pump heuristic {''no''}, ''yes'' ] \n');
fprintf('                     pump_for_minlp: [ Use FP for MINLP {''no''}, ''yes'' ] \n');

fprintf('\n  BONMIN NON-CONVEX PROBLEM SETTINGS:\n');
fprintf('                coeff_var_threshold: [ Coefficient of variation threshold (for dynamic definition of cutoff_decr) {0.1} ] \n');
fprintf('            dynamic_def_cutoff_decr: [ Define cutoff_decr dynamically? {''no''}, ''yes'' ] \n');
fprintf('         first_perc_for_cutoff_decr: [ Percentage used when the coeff of variance is smaller than the threshold, to compute cutoff_decr dynamically {-0.02} ] \n');
fprintf('         max_consecutive_infeasible: [ Maximum number of consecutive infeasible subproblems before aborting a branch {0} ] \n');
fprintf('         num_resolve_at_infeasibles: [ Number of tries to resolve an infeasible node (other than the root) of the tree with different starting points {0} ] \n');
fprintf('                num_resolve_at_node: [ Number of tries to resolve a node (other than the root) of the tree with different starting points (like multi-start) {0} ] \n');
fprintf('                num_resolve_at_root: [ Number of tries to resolve the root node with different starting points {0} ] \n');
fprintf('        second_perc_for_cutoff_decr: [ Percentage used when the coeff of variance is greater than the threshold, to compute cutoff_decr dynamically {-0.05} ] \n');

fprintf('\n  BONMIN NLP SOLUTION ROBUSTNESS SETTINGS:\n');
fprintf('           max_consecutive_failures: [ Number of consecutive unsolved problems before aborting a branch of the tree {10} ] \n');
fprintf('            max_random_point_radius: [ Max value for coordinate of a random point {100000} ] \n');
fprintf('    num_retry_unsolved_random_point: [ Number of times that the algorithm will try to resolve an unsolved NLP with a random starting point (with new point) {0} ] \n');
fprintf(' random_point_perturbation_interval: [ Amount by which starting point is perturbed when choosing a random point {1} ] \n');
fprintf('                  random_point_type: [ Random starting point method {''Jon''}, ''Andreas'', ''Claudia'' ] \n');
fprintf('                         warm_start: [ Warm start method {''none''}, ''fake_basis'', ''optimum'', ''interior'' ] \n');

fprintf('\n  BONMIN STRONG BRANCHING SETTINGS:\n');
fprintf('           candidate_sort_criterion: [ Criterion used to choose candidates in strong-branching {''best-ps-cost''}, ''worst-ps-cost'', ''most-fractional'', ''least-fractional'' ] \n')
fprintf('               maxmin_crit_have_sol: [ Weight towards minimum of lower and upper branching estimates when a solution has been found {0.1} ] \n')
fprintf('                 maxmin_crit_no_sol: [ Weight towards minimum of lower and upper branching estimates when no solution has been found {0.7} ] \n')
fprintf('           min_number_strong_branch: [ Minimum number of variables for strong branching (overriding trust) {0} ] \n')
fprintf('           number_before_trust_list: [ Number of branches on a variable vbefore its pseudo costs are to be believed during setup of strong branching list {0} ] \n')
fprintf('                  number_look_ahead: [ Limit of look-ahead strong-branching trials {0} ] \n')
fprintf('          number_strong_branch_root: [ Maximum number of variables considered for strong branching at root node {2^31-1} ] \n')
fprintf('                  setup_pseudo_frac: [ Proportion of strong branching list that has to be taken from most integer infeasible list {0.5} ] \n')

fprintf('\n  BONMIN MILP SOLVER SETTINGS:\n');
fprintf('                        milp_solver: [ Subsolver to solve MILP problems in OA decompositions {''Cbc_D''}, ''Cplex'' (must be installed on your PC) ] \n');
fprintf('                      milp_strategy: [ MILP solving strategy {''find_good_sol''}, ''solve_to_optimality'' ] \n');

fprintf('\n  BONMIN OUPUT AND LOG LEVEL SETTINGS:\n');
fprintf('                    bb_log_interval: [ Interval at which node level output is printed (number of nodes) {100} ] \n');
fprintf('                       bb_log_level: [ Level of branch and bound log detail (0-5) {1} ] \n');
fprintf('                       lp_log_level: [ Level of LP solver log detail (0-4) {0} ] \n');
fprintf('                     milp_log_level: [ Level of MILP solver log detail (0-4) {0} ] \n');
fprintf('                      nlp_log_level: [ Level of NLP solver log detail (0-2) {0} ] \n');
fprintf('                    nlp_log_at_root: [ Level of NLP solver log detail at root node (0-12) {0} ] \n');
fprintf('                   oa_log_frequency: [ Frequency (in seconds) of OA log messages  {100} ] \n');
fprintf('                       oa_log_level: [ Level of OA decomposition log detail (0-2) {1} ] \n');

fprintf('\n ----- IPOPT (RELAXED SOLVER) SETTINGS ----- \n');
ipoptset('bonmin');


function t = Xaxis_string(Xt,bnames,R,fs);

ax = axis;
set(gca,'XLimMode','manual')
Yl = ax(3:4);
t = text(Xt,Yl(1)*ones(1,length(Xt)),bnames);
if R == 0
  set(t,'HorizontalAlignment','center','VerticalAlignment','top', 'Rotation',R,'fontsize',fs);
elseif R == 90
  set(t,'HorizontalAlignment','right','VerticalAlignment','middle', 'Rotation',R,'fontsize',fs);
else
  set(t,'HorizontalAlignment','right','VerticalAlignment','top', 'Rotation',R,'fontsize',fs);
end
set(gca,'XTickLabel','')


%% PTspec2DUIcontrol - ui controls for spectral analyses plots

% ----------------------------------------------------------------------------------
% "THE BEER-WARE LICENSE" (Revision 42):
% <brian.white@queensu.ca> wrote this file. As long as you retain this notice you
% can do whatever you want with this stuff. If we meet some day, and you think
% this stuff is worth it, you can buy me a beer in return. -Brian White
% ----------------------------------------------------------------------------------

if ~isempty(fnameMaster)

%%% tooltips
TooltipString_specRun=['Run current spectral configuration'];
TooltipString_cmap=['Choose from a selection of colormaps'];
TooltipString_smooth=['Choose amount of smoothing'];
TooltipString_user=['Choose the variable you wish to plot'];
TooltipString_sub100=['Zoom data to show sub 100Hz details',...
    newline, 'Typically used to see propwash or mid-throttle vibration in e.g. Gyro/Pterm/PIDerror'];

%%%
PTcolormap;
% define
smat=[];%string
ampmat=[];%spec matrix
amp2d2=[];%spec 2d
freq2d2=[];% freq

clear posInfo.Spec2Pos
cols=[0.05 0.48];
rows=[0.69 0.395 0.1];
k=0;
for c=1 : size(cols,2)
    for r=1 : size(rows,2)
        k=k+1;
        if c == 1
            posInfo.Spec2Pos(k,:)=[cols(c) rows(r) 0.38 0.25];
        else
            posInfo.Spec2Pos(k,:)=[cols(c) rows(r) 0.38 0.25];
        end
    end
end

vPosSpec2d = .037;

posInfo.fileListWindowSpec=[.898 .7+vPosSpec2d .088 .20];
posInfo.TermListWindowSpec=[.898 .55+vPosSpec2d .088 .14];

posInfo.computeSpec=            [.896 .52+vPosSpec2d .0455 .026];
posInfo.resetSpec=              [.942 .52+vPosSpec2d .0455 .026];
posInfo.spectrogramButton2=     [.896 .495+vPosSpec2d .0915 .026];
posInfo.spectrogramButton3=    [.896 .47+vPosSpec2d .0915 .026];
posInfo.saveFig2=               [.896 .445+vPosSpec2d .0455 .026]; % .896 .495 .092 .026
posInfo.saveSettings2=          [.942 .445+vPosSpec2d .0455 .026];

posInfo.smooth_select =         [.895 .405+vPosSpec2d .0955 .04];
posInfo.Delay =                 [.895 .379+vPosSpec2d .0955 .04];

posInfo.plotRspec =                 [.90 .37+vPosSpec2d .03 .025];
posInfo.plotPspec =                 [.925 .37+vPosSpec2d .03 .025];
posInfo.plotYspec =                 [.95 .37+vPosSpec2d .03 .025];

posInfo.checkboxPSD =            [.90 .35+vPosSpec2d .03 .02];
posInfo.RPYcomboSpec =           [.932 .35+vPosSpec2d .055 .02];

posInfo.climMax1_text = [.894 .322+vPosSpec2d .026 .022];
posInfo.climMax1_input = [.918 .322+vPosSpec2d .022 .022];
posInfo.climMax2_text = [.943 .322+vPosSpec2d .026 .022];
posInfo.climMax2_input = [.968 .322+vPosSpec2d .022 .022];

climScale1=[0 ; -50 ];
climScale2=[0.5 ; 20];

PTspecfig2=figure(3);
set(PTspecfig2, 'units','normalized','outerposition',[.1 .1 .75 .8])
PTspecfig2.NumberTitle='off';
PTspecfig2.Name= ['PIDtoolbox (' PtbVersion ') - Spectral Analyzer'];
PTspecfig2.InvertHardcopy='off';
set(PTspecfig2,'color',bgcolor);

dcm_obj2 = datacursormode(PTspecfig2);
set(dcm_obj2,'UpdateFcn',@PTdatatip);

specCrtlpanel = uipanel('Title','select files (max 10)','FontSize',fontsz,...
              'BackgroundColor',[.95 .95 .95],...
              'Position',[.89 .31+vPosSpec2d .105 .61]);

guiHandlesSpec2.computeSpec = uicontrol(PTspecfig2,'string','Run','fontsize',fontsz,'TooltipString', [TooltipString_specRun],'units','normalized','outerposition',[posInfo.computeSpec],...
    'callback','PTplotSpec2D;');
guiHandlesSpec2.computeSpec.ForegroundColor=[colRun];

guiHandlesSpec2.resetSpec = uicontrol(PTspecfig2,'string','Reset','fontsize',fontsz,'TooltipString', ['Reset Spectral Tool'],'units','normalized','outerposition',[posInfo.resetSpec],...
    'callback',' for k = 1 : 6, delete(subplot(''position'',posInfo.Spec2Pos(k,:))), end; set(PTspecfig2, ''pointer'', ''arrow'');');
guiHandlesSpec2.resetSpec.ForegroundColor=[cautionCol];

guiHandlesSpec2.saveFig2 = uicontrol(PTspecfig2,'string','Save Fig','fontsize',fontsz,'TooltipString',[TooltipString_saveFig],'units','normalized','ForegroundColor',[saveCol],'outerposition',[posInfo.saveFig2],...
    'callback','guiHandlesSpec2.saveFig2.FontWeight=''bold'';PTsaveFig;guiHandlesSpec2.saveFig2.FontWeight=''normal'';');

guiHandlesSpec2.saveSettings2 = uicontrol(PTspecfig2,'string','Save Settings','fontsize',fontsz, 'TooltipString',['Save current settings to PTB defaults' ], 'units','normalized','outerposition',[posInfo.saveSettings2],...
    'callback','guiHandlesSpec2.saveSettings2.FontWeight=''bold'';PTsaveSettings; guiHandlesSpec2.saveSettings2.FontWeight=''normal'';');
guiHandlesSpec2.saveSettings2.ForegroundColor=[saveCol];

% create string list for SpecSelect
sA={'Gyro','Gyro prefilt','Dterm','Dterm prefilt','Pterm','PID error','Set point','PIDsum'};

guiHandlesSpec2.SpecList = uicontrol(PTspecfig2,'Style','listbox','string',[sA],'max',3,'min',1, 'fontsize',fontsz, 'TooltipString',[TooltipString_user],'units','normalized','outerposition', [posInfo.TermListWindowSpec], 'callback', 'if length(guiHandlesSpec2.SpecList.Value) > 2, guiHandlesSpec2.SpecList.Value=1; end;');
guiHandlesSpec2.SpecList.Value =[1 2];

guiHandlesSpec2.FileSelect = uicontrol(PTspecfig2,'Style','listbox','string',[fnameMaster],'max', 10, 'min', 1, 'fontsize',fontsz,'TooltipString',[TooltipString_user],'units','normalized','outerposition', [posInfo.fileListWindowSpec], 'callback', 'if length(guiHandlesSpec2.FileSelect.Value) > 10, guiHandlesSpec2.FileSelect.Value=1; end;');

guiHandlesSpec2.smoothFactor_select = uicontrol(PTspecfig2,'style','popupmenu','string',{'smoothing low' 'smoothing low-med' 'smoothing medium' 'smoothing med-high' 'smoothing high'},'fontsize',fontsz,'TooltipString', [TooltipString_smooth], 'units','normalized','outerposition',[posInfo.smooth_select],...
     'callback','@selection2;PTplotSpec2D;');

guiHandlesSpec2.spectrogramButton2 = uicontrol(PTspecfig2,'string','Freq x Throttle','fontsize',fontsz,'TooltipString', ['Opens Freq x Throttle Spectrogram in New Window'], 'units','normalized','outerposition',[posInfo.spectrogramButton2],...
    'callback','PTspecUIcontrol;');
guiHandlesSpec2.spectrogramButton2.ForegroundColor=[colorA];

 guiHandlesSpec2.spectrogramButton3 = uicontrol(PTspecfig2,'string','Freq x Time','fontsize',fontsz,'TooltipString', ['Opens Freq x Time Spectrogram in New Window'], 'units','normalized','outerposition',[posInfo.spectrogramButton3],...
     'callback','PTfreqTimeUIcontrol;');
 guiHandlesSpec2.spectrogramButton3.ForegroundColor=[colorB];

 guiHandlesSpec2.Delay = uicontrol(PTspecfig2,'style','popupmenu','string',{'filter delay', 'SP-gyro delay', 'SP smoothing delay', 'phase shift'},'fontsize',fontsz,'TooltipString', ['Select which Delay Display'], 'units','normalized','outerposition',[posInfo.Delay],...
     'callback','PTplotSpec2D;');

guiHandlesSpec2.plotR =uicontrol(PTspecfig2,'Style','checkbox','String','R','fontsize',fontsz,'TooltipString', ['Plot Roll '],...
    'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.plotRspec], 'callback', 'for k = 1 : 6, delete(subplot(''position'',posInfo.Spec2Pos(k,:))), end; set(PTspecfig2, ''pointer'', ''arrow'');');

guiHandlesSpec2.plotP =uicontrol(PTspecfig2,'Style','checkbox','String','P','fontsize',fontsz,'TooltipString', ['Plot Pitch '],...
    'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.plotPspec], 'callback', 'for k = 1 : 6, delete(subplot(''position'',posInfo.Spec2Pos(k,:))), end; set(PTspecfig2, ''pointer'', ''arrow'');');

guiHandlesSpec2.plotY =uicontrol(PTspecfig2,'Style','checkbox','String','Y','fontsize',fontsz,'TooltipString', ['Plot Yaw '],...
    'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.plotYspec], 'callback', 'for k = 1 : 6, delete(subplot(''position'',posInfo.Spec2Pos(k,:))), end; set(PTspecfig2, ''pointer'', ''arrow'');');

guiHandlesSpec2.checkboxPSD =uicontrol(PTspecfig2,'Style','checkbox','String','PSD','fontsize',fontsz,'TooltipString', ['Power Spectral Density'],...
    'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.checkboxPSD],'callback', 'PTplotSpec2D;');
guiHandlesSpec2.checkboxPSD.Value = 1;

guiHandlesSpec2.RPYcomboSpec =uicontrol(PTspecfig2,'Style','checkbox','String','Single Panel','fontsize',fontsz,'TooltipString', ['Plot RPY in same panel '],...
    'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.RPYcomboSpec],'callback', 'PTplotSpec2D;');

guiHandlesSpec2.climMax1_text = uicontrol(PTspecfig2,'style','text','string','Y min','fontsize',fontsz,'TooltipString',['Y min'],'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.climMax1_text]);
guiHandlesSpec2.climMax1_input = uicontrol(PTspecfig2,'style','edit','string',[num2str(climScale1(guiHandlesSpec2.checkboxPSD.Value+1, 1))],'fontsize',fontsz,'TooltipString',['Y min'],'units','normalized','outerposition',[posInfo.climMax1_input],...
     'callback','@textinput_call2; climScale1(guiHandlesSpec2.checkboxPSD.Value+1, 1)=str2num(guiHandlesSpec2.climMax1_input.String);PTplotSpec2D;');

 guiHandlesSpec2.climMax2_text = uicontrol(PTspecfig2,'style','text','string','Y max','fontsize',fontsz,'TooltipString',['Y max'],'units','normalized','BackgroundColor',bgcolor,'outerposition',[posInfo.climMax2_text]);
guiHandlesSpec2.climMax2_input = uicontrol(PTspecfig2,'style','edit','string',[num2str(climScale2(guiHandlesSpec2.checkboxPSD.Value+1, 1))],'fontsize',fontsz,'TooltipString',['Y max'],'units','normalized','outerposition',[posInfo.climMax2_input],...
     'callback','@textinput_call2; climScale2(guiHandlesSpec2.checkboxPSD.Value+1, 1)=str2num(guiHandlesSpec2.climMax2_input.String);PTplotSpec2D;');

try guiHandlesSpec2.SpecList.Value = [defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-term1'))) defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-term2')))]; catch, guiHandlesSpec2.SpecList.Value = [1 2], end
try guiHandlesSpec2.smoothFactor_select.Value = defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-smoothing'))), catch, guiHandlesSpec2.smoothFactor_select.Value = 3, end
try guiHandlesSpec2.Delay.Value = defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-delay'))), catch, guiHandlesSpec2.Delay.Value = 1, end
try guiHandlesSpec2.plotR.Value = defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-plotR'))), catch, guiHandlesSpec2.plotR.Value = 1, end
try guiHandlesSpec2.plotP.Value = defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-plotP'))), catch, guiHandlesSpec2.plotP.Value = 1, end
try guiHandlesSpec2.plotY.Value = defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-plotY'))), catch, guiHandlesSpec2.plotY.Value = 1, end
try guiHandlesSpec2.RPYcomboSpec.Value = defaults.Values(find(strcmp(defaults.Parameters, 'spec2D-SinglePanel'))), catch, guiHandlesSpec2.RPYcomboSpec.Value = 0, end

FilterDelayDterm={};
SPGyroDelay=[];
Debug01={};
Debug02={};
gyro_phase_shift_deg=[];
dterm_phase_shift_deg=[];
for k = 1 : Nfiles
    Fs=1000/A_lograte(k);% yields more consistent results (mode(diff(tta)));
    maxlag=int8(round(30000/Fs)); %~30ms delay

    clear d pg g1 g1 s1 g2 s2  g3 s3
    try
        pg = smooth(T{k}.debug_0_(tIND{k}),50);
    catch
        pg = 0;
    end
    g1 = smooth(T{k}.gyroADC_0_(tIND{k}),50);
    s1 = smooth(T{k}.setpoint_0_(tIND{k}),50);

    g2 = smooth(T{k}.gyroADC_1_(tIND{k}),50);
    s2 = smooth(T{k}.setpoint_1_(tIND{k}),50);

    g3 = smooth(T{k}.gyroADC_2_(tIND{k}),50);
    s3 = smooth(T{k}.setpoint_2_(tIND{k}),50);

    [c,lags] = xcorr(g1,pg,maxlag);
    d = lags(find(c==max(c),1));
    d = d * (Fs / 1000);
    if d<.1,  Debug01{k} = ' '; else Debug01{k} = num2str(d);end

    [c,lags] = xcorr(s1,pg,maxlag);
    d = lags(find(c==max(c),1));
    d = d * (Fs / 1000);
    if d<.1,  Debug02{k} = ' '; else Debug02{k} = num2str(d);end

    [c,lags] = xcorr(g1,s1,maxlag);
    d = lags(find(c==max(c),1));
    d = d * (Fs / 1000);
    if d<.1, SPGyroDelay(k,1) = 0, else, SPGyroDelay(k,1) = d; end

    [c,lags] = xcorr(g2,s2,maxlag);
    d = lags(find(c==max(c),1));
    d = d * (Fs / 1000);
    if d<.1, SPGyroDelay(k,2) = 0, else, SPGyroDelay(k,2) = d; end

    [c,lags] = xcorr(g3,s3,maxlag);
    d = lags(find(c==max(c),1));
    d = d * (Fs / 1000);
    if d<.1, SPGyroDelay(k,3) = 0, else, SPGyroDelay(k,3) = d; end

    clear d d1 d2
    d1 = smooth(T{k}.axisDpf_0_(tIND{k}),50);
    d2 = smooth(T{k}.axisD_0_(tIND{k}),50);
    [c,lags] = xcorr(d2,d1,maxlag);
    d = lags(find(c==max(c)));
    d=d * (Fs / 1000);
    if d<.1, FilterDelayDterm{k} = ' '; else FilterDelayDterm{k} = num2str(d); end

    if ~isempty(str2num(Debug01{k})) && ~isempty(SPGyroDelay(k,1))
        [gyro_phase_shift_deg(k,1)] = round(PTphaseShiftDeg(str2num(Debug01{k}), 1000/(SPGyroDelay(k,1)) ));
    end
    if ~isempty(str2num(FilterDelayDterm{k})) && ~isempty(SPGyroDelay(k,1))
        [dterm_phase_shift_deg(k,1)] = round(PTphaseShiftDeg(str2num(FilterDelayDterm{k}), 1000/(SPGyroDelay(k,1)) ));
    end
end

else
     warndlg('Please select file(s)');
end

% functions
function selection2(src,event)
    val = c.Value;
    str = c.String;
    str{val};
end

function getList2(hObj,event)
v=get(hObj,'value')
end

function textinput_call2(src,eventdata)
str=get(src,'String');
    if isempty(str2num(str))
        set(src,'string','0');
        warndlg('Input must be numerical');
    end
end