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

% Last Modified by GUIDE v2.5 17-Apr-2014 16:37:36

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @GradDesignPanel_OpeningFcn, ...
    'gui_OutputFcn',  @GradDesignPanel_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 GradDesignPanel is made visible.
function GradDesignPanel_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 GradDesignPanel (see VARARGIN)
global VCtl;
global VObj;
global VMgd;

handles.Simuh=varargin{1};
% Load Gradient element list
try
    handles.GradElemListStruct=DoParseXML([handles.Simuh.MRiLabPath filesep 'Macro' filesep 'GradElem' filesep 'GradElem.xml']);
    guidata(hObject,handles);
    Root=DoConvStruct2Tree(handles.GradElemListStruct);
    handles.GradElemListTree=uitree('v0', 'Root',Root,'SelectionChangeFcn', {@ChkGradElemListTreeNode,handles});
    set(handles.GradElemListTree.getUIContainer,'Units','normalized');
    set(handles.GradElemListTree.getUIContainer,'Position',[0.0,0.4,0.2,0.58]);
    handles.Attrh1=[];
catch ME
    errordlg('Grad element list can not be loaded!');
    close(hObject);
    return;
end

%Load tabs for Grad Simulation
try
    handles.GradSimuAttrStruct=DoParseXML([handles.Simuh.MRiLabPath filesep 'Macro' filesep 'GradElem' filesep 'GradSimuAttr.xml']);
catch ME
    errordlg('GradSimuAttr.xml file is missing or can not be loaded!');
    close(hObject);
    return;
end

handles.Setting_tabgroup=uitabgroup(handles.Setting_uipanel);
guidata(handles.GradDesignPanel_figure,handles);
for i=1:length(handles.GradSimuAttrStruct.Children)
    eval(['handles.' handles.GradSimuAttrStruct.Children(i).Name '_tab=uitab( handles.Setting_tabgroup,' '''title'',' '''' handles.GradSimuAttrStruct.Children(i).Name ''',''Units'',''normalized'');']);
    eval(['DoEditValue(handles,handles.' handles.GradSimuAttrStruct.Children(i).Name '_tab,handles.GradSimuAttrStruct.Children(' num2str(i) ').Attributes,2,[0.2,0.15,0.0,0.15,0.15,0.05]);']);
    handles=guidata(handles.GradDesignPanel_figure);
end

% Create grid and display structure
VMgd.xdimres=str2num(get(handles.Attrh2.('XDimRes'),'String'));
VMgd.ydimres=str2num(get(handles.Attrh2.('YDimRes'),'String'));
VMgd.zdimres=str2num(get(handles.Attrh2.('ZDimRes'),'String'));

[VMgd.xgrid,VMgd.ygrid,VMgd.zgrid]=meshgrid((-VCtl.ISO(1)+1)*VObj.XDimRes:VMgd.xdimres:(VObj.XDim-VCtl.ISO(1))*VObj.XDimRes,...
    (-VCtl.ISO(2)+1)*VObj.YDimRes:VMgd.ydimres:(VObj.YDim-VCtl.ISO(2))*VObj.YDimRes,...
    (-VCtl.ISO(3)+1)*VObj.ZDimRes:VMgd.zdimres:(VObj.ZDim-VCtl.ISO(3))*VObj.ZDimRes);

VMgd.axes=handles.GradField_axes;
handles.IV=struct(...
    'xslice',0,...
    'yslice',0,...
    'zslice',0 ...
    );
view(handles.GradField_axes,3);

%Open current loaded Grad XML file
if isfield(handles.Simuh,'GradXMLFile')
    import javax.swing.*
    import javax.swing.tree.*;
    handles.GradStruct=DoParseXML(handles.Simuh.GradXMLFile);
    handles.GradXMLFile=handles.Simuh.GradXMLFile;
    DoWriteXML2m(handles.GradStruct,[handles.GradXMLFile(1:end-3) 'm']);
    %     guidata(hObject, handles);
    Root=DoConvStruct2Tree(handles.GradStruct);
    handles.GradTree=uitree('V0','Root',Root,'SelectionChangeFcn', {@ChkNode,handles});
    set(handles.GradTree.getUIContainer,'Units','normalized');
    set(handles.GradTree.getUIContainer,'Position',[0.205,0.4,0.2,0.58]);
    handles.GradTreeModel=DefaultTreeModel(Root);
    handles.GradTree.setModel(handles.GradTreeModel);
    try
        DoPlotGradFie(handles);
        set(handles.Forwards_pushbutton,'Enable','on');
        set(handles.Backwards_pushbutton,'Enable','on');
        handles=guidata(hObject);
    catch me
        error_msg{1,1}='ERROR!!! Displaying gradient field aborted.';
        error_msg{2,1}=me.message;
        errordlg(error_msg);
    end

end

% Choose default command line output for GradDesignPanel
handles.input=varargin;
handles.output=hObject;

% Update handles structure
guidata(hObject, handles);

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

function ChkGradElemListTreeNode(tree, value, handles)

handles=guidata(handles.GradDesignPanel_figure);
SelNode=tree.SelectedNodes;
SelNode=SelNode(1);
Level=SelNode.getValue;
if ~ischar(Level)
    LevelChg=diff(Level,1);
    Level([LevelChg; -1]==1)=[];
end

Node='handles.GradElemListStruct';
if Level=='0'
    eval(['handles.GradElemNode=' Node ';']);
else
    for i=1:length(Level)
        Node=[Node '.Children(' num2str(Level(i)) ')'];
    end
    eval(['handles.GradElemNode=' Node ';']);
end
guidata(handles.GradDesignPanel_figure, handles);

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

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

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

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

import javax.swing.*
import javax.swing.tree.*;

[filename,pathname,filterindex]=uigetfile({'Grad*.xml','XML-files (*.xml)'},'MultiSelect','off');
if filename~=0
    if ~isempty(handles.Attrh1)
        Attrh1name=fieldnames(handles.Attrh1);
        for i=1:length(Attrh1name)
            delete(handles.Attrh1.(Attrh1name{i}));
        end
        handles.Attrh1=[];
    end
    handles.GradStruct=DoParseXML(fullfile(pathname,filename));
    handles.GradXMLFile=fullfile(pathname,filename);
    guidata(hObject, handles);
    Root=DoConvStruct2Tree(handles.GradStruct);
    handles.GradTree=uitree('v0', 'Root',Root,'SelectionChangeFcn', {@ChkNode,handles});
    set(handles.GradTree.getUIContainer,'Units','normalized');
    set(handles.GradTree.getUIContainer,'Position',[0.205,0.4,0.2,0.58]);
    handles.GradTreeModel=DefaultTreeModel(Root);
    handles.GradTree.setModel(handles.GradTreeModel);
    % Add searchig path
    path(path,pathname);
else
    errordlg('No Grad is loaded!');
    return;
end
guidata(hObject, handles);

function ChkNode(tree, value, handles)

handles=guidata(handles.GradDesignPanel_figure);
SelNode=tree.SelectedNodes;
SelNode=SelNode(1);
Level=SelNode.getValue;
if ~ischar(Level)
    LevelChg=diff(Level,1);
    Level([LevelChg; -1]==1)=[];
end

Node='handles.GradStruct';
if Level=='0'
    eval(['handles.GradNode=' Node ';']);
else
    for i=1:length(Level)
        Node=[Node '.Children(' num2str(Level(i)) ')'];
    end
    eval(['handles.GradNode=' Node ';']);
end
handles.GradNodeLvl=Node;
handles.SelNode=SelNode;

if ~isempty(handles.Attrh1)
    Attrh1name=fieldnames(handles.Attrh1);
    for i=1:length(Attrh1name)
        delete(handles.Attrh1.(Attrh1name{i}));
    end
    handles.Attrh1=[];
end

set(handles.GradAttri_uipanel,'Title',['''' char(SelNode.getName) ''' Grad Attribute'],'Unit','normalized');
if SelNode.isLeaf | SelNode.isRoot
    if strcmp(char(SelNode.getName),'Specials')
        DoEditValue(handles,handles.GradAttri_uipanel,handles.GradNode.Attributes,1,[0.25,0.25,0.0,0.1,0.1,0.05]);
    else
        DoEditValue(handles,handles.GradAttri_uipanel,handles.GradNode.Attributes,1,[0.25,0.25,0.0,0.1,0.1,0.05]);
    end
else
    guidata(handles.GradDesignPanel_figure, handles);
end

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

import javax.swing.*
import javax.swing.tree.*;

try
    switch handles.GradNode.Name
        case 'MRiLabGrad'
            errordlg('MRiLabGrad Root can not be deleted!');
            return;
    end

    eval([handles.GradNodeLvl '=[];']);
    nN=handles.SelNode.getNextSibling;
    while ~isempty(nN)
        Level=nN.getValue;
        Level(end)=[];
        nN.setValue(Level);
        nN=nN.getNextSibling;
    end
    guidata(hObject, handles);
    pause(0.1);

    % remove node
    handles.GradTree.setSelectedNode(handles.SelNode.getParent);
    handles.GradTreeModel.removeNodeFromParent(handles.SelNode);

    DoWriteXML(handles.GradStruct,handles.GradXMLFile);
catch me
    error_msg{1,1}='ERROR!!! Node operation aborted.';
    error_msg{2,1}=me.message;
    errordlg(error_msg);

end

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

import javax.swing.*
import javax.swing.tree.*;

try
    ChkGradElemListTreeNode(handles.GradElemListTree, [], handles); % In case GradElem.xml updated
    handles=guidata(handles.GradDesignPanel_figure);
    switch handles.GradNode.Name
        case {'MRiLabGrad'}
            % add node
            SelNode=handles.GradElemListTree.SelectedNodes;
            SelNode=SelNode(1);
            AddedNode=SelNode.clone;
            switch char(AddedNode.getName)
                case {'GradElem'}
                    errordlg([char(AddedNode.getName) ' can not be added!']);
                    return;
            end
            handles.GradTreeModel.insertNodeInto(AddedNode,handles.SelNode,handles.SelNode.getChildCount());
            handles.GradTree.setSelectedNode(AddedNode); % expand to show added child
            handles.GradTree.setSelectedNode(handles.SelNode); % insure additional nodes are added to parent

            nP=AddedNode.getPreviousSibling;
            if ~isempty(nP)
                Level=nP.getValue;
                AddedNode.setValue([Level; Level(end)+1]);
                eval([handles.GradNodeLvl '.Children(' num2str(Level(end)+1) ')=handles.GradElemNode;']);
                DoWriteXML(handles.GradStruct,handles.GradXMLFile);
            else
                nP=AddedNode.getParent;
                Level=nP.getValue;
                AddedNode.setValue([Level; 1]);
                eval([handles.GradNodeLvl '.Children=handles.GradElemNode;']);
                DoWriteXML(handles.GradStruct,handles.GradXMLFile);
            end
        otherwise
            errordlg(['Grad Element can not be added under ' handles.GradNode.Name '!']);
            return;
    end
    guidata(hObject, handles);
catch me
    error_msg{1,1}='ERROR!!! Node operation aborted.';
    error_msg{2,1}=me.message;
    errordlg(error_msg);

end

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

% update Grad XML file
if ~isempty(handles.Attrh1)
    Attrh1name=fieldnames(handles.Attrh1);
    for i=1:2:length(Attrh1name)
        switch get(handles.Attrh1.(Attrh1name{i+1}),'Style')
            case 'edit'
                handles.GradNode.Attributes((i+1)/2).Value=get(handles.Attrh1.(Attrh1name{i+1}),'String');
            case 'checkbox'
                if get(handles.Attrh1.(Attrh1name{i+1}),'Value')
                    handles.GradNode.Attributes((i+1)/2).Value='^1';
                else
                    handles.GradNode.Attributes((i+1)/2).Value='^0';
                end
            case 'popupmenu'
                handles.GradNode.Attributes((i+1)/2).Value(2)=num2str(get(handles.Attrh1.(Attrh1name{i+1}),'Value'));
        end
    end
    eval([handles.GradNodeLvl '=handles.GradNode;']);
    DoWriteXML(handles.GradStruct,handles.GradXMLFile);
    % update associated m function
    DoWriteXML2m(handles.GradStruct,[handles.GradXMLFile(1:end-3) 'm']);
end

% update GradSimuAttr.xml
tabs=get(handles.Setting_tabgroup,'Children');
for j=1:length(handles.GradSimuAttrStruct.Children)
    Attrh2=get(tabs(j),'Children');
    for i=1:2:length(Attrh2)
        if ~iscell(get(Attrh2(end-i),'String'))
            handles.GradSimuAttrStruct.Children(j).Attributes((i+1)/2).Value=get(Attrh2(end-i),'String');
        else
            handles.GradSimuAttrStruct.Children(j).Attributes((i+1)/2).Value(2)=num2str(get(Attrh2(end-i),'Value'));
        end
    end
end
DoWriteXML(handles.GradSimuAttrStruct,[handles.Simuh.MRiLabPath filesep 'Macro' filesep 'GradElem' filesep 'GradSimuAttr.xml']);

guidata(hObject, handles);

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

import javax.swing.*
import javax.swing.tree.*;

try
    switch handles.GradNode.Name
        case 'MRiLabGrad'
            errordlg('MRiLabGrad Root can not be copied!');
            return;
    end
    handles.CopSelNode=handles.SelNode.clone;
    handles.CopGradNode=handles.GradNode;
    guidata(hObject, handles);
catch me
    error_msg{1,1}='ERROR!!! Node operation aborted.';
    error_msg{2,1}=me.message;
    errordlg(error_msg);

end

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

import javax.swing.*
import javax.swing.tree.*;

try
    switch handles.GradNode.Name
        case {'MRiLabGrad'}
            % paste node
            handles.GradTreeModel.insertNodeInto(handles.CopSelNode,handles.SelNode,handles.SelNode.getChildCount());
            handles.GradTree.setSelectedNode(handles.CopSelNode); % expand to show added child
            handles.GradTree.setSelectedNode(handles.SelNode); % insure additional nodes are added to parent

            nP=handles.CopSelNode.getPreviousSibling;
            if ~isempty(nP)
                Level=nP.getValue;
                handles.CopSelNode.setValue([Level; Level(end)+1]);
                eval([handles.GradNodeLvl '.Children(' num2str(Level(end)+1) ')=handles.CopGradNode;']);
                DoWriteXML(handles.GradStruct,handles.GradXMLFile);
            else
                nP=handles.CopSelNode.getParent;
                Level=nP.getValue;
                handles.CopSelNode.setValue([Level; 1]);
                eval([handles.GradNodeLvl '.Children=handles.CopGradNode;']);
                DoWriteXML(handles.GradStruct,handles.GradXMLFile);
            end
        otherwise
            errordlg(['Grad Element can not be added under ' handles.GradNode.Name '!']);
            return;
    end
    handles.CopSelNode=[];
    handles.CopGradNode=[];
    guidata(hObject, handles);
catch me
    error_msg{1,1}='ERROR!!! Node operation aborted.';
    error_msg{2,1}=me.message;
    errordlg(error_msg);

end

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

set(hObject,'Enable','off');
set(hObject,'String','Calc...');
pause(0.01);
try
    DoPlotGradFie(handles);
    set(handles.Forwards_pushbutton,'Enable','on');
    set(handles.Backwards_pushbutton,'Enable','on');
catch me
    error_msg{1,1}='Error occurred at displaying gradient field.';
    error_msg{2,1}=me.message;
    errordlg(error_msg);
end
set(hObject,'Enable','on');
set(hObject,'String','Execute');

% --------------------------------------------------------------------
function SavePanel_uipushtool_ClickedCallback(hObject, eventdata, handles)
% hObject    handle to SavePanel_uipushtool (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
DoSaveSnapshot(handles.GradDesignPanel_figure);

% --- Executes when user attempts to close GradDesignPanel_figure.
function GradDesignPanel_figure_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to GradDesignPanel_figure (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: delete(hObject) closes the figure
delete(hObject);

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

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

global VObj;
TAttr=get(handles.Attrh2.('Plane'),'String');
switch TAttr{get(handles.Attrh2.('Plane'),'Value')}
    case 'XY'
        handles.IV.zslice=handles.IV.zslice+VObj.ZDimRes;
    case 'XZ'
        handles.IV.yslice=handles.IV.yslice+VObj.YDimRes;
    case 'YZ'
        handles.IV.xslice=handles.IV.xslice+VObj.XDimRes;
end
DoUpdateSlice(handles.GradField_axes,handles.G,handles.IV,'Grad');
guidata(hObject, handles);

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

global VObj;
TAttr=get(handles.Attrh2.('Plane'),'String');
switch TAttr{get(handles.Attrh2.('Plane'),'Value')}
    case 'XY'
        handles.IV.zslice=handles.IV.zslice-VObj.ZDimRes;
    case 'XZ'
        handles.IV.yslice=handles.IV.yslice-VObj.YDimRes;
    case 'YZ'
        handles.IV.xslice=handles.IV.xslice-VObj.XDimRes;
end
DoUpdateSlice(handles.GradField_axes,handles.G,handles.IV,'Grad');
guidata(hObject, handles);

% --------------------------------------------------------------------
function Cursor_uitoggletool_ClickedCallback(hObject, eventdata, handles)
% hObject    handle to Cursor_uitoggletool (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if ~isfield(handles,'dcm')
    handles.dcm=datacursormode(handles.GradDesignPanel_figure);
    datacursormode on
    set(handles.dcm,'updatefcn',{@Cursor_update,handles});
else
    if strcmp(get(handles.dcm,'Enable'),'on')
        set(handles.dcm,'Enable','off');
    else
        set(handles.dcm,'Enable','on');
    end
end
guidata(hObject, handles);

function output_txt = Cursor_update(obj,event_obj,handles)
% Display the position of the data cursor
% obj          Currently not used (empty)
% event_obj    Handle to event object
% output_txt   Data cursor text string (string or cell array of strings).

global VObj;
global VCtl;
global VMgd;

handles=guidata(handles.GradDesignPanel_figure);
pos = get(event_obj,'Position');
pos(1)=round((pos(1)+VCtl.ISO(1)*VObj.XDimRes)/VMgd.xdimres);
pos(2)=round((pos(2)+VCtl.ISO(2)*VObj.YDimRes)/VMgd.ydimres);
pos(3)=round((pos(3)+VCtl.ISO(3)*VObj.ZDimRes)/VMgd.zdimres);

output_txt = {['X: ',num2str(pos(1),4)],...
    ['Y: ',num2str(pos(2),4)],...
    ['Z: ',num2str(pos(3),4)],...
    ['Value: ',num2str(handles.G(pos(2),pos(1),pos(3)),4)]};

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

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

prompt = {'Enter NEW grad name:','Enter NEW grad note:'};
dlg_title = 'Input for creating new grad';
num_lines = 1;
def = {'Grad_CustomHead','Customized Gradient Field for Head'};
answer = inputdlg(prompt,dlg_title,num_lines,def);
if isempty(answer)
    warndlg('No new grad file is created!');
    return
end
if isempty(answer{1})
    warndlg('No new grad file is created!');
    return
end
if ~strcmp(answer{1}(1:5),'Grad_')
    warndlg('Grad name must have a prefix ''Grad_'', please rename your grad!');
    return
end
gradpath=uigetdir(pwd,'Specify a saving path for new grad file.');
if gradpath==0
    warndlg('You have to specify a saving path!');
    return;
end

% Create new grad file
mkdir([gradpath filesep answer{1}]); % make folder
copyfile([handles.Simuh.MRiLabPath filesep 'Config' filesep 'Grad' filesep 'Head' filesep 'Grad_LinearHead' filesep 'Grad_LinearHead.xml'],...
    [gradpath filesep answer{1} filesep answer{1} '.xml']); % copy grad temple
% Add searchig path
path(path,[gradpath filesep answer{1}]);
% Load new grad file
import javax.swing.*;
import javax.swing.tree.*;
if ~isempty(handles.Attrh1)
    Attrh1name=fieldnames(handles.Attrh1);
    for i=1:length(Attrh1name)
        delete(handles.Attrh1.(Attrh1name{i}));
    end
    handles.Attrh1=[];
end
handles.GradStruct=DoParseXML([gradpath filesep answer{1} filesep answer{1} '.xml']);
for i=1:length(handles.GradStruct.Attributes)
    if strcmp(handles.GradStruct.Attributes(i).Name,'Name')
        handles.GradStruct.Attributes(i).Value = answer{1};
    elseif strcmp(handles.GradStruct.Attributes(i).Name,'Notes')
        handles.GradStruct.Attributes(i).Value = answer{2};
    end
end
DoWriteXML(handles.GradStruct,[gradpath filesep answer{1} filesep answer{1} '.xml']); %update new grad file
handles.GradXMLFile=[gradpath filesep answer{1} filesep answer{1} '.xml'];
DoWriteXML2m(handles.GradStruct,[handles.GradXMLFile(1:end-3) 'm']);
guidata(hObject, handles);
Root=DoConvStruct2Tree(handles.GradStruct);
handles.GradTree=uitree('V0','Root',Root,'SelectionChangeFcn', {@ChkNode,handles});
set(handles.GradTree.getUIContainer,'Units','normalized');
set(handles.GradTree.getUIContainer,'Position',[0.205,0.4,0.2,0.58]);
handles.GradTreeModel=DefaultTreeModel(Root);
handles.GradTree.setModel(handles.GradTreeModel);
cla(handles.GradField_axes);
guidata(hObject, handles);

% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function GradDesignPanel_figure_WindowButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to GradDesignPanel_figure (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

tempaxes = gca;
try
    if strcmp(get(gcf,'Selectiontype'),'alt')
        figure 			% Create a new figure
        ax_new = axes;
        copyaxes(tempaxes, ax_new);
    end
catch me
end


function [mri] = ft_read_mri(filename, varargin)

% FT_READ_MRI reads anatomical and functional MRI data from different file formats.
% The output data is structured in such a way that it is compatible with
% FT_DATATYPE_VOLUME.
%
% Use as
%   [mri] = ft_read_mri(filename)
%
% Additional options should be specified in key-value pairs and can be
%   'dataformat' = string specifying the file format, determining the low-
%                  level reading routine to be used. If no explicit format
%                  is given, it is determined automatically from the filename.
%
% The following values apply for the dataformat
%   'afni_head'/'afni_brik'      uses AFNI code
%   'analyze_img'/'analyze_hdr'  uses SPM code
%   'analyze_old'                uses Darren Webber's code
%   'asa_mri'
%   'ctf_mri'
%   'ctf_mri4'
%   'ctf_svl'
%   'dicom'                      uses FreeSurfer code
%   'dicom_old'                  uses own code
%   'freesurfer_mgh'             uses FreeSurfer code
%   'freesurfer_mgz'             uses FreeSurfer code
%   'matlab'                     assumes a MATLAB *.mat file containing a mri structure according to FT_DATATYPE_VOLUME
%   'minc'                       uses SPM (<= version SPM5)
%   'neuromag_fif'               uses MNE toolbox
%   'neuromag_fif_old'           uses meg-pd toolbox
%   'nifti'                      uses FreeSurfer code
%   'nifti_fsl'                  uses FreeSurfer code
%   'nifti_spm'                  uses SPM
%   'yokogawa_mri'
%   'mrtrix_mif'                 uses mrtrix code
%
% The following MRI file formats are supported
%   CTF (*.svl, *.mri version 4 and 5)
%   NIFTi (*.nii) and zipped NIFTi (*.nii.gz)
%   Analyze (*.img, *.hdr)
%   DICOM (*.dcm, *.ima)
%   AFNI (*.head, *.brik)
%   FreeSurfer (*.mgz, *.mgh)
%   MINC (*.mnc)
%   Neuromag/Elekta (*.fif)
%   ANT - Advanced Neuro Technology (*.mri)
%   Yokogawa (*.mrk, incomplete)
%   Mrtrix image format (*.mif)
%
% If you have a series of DICOM files, please provide the name of any of the files
% in the series (e.g. the first one). The other files will be found automatically.
%
% The output MRI may have a homogenous transformation matrix that converts
% the coordinates of each voxel (in xgrid/ygrid/zgrid) into head
% coordinates.
%
% See also FT_DATATYPE_VOLUME, FT_WRITE_MRI, FT_READ_DATA, FT_READ_HEADER, FT_READ_EVENT

% Copyright (C) 2008-2013, Robert Oostenveld & Jan-Mathijs Schoffelen
%
% 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$

% optionally get the data from the URL and make a temporary local copy
filename = fetch_url(filename);

% get the options
dataformat = ft_getopt(varargin, 'dataformat');

% the following is added for backward compatibility of using 'format' rather than 'dataformat'
format    = ft_getopt(varargin, 'format');
if ~isempty(format)
  ft_warning('the option ''format'' will be deprecated soon, please use ''dataformat'' instead');
  if isempty(dataformat)
    dataformat  = format;
  end
end

if isempty(dataformat)
  % only do the autodetection if the format was not specified
  dataformat = ft_filetype(filename);
end

if strcmp(dataformat, 'compressed')
  % the file is compressed, unzip on the fly
  inflated = true;
  filename = inflate_file(filename);
  dataformat = ft_filetype(filename);
else
  inflated = false;
end

% test whether the file exists
if ~exist(filename, 'file')
  ft_error('file ''%s'' does not exist', filename);
end

% test for the presence of some external functions from other toolboxes
hasspm2  = ft_hastoolbox('spm2');    % see http://www.fil.ion.ucl.ac.uk/spm/
hasspm5  = ft_hastoolbox('spm5');    % see http://www.fil.ion.ucl.ac.uk/spm/
hasspm8  = ft_hastoolbox('spm8');    % see http://www.fil.ion.ucl.ac.uk/spm/
hasspm12 = ft_hastoolbox('spm12');   % see http://www.fil.ion.ucl.ac.uk/spm/

switch dataformat
  case 'ctf_mri'
    [img, hdr] = read_ctf_mri(filename);
    transform = hdr.transformMRI2Head;
    coordsys  = 'ctf';

  case 'ctf_mri4'
    [img, hdr] = read_ctf_mri4(filename);
    transform = hdr.transformMRI2Head;
    coordsys  = 'ctf';

  case 'ctf_svl'
    [img, hdr] = read_ctf_svl(filename);
    transform = hdr.transform;

  case 'asa_mri'
    [img, seg, hdr] = read_asa_mri(filename);
    transform = hdr.transformMRI2Head;
    if isempty(seg)
      % in case seg exists it will be added to the output
      clear seg
    end

  case 'minc'
    if ~(hasspm2 || hasspm5)
      fprintf('the SPM2 or SPM5 toolbox is required to read *.mnc files\n');
      ft_hastoolbox('spm2', 1);
    end
    % use the functions from SPM
    hdr = spm_vol_minc(filename);
    img = spm_read_vols(hdr);
    transform = hdr.mat;

  case 'nifti_spm'
    if ~(hasspm5 || hasspm8 || hasspm12)
      fprintf('the SPM5 or newer toolbox is required to read *.nii files\n');
      ft_hastoolbox('spm12', 1);
    end
    % use the functions from SPM
    hdr = spm_vol_nifti(filename);
    img = double(hdr.private.dat);
    %img = spm_read_vols(hdr);
    transform = hdr.mat;

  case {'analyze_img' 'analyze_hdr'}
    if ~(hasspm8 || hasspm12)
      fprintf('the SPM8 or newer toolbox is required to read analyze files\n');
      ft_hastoolbox('spm8up', 1);
    end

    % use the image file instead of the header
    filename((end-2):end) = 'img';
    % use the functions from SPM to read the Analyze MRI
    hdr = spm_vol(filename);
    img = spm_read_vols(hdr);
    transform = hdr.mat;

  case 'analyze_old'
    % use the functions from Darren Weber's mri_toolbox to read the Analyze MRI
    ft_hastoolbox('mri', 1);     % from Darren Weber, see http://eeg.sourceforge.net/

    avw = avw_img_read(filename, 0); % returned volume is LAS*
    img = avw.img;
    hdr = avw.hdr;
    % The default Analyze orientation is axial unflipped (LAS*), which means
    % that the resulting volume is according to the radiological convention.
    % Most other fMRI and EEG/MEG software (except Mayo/Analyze) uses
    % neurological conventions and a right-handed coordinate system, hence
    % the first axis of the 3D volume (right-left) should be flipped to make
    % the coordinate system comparable to SPM
    ft_warning('flipping 1st dimension (L-R) to obtain volume in neurological convention');
    img = flipdim(img, 1);

    transform      = diag(hdr.dime.pixdim(2:4));
    transform(4,4) = 1;

  case {'afni_brik' 'afni_head'}
    % needs afni
    ft_hastoolbox('afni', 1);    % see http://afni.nimh.nih.gov/

    [err, img, hdr, ErrMessage] = BrikLoad(filename);
    if err
      ft_error('could not read AFNI file');
    end

    % FIXME: this should be checked, but I only have a single BRIK file
    % construct the homogenous transformation matrix that defines the axes
    ft_warning('homogenous transformation might be incorrect for AFNI file');
    transform        = eye(4);
    transform(1:3,4) = hdr.ORIGIN(:);
    transform(1,1)   = hdr.DELTA(1);
    transform(2,2)   = hdr.DELTA(2);
    transform(3,3)   = hdr.DELTA(3);

    % FIXME: I am not sure about the "RAI" image orientation
    img = flipdim(img,1);
    img = flipdim(img,2);
    dim = size(img);
    transform(1,4) = -dim(1) - transform(1,4);
    transform(2,4) = -dim(2) - transform(2,4);

  case 'neuromag_fif'
    % needs mne toolbox
    ft_hastoolbox('mne', 1);

    % use the mne functions to read the Neuromag MRI
    hdr = fiff_read_mri(filename);
    img_t = cat(3, hdr.slices.data);
    img = permute(img_t,[2 1 3]);
    hdr.slices = rmfield(hdr.slices, 'data'); % remove the image data to save memory

    % information below is from MNE - fiff_define_constants.m
    % coordinate system 4 - is the MEG head coordinate system (fiducials)
    % coordinate system 5 - is the MRI coordinate system
    % coordinate system 2001 - MRI voxel coordinates
    % coordinate system 2002 - Surface RAS coordinates (is mainly vertical
    %                                     shift, no rotation to 2001)
    % MEG sensor positions come in system 4
    % MRI comes in system 2001

    transform = eye(4);
    if isfield(hdr, 'trans') && issubfield(hdr.trans, 'trans')
      if (hdr.trans.from == 4) && (hdr.trans.to == 5)
        transform = hdr.trans.trans;
      else
        ft_warning('W: trans does not transform from 4 to 5.');
        ft_warning('W: Please check the MRI fif-file');
      end
    else
      ft_warning('W: trans structure is not defined.');
      ft_warning('W: Maybe coregistration is missing?');
    end
    if isfield(hdr, 'voxel_trans') && issubfield(hdr.voxel_trans, 'trans')
      % centers the coordinate system
      % and switches from mm to m
      if (hdr.voxel_trans.from == 2001) && (hdr.voxel_trans.to == 5)
        % matlab_shift compensates for the different index conventions
        % between C and matlab

        % the lines below is old code (prior to Jan 3, 2013) and only works with
        % 1 mm resolution MRIs
        %matlab_shift = [ 0 0 0 0.001; 0 0 0 -0.001; 0 0 0 0.001; 0 0 0 0];
        % transform transforms from 2001 to 5 and further to 4
        %transform = transform\(hdr.voxel_trans.trans+matlab_shift);

        % the lines below should work with arbitrary resolution
        matlab_shift = eye(4);
        matlab_shift(1:3,4) = [-1,-1,-1];
        transform = transform\(hdr.voxel_trans.trans * matlab_shift);

        coordsys  = 'neuromag';
        mri.unit  = 'm';
      else
        ft_warning('W: voxel_trans does not transform from 2001 to 5.');
        ft_warning('W: Please check the MRI fif-file');
      end
    else
      ft_warning('W: voxel_trans structure is not defined.');
      ft_warning('W: Please check the MRI fif-file');
    end

  case 'neuromag_fif_old'
    % needs meg_pd toolbox
    ft_hastoolbox('meg-pd', 1);

    % use the meg_pd functions to read the Neuromag MRI
    [img,coords] = loadmri(filename);
    dev = loadtrans(filename,'MRI','HEAD');
    transform  = dev*coords;
    hdr.coords = coords;
    hdr.dev    = dev;

  case 'dicom'
    % this seems to return a right-handed volume with the transformation
    % matrix stored in the file headers.

    % needs the freesurfer toolbox
    ft_hastoolbox('freesurfer', 1);
    [dcmdir,junk1,junk2] = fileparts(filename);
    if isempty(dcmdir),
      dcmdir = '.';
    end
    [img,transform,hdr,mr_params] = load_dicom_series(dcmdir,dcmdir,filename);
    transform = vox2ras_0to1(transform);

  case 'dicom_old'
    % this does not necessarily return a right-handed volume and only a
    % transformation-matrix with the voxel size

    % this uses the Image processing toolbox
    % the DICOM file probably represents a stack of slices, possibly even multiple volumes
    orig = dicominfo(filename);
    dim(1) = orig.Rows;
    dim(2) = orig.Columns;

    [p, f] = fileparts(filename);

    % this works for the Siemens scanners at the FCDC
    tok = tokenize(f, '.');
    for i=5:length(tok)
      tok{i} = '*';
    end
    filename = sprintf('%s.', tok{:});  % reconstruct the filename with wildcards and '.' between the segments
    filename = filename(1:end-1);       % remove the last '.'
    dirlist  = dir(fullfile(p, filename));
    dirlist  = {dirlist.name};

    if isempty(dirlist)
      % this is for the Philips data acquired at KI
      ft_warning('could not determine list of dicom files, trying with *.dcm');
      dirlist  = dir(fullfile(p, '*.dcm'));
      dirlist  = {dirlist.name};
    end

    if isempty(dirlist)
      ft_warning('could not determine list of dicom files, trying with *.ima');
      dirlist  = dir(fullfile(p, '*.ima'));
      dirlist  = {dirlist.name};
    end

    if length(dirlist)==1
      % try something else to get a list of all the slices
      dirlist = dir(fullfile(p, '*'));
      dirlist = {dirlist(~[dirlist.isdir]).name};
    end

    keep = false(1, length(dirlist));
    for i=1:length(dirlist)
      filename = char(fullfile(p, dirlist{i}));
      if ~strcmp(dataformat, 'dicom_old')
        keep(i) = false;
        fprintf('skipping ''%s'' because of incorrect filetype\n', filename);
      end
      % read the header information
      info     = dicominfo(filename);
      if info.SeriesNumber~=orig.SeriesNumber
        keep(i) = false;
        fprintf('skipping ''%s'' because of different SeriesNumber\n', filename);
      else
        keep(i) = true;
        hdr(i)  = info;
      end
    end
    % remove the files that were skipped
    hdr     = hdr(keep);
    dirlist = dirlist(keep);

    % pre-allocate enough space for the subsequent slices
    dim(3) = length(dirlist);
    img    = zeros(dim(1), dim(2), dim(3));
    for i=1:length(dirlist)
      filename = char(fullfile(p, dirlist{i}));
      fprintf('reading image data from ''%s''\n', filename);
      img(:,:,i) = dicomread(hdr(i));
    end

    % reorder the slices
    [z, indx]   = sort(cell2mat({hdr.SliceLocation}));
    hdr = hdr(indx);
    img = img(:,:,indx);

    try
      % construct a homgeneous transformation matrix that performs the scaling from voxels to mm
      dx = hdr(1).PixelSpacing(1);
      dy = hdr(1).PixelSpacing(2);
      dz = hdr(2).SliceLocation - hdr(1).SliceLocation;
      transform = eye(4);
      transform(1,1) = dx;
      transform(2,2) = dy;
      transform(3,3) = dz;
    end

  case {'nifti', 'freesurfer_mgz', 'freesurfer_mgh', 'nifti_fsl'}
    if strcmp(dataformat, 'freesurfer_mgz') && ispc
      ft_error('Compressed .mgz files cannot be read on a PC');
    end

    ft_hastoolbox('freesurfer', 1);
    tmp = MRIread(filename);
    ndims = numel(size(tmp.vol));
    if ndims==3
      img = permute(tmp.vol, [2 1 3]); %FIXME although this is probably correct
      %see the help of MRIread, anecdotally columns and rows seem to need a swap
      %in order to match the transform matrix (alternatively a row switch of the
      %latter can be done)
    elseif ndims==4
      img = permute(tmp.vol, [2 1 3 4]);
    end
    hdr = rmfield(tmp, 'vol');
    transform = tmp.vox2ras1;

  case 'yokogawa_mri'
    ft_hastoolbox('yokogawa', 1);
    fid = fopen_or_error(filename, 'rb');
    mri_info = GetMeg160MriInfoM(fid);
    patient_info = GetMeg160PatientInfoFromMriFileM(fid);
    [data_style, model, marker, image_parameter, normalize, besa_fiducial_point] = GetMeg160MriFileHeaderInfoM(fid);
    fclose(fid);

    % gather all meta-information
    hdr.mri_info = mri_info;
    hdr.patient_info = patient_info;
    hdr.data_style = data_style;
    hdr.model = model;
    hdr.marker = marker;
    hdr.image_parameter = image_parameter;
    hdr.normalize = normalize;
    hdr.besa_fiducial_point = besa_fiducial_point;

    ft_error('FIXME yokogawa_mri implementation is incomplete');

  case 'matlab'
    mri = loadvar(filename, 'mri');

  case {'mif' 'mrtrix_mif'}
    ft_hastoolbox('mrtrix', 1);
    tmp = read_mrtrix(filename);

    mri.anatomy = tmp.data;
    mri.dim     = tmp.dim;
    mri.transform = tmp.transform;
    mri.transform(1:3,1:3) = diag(tmp.vox(1:3))*mri.transform(1:3,1:3);

  otherwise
    ft_error('unrecognized filetype ''%s'' for ''%s''', dataformat, filename);
end

if exist('img', 'var')
  % set up the axes of the volume in voxel coordinates
  %nx = size(img,1);
  %ny = size(img,2);
  %nz = size(img,3);
  mri.dim = size(img); %[nx ny nz];
  % store the anatomical data
  mri.anatomy = img;
end

if exist('seg', 'var')
  % store the segmented data
  mri.seg = seg;
end

if exist('hdr', 'var')
  % store the header with all file format specific details
  mri.hdr = hdr;
end

try
  % store the homogenous transformation matrix if present
  mri.transform = transform;
end

try
  % try to determine the units of the coordinate system
  mri = ft_determine_units(mri);
end

try
  % try to add a descriptive label for the coordinate system
  mri.coordsys = coordsys;
end

if inflated
  % compressed file has been unzipped on the fly, clean up
  delete(filename);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function value = loadvar(filename, varname)
var = whos('-file', filename);
if length(var)==1
  filecontent = load(filename); % read the one variable in the file, regardless of how it is called
  value       = filecontent.(var.name);
  clear filecontent
else
  filecontent = load(filename, varname);
  value       = filecontent.(varname);  % read the variable named according to the input specification
  clear filecontent
end


classdef EigenValueAndVectorComputerFactory < handle

    methods (Access = public, Static)

        function obj = create(cParams)
            switch cParams.type
                case 'SYMBOLIC'
                    obj = EigenValueAndVectorComputerSymbolic(cParams);
                case 'PRECOMPUTED'
                    obj = EigenValueAndVectorComputerPrecomputed(cParams);
            end
        end

    end

end


%% cell fill_method_listbox(void)
%
function [list] = get_method_list()
  L = load_method_list();
  [m,n] = size(L{1,1});
  list = {};
  k = 1;
  for i = 1 : m
    method_id = strtrim(char(L{1,1}(i)));
    method_name = strtrim(char(L{1,2}(i)));

    if(method_id == '-')
      method = [method_id];
    else
      method = [method_id ' - ' method_name];
    end

    list{k,1} = method;
    k = k + 1;
  end
end


function f = uplus(f)
%UPLUS   Unary plus for a SEPARABLEAPPROX.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

% The algorithm below is advocated by Vladimir Rohklin:

end


report_this_filefun(mfilename('fullpath'));

str = [];
[newmatfile, newpath] = uiputfile([ hodo '*.dat'], 'Save As');

s = [a.Magnitude ];
le = a.Count;

fid = fopen([newpath newmatfile],'w') ;
fprintf(fid,'%5.0f %2.0f %2.0f\n',[floor(a(1,3)) a(1,4) a(1,5)]);
fprintf(fid,'%5.0f %2.0f %2.0f\n',[floor(a(le,3)) a(le,4) a(le,5)]);
fprintf(fid,'%4.1f \n',2.0);
fprintf(fid,'%4.1f \n',0.3);
fprintf(fid,'%4.1f\n',s');

fclose(fid);
clear s
cd kijko
!hn

return

%historic part

str = [];
[newmatfile, newpath] = uiputfile([ hodo '*.dat'], 'Save As');

s = [a.Date.Year a.Date.Month a.Date.Day a.Magnitude ];
le = a.Count;

fid = fopen([newpath newmatfile],'w') ;
fprintf(fid,'%5.0f %2.0f %2.0f\n',[floor(a(1,3))-1 a(1,4) a(1,5)]);
fprintf(fid,'%5.0f %2.0f %2.0f\n',[floor(a(le,3))+1 a(le,4) a(le,5)]);
fprintf(fid,'%5.2f \n',0.50);
fprintf(fid,'%5.0f %2.0f %2.0f %5.1f\n',s');

fclose(fid);


function varargout = process_evt_groupname( varargin )
% PROCESS_EVT_GROUPNAME: Combine different categories of events into one (by name)
%
% USAGE:  OutputFiles = process_evt_groupname('Run', sProcess, sInputs)

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

eval(macro_method);
end

%% ===== GET DESCRIPTION =====
function sProcess = GetDescription() %#ok<DEFNU>
    % Description the process
    sProcess.Comment     = 'Group by name';
    sProcess.Category    = 'Custom';
    sProcess.SubGroup    = 'Events';
    sProcess.Index       = 51;
    sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/EventMarkers#Other_menus';
    % Definition of the input accepted by this process
    sProcess.InputTypes  = {'data', 'raw', 'matrix'};
    sProcess.OutputTypes = {'data', 'raw', 'matrix'};
    sProcess.nInputs     = 1;
    sProcess.nMinFiles   = 1;
    % Event name
    sProcess.options.combine.Comment = ['Example: We have three events (A,B,C) and want to create new combinations:
' ...
                                        '    E: Event A and B occurring at the same time
' ...
                                        '    F: Event A and C occurring at the same time
' ...
                                        'For that, use the following classification:
' ...
                                        '    E = A,B
' ...
                                        '    F = A,C
' ...
                                        'You may add as many combinations as needed, one per line.
' ...
                                        'You can rename events with the following syntax: E=A.
' ...
                                        'You can delete or keep the original events (A,B,C) with the checkbox below.

'];
    sProcess.options.combine.Type    = 'textarea';
    sProcess.options.combine.Value   = '';
    % Maximum duration between simulateous events
    sProcess.options.dt.Comment = 'Maximum delay between simultaneous events: ';
    sProcess.options.dt.Type    = 'value';
    sProcess.options.dt.Value   = {0, 'ms', 0};
    % Maximum duration between simulateous events
    sProcess.options.order.Comment = {'First', 'Last', 'Event to select (if not strictly aligned): '; ...
                                     'first', 'last', ''};
    sProcess.options.order.Type    = 'radio_linelabel';
    sProcess.options.order.Value   = 'first';
    % Delete original events
    sProcess.options.delete.Comment = 'Delete the original events';
    sProcess.options.delete.Type    = 'checkbox';
    sProcess.options.delete.Value   = 0;
end

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

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

    % ===== GET OPTIONS =====
    % Get the options
    isDelete = sProcess.options.delete.Value;
    Order = sProcess.options.order.Value;
    dt = sProcess.options.dt.Value{1};
    % Combination string
    combineStr = strtrim(sProcess.options.combine.Value);
    % Split in lines
    combine_lines = str_split(combineStr, [10 13]);
    % Split each line
    combineCell = {};
    for i = 1:length(combine_lines)
        % No information on this line: skip
        combine_lines{i} = strtrim(combine_lines{i});
        if isempty(combine_lines{i})
            continue;
        end
        % Split with "="
        lineCell = str_split(combine_lines{i}, '=');
        if (length(lineCell) ~= 2)
            continue;
        end
        % Split with ";,"
        eventsCell = str_split(lineCell{2}, ';,');
        % Add combination entry
        iComb = size(combineCell,1) + 1;
        combineCell{iComb,1} = strtrim(lineCell{1});
        combineCell{iComb,2} = cellfun(@strtrim, eventsCell, 'UniformOutput', 0);
    end
    % If no combination available
    if isempty(combineCell)
        bst_report('Error', sProcess, [], 'Invalid combinations format.');
        return;
    end

    % ===== PROCESS ALL FILES =====
    % For each file
    for iFile = 1:length(sInputs)
        % ===== GET FILE DESCRIPTOR =====
        % Load the raw file descriptor
        isRaw = strcmpi(sInputs(iFile).FileType, 'raw');
        if isRaw
            DataMat = in_bst_data(sInputs(iFile).FileName, 'F');
            sEvents = DataMat.F.events;
            sFreq = DataMat.F.prop.sfreq;
        else
            DataMat = in_bst_data(sInputs(iFile).FileName, 'Events', 'Time');
            sEvents = DataMat.Events;
            sFreq = 1 ./ (DataMat.Time(2) - DataMat.Time(1));
        end
        % If no markers are present in this file
        if isempty(sEvents)
            bst_report('Error', sProcess, sInputs(iFile), 'This file does not contain any event. Skipping File...');
            continue;
        end
        % Convert the distance in time to distance in samples
        ds = round(dt .* sFreq);
        % Call the grouping function
        [sEvents, isModified] = Compute(sInputs(iFile), sEvents, combineCell, ds, isDelete, sFreq, Order);

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

%% ===== GROUP EVENTS =====
function [eventsNew, isModified] = Compute(sInput, events, combineCell, ds, isDelete, sfreq, Order)
    % Parse inputs
    if (nargin < 7) || isempty(Order)
        Order = 'first';
    end
    % No modification
    isModified = 0;
    eventsNew = events;
    removeEvt = zeros(0,2);
    % Loop on the different combinations
    for iComb = 1:size(combineCell,1)
        AllEvt = zeros(2,0);
        iEvtList = [];
        isSkip = 0;
        % Use the output of the previous combination as the input to this combination
        events = eventsNew;
        % Remove duplicated events
        evtList = unique(combineCell{iComb,2});
        % Get events for this combination
        for iCombEvt = 1:length(evtList)
            % Find event in the list
            evtLabel = evtList{iCombEvt};
            iEvt = find(strcmpi({events.label}, evtLabel));
            % If events doesn't exist: skip
            if isempty(iEvt)
                bst_report('Warning', 'process_evt_groupname', sInput, ['Event "' evtLabel '" does not exist. Skipping group...']);
                isSkip = 1;
                break;
            end
            % If renaming event: simply update the label and move on
            if (length(combineCell{iComb,2}) == 1)
                eventsNew(iEvt).label = combineCell{iComb,1};
                isSkip = 1;
                isModified = 1;
                break;
            end
            % If events are extended events: skip
            if (size(events(iEvt).times,1) > 1)
                bst_report('Error', 'process_evt_groupname', sInput, 'Cannot process extended events. Skipping group...');
                isSkip = 1;
                break;
            end
            % Add to the list of all the processes
            iEvtList(end+1) = iEvt;
            AllEvt = [AllEvt, [round(events(iEvt).times .* sfreq); repmat(iEvt, size(events(iEvt).times))]];
        end
        % Skip combination if one of the events is not found or not a simple event
        if isSkip
            continue;
        end

        % Fix the events times according to the maximum allowed distance between events
        if (ds > 0)
            N = size(AllEvt,2);
            % Calculate distance between all the pairs of events:
            % [alldist(i,j)=5] means that event #i is 5 samples before event #j
            alldist = repmat(AllEvt(1,:),N,1) - repmat(AllEvt(1,:)',1,N);
            % Get the distances for the different event types only: we don't want to collapse two events of the same category
            if (length(iEvtList) > 1)
                diffmask = (repmat(AllEvt(2,:),N,1) ~= repmat(AllEvt(2,:)',1,N));
            % Unless there is only one event in input
            else
                diffmask = (eye(N) == 0);
            end
            % Find the events that can be collapsed
            collapse = ((alldist > 0) & (alldist <= ds)) .* diffmask;
            collapse(:,sum(collapse,1) > 1) = 0;
            collapse(sum(collapse,2) > 1,:) = 0;
            [iBefore, iAfter] = find(collapse);
            % Remove cycles
            iCycles = find(ismember(iBefore, iAfter));
            iBefore(iCycles) = [];
            iAfter(iCycles) = [];
            % Replace the time of the last events with the time of the first event
            if ~isempty(iBefore)
                for iEvt = 1:length(iAfter)
                    smpBefore = round(events(AllEvt(2,iBefore(iEvt))).times .* sfreq);
                    smpAfter = round(events(AllEvt(2,iAfter(iEvt))).times .* sfreq);
                    iOccBefore = find(smpBefore == AllEvt(1,iBefore(iEvt)));
                    iOccAfter  = find(smpAfter == AllEvt(1,iAfter(iEvt)));
                    switch (Order)
                        case 'first'
                            events(AllEvt(2,iAfter(iEvt))).times(iOccAfter) = events(AllEvt(2,iBefore(iEvt))).times(iOccBefore);
                        case 'last'
                            events(AllEvt(2,iAfter(iEvt))).times(iOccBefore) = events(AllEvt(2,iBefore(iEvt))).times(iOccAfter);
                    end
                end
                switch (Order)
                    case 'first'
                        AllEvt(1,iAfter) = AllEvt(1,iBefore);
                    case 'last'
                        AllEvt(1,iBefore) = AllEvt(1,iAfter);
                end
            end
        end

        % Process each unique time value
        uniqueSamples = unique(AllEvt(1,:));
        for iSmp = 1:length(uniqueSamples)
            % Look for all the events happening at this time
            iEvts = AllEvt(2, (AllEvt(1,:) == uniqueSamples(iSmp)));
            % If only one occurrence: skip to the next time
            if (length(iEvtList) > 1) && (length(iEvts) < length(iEvtList))   % Two different events
                continue;
            elseif (length(iEvtList) == 1) && (length(iEvts) < 2)    % One event with itself
                continue;
            end
            % Remove occurrence from each event type (and build new event name)
            for i = 1:length(iEvts)
                % Find the occurrence indice
                iOcc = find(round(events(iEvts(i)).times .* sfreq) == uniqueSamples(iSmp));
                % Get the values
                if (i == 1)
                    newTime     = events(iEvts(i)).times(iOcc);
                    newEpoch    = events(iEvts(i)).epochs(iOcc);
                    if ~isempty(events(iEvts(i)).channels)
                        newChannels = events(iEvts(i)).channels(iOcc);
                    else
                        newChannels = [];
                    end
                    if ~isempty(events(iEvts(i)).notes)
                        newNotes = events(iEvts(i)).notes(iOcc);
                    else
                        newNotes = [];
                    end
                end
                % Remove this occurrence
                if isDelete
                    removeEvt = [removeEvt; repmat(iEvts(i),length(iOcc),1), reshape(iOcc,[],1)];
                end
            end
            % New event name
            newLabel = combineCell{iComb,1};
            % Find this event in the list
            iNewEvt = find(strcmpi(newLabel, {eventsNew.label}));
            % Create event category if does not exist yet
            if isempty(iNewEvt)
                % Initialize new event
                iNewEvt = length(eventsNew) + 1;
                sEvent = db_template('event');
                sEvent.label = newLabel;
                % Re-use color of renamed event
                if (length(iEvtList) == 1) && isDelete
                    sEvent.color = events(iEvtList(1)).color;
                % Create a new color
                else
                    sEvent.color = panel_record('GetNewEventColor', iNewEvt, eventsNew);
                end
                % Add new event to list
                eventsNew(iNewEvt) = sEvent;
            end
            % Add occurrences
            eventsNew(iNewEvt).times    = [eventsNew(iNewEvt).times,    newTime];
            eventsNew(iNewEvt).epochs   = [eventsNew(iNewEvt).epochs,   newEpoch];
            % Sort
            [eventsNew(iNewEvt).times, indSort] = unique(eventsNew(iNewEvt).times);
            eventsNew(iNewEvt).epochs   = eventsNew(iNewEvt).epochs(indSort);
            % Channels
            if ~isempty(newChannels)
                if isempty(eventsNew(iNewEvt).channels)
                    eventsNew(iNewEvt).channels = cell(1, size(eventsNew(iNewEvt).times,2) - size(newTime,2));
                end
                eventsNew(iNewEvt).channels = [eventsNew(iNewEvt).channels, newChannels];
                eventsNew(iNewEvt).channels = eventsNew(iNewEvt).channels(indSort);
            end
            % Notes
            if ~isempty(newNotes)
                if isempty(eventsNew(iNewEvt).notes)
                    eventsNew(iNewEvt).notes = cell(1, size(eventsNew(iNewEvt).times,2) - size(newTime,2));
                end
                eventsNew(iNewEvt).notes = [eventsNew(iNewEvt).notes, newNotes];
                eventsNew(iNewEvt).notes = eventsNew(iNewEvt).notes(indSort);
            end
            isModified = 1;
        end
    end
    % Remove events that were tagged
    if ~isempty(removeEvt)
        uniqueEvt = unique(removeEvt(:,1));
        for i = 1:length(uniqueEvt)
            iEvt = uniqueEvt(i);
            iOcc = removeEvt(removeEvt(:,1)==iEvt,2)';
            eventsNew(iEvt).times(iOcc)    = [];
            eventsNew(iEvt).epochs(iOcc)   = [];
            if ~isempty(eventsNew(iEvt).channels)
                eventsNew(iEvt).channels(iOcc) = [];
            end
            if ~isempty(eventsNew(iEvt).notes)
                eventsNew(iEvt).notes(iOcc) = [];
            end
        end
        % Remove empty categories
        iEmptyEvt = find(cellfun(@isempty, {eventsNew.times}));
        if ~isempty(iEmptyEvt)
            eventsNew(iEmptyEvt) = [];
        end
    end
end


function handles = updateStandardSpaceValue(handles, acpcCoord)
% Get the standard space popup string and set the position appropriately.
% This code needs better comments.  I did a little below, but ...
%
% Pulled out of dtiFiberUI
%
% Brian (c) VISTASOFT Team, 2012.

% The acpc coordinate was either passed in, or we get it from the position
if(~exist('acpcCoord','var'))
    acpcCoord = str2num(get(handles.editPosition, 'String'));
end

% Determine the standard space.
ssVals = get(handles.popupStandardSpace,'String');
curSs  = ssVals{get(handles.popupStandardSpace,'Value')};
curPosSs = '';
if(strcmpi(curSs,'Image'))
    % What the heck is this?
    % OK, so Bob made handles.bg a structure.  One of the fields is .mat,
    % which contains a matrix.  This matrix apparently transforms data from
    % somewhere to somewhere else.  This code, which was worse before,
    % inverts the .mat matrix from the currently selected bg.
    %
    % This should Probably be something like
    %   acpc2img = dtiGet(handles,'acpc2img')
    %   curPosSs = mrAnatomXformCoords(acpc2img);
    T = inv(handles.bg(get(handles.popupBackground,'Value')).mat);
    curPosSs = mrAnatXformCoords(T, acpcCoord);
elseif(strcmpi(curSs,'Talairach'))
    % Talairach version instead of general transform as above.
    curPosSs = mrAnatAcpc2Tal(handles.talairachScale, acpcCoord);
else
    % Check for other standard spaces
    if(isfield(handles,'t1NormParams')&&~isempty(handles.t1NormParams))
        normSs = strmatch(curSs,{handles.t1NormParams(:).name});
        if(~isempty(normSs))
            if(~isfield(handles.t1NormParams(normSs),'coordLUT') || isempty(handles.t1NormParams(normSs).coordLUT))

                lutFile = dtiGetFilenameInDT6(handles.dataFile,'lutMNI');
                if(exist(lutFile,'file') && ~isempty(lutFile))
                    disp(['Loading inverse deformation from ' lutFile '...']);
                    ni = niftiRead(lutFile);
                    handles.t1NormParams(normSs).coordLUT = squeeze(ni.data(:,:,:,1,:));
                    handles.t1NormParams(normSs).inMat = ni.qto_ijk;
                    clear ni;
                else
                    lutFile = fullfile(handles.dataDir,[curSs, '_coordLUT.nii.gz']);
                    disp('Computing inverse deformation...');
                    set(handles.editPositionTal, 'String', 'computing...');pause(0.1);
                    [defX, defY, defZ] = mrAnatInvertSn(handles.t1NormParams(normSs).sn);
                    if(max(abs(defX(:)))<127.5 && max(abs(defY(:)))<127.5 && max(abs(defZ(:)))<127.5)
                        defX(isnan(defX)) = -127; defY(isnan(defY)) = -127; defZ(isnan(defZ)) = -127;
                        handles.t1NormParams(normSs).coordLUT = int8(round(cat(4,defX,defY,defZ)));
                    else
                        defX(isnan(defX)) = -999; defY(isnan(defY)) = -999; defZ(isnan(defZ)) = -999;
                        handles.t1NormParams(normSs).coordLUT = int16(round(cat(4,defX,defY,defZ)));
                    end
                    handles.t1NormParams(normSs).inMat = inv(handles.t1NormParams(normSs).sn.VF.mat);
                    % NIFTI_INTENT_DISPVECT=1006
                    intentCode = 1006;
                    intentName = ['To' curSs];
                    % NIFTI format requires that the 4th dim is always
                    % time, so we put the deformation vector [x,y,z] in the
                    % 5th dimension.
                    tmp = reshape(handles.t1NormParams(normSs).coordLUT,[size(defX) 1 3]);
                    try
                        dtiWriteNiftiWrapper(tmp,inv(handles.t1NormParams(normSs).inMat),lutFile,1,'',intentName,intentCode);
                        dtiSetFilenameInDT6(handles.dataFile,'lutMNI',lutFile);
                    catch
                        disp('Could not save LUT transform- check permissions.');
                    end
                end
            end
            curPosSs = mrAnatXformCoords(handles.t1NormParams(normSs), acpcCoord);
        end
    end
    % Try an MNI label map
    if(isempty(curPosSs))
        % strmatch will be deprecated.  Figure out what this does and
        % replace it with strcmp
        mniSs = strmatch('MNI',{handles.t1NormParams(:).name});
        curPosSs = dtiGetBrainLabel(mrAnatXformCoords(handles.t1NormParams(mniSs), acpcCoord), curSs);
    end
end
if(isnumeric(curPosSs)), curPosSs = sprintf('%.0f, %.0f, %.0f', round(curPosSs)); end
set(handles.editPositionTal, 'String', curPosSs);

return


function [ names, sizes ] = cvx_dispvar( v, name, isdual )
[ names, sizes ] = dispvar_( v, name, isdual );
if nargout <= 1 && ~isempty( names ),
    mlen = max( cellfun( @numel, names ) ) + 3;
    spc = ' '; spc(1,2:mlen+3) = ' ';
    names = cellfun( @(x)[x,spc(1:mlen-numel(x))], names, 'UniformOutput', false );
    names = strcat( names, sizes );
end
if nargout == 0,
    names = sprintf( '   %s\n', names{:} );
    fprintf( 1, '\n%s\n', names );
    clear names
end

function [ names, sizes ] = dispvar_( v, name, isdual )
names = {};
sizes = {};
switch class( v ),
    case 'struct',
        if numel( v ) > 1,
            sv = size( v );
            sstr = struct( 'type', '()', 'subs', {cell(1,length(sv))} );
            isvec = all(sv(2:end)==1);
            for k = 1 : prod(sv),
                [ sstr.subs{:} ] = ind2sub( sv, k );
                if isvec,
                    label = sprintf( '%s(%d)', name, k );
                else
                    label = sprintf( ',%d', sstr.subs{:} );
                    label = sprintf( '%s(%s)', name, label(2:end) );
                end
                [ name2, size2 ] = dispvar_( v(k), sstr, label, isdual );
                names = [ names, name2 ]; %#ok
                sizes = [ sizes, size2 ]; %#ok
                if k == 1, name(:) = ' '; end
            end
        else
            fn = fieldnames( v );
            if ~isempty( name ), name( end + 1 ) = '.'; end
            names = {}; sizes = {};
            for k = 1 : length( fn ),
                [ name2, size2 ] = dispvar_( v.(fn{k}), [ name, fn{k} ], isdual );
                names = [ names, name2 ]; %#ok
                sizes = [ sizes, size2 ]; %#ok
                if k == 1, name(1:end-1) = ' '; end
            end
        end
    case 'cell',
        sv = size( v );
        sstr = cell( 1, length(sv) );
        isvec = all(sv(2:end)==1);
        for k = 1 : prod(sv),
            [ sstr{:} ] = ind2sub( sv, k );
            if isvec,
                label = sprintf( '%s{%d}', name, k );
            else
                label = sprintf( ',%d', sstr{:} );
                label = sprintf( '%s{%s}', name, label(2:end) );
            end
            [ name2, size2 ] = dispvar_( v{k}, label, isdual );
            names = [ names, name2 ]; %#ok
            sizes = [ sizes, size2 ]; %#ok
            if k == 1, name( 1 : end ) = ' '; end
        end
    case 'cvx';
        names{1} = name;
        sizes{1} = type(v);
    case 'double',
        names{1} = name;
        if isdual,
            sizes{1} = 'unassigned';
        else
            sizes{1} = [ type(cvx(v)), ' constant' ];
        end
    otherwise,
        names{1} = name;
        sizes{1} = 'unknown';
end


function varargout = quiver3(varargin)
%QUIVER3  3-D quiver plot of a SPHEREFUNV at data mapped by a SPHEREFUN.
%
%   This is not allowed and returns an error.  This function exists so that
%   the error message is meaningful to a SPHEREFUN user.
%
% See also SPHEREFUNV/QUIVER3.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

error('CHEBFUN:SPHEREFUN:QUIVER3:notSupported',...
        'quiver3 is not yet supported for SPHEREFUN.');

end


classdef CumPwrStorageStateOfChargeConstraint < AbstractConstraint
    %CumPwrStorageStateOfChargeConstraint Summary of this class goes here
    %   Detailed explanation goes here

    properties
        normFact = 1;
        event LaunchVehicleEvent
        eventNode(1,1) ConstraintStateComparisonNodeEnum = ConstraintStateComparisonNodeEnum.FinalState;

        lb(1,1) double = 0;
        ub(1,1) double = 0;

        evalType(1,1) ConstraintEvalTypeEnum = ConstraintEvalTypeEnum.FixedBounds;
        stateCompType(1,1) ConstraintStateComparisonTypeEnum = ConstraintStateComparisonTypeEnum.Equals;
        stateCompEvent LaunchVehicleEvent
        stateCompNode(1,1) ConstraintStateComparisonNodeEnum = ConstraintStateComparisonNodeEnum.FinalState;
    end

    methods
        function obj = CumPwrStorageStateOfChargeConstraint(event, lb, ub)
            obj.event = event;
            obj.lb = lb;
            obj.ub = ub;

             obj.id = rand();
        end

        function [lb, ub] = getBounds(obj)
            lb = obj.lb;
            ub = obj.ub;
        end

        function [c, ceq, value, lwrBnd, uprBnd, type, eventNum, valueStateComp] = evalConstraint(obj, stateLog, ~)
            type = obj.getConstraintType();

            switch obj.eventNode
                case ConstraintStateComparisonNodeEnum.FinalState
                    stateLogEntry = stateLog.getLastStateLogForEvent(obj.event);

                case ConstraintStateComparisonNodeEnum.InitialState
                    stateLogEntry = stateLog.getFirstStateLogForEvent(obj.event);

                otherwise
                    error('Unknown event node.');
            end

            [value, ~] = lvd_ElectricalPowerGlobalTasks(stateLogEntry, 'cumStorageSoC');

            if(obj.evalType == ConstraintEvalTypeEnum.StateComparison)
                switch obj.stateCompNode
                    case ConstraintStateComparisonNodeEnum.FinalState
                        stateLogEntryStateComp = stateLog.getLastStateLogForEvent(obj.stateCompEvent);

                    case ConstraintStateComparisonNodeEnum.InitialState
                        stateLogEntryStateComp = stateLog.getFirstStateLogForEvent(obj.stateCompEvent);

                    otherwise
                        error('Unknown event node.');
                end

                [valueStateComp, ~] = lvd_ElectricalPowerGlobalTasks(stateLogEntryStateComp, 'cumStorageSoC');
            else
                valueStateComp = NaN;
            end

            [c, ceq] = obj.computeCAndCeqValues(value, valueStateComp);

            lwrBnd = obj.lb;
            uprBnd = obj.ub;

            eventNum = obj.event.getEventNum();
        end

        function sF = getScaleFactor(obj)
            sF = obj.normFact;
        end

        function setScaleFactor(obj, sF)
            obj.normFact = sF;
        end

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

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

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

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

        function tf = usesEvent(obj, event)
            tf = obj.event == event;
            if(obj.evalType == ConstraintEvalTypeEnum.StateComparison)
                tf = tf || obj.stateCompEvent == event;
            end
        end

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

        function event = getConstraintEvent(obj)
            event = obj.event;
        end

        function type = getConstraintType(obj)
            type = 'Electrical Power Cumulative Storage State of Charge';
        end

        function [unit, lbLim, ubLim, usesLbUb, usesCelBody, usesRefSc] = getConstraintStaticDetails(obj)
            unit = 'EC';
            lbLim = 0;
            ubLim = Inf;
            usesLbUb = true;
            usesCelBody = false;
            usesRefSc = false;
        end

        function addConstraintTf = openEditConstraintUI(obj, lvdData)
%             addConstraintTf = lvd_EditGenericMAConstraintGUI(obj, lvdData);

            output = AppDesignerGUIOutput({false});
            lvd_EditGenericMAConstraintGUI_App(obj, lvdData, output);
            addConstraintTf = output.output{1};
        end

        function tf = canUseSparseOutput(obj)
            tf = true;
        end
    end

    methods(Static)
        function constraint = getDefaultConstraint(~, ~)
            constraint = CumPwrStorageStateOfChargeConstraint(LaunchVehicleEvent.empty(1,0),0,0);
        end
    end
end


function [refBody, scName] = orbitPanelGetOrbitFromSFSContextCallBack(mainGUIHandle, hSMA, hECC, hINC, hRAAN, hARG, varargin)
%orbitPanelGetOrbitFromSFSContextCallBack Summary of this function goes here
%   Detailed explanation goes here
    if(not(isempty(mainGUIHandle)))
        mainUserData = get(mainGUIHandle,'UserData');
        prevPathName = mainUserData{3,1};
    else
        mainUserData = [];
        prevPathName = [];
    end

    refBody = [];
%     [orbit,PathName,scName] = importOrbitGUI(1, prevPathName);

    output = AppDesignerGUIOutput({[],[],''});
    importOrbitGUI_App(1, prevPathName, output);
    orbit = output.output{1};
    PathName = output.output{3};
    scName = output.output{3};

    if(not(isempty(orbit)))
        if(not(isempty(hSMA)))
            set(hSMA, 'String', fullAccNum2Str(orbit{3}));
        end

        if(not(isempty(hECC)))
            set(hECC, 'String', fullAccNum2Str(orbit{4}));
        end

        if(not(isempty(hINC)))
            set(hINC, 'String', fullAccNum2Str(orbit{5}));
        end

        if(not(isempty(hRAAN)))
            set(hRAAN, 'String', fullAccNum2Str(orbit{6}));
        end

        if(not(isempty(hARG)))
            set(hARG, 'String', fullAccNum2Str(orbit{7}));
        end

        refBody = orbit{10};

        if(nargin == 8)
            hMA = varargin{1};
            hEpoch = varargin{2};
            set(hMA, 'String', fullAccNum2Str(orbit{8}));
            set(hEpoch, 'String', fullAccNum2Str(orbit{9}));
        end

        if(not(isempty(mainUserData)))
            mainUserData{3,1} = PathName;
            set(mainGUIHandle,'UserData',mainUserData);
        end
    end
end


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

% Copyright 2002-2003 The MathWorks, Inc.

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

% Last Modified by GUIDE v2.5 06-Dec-2007 10:09:18

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

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

% Update handles structure
guidata(hObject, handles);

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

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

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

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

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

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

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

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

% --- Executes on key press over pushbutton1 with no controls selected.
function pushbutton1_KeyPressFcn(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

run final_riccati

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


function [rev,file] = headRev(folders,strs,rec)
%HEADREV Retrieve the head revision for specified files
%
%   This function finds the most recently committed file in the specified
%   folders(s) and returns its revision and filename. The files must
%   contain the 'Revision' and 'Date' keywords.
%
%   REV = IOSR.SVN.HEADREV(FOLDERS) returns the head revision (i.e. the
%   highest revision) for all files in FOLDERS.
%
%   REV = IOSR.SVN.HEADREV(FOLDERS,STRS) allows additional filter strings
%   STRS to be specified. See GETCONTENTS for details of permitted filter
%   strings.
%
%   REV = IOSR.SVN.HEADREV(FOLDERS,STRS,REC), with REC = true, allows
%   folders to be searched recursively (default is false).
%
%   [REV,FILE] = IOSR.SVN.HEADREV(...) returns the filename to FILE of the
%   file with the highest revision.
%
%   FOLDERS and STRS may be a string specifying a single occurrence, or a
%   cell array of strings specifying multiple occurrences. This function
%   requires that the 'Revision' keyword is used in the searched functions.
%
%   Note that if the folders include files from an externally-defined
%   repository (which has been updated more recently than the native
%   repository), a misleading revision number may be presented.
%
%   See also IOSR.GENERAL.GETCONTENTS, IOSR.SVN.BUILDSVNPROFILE,
%            IOSR.SVN.READSVNKEYWORD.

%   Copyright 2016 University of Surrey.

    keyword = 'Date'; % use this data to sort files (doubtful that any others would work, without considerable parsing)

    if ischar(folders)
        folders = cellstr(folders);
    end

    if nargin > 1
        if ischar(strs)
            strs = cellstr(strs);
        end
        if isempty(strs)
            strs = {'files'};
        end
    else
        strs = {'files'};
    end

    % add subfolders if recursion is requested
    if nargin > 2
        if rec
            for f = folders
                folders = [folders; iosr.general.getContents(char(f),'filter','folders','rec',true,'path','full')]; %#ok<AGROW>
            end
        end
    end

    % get revision info for files
    svn_profile = iosr.svn.buildSvnProfile(folders,keyword,strs);

    % remove the keyword and convert revision strings to numbers
    svn_profile(:,2) = cellfun(@(x) (x(length(keyword)+3:end)),svn_profile(:,2),'uni',false);

    % remove NaN (files that don't have the revision keyword)
    IX1 = cellfun(@isempty,svn_profile(:,2));
    svn_profile = svn_profile(~IX1,:);

    % sort by revision number
    [~,IX2] = sort(svn_profile(:,2));
    svn_profile = svn_profile(IX2,:);

    % get highest revision number
    rev = iosr.svn.readSvnKeyword(svn_profile{end,1},'Revision');

    % return corresponding filename, if requested
    if nargout>1
        file = svn_profile{end,1};
    end

end


function out_spm_gii( GiiTessFile, GiiDataFile, Data )
% OUT_TESS_GII: Exports a source map to a set of SPM/GIfTI .gii/.dat file.
%
% USAGE:  out_spm_gii( GiiTessFile, GiiDataFile, Data )
%
% INPUT:
%    - GiiTessFile : Brainstorm tesselation matrix
%    - GiiDataFile : full path to output file

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

% Get file paths
[giiPath, giiBase, giiExt] = bst_fileparts(GiiTessFile);
[outPath, outBase, outExt] = bst_fileparts(GiiDataFile);
% If the two files are in the same folder: do not use the path for the .gii surface
if strcmp(giiPath, outPath)
    GiiTessFile = [giiBase, giiExt];
end
% .dat filename, to save the actual data
DatFileShort = [outBase, '.dat'];
DatFile = bst_fullfile(outPath, DatFileShort);

% ===== CREATE XML STRING =====
% Create XML file from a template
strXml = [...
    '<?xml version="1.0" encoding="UTF-8"?>' 13 10 ...
    '<!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/115/gifti.dtd">' 13 10 ...
    '<GIFTI Version="1.0"  NumberOfDataArrays="1">' 13 10 ...
    '   <MetaData>' 13 10 ...
    '      <MD>' 13 10 ...
    '         <Name><![CDATA[SurfaceID]]></Name>' 13 10 ...
    '         <Value><![CDATA[' GiiTessFile ']]></Value>' 13 10 ...
    '      </MD>' 13 10 ...
    '   </MetaData>' 13 10 ...
    '   <LabelTable/>' 13 10 ...
    '   <DataArray  ArrayIndexingOrder="ColumnMajorOrder"' 13 10 ...
    '               DataType="NIFTI_TYPE_FLOAT32"' 13 10 ...
    '               Dim0="' num2str(size(Data,1)) '"' 13 10 ...
    '               Dim1="1"' 13 10 ...
    '               Dimensionality="2"' 13 10 ...
    '               Encoding="ExternalFileBinary"' 13 10 ...
    '               Endian="LittleEndian"' 13 10 ...
    '               ExternalFileName="' DatFileShort '"' 13 10 ...
    '               ExternalFileOffset="0"' 13 10 ...
    '               Intent="NIFTI_INTENT_NONE">' 13 10 ...
    '      <MetaData>' 13 10 ...
    '      </MetaData>' 13 10 ...
    '      <Data></Data>' 13 10 ...
    '   </DataArray>' 13 10 ...
    '</GIFTI>' 13 10];

% ===== SAVE XML FILE =====
% Open file for binary writing
[fid, message] = fopen(GiiDataFile, 'wb');
if (fid < 0)
    error(['Could not create file : ' message]);
end
% Write XML contents
fwrite(fid, strXml, 'char');
% Close file
fclose(fid);

% ===== SAVE DAT FILE =====
% Open file for binary writing
fid = fopen(DatFile,'w');
if (fid < 0)
    error(['Could not create file : ' message]);
end
% Write data vector
fwrite(fid, Data, 'float32');
% Close file
fclose(fid);

end


function [DAT newFileName] = PTimport(csvFname, BBLFileName)
%% [DAT newFileName] = PTimport(filename, BBLFileName)
%  Imports log data in multiple formats (fw=selected firmware/logfile type). Default is .csv, but if using .bbl or .bfl files,

% ----------------------------------------------------------------------------------
% "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
% ----------------------------------------------------------------------------------

newFileName=csvFname;
try % speed things up a bit with this method
    hdr=detectImportOptions(csvFname);
    T=readtable(csvFname, 'HeaderLines', 2);
    T.Properties.VariableNames=hdr.VariableNames;
catch
    T=readtable(csvFname);
end

delete(csvFname);% we r done with this-dont wanna leave junk on main directory

% get header info from .bbl/.bfl file directly
a=strfind(BBLFileName,'.');
fid = fopen(BBLFileName, 'r');
c = textscan(fid, '%s', 'Delimiter','\n','CollectOutput',1); %c2 = native2unicode(c)
fclose(fid);

logStartPoints=[];
logEndPoints=[];

a=strfind(c{1},'Firmware version');
if isempty(find(cellfun(@(a)~isempty(a)&&a>0,a)))
    a=strfind(c{1},'Firmware revision');
    logStartPoints=find(cellfun(@(a)~isempty(a)&&a>0,a));
else
    a=strfind(c{1},'Firmware version');
    logStartPoints=find(cellfun(@(a)~isempty(a)&&a>0,a));
end

endStr={'throttle_boost_cutoff'; 'debug_mode' ; 'motor_pwm_rate' ; 'use_unsynced_pwm' ; 'gyro_32khz_hardware_lpf' ; 'gyro_hardware_lpf' ; 'yaw_deadband' ; 'deadband' ; 'pidsum_limit_yaw' ; 'pidsum_limit' ; 'energyCumulative (mAh)'; 'looptime'};% strings not in all revisions, try a few
m=1; a=strfind(c{1},endStr{m});
while isempty(find(cellfun(@(a)~isempty(a)&&a>0,a)))
    a=strfind(c{1},endStr{m});
    m=m+1;
end
logEndPoints = find(cellfun(@(a)~isempty(a)&&a>0,a));

relevantLogNum=str2num(csvFname(end-5:end-4));
s=c{1}(logStartPoints(relevantLogNum):logEndPoints(relevantLogNum));
n=1;
for m=1:size(s,1)
    if size(strsplit(char(s(m)),':'),2)==2
        SetupInfo(n,:)=(strsplit(char(s(m)),':'));
        a=char(SetupInfo(n,1));
        if strcmp(a(1:2),'H ')
            SetupInfo(n,1)={a(3:end)};
        end
        n=n+1;
    end
end

%
DAT.T=T;
DAT.mainFname=BBLFileName;
DAT.csvFname=csvFname;
DAT.SetupInfo=SetupInfo;
try
DAT.blackbox_decode_results=result;
catch
end

end


function name = p09_name ( )

%*****************************************************************************80
%
%% P09_NAME returns the name of problem 09.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string NAME, the name of the problem.
%
  name = 'Patterson #7';

  return
end


function varargout = maindalta(varargin)

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

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

% Update handles structure
guidata(hObject, handles);

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

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

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

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
global a;
handles.text7.String = 'Frame t';
handles.text6.String = 'Threshold c';
handles.text2.String = 'image f';
set(handles.edit1,'string',num2str(get(hObject,'value')));

dalta = get(handles.slider1,'Value');

[I,blur,et,newEt] = generalclean(dalta);
imshow(blur,'Parent',handles.axes1)
imshow(mat2gray(newEt),'Parent',handles.axes2)
imshow((I),'Parent',handles.axes3)

ts = get(handles.slider3,'Value');
[It,et] = reconstructAvideo(dalta,ts);
%
imshow((It),'Parent',handles.axes4)
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)

if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function edit1_Callback(hObject, eventdata, handles)

global a;
handles.text7.String = 'Frame t';
handles.text6.String = 'Threshold c';
handles.text2.String = 'image f';
set(handles.slider1,'value',str2double(get(hObject,'string')));
sliderValue = get(handles.edit1,'String');
ang = str2double(sliderValue);
set(handles.slider1,'Value',ang);

dalta = get(handles.slider1,'Value');

[I,blur,et,newEt] = generalclean(dalta);
imshow(blur,'Parent',handles.axes1)
imshow(mat2gray(newEt),'Parent',handles.axes2)
imshow((I),'Parent',handles.axes3)

ts = get(handles.slider3,'Value');
[It,et] = reconstructAvideo(dalta,ts);
%
imshow((It),'Parent',handles.axes4)
guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
%
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on slider movement.
function slider3_Callback(hObject, eventdata, handles)
global b;
handles.text7.String = 'Frame t';
handles.text6.String = 'Threshold c';
handles.text2.String = 'image f';
set(handles.edit2,'string',num2str(get(hObject,'value')));
dalta = get(handles.slider1,'Value');
ts = get(handles.slider3,'Value');
[It,Et] = reconstructAvideo(dalta,ts);%_old

imshow(mat2gray((Et)),'Parent',handles.axes2)
imshow(((It)),'Parent',handles.axes4)

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function edit2_Callback(hObject, eventdata, handles)
global b;
handles.text7.String = 'Frame t';
handles.text6.String = 'Threshold c';
handles.text2.String = 'image f';
set(handles.slider3,'value',str2double(get(hObject,'string')));
sliderValue = get(handles.edit2,'String');
ang = str2double(sliderValue);
set(handles.slider3,'Value',ang);

dalta = get(handles.slider1,'Value');
ts = get(handles.slider3,'Value');
[It,Et] = reconstructAvideo(dalta,ts);%_old

imshow(mat2gray((Et)),'Parent',handles.axes2)
imshow(((It)),'Parent',handles.axes4)

% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function [status] = isplottingfunction(function_name)

% ISPLOTTINGFUNCTION is a helper function for reproducescript, and
% is used for the cfg.reproducescript functionality. It compares the input
% function name with the list of known FieldTrip plotting functions and
% returns 1 if it is a plotting function, and 0 otherwise.

% determine FieldTrip path
[ftver, ftpath] = ft_version;

functionlist = [];
% browse the main FieldTrip directory
functionlist = cat(1, functionlist, dir(fullfile(ftpath, '*plot*.m')));
functionlist = cat(1, functionlist, dir(fullfile(ftpath, '*movie*.m')));
% browse the plotting directory
functionlist = cat(1, functionlist, dir(fullfile(ftpath, 'plotting', '*plot*.m')));
functionlist = cat(1, functionlist, dir(fullfile(ftpath, 'plotting', '*movie*.m')));

% concatenate all function names
functionlist = struct2cell(functionlist);
functionlist(2:end,:) = [];

% compare the function with the list of plotting functions
isinlist = strfind(functionlist, function_name);
status = any(cat(1,isinlist{:}));