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

% Last Modified by GUIDE v2.5 26-Aug-2013 12:59:22

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
        'gui_Singleton',  gui_Singleton, ...
        'gui_OpeningFcn', @eventlist2erpGUI_OpeningFcn, ...
        'gui_OutputFcn',  @eventlist2erpGUI_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

%--------------------------------------------------------------------------
function eventlist2erpGUI_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for eventlist2erpGUI
handles.output = hObject;
ERP = varargin{1};

if isfield(ERP, 'EVENTLIST')
        if ~isempty(ERP.EVENTLIST)
                nel = length(ERP.EVENTLIST);
        else
                title      = 'ERPLAB: eventlist2erpGUI()';
                question{1} = 'EVENTLIST structure is empty in this ERPset';
                question{2} = 'Do you want to continue anyway?';
                button = askquest(question, title);

                if ~strcmpi(button,'yes')
                        disp('User selected Cancel')
                        return
                end
                nel = 0;
        end
else
        title      = 'ERPLAB: eventlist2erpGUI()';
        question{1} = 'EVENTLIST structure was not found in this ERPset';
        question{2} = 'Do you want to continue anyway?';
        button = askquest(question, title);

        if ~strcmpi(button,'yes')
                disp('User selected Cancel')
                return
        end
        nel = 0;
end

handles.nel = nel;

if nel==0
        text_message1 = sprintf('This ERPset contains %g EVENTLIST', nel);
        text_message2 = '';
        set(handles.text_message1, 'String', text_message1)
        set(handles.radiobutton_make1, 'Enable', 'off')
        set(handles.radiobutton_replace, 'Enable', 'off')
        set(handles.edit_replace, 'Enable', 'off')
        set(handles.text_replace, 'Enable', 'off')
elseif nel==1
        text_message1 = sprintf('This ERPset contains %g EVENTLIST', nel);
        text_message2 = 'What would you like to do with the imported EVENTLIST?';
        set(handles.text_message1, 'String', text_message1)
        set(handles.radiobutton_replace, 'Enable', 'off')
        set(handles.edit_replace, 'Enable', 'off')
        set(handles.text_replace, 'Enable', 'off')
else
        text_message1 = sprintf('This ERPset contains %g EVENTLISTs (1-%g)', nel, nel);
        text_message2 = 'What would you like to do with the imported EVENTLIST?';
        set(handles.text_message1, 'String', text_message1)
end

set(handles.text_message2, 'String', text_message2)
text_message3 = sprintf('Append imported EVENTLIST as #%g', nel+1);
set(handles.radiobutton_append, 'String', text_message3)
set(handles.radiobutton_append, 'Value', 1)

%
% Name & version
%
version = geterplabversion;
set(handles.gui_chassis,'Name', ['ERPLAB ' version '   -   Import EVENTLIST from Text to ERP GUI'])

%
% Color GUI
%
handles = painterplab(handles);

%
% Set font size
%
handles = setfonterplab(handles);

% Update handles structure
guidata(hObject, handles);

% help
% helpbutton

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

%--------------------------------------------------------------------------
function varargout = eventlist2erpGUI_OutputFcn(hObject, eventdata, handles)

varargout{1} = handles.output;

% The figure can be deleted now
delete(handles.gui_chassis);
pause(0.5)

%--------------------------------------------------------------------------
function radiobutton_make1_Callback(hObject, eventdata, handles)

if get(hObject, 'Value')
        set(handles.radiobutton_replace, 'Value', 0)
        set(handles.radiobutton_append, 'Value', 0)
else
        set(handles.radiobutton_make1, 'Value', 1)
end

%--------------------------------------------------------------------------
function radiobutton_replace_Callback(hObject, eventdata, handles)

if get(hObject, 'Value')
        set(handles.radiobutton_make1, 'Value', 0)
        set(handles.radiobutton_append, 'Value', 0)
else
        set(handles.radiobutton_replace, 'Value', 1)
end

%--------------------------------------------------------------------------
function radiobutton_append_Callback(hObject, eventdata, handles)

if get(hObject, 'Value')
        set(handles.radiobutton_replace, 'Value', 0)
        set(handles.radiobutton_make1, 'Value', 0)
else
        set(handles.radiobutton_append, 'Value', 1)
end

%--------------------------------------------------------------------------
function pushbutton_cancel_Callback(hObject, eventdata, handles)

handles.output = [];

% Update handles structure
guidata(hObject, handles);
uiresume(handles.gui_chassis);

%--------------------------------------------------------------------------
function pushbutton_OK_Callback(hObject, eventdata, handles)

eventlistname = get(handles.edit_eventlistname, 'String');
nel = handles.nel;

if isempty(strtrim(eventlistname))
        msgboxText{1} =  'Error: You must choose an EVENTLIST text file.';
        title = 'ERPLAB: eventlist2erpGUI';
        errorfound(msgboxText, title);
        return
end

if get(handles.radiobutton_make1, 'Value')
        option = 0;
        index  = [];

elseif get(handles.radiobutton_replace, 'Value')

        option = 1;
        index = str2num(get(handles.edit_replace, 'String'));

        if isempty(index) || index<1 || index>nel
                msgboxText{1} =  'Error: invalid EVENTLIST index.';
                title = 'ERPLAB: eventlist2erpGUI';
                errorfound(msgboxText, title);
                return
        end

elseif get(handles.radiobutton_append, 'Value')
        option = 2;
        index  = [];

else
        return
end

outputarray = {eventlistname, option, index};
handles.output = outputarray;

% Update handles structure
guidata(hObject, handles);
uiresume(handles.gui_chassis);

%--------------------------------------------------------------------------
function edit_replace_Callback(hObject, eventdata, handles)

%--------------------------------------------------------------------------
function edit_replace_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
end

%--------------------------------------------------------------------------
function edit_eventlistname_Callback(hObject, eventdata, handles)

%--------------------------------------------------------------------------
function edit_eventlistname_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
        set(hObject,'BackgroundColor','white');
end

%--------------------------------------------------------------------------
function pushbutton_browse_Callback(hObject, eventdata, handles)

[bdfilename,bdfpathname] = uigetfile({'*.txt';'*.dat';'*.*'},'Select an EVENTLIST text file');

if isequal(bdfilename,0)
        disp('User selected Cancel')
        return
else
        set(handles.edit_eventlistname, 'String', fullfile(bdfpathname, bdfilename));

        % Update handles structure
        guidata(hObject, handles);

        flinkname = fullfile(bdfpathname, bdfilename);
        disp(['For EVENTLIST text file, user selected ' flinkname ''])
end

%--------------------------------------------------------------------------
function gui_chassis_CloseRequestFcn(hObject, eventdata, handles)

if isequal(get(handles.gui_chassis, 'waitstatus'), 'waiting')

        handles.output = [];
        %Update handles structure
        guidata(hObject, handles);
        uiresume(handles.gui_chassis);
else
        % The GUI is no longer waiting, just close it
        delete(handles.gui_chassis);
end


function [Flag,outputCommand]=dialog_setOutput_To_CommandLine()
% Dialog box used by the user to change the logical state of the output of
% robot's touch-pneumatic flange

% Copyright: Mohammad SAFEEA, 2018-July-20

global daHandleof_dialog_set_output_to_command_line;
global dialog_set_output_to_command_line_button_hit;
global dialog_set_output_to_command_line_flag;
global dialog_set_output_to_command_line_outputStateWrite;
global dialog_set_output_to_command_line_outputChekcboxHandles;

dialog_set_output_to_command_line_button_hit=0;
dialog_set_output_to_command_line_flag=false;
dialog_set_output_to_command_line_outputStateWrite={};
dialog_set_output_to_command_line_outputChekcboxHandles=[];

%% Interface container
dialog_width=400;
dialog_height=300;
dialog_x0=10;
dialog_y0=100;
daCaption='Set outputs val';
jointAnglesDialogHandle=figure('Name',daCaption,'rend','painters','pos',[dialog_x0 dialog_y0 dialog_width dialog_height]);
daHandleof_dialog_set_output_to_command_line=jointAnglesDialogHandle;
pause(0.5);
%% Button dimension
enter_buttons_separator=40;
button_width=100;
button_height=50;
%% Add ok button
fcn=@callback_dialog_set_output_to_command_line_okBtn;
btn_ok_h= uicontrol(jointAnglesDialogHandle,'Style', 'pushbutton', 'String', 'OK',...
                'Units','pixels',...
                'Callback', fcn);
x0=round((dialog_width-enter_buttons_separator-button_width*2)/2);
xtemp=x0;
y0=enter_buttons_separator;
ytemp=y0;
btn_ok_h.HorizontalAlignment='center';
btn_ok_h.Position=[x0 y0 button_width button_height];
%% Add cancel button
fcn=@callback_dialog_set_output_to_command_line_cancelBtn;
btn_cancel_h= uicontrol(jointAnglesDialogHandle,'Style', 'pushbutton', 'String', 'Cancel',...
                'Units','pixels',...
                'Callback', fcn);
x0=xtemp+enter_buttons_separator+button_width;
y0=ytemp;
btn_cancel_h.HorizontalAlignment='center';
btn_cancel_h.Position=[x0 y0 button_width button_height];
%% Dimensions of lables and sliders,
labelsNum=4;
enter_controls_horizontal_margin=10;
x0=enter_controls_horizontal_margin;
y0=ytemp+button_height;

labels_width=170;
enter_labels_vertical_margin=20;
labels_height=(dialog_height-enter_labels_vertical_margin*(labelsNum+1)-y0)/labelsNum;

x0=(dialog_width-labels_width/2)/2;
%% Add lables and sliders,
h=daHandleof_dialog_set_output_to_command_line;
labels_text_array={'OuputPin_11','OuputPin_12','OuputPin_1','OuputPin_2'};

for i=1:4
    labels_text=labels_text_array{i};
    lbl_handle= uicontrol('Style','checkbox','String',labels_text, ...
                       'Value',0, 'Units','pixels');
    x_labels_0=x0;
    y_labels_0=y0+(enter_labels_vertical_margin)*i+(labels_height)*(i-1);
    lbl_handle.HorizontalAlignment='center';
    lbl_handle.Position=[x_labels_0 y_labels_0 labels_width labels_height];
    dialog_set_output_to_command_line_outputChekcboxHandles{i}=lbl_handle;
end

while(dialog_set_output_to_command_line_button_hit==0)
    figure(daHandleof_dialog_set_output_to_command_line)
    pause(0.1);
end
outputCommand=dialog_set_output_to_command_line_outputStateWrite;
Flag=dialog_set_output_to_command_line_flag;

clear daHandleof_dialog_set_output_to_command_line;
clear dialog_set_output_to_command_line_button_hit;
clear dialog_set_output_to_command_line_flag;
clear dialog_set_output_to_command_line_outputStateWrite;
end

function callback_dialog_set_output_to_command_line_okBtn(PushButton, EventData)
    global daHandleof_dialog_set_output_to_command_line;
    global dialog_set_output_to_command_line_button_hit;
    global dialog_set_output_to_command_line_flag;
    global dialog_set_output_to_command_line_outputStateWrite;
    global dialog_set_output_to_command_line_outputChekcboxHandles;

    y=[];
    labels_text_array={'OuputPin_11','OuputPin_12','OuputPin_1','OuputPin_2'};
    for i=1:4
        h=dialog_set_output_to_command_line_outputChekcboxHandles{i};
        v=get(h,'Value');
        if v==1
            val='ON';
        else
            val='OFF';
        end
        y{i}=[labels_text_array{i},'_',val];
    end
    close(daHandleof_dialog_set_output_to_command_line);
    dialog_set_output_to_command_line_flag=true;
    dialog_set_output_to_command_line_outputStateWrite=y;
    dialog_set_output_to_command_line_button_hit=1;
end

function callback_dialog_set_output_to_command_line_cancelBtn(PushButton, EventData)
    global daHandleof_dialog_set_output_to_command_line;
    global dialog_set_output_to_command_line_button_hit;
    global dialog_set_output_to_command_line_flag;
    global dialog_set_output_to_command_line_outputStateWrite;

    close(daHandleof_dialog_set_output_to_command_line);
    dialog_set_output_to_command_line_flag=false;
    dialog_set_output_to_command_line_outputStateWrite=[];
    dialog_set_output_to_command_line_button_hit=1;
end


% this function convert the input to a correspounding kVA.

function OutVal = SP_2kva(InVal)

global KWTransformersTypes TransformersTypes
Tag = find(KWTransformersTypes == InVal);
OutVal = TransformersTypes(1,Tag);


function item = cfg_branch(varargin)

% This is the branch configuration item class for non-executable
% branches. It implements branch harvest, all_set, get_strings.
%
% Data structure
% ==============
% Description fields
%    * name  - display name of config item
%    * tag   - tag of the menu item
%    * val   - 1xn cell array of cfg_item objects
%    * check - (optional) function handle to implement configuration
%              specific subsasgn checks based on the harvested subtree
%              rooted at this node
%    * help  - help text
% GUI/job manager fields
%    * expanded
%    * hidden
% All fields are inherited from the generic configuration item class.
%
% Public Methods
% ==============
%    * get_strings - returns name of object
%    * gettag      - returns tag
%    * help        - returns help text
%    * harvest     - returns struct, field names correspond to tags of
%                    items in .val field
%    * all_set     - returns all(all_set(item.val{...}))
%
% Output in Job Structure (harvest)
% =================================
% The resulting structure is a struct. Its fieldnames correspond to the
% tags of the cfg_items in item.val, the value of each field is the
% harvested data of the corresponding child item.
%
% The layout of the configuration tree and the types of configuration items
% have been kept compatible to a configuration system and job manager
% implementation in SPM5 (Statistical Parametric Mapping, Copyright (C)
% 2005 Wellcome Department of Imaging Neuroscience). This code has been
% completely rewritten based on an object oriented model of the
% configuration tree.
%
%   The resulting data structure is a struct, with fieldnames according
%   to the 'tag's of the child nodes.
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: cfg_branch.m 5678 2013-10-11 14:58:04Z volkmar $

rev = '$Rev: 5678 $'; %#ok

myclass = mfilename;
% Get local fields and defaults from private/mysubs_fields
[fn, defs] = mysubs_fields;

if nargin == 1
    if isstruct(varargin{1})
        % assume input is a struct to be converted back into a class
        % return with error if this does not work
        if numel(fieldnames(varargin{1})) == numel(fn)+2 && ...
                all(isfield(varargin{1}, [fn(:)', {'cfg_item' 'cfg_intree'}]))
            gitem = varargin{1}.cfg_item;
            sitem = rmfield(varargin{1},{'cfg_item','cfg_intree'});
            item  = class(sitem, myclass, gitem, cfg_intree);
            return;
        else
            cfg_message('matlabbatch:constructor:reclassify', ['Don''t know how to convert this ' ...
                                'into class ''%s''.'], myclass);
        end;
    end;
    if isa(varargin{1},myclass)
        item = varargin{1};
        return;
    end;
end;

mxpnargin = 4; % Max 4 arguments to parent initialisation
pnargin = min([nargin,mxpnargin]);
switch nargin
    case 0
        gitem = cfg_item;
    case {1,2,3,4,5}
        gitem = cfg_item(varargin{1:pnargin});
    otherwise
        cfg_message('matlabbatch:constructor:nargin', 'Wrong number of arguments.');
end;
item = class(struct([]), myclass, gitem, cfg_intree);
if nargin > mxpnargin
    item.cfg_item.val{1} = varargin{mxpnargin+1};
    mxpnargin = mxpnargin+1;
end;


function indxV = getAssociatedStr(uid)
%"getAssociatedStr"
%   Returns a structure index for corresponding structure uid passed. uid can be a
%   cell array of strUID's in that case output will be an array of structure indices
%
%	DK 12/07/2006
%
%Usage:
%   indxV = getAssociatedStr(uid)

% copyright (c) 2001-2008, Washington University in St. Louis.
% Permission is granted to use or modify only for non-commercial,
% non-treatment-decision applications, and further only if this header is
% not removed from any file. No warranty is expressed or implied for any
% use whatever: use at your own risk.  Users can request use of CERR for
% institutional review board-approved protocols.  Commercial users can
% request a license.  Contact Joe Deasy for more information
% (radonc.wustl.edu@jdeasy, reversed).

global planC
indexS = planC{end};

if length(planC{indexS.structures})< 1
    indxV = [];
    return
end

[strUID{1:length(planC{indexS.structures})}] = deal(planC{indexS.structures}.strUID);

if length(uid)==0
    indxV = [];
else
    [jnk,indxV] = ismember(uid,strUID);
    if indxV == 0;
        indxV = [];
    end
end


function n = numel(varargin)
%NUMEL        Overloaded functions, necessary for Matlab V6.1f
%

% written  10/03/02     S.M. Rump
%

  n = 1;


function addCERRFigureHandle(handle, name)
%function addCERRFigureHandle(handle, name)
%after creating a new figure within the context of CERR, this function should be called
%so that the program can close the figure if CERR is shut down entirely.
%The handle can also be referenced from any function using global CERRHandlesC.
%-Note that the CloseRequestFcn is modified.  Any changes made to the CloseRequestFcn after this function
% is called should include a call to removeCERRFigureHandle.
%-'name' should be the same as the tag for the figure.
%
% 15 Aug 02, V H Clark
%LM  28 Oct 02, JOD
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

global stateS

CERRHandlesC = stateS.CERRHandlesC

if isfield(CERRHandlesC{end}, name)
  handleLocation = getfield(CERRHandlesC{end}, name);
else
  handleLocation = length(CERRHandlesC);
  CERRHandlesC{end+1} = CERRHandlesC{end}; %move the index structure cell
  CERRHandlesC{end} = setfield(CERRHandlesC{end}, name, handleLocation);
end

CERRHandlesC{handleLocation} = handle;

% fix the figure to call 'removeCERRFigureHandle' on close.  If a CloseRequestFcn is changed in the code,
% it should include a call to 'removeCERRFigureHandle'.
prevCRF = get(handle, 'CloseRequestFcn');
set(handle, 'CloseRequestFcn', [prevCRF ', removeCERRFigureHandle(''' name ''')']);

stateS.CERRHandlesC = CERRHandlesC;


classdef MimBrushSizeSlider < MimGuiPluginSlider
    % MimBrushSizeSlider. Gui Plugin for changing the size of the edit brush
    %
    %     You should not use this class within your own code. It is intended to
    %     be used by the gui of the TD MIM Toolkit.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, Copyright Tom Doel 2014.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    properties
        ButtonText = 'Brush size'
        SelectedText = 'Brush size'

        ToolTip = 'Change the size of the editing paint brush'
        Category = 'Paint'
        Visibility = 'Dataset'
        Mode = 'Edit'

        HidePluginInDisplay = false
        PTKVersion = '1'
        ButtonWidth = 6
        ButtonHeight = 1
        Location = 42

        MinValue = 0
        MaxValue = 100
        SmallStep = 0.01
        LargeStep = 0.1
        DefaultValue = 50

        EditBoxPosition = 90
        EditBoxWidth = 30

        StackVertically = false
    end

    methods (Static)
        function RunGuiPlugin(gui_app)
        end

        function enabled = IsEnabled(gui_app)
            enabled = gui_app.IsDatasetLoaded && gui_app.ImagePanel.OverlayImage.ImageExists && ...
                isequal(gui_app.ImagePanel.SelectedControl, 'Paint');
        end

        function is_selected = IsSelected(gui_app)
            is_selected = true;
        end

        function [value_instance_handle, value_property_name, limits_instance_handle, limits_property_name] = GetHandleAndProperty(gui_app)
            value_instance_handle = gui_app.ImagePanel;
            value_property_name = 'PaintBrushSize';
            limits_instance_handle = [];
            limits_property_name = [];
        end

    end
end


function dataout = ft_annotate(cfg, datain)

% FT_ANNOTATE returns the same output data as the user has provided as input, but allows
% to add comments to that data structure. These comments are stored along with the other
% provenance information and can be displayed with FT_ANALYSISPIPELINE. Adding comments
% is especially useful if you have manually (i.e. in plain MATLAB) modified the data
% structure, whereby some provenance information is missing.
%
% Use as
%   outdata = ft_annotate(cfg, indata)
% where the input data structure can be any of the FieldTrip data structures and
% the configuration structure should contain
%   cfg.comment    = string
%
% To facilitate data-handling and distributed computing you can use
%   cfg.inputfile   =  ...
%   cfg.outputfile  =  ...
% If you specify one of these (or both) the input data will be read from a *.mat
% file on disk and/or the output data will be written to a *.mat file. These mat
% files should contain only a single variable, corresponding with the
% input/output structure.
%
% See also FT_ANALYSISPIPELINE, FT_MATH

% Copyright (C) 2013, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

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

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

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

% ensure that the required options are present
cfg = ft_checkconfig(cfg, 'required', 'comment');

% simply copy the input data to the output data
dataout = datain;

% this line is meant to provide some information
fprintf('adding the comment: %s\n', cfg.comment);

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


function [reverseStr] = cmdWaitbar(i,nItems,reverseStr,varargin)
	% Puts a txt waitbar into the cmd window, less intrusive than pop-up waitbar.
	% Biafra Ahanonu
	% started: 2014.01.14
	% thanks to:
		% http://www.mathworks.com/matlabcentral/newsreader/view_thread/32291
		% http://stackoverflow.com/questions/11050205/text-progress-bar-in-matlab
	% inputs
			%
	% outputs
			%

	% changelog
			% 2014.02.14 [16:35:55] now is mostly
	% TODO
			% Should reverseStr be made global so function is entirely self-contained? - NO, globals are evil.
			% change so waitbarOn = 0 can short circuit getOptions to save speed execution time
	% example
		% before loop = reverseStr
		% reverseStr = cmdWaitbar(i,nItems,reverseStr,'inputStr','loading hdf5','waitbarOn',options.waitbarOn,'displayEvery',50);

	[reverseStr] = ciapkg.view.cmdWaitbar(i,nItems,reverseStr,'passArgs', varargin);
end


function error_handler(ME, optional)
    % unhandled_error provides a one-stop place to track certain errors
    %
    % it is designed to be a drop-in replacement for simple try-catch display
    %
    % usage:
    %   try
    %      do something that might fail
    %   catch ME
    %      unhandled_error(ME) % prints the error message
    %      unhandled_error(ME, "oops") % prints "oops"
    %      unhandled_error(ME, @do_nothing) % does nothing
    %      unhandled_error(ME, @function_name) % executes function function_name
    %   end
    %
    %  Celso G Reyes, 2017

    if exist('optional','var') && ~isempty(optional)
        if isa('optional','function_handle')
            optional();
        else
            disp(optional)
        end
    elseif exist('ME', 'var')
        disp('ignored exception:');
        disp(ME)
    else
        % do nothing
    end

end


function display(panel)
% Display function for BstPanel object.

% @=============================================================================
% 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, 2008

% If displaying a template : do not display anything
if ((size(panel,1)==0) || (size(panel,2)==0))
    disp('Template Brainstorm panel...');
    return
end

for iPanel = 1:length(panel)
    % Display title and simple properties
    disp('Brainstorm window panel:');
    disp(sprintf('           name: %s', panel(iPanel).name));
    disp(sprintf('        jHandle: %s', char(panel(iPanel).jHandle.getClass())));
    switch (panel(iPanel).container.type)
        case ''
            disp(sprintf('      container: N/A'));
        case 'JavaWindow'
            disp(sprintf('      container: JavaWindow (%s)', char(panel(iPanel).container.handle{1})));
        case 'MatlabFigure'
            disp(sprintf('      container: MatlabFigure (%d)', panel(iPanel).container.handle{1}));
        case 'BrainstormTab'
            disp(sprintf('      container: BrainstormTab (''%s'')', panel(iPanel).container.handle{1}));
        case 'BrainstormPanel'
            disp(sprintf('      container: BrainstormPanel (''%s'')', panel(iPanel).container.handle{1}));
    end
    % Display sControls structure
    sControlsStr = '      sControls: ';
    sControlsFields = fieldnames(panel(iPanel).sControls);
    if isempty(sControlsFields)
        % No fields
        sControlsStr = [sControlsStr 'No controls registered'];
    else
        % Display all the fields
        for i=1:length(sControlsFields)
            if isjava(panel(iPanel).sControls.(sControlsFields{i}))
                controlDesc = class(panel(iPanel).sControls.(sControlsFields{i}));
            else
                controlDesc = 'User value';
            end
            if (i == 1)
                sControlsStr = sprintf('%s%s (%s)', sControlsStr, sControlsFields{i}, controlDesc);
            else
                sControlsStr = sprintf('%s\n                 %s (%s)', sControlsStr, sControlsFields{i}, controlDesc);
            end
        end
    end
    disp(sControlsStr);
    disp(' ');
end


function [new, fittype]=dfcreatecopy(original);

%   $Revision: 1.1.6.3 $  $Date: 2004/01/24 09:35:23 $
%   Copyright 2003-2004 The MathWorks, Inc.

fittype = original.fittype;

new = copyfit(original);
new = java(new);


function outputWaveforms = load_antelope(request, specificDatabase)
   % load a waveform from antelope
   %  w = load_antelope(request, specificDatabase)
   %   CRITERIA is the search criteria, created with buildAntelopeCriteria
   %   request.sTime is the startTimes
   %   endTimes is the endTimes
   %   combineWaves is a logical value:
   %     Should segmented waveforms be combined,(within requested timerange)?
   %   database is the antelope database

   % AUTHOR: Celso Reyes
   % MODIFICATIONS: Glenn Thompson, Carl Tape

   %TODO: maybe order of operations can be changed to avoid unpacking
   %request when unnecessary.

   [~, chanInfo, startTimes, endTimes, combineWaves] = unpackDataRequest(request);
   assert(numel(startTimes) == numel(endTimes),...
      'Waveform:load_antelope:startEndMismatch', 'Unequal number of start and end times');

   %call this routine for each database, then return the waveforms.
   if exist('specificDatabase','var')
      database = specificDatabase;
      outputWaveforms = emptyWaveform();

      [criteria, nCriteria] = buildAntelopeCriteria(chanInfo);
      for i = 1:nCriteria
         %if multiple traces will result, then there may be multiple records for tr
         [tr, database, fdb] = get_antelope_traces(...
            startTimes, endTimes, criteria(i).group, database);
         w = cycleThroughTraces(tr, combineWaves);
         outputWaveforms = [outputWaveforms; w]; %#ok<AGROW>
      end
      dbclose(fdb);
   else
      outputWaveforms = RecursivelyLoadFromEachDatabase(request);
   end
end

function outputWaveforms = RecursivelyLoadFromEachDatabase(request)
   TRY_MULTIDAY = false;
   database = getDatabase(request, TRY_MULTIDAY);
   database = unique(database, 'stable'); %  avoid changing requested order
   outputWaveforms = emptyWaveform();
   for n = 1 : numel(database)
      w = load_antelope(request, database(n));
      outputWaveforms = [outputWaveforms; w(:)]; %#ok<AGROW>
   end
end

function w = emptyWaveform()
   w = waveform;
   w = w([]);
end

function database = getDatabase(request, TRY_MULTIDAY)
   [ds, chanInfo, startTimes, endTimes] = unpackDataRequest(request);
   if TRY_MULTIDAY %good luck splicing
      dbDatesToCheck = subdivide_files_by_date(ds,startTimes, endTimes);
      database =  getfilename(ds,chanInfo, dbDatesToCheck);
   else
      database =  getfilename(ds,chanInfo, startTimes);
   end
end

function w = cycleThroughTraces(tr, COMBINE_WAVEFORMS)
   %cycleThroughTraces  converts each trace into one or more waveforms
   %   returns a Nx1 waveform
   w(numel(tr)).waves = waveform;
   for traceidx = 1:numel(tr)
      w(traceidx) = wavesfromtraces(tr, traceidx, COMBINE_WAVEFORMS);
   end
   w = [w.waves]; %horizontal cat
   w = w(:);
end

function w_scnl = wavesfromtraces(tr, traceidx, COMBINE_WAVEFORMS)
   if ~isstruct(tr{traceidx}) % marker for no data
      w_scnl.waves = emptyWaveform();
   else
      w_scnl.waves = traceToWaveform(tr{traceidx}); %create waveform list
      trdestroy(tr{traceidx});
   end
   if COMBINE_WAVEFORMS %combine all of this trace's records
      w_scnl.waves = combine(w_scnl.waves);
   end;
   w_scnl.waves = reshape(w_scnl.waves,  numel(w_scnl.waves), 1);
end

%% helper functions

function [critList, nCrit] = buildAntelopeCriteria(chanTag)
   % builds a criteria list from SCNL (Station-Channel-Network-Location)
   % returns a structure array of cells with criteria for use with get_antelope_trace
   % structure returned as critList(n).group, where group is a cell containing
   % the criteria, such as {'sta == "OKCF"','chan=="EHZ"'}
   %
   % ex. myscnls = scnlobject({'OKCF','OKFG','OKSO'},{'EHZ','BHZ','BHZ'});
   % ex.  cl =
   % builtAntelopeCriteria(myscnls)
   % ... CL will then contain
   %
   % CL(1).group(1).field = 'sta'
   % CL(1).group(1).relation = '=='
   % CL(1).group(1).data = 'OKCF'
   % CL(1).group(2).field = 'chan'
   % CL(1).group(2).relation = '=='
   % CL(1).group(2).data = 'EHZ'
   % ...
   % CL(N).group(4).field = 'loc'
   % CL(N).group(4).relation = '=='
   % CL(N).group(4).data = '--'
   %
   % so...    getCritListExpression(CL(1).group(1)) --> 'sta == "OKCF"'
   % It was done this way so that the dabase could be checked to ensure
   % that the view actually supports each search parameter.
   %
   % either multiple stations OR multiple channels may work... not both.
   % also, if any of the SCNL parameters are left empty, they will not be used
   % in subsetting the antelope database.
   %

   for N = numel(chanTag) : -1: 1
      if ~isempty(chanTag(N).station)
         critList(N).group(1) = grabCritList('sta', chanTag(N).station);
      end
      if ~isempty(chanTag(N).network)
         critList(N).group(2) = grabCritList('net', chanTag(N).network);
      end
      if ~isempty(chanTag(N).channel)
         critList(N).group(3) = grabCritList('chan', chanTag(N).channel);
      end
      if ~isempty(chanTag(N).location);
         critList(N).group(4) = grabCritList('loc', chanTag(N).location);
      end
   end

   critList = critList(:);
   nCrit = numel(critList);
end

function A = grabCritList(key, value)
   if ~isempty(value)
      value = regexprep(value,'(?<!\.)\*','\.\*'); %replace * with .*, but leave existing .* alone
      value = makecell(value);
      for i = numel(value) : -1 : 1
         A(i).field = key;
         A(i).relationship = '=~';
         A(i).value = value{i};
      end
   elseif ismember(key,{'sta','cha'})  %ew. get rid of special treatment
      erid = sprintf('Waveform:load_antelope:no%sTerm',key);
      error(erid,'No %s  requested. To retrieve all %ss use ''*''', key, key);
   else
      A.field='';
      A.relationship = '';
      A.value = '';
   end
end

function [tr, rawDb, filteredDb] =  get_antelope_traces(startdates, enddates, criteriaList, database)
   % GET_ANTELOPE_TRACE gets interesting data from database, and returns the tracebuf object
   % [tr(1:end)] =  get_antelope_trace(startdates, enddates, criteriaList, database)
   %    STARTDATE is a matlab datenum
   %    ENDDATE is also in matlab datenum
   %    CRITERIALIST is a cell of statements used to filter the antelope
   %        database.  example: {'sta=="OKCF"','chan=="BHZ"'}
   %    DATABASE can either be a database name, or an open antelope database
   %    pointer.
   %
   %    TR is a tracebuf object containing the data requested.
   %
   %  In this usage, with a single output argument, TR, the database is opened
   %  and then closed before the function returns.
   %
   % You can opt to keep the database open, which can make subsequent calls to
   % get_antelope_trace much faster.  To do this, ask for the database pointer
   % as one of the output arguments.  The database will be closed by any
   % function call that uses the database pointer as the 'database' parameter,
   % and does not ask for a database pointer back.
   %
   % [tr, mydb] = get_antelope_trace(...)
   %    if mydb is asked for, then the database will not be closed, allowing for
   %    more efficient reuse.  mydb is the unfiltered (and open) wfdisc table
   %
   % [tr, mydb, filteredDB] = get_antelope_trace(...)
   %   returns wfdisc table in mydb, and a filtered wfdisc table in filteredDB
   %
   % if no records are found, then tr will be set to []
   %
   % will generate error message if no records found, so consider using in a
   % TRY-CATCH loop.
   %
   %
   % Example:
   %  % set up the data
   %  sDate = datenum('7/12/2008 05:00:00.00');
   %  eDate = datenum('7/12/2008 05:10:00.00');
   %  stationsToGet = {'OKFG','OKSO','OMG'};
   %  channelsToGet = {'BHZ', 'BHE'};
   %  mydb = '/mydir/my_antelope_database';
   %
   %  % get our criteria together
   %  for st = 1:numel(stationsToGet)
   %    staCriteria(st) = {sprintf('sta=="%s"',stationsToGet(st)};
   %  end
   %  for ch = 1:numel(channelsToGet)
   %    chanCriteria(ch) = {sprintf('chan=="%s"',channelsToGet(ch)};
   %  end
   %
   %  % open the database once, and read in each tracebuf. Then translate into
   %  % waveforms.
   %  n = 1;
   %  for sta = 1:numel(staCriteria)
   %    for ch = 1:numel(chanCriteria)
   %      critera = [chanCriteria(ch),staCriteria(sta)];
   %      [tr, mydb] = get_antelope_trace(sDate,eDate, criteria, mydb)
   %      w(n) = traceToWaveform(tr);
   %      n = n+1;
   %    end
   %  end
   %  % finally, close up shop.
   %  dbclose(mydb)

   % Modifications
   %%% Glenn Thompson 2012/02/06: Occasionally the C program trload_css cannot even load the trace data. Added try...catch..end to handle this.

   useExistingDatabasePtr =  isAntelopeDatabasePtr(database);

   if useExistingDatabasePtr
      try
         dbnrecs(database);
      catch
         warning('Waveform:load_antelope:databaseNotOpen', ...
            'a Database Pointer was passed to trace, but the database was not open');
         %tr = trnew; %return a new object, forcing the ability to destroy it later
         tr = { -1 };
         return;
      end
   end

   % do not close the database if a pointer is asked for in the return arguments
   onFinishCloseDB = nargout < 2;

   antelope_starts = mep2dep(startdates);
   antelope_ends = mep2dep(enddates);

   %if the database isn't already open, then open it for reading
   if ~useExistingDatabasePtr
      mydb = dbopen(database,'r');
      mydb = dblookup_table(mydb,'wfdisc');
   else
      mydb = database;
   end
   %check to ensure wfdisk table exists and is populated

   if safe_dbnrecs(mydb) == 0,
      cleanUpFail('Waveform:load_antelope:databaseNotFound', ...
         'Database not found: %s', dbquery(mydb,'dbTABLE_FILENAME'));
      return;
   end;

   rawDb = mydb;   % keep a copy of the pre-subset (raw) database

   % subset the data based upon the desired criteria
   criteriaList = keepCriteriaThatMatchDatabaseFields(criteriaList, mydb);
   allExp = getAsExpressions(criteriaList);

   %subset the database based on this particular criterion
   mydb = dbsubset(mydb,allExp);
   if safe_dbnrecs(mydb) == 0
      cleanUpFail('Waveform:load_antelope:dataNotFound', 'No records found for criteria [%s].', allExp);
      return;
   end;

   filteredDb = mydb;

   [st, ed] = dbgetv(mydb,'time','endtime');
   %% Get the tracebuf object for this starttime, endtime
   % Loop through all times.  Result is tr(1:numel(starttimes) of all tracebuffers.
   for mytimeIDX = 1:numel(antelope_starts)
      someDataExists = any(antelope_starts(mytimeIDX)<= (ed) & antelope_ends(mytimeIDX) >= (st));
      if someDataExists
         %%% Glenn Thompson 2012/02/06: Occasionally the C program trload_css cannot even load the trace data.
         % This error needs to be handled. So adding a try..catch..end around the original instruction.
         try
            tr{mytimeIDX} = trload_css(mydb, antelope_starts(mytimeIDX), antelope_ends(mytimeIDX)); %#ok<AGROW>
         catch
            cleanUpFail('Waveform:load_antelope:trload_css failed', ...
               'Database not found: %s', dbquery(mydb,'dbTABLE_FILENAME'));
            disp(database)
            disp(allExp)
            starttimes = antelope_starts(mytimeIDX);
            endtimes = antelope_ends(mytimeIDX);
            fprintf('%.0f %.0f\n ',starttimes,endtimes);
            disp(['starttimes: ', datestr(epoch2datenum(starttimes))]);
            disp(['endtimes: ', datestr(epoch2datenum(endtimes))]);
            fprintf('trload_css(mydb, starttimes, endtimes))\n');
            return
         end
         trsplice(tr{mytimeIDX},20);
      else
         tr{mytimeIDX} = -1; %#ok<AGROW>
      end
   end %mytimeIDX
   closeIfAppropriate(mydb, onFinishCloseDB);

   function cleanUpFail(varargin)
      %cleanUpFail   tidy up database and records and display warning
      closeIfAppropriate(mydb, onFinishCloseDB);
      tr = { -1 };
      filteredDb = dbinvalid;
      warning(varargin{:});
   end
end

function  critList = keepCriteriaThatMatchDatabaseFields(critList, mydb)
   dbFields = dbquery(mydb, 'dbTABLE_FIELDS');
   critFields = {critList.field};  % all criteria we've parsed
   validCritIdx = true(size(critFields)); % preallocation
   for n = 1:numel(critFields)
      validCritIdx(n) = ...                %make sure:
         ~isempty(critFields{n}) && ...    % isn't empty and
         ismember(critFields{n}, dbFields);%  is a database field
   end
   critList = critList(validCritIdx);   %keep only good ones
end
function allExp = getAsExpressions(criteria)
   for n=1:numel(criteria)
      eachExp(n) = crit2expression(criteria(n)); %#ok<AGROW>
   end
   allExp = eachExp{1};
   for i= 2 : (numel(eachExp))
      allExp = [allExp,' && ', eachExp{i}]; %#ok<AGROW>
   end
end

function cle = crit2expression(cl)
   if ischar(cl.value)
      cle = {sprintf('%s%s/%s/',cl.field, cl.relationship, cl.value)};
   else
      cle =  {sprintf('%s %s %s',cl.field,cl.relationship,num2str(cl.value))};
   end
end

function n = safe_dbnrecs(mydb)
   %safe_dbnrecs   return either the number of records or 0
   %   n = safe_dbnrecs(mydb)  when accessing dbnrecs fails, this returns 0
   try
      n = dbnrecs(mydb);
   catch
      n = 0;
   end
end

function closeIfAppropriate(mydb, closeDatabase)
   if closeDatabase
      dbclose(mydb);
   end
end

function result = isAntelopeDatabasePtr(database)
   result = isa(database,'struct');
   result = result && any(strcmpi(fieldnames(database),'database'));
end

function X = makecell(X)
   if ~iscell(X)
      X = {X};
   end
end

function allw = traceToWaveform(tr)
   %traceToWaveform converts traceobjects to waveforms
   %    w = traceToWaveform(blankwaveform, all_tracobjects)
   %
   % Note: this may return multiple waveform objects, depending upon
   % how many segments and/or scnl's.

   persistent wBlank           % cannot test if wBlank is empty because
   persistent blankWaveExists  %   isempty(wBlank) is always true.

   if isempty(blankWaveExists)
      wBlank = waveform;
      wBlank =  addfield(wBlank,'calib', 0);
      wBlank = addfield(wBlank, 'calibration_applied', 'NO');
      blankWaveExists = true;
   end

   try
      traceCount = dbnrecs(tr);
      assert(traceCount > 0);
   catch
      allw = wBlank([]);
      return
   end

   % preallocations
   spikes(traceCount).mask = false; %used to track data spikes & inf values
   allw = repmat(wBlank,traceCount,1);

   maxAllowableSignal = (realmax('single') * 1e-2);

   % LOOP twice through segments represented by this trace object
   % 1st loop: find signal spikes, and get header info.
   for seg = 1:traceCount
      tr.record = seg - 1;
      s = db2struct(tr); %do once, get one for each segment
      [sunit, ~] = segtype2units(s.segtype);
      allw(seg) = set(wBlank, ...
         'station', s.sta, ...
         'channel', s.chan, ...
         'network', s.net, ...
         ... 'location', s.loc, ... % unknown if 'loc' really is a field
         'start', dep2mep(s.time), ...
         'freq', s.samprate, ...
         'units', sunit, ...
         'calib', s.calib);

      % data spikes must be known PRIOR to applying calibration
      data = trextract_data(tr);
      spikes(seg).mask =(abs(data) >= maxAllowableSignal) | isinf(data);
   end

   % now, apply calibrations to all traces at once
   trapply_calib(tr);
   hasCalibs = get(allw,'calib') ~= 0;
   allw(hasCalibs) = set(allw(hasCalibs),'calibration_applied','YES');

   % 2nd loop: assign data to the waveforms.
   replaceWithNan = @(W,BAD) setsamples(W, BAD.mask, nan);
   for seg = 1:traceCount
      tr.record = seg - 1;
      allw(seg) = set(allw(seg), 'data', trextract_data(tr));
      allw(seg) = replaceWithNan(allw(seg), spikes(seg));
   end
end

function [units, data_description] = segtype2units(unitCode)
   %segtype2units   retrieves unit and description based on the segtype code
   %'segtype' in antelope datasets indicate the natural units of the detector
   persistent codeKey
   if isempty(codeKey)
      codeKey = createCodeKey();
   end
   if codeKey.isKey(unitCode)
      details = codeKey(unitCode);
      units = details{1};
      data_description = details{2};
   else
      [units, data_description] = deal('null');
   end

   function SU = createCodeKey()
      %createSegUnits   creates a map  where SU(char) = {units, data_description}
      SU = containers.Map;
      SU('A') = {'nm / sec / sec','acceleration'};
      SU('B') = {'25 mw / m / m','UV (sunburn) index(NOAA)'};
      SU('D') = {'nm', 'displacement'};
      SU('H') = {'Pa','hydroacoustic'};
      SU('I') = {'Pa','infrasound'};
      SU('J') = {'watts','power (Joulses/sec) (UCSD)'};
      SU('K') = {'kPa','generic pressure (UCSB)'};
      SU('M') = {'mm','Wood-Anderson drum recorder'};
      SU('P') = {'mb','barometric pressure'};
      SU('R') = {'mm','rain fall (UCSD)'};
      SU('S') = {'nm / m','strain'};
      SU('T') = {'sec','time'};
      SU('V') = {'nm / sec','velocity'};
      SU('W') = {'watts / m / m', 'insolation'};
      SU('a') = {'deg', 'azimuth'};
      SU('b') = {'bits/ sec', 'bit rate'};
      SU('c') = {'counts', 'dimensionless integer'};
      SU('d') = {'m', 'depth or height (e.g., water)'};
      SU('f') = {'micromoles / sec / m /m', 'photoactive radiation flux'};
      SU('h') = {'pH','hydrogen ion concentration'};
      SU('i') = {'amp','electric curent'};
      SU('m') = {'bitmap','dimensionless bitmap'};
      SU('n') = {'nanoradians','angle (tilt)'};
      SU('o') = {'mg/l','diliution of oxygen (Mark VanScoy)'};
      SU('p') = {'percent','percentage'};
      SU('r') = {'in','rainfall (UCSD)'};
      SU('s') = {'m / sec', 'speed (e.g., wind)'};
      SU('t') = {'C','temperature'};
      SU('u') = {'microsiemens/cm','conductivity'};
      SU('v') = {'volts','electric potential'};
      SU('w') = {'rad / sec', 'rotation rate'};
      SU('-') = {'null','null'};
   end
end


function visData = sc_vis_planar_structure(modelPlane, modelReg)
%
%     sc_vis_planar_structure:
%     visualize the extracted planar structure

%%
visData = [];

end


function path_name = PTKSaveAs(image_data, patient_name, path_name, is_secondary_capture, dicom_metadata, reporting)
    % MimSaveAs. Prompts the user for a filename and file type, and saves the image
    %
    %     Syntax
    %     ------
    %
    %         PTKSaveAs(image_data, patient_name, path_name, is_secondary_capture, dicom_metadata, reporting)
    %
    %             image_data      is a PTKImage (or PTKDicomImage) class containing the image
    %                             to be saved
    %             patient_name    specifies the patient name to be stored in the image (only
    %                             used when there is no metadata available in the image)
    %             path_name       specify the location to save the DICOM data. One 2D file
    %                             will be created for each image slice in the z direction.
    %                             Each file is numbered, starting from 0.
    %                             So if filename is 'MyImage.DCM' then the files will be
    %                             'MyImage0.DCM', 'MyImage1.DCM', etc.
    %             is_secondary_capture   true if the image is derived, false if the pixel data
    %                             directly corresponds to the original image pixel data
    %             dicom_metadata  a structure containing additional manufacturer tags
    %                             used to construct Dicom images
    %             reporting       an object implementing CoreReportingInterface
    %                             for reporting progress and warnings
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, Copyright Tom Doel 2014.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    if ~isa(image_data, 'PTKImage')
        error('Requires a PTKImage as input');
    end

    if nargin < 4 || isempty(is_secondary_capture)
        is_secondary_capture = false;
    end

    if nargin < 5 || isempty(dicom_metadata)
        dicom_metadata = PTKDicomMetadata();
    end

    if nargin < 6
        reporting = CoreReportingDefault();
    end

    path_name = MimSaveAs(image_data, patient_name, path_name, is_secondary_capture, dicom_metadata, reporting);
end


addpath(genpath('./dependence'))
addpath data/

slaveRun('localhost', 10000);


2
37
4
GD
2
male
female
CN
2
C1
C2
EM
3
P
U
N
SJ
10
S1
S2
S3
S4
S5
S6
S7
S8
S9
S10
1
0
20
6
../Lukas_Coarse2/m.AlvaranP051303.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.AstorA072903.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.BlumenkronF070103.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.CabrerraD121002.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.ChieppaM112703.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.CrawfordA020604.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.DeleonM062403.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.DezwartJ120302.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.DuaneD010904.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/m.DudekJ062303.full.reg+tlrc.BRIK
1
../Lukas_Coarse2/f.AhnS102803.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.BosettiF090103.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.BrewerD040113.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.BrownC011403.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.ChapinH090103.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.DakinK101403.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.DanubeC050103.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.GauriT121603.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.GoltzM111103.full.reg+tlrc.BRIK
2
../Lukas_Coarse2/f.GrutzmacherS090903.full.reg+tlrc.BRIK
2
1
1
1
2
1
3
2
1
2
2
2
3
test3


function rmgismo()

% RMGISMO(SOURCE) removes all existing paths containing the phrase
% 'GISMO'.

% Author: Michael West, Geophysical Institute, Univ. of Alaska Fairbanks
% $Date$
% $Revision$

admin.deprecated(mfilename,'admin.remove');

% REMOVE EXISTING GISMO PATHS
pathList = path;
n = 1;
while true
    t = strtok(pathList(n:end), pathsep);
    OnePath = sprintf('%s', t);

    if strfind(OnePath,'GISMO');
        %disp(['removing: ' OnePath])
        rmpath(OnePath);
    end;
    n = n + length(t) + 1;
    if isempty(strfind(pathList(n:end),':'))
        break
    end;
end


function add_legend_entry(plot_obj,lh,legend_string,append_name)
% A private method that stores legend information for when
% 'display_legend' is called.
% Inputs:
%   lh: The handle for the curve.
%   legend_string: A string describing the curve.
%   append_name: A boolean indicating whether to prepend the system
%     name (set in 'set_system') to the 'legend_string'.

assert(ischar(legend_string))

if ~strcmp(legend_string,'')
    plot_obj.handles_vec = [plot_obj.handles_vec lh];
    if exist('append_name','var') && append_name
	plot_obj.legend_strings = {plot_obj.legend_strings{:},[plot_obj.sys_name ' ' legend_string]};
    else
	plot_obj.legend_strings = {plot_obj.legend_strings{:},legend_string};
    end
end
end


function tP = subsasgn(tP,s,b)
% overloads subsasgn

if ~isa(tP,'triplePointList'), tP = b([]); end

switch s(1).type

  case '()'

    if numel(s)>1, b =  subsasgn(subsref(tP,s(1)),s(2:end),b); end

    s(1).subs = {subsind(tP,s(1).subs)};

    if isempty(b)

      s(1).subs = {~s(1).subs{1}};
      tP = subsref(tP,s(1));

    else

      tP = subsasgn@dynProp(tP,s(1),b);
      tP.misrotation = subsasgn(tP.misrotation,s(1),b.misrotation);

      id1 = subsasgn(tP.grainId(:,1),s(1),b.grainId(:,1));
      id2 = subsasgn(tP.grainId(:,2),s(1),b.grainId(:,2));
      tP.grainId = [id1(:),id2(:)];

      id1 = subsasgn(tP.phaseId(:,1),s(1),b.phaseId(:,1));
      id2 = subsasgn(tP.phaseId(:,2),s(1),b.phaseId(:,2));
      tP.phaseId = [id1(:),id2(:)];

      id1 = subsasgn(tP.F(:,1),s(1),b.F(:,1));
      id2 = subsasgn(tP.F(:,2),s(1),b.F(:,2));
      tP.F = [id1(:),id2(:)];

      tP.V = b.V;
      tP.CSList = b.CSList;
      tP.phaseMap = b.phaseMap;

    end

  otherwise

    if tP.isProperty(s(1).subs) % otherwise a property

      tP = subsasgn@dynProp(tP,s,b);

    else

      tP = builtin('subsasgn',tP,s,b);

    end

end
end


%   AUTHORSHIP
%   Primary Developer: Stephen Meehan <swmeehan@stanford.edu>
%   Math Lead & Secondary Developer:  Connor Meehan <connor.gw.meehan@gmail.com>
%   Bioinformatics Lead:  Wayne Moore <wmoore@stanford.edu>
%   Provided by the Herzenberg Lab at Stanford University
%   License: BSD 3 clause
%
function [d, resized]=resizeJavaPrefs(app, J, H)
d=J.getPreferredSize;
if app.toolBarFactor>0
    d=java.awt.Dimension(d.width*.55, d.height*.6);
    J.setPreferredSize(d);
    resized=true;
else
    resized=false;
end
end


function FileString = generateFieldDescriptionFile(FileName)
% Generates the ModelFields.md file describing the Required and Optional Fields of a COBRA model.
%
% USAGE:
%
%    FileString = generateFieldDescriptionFile(FileName)
%
% OPTIONAL INPUT:
%    FileName:      The FileName to write to. (default [CBTDIR filesep 'docs' filesep 'notes' filesep 'COBRAModelFields.md'])
%
% OUTPUT:
%    FileString:    The string written to the specified filename (or the default file)
%
% .. Author: - Thomas Pfau May 2017

global CBTDIR
if ~exist('FileName','var')
    if isempty(CBTDIR)
        initCobraToolbox(false); %Don't update the toolbox automatically
    end
    FileName = [CBTDIR filesep 'docs' filesep 'source' filesep 'notes' filesep 'COBRAModelFields.md'];
end

fieldProperties = getDefinedFieldProperties('Descriptions', true);

FileString = sprintf('# Fields in the model structure\n\n');
FileString = strjoin({FileString, sprintf(['Contents:\n',...
                                        '1. [Model Fields](#model-fields)\n',...
                    '2. [Field Support](#field-support)\n',...
					'3. [Model Specific Fields](#model-specific-fields)\n',...
					'4. [Annotation Definitions](#annotation-definitions)\n',...
					'\n',...
					'### Model Fields:\n',...
					'The following fields are defined in the COBRA toolbox. IF the field is present in a model, it should have the properties defined here and should be of the mentioned dimensions.\n '...
                    'The dimensions refer to m (the number of metabolites), n (the number of reactions), g (the number of genes) and c (the number of compartments).\n',...
					'\n',...
					'| Field Name | Dimension | Field Type | Field Description |\n',...
					'|---|---|---|---|\n'])},'');

for i=1:size(fieldProperties,1)
	string = sprintf('|`model.%s`| `%s` | %s | %s | \n',fieldProperties{i,1},fieldProperties{i,2},fieldProperties{i,3},fieldProperties{i,4});
	FileString = strjoin({FileString,string},'');
end
FileString = strjoin({FileString,sprintf(['### Model Specific Fields\n',...
					'Some models might contain additional model specific fields that are not defined COBRA model fields. These fields will commonly not be considered by COBRA toolbox methods, and using toolbox methods can render these fields inconsistent (e.g. if the number of reactions changes, a model specific field linked to reactions might have the wrong number of entries or the values might no longer correspond to the correct indices).\n',...
					'\n',...
					'### Field Support\n',...
					'All fields mentioned above are supported by COBRA Toolbox functions.'...
                    'Using COBRA Toolbox Functions will not make a model inconsistent, but manual modifications of fields might lead to an inconsistent model.\n',...
					'Use verifyModel(model) to determine, if the model is a valid COBRA Toolbox model.\n',...
					'\n',...
					'### Additional fields\n',...
					'Fields starting with met, rxn, comp, protein or gene that are not defined above, will be assumed to be annotation fields, and IO methods will try to map them to identifiers.org registered databases.'])},'');
fileID = fopen(FileName,'w');
fprintf(fileID,FileString);
fclose(fileID);


function toThing = copyfields(toThing, fromThing, varargin)
    % copy fields (or properties) from one structure (or object) to another. Types may be different
    %
    % toThing = copyfields(toThing, fromThing) copies fields/properties from fromThing into toThing,
    % returning toThing.  if THISONE is a handle object, the return can be ignored.
    %
    % Options:
    % copyfields(... , "safe") will copy all fields.  A warning will be displayed for any field that
    % doesn't exist.
    % copyfields(... , "safe", "quietfail") will not warn or error when a field doesn't exist.

    failQuietly =  any(varargin == "quietfail");

    if isstruct(fromThing)
        fn = fieldnames(fromThing);
    elseif isobject(fromThing)
        fn = properties(fromThing);
    elseif failQuietly
        return
    else
        error('cannot copy fields/properties from ["%s"], since it is neither an object nor a struct', inputname(2));
    end

    if any(varargin=="safe")
        for i = 1 : numel(fn)
            try
                toThing.(fn{i}) = fromThing.(fn{i});
            catch ME
                if failQuietly
                    do_nothing(); % do not copy
                else
                    warning(ME.identifier, 'Error copying property/field: %s',fn{i})
                end
            end
        end
    else
        for i = 1 : numel(fn)
            toThing.(fn{i}) = fromThing.(fn{i});
        end

    end
end


function out = isempty(f)
% overloads isempty

out = isempty(f.h);


function url = prtGraphDataUrl
% url = prtGraphDataUrl
%   Return the url where the big graph data can be found.

url = 'http://www.duke.edu/~pat7/prtGraphData/';


classdef obspysource < dataretrieval.spatiotemporal_file
   %UNTITLED2 Summary of this class goes here
   %   Detailed explanation goes here

   properties
   end

   methods
      function data = retrieve(obj, where_, from_ , until_)
         error('unimplemented obspy data source');
      end

      function out_ = translate(obj, in_)

      end
   end

end


function vw = getCurView
%Returns the selected mrVista view.
%
%    vw = getCurView;
%
% If it can't find a selected one, it initializes a hidden inplane. A sort
% of super-function to getSelectedInplane, getSelectedGray, etc.
%
% How it looks: first, it checks if any views are open in the global
% INPLANE, VOLUME, or FLAT variables. If not, opens a hidden inplane.
% If there are open views, it checks if the current figure is the handle to
% one of the views. If this fails, then tries to find the selected inplane;
% then the selected volume; then the selected flat.
%
% ras, 05/01/06.
mrGlobals;

vw = [];

if isempty(cellfind(INPLANE)) && isempty(cellfind(VOLUME)) && ...
        isempty(cellfind(FLAT))
    disp('No open mrVista UIs. Initializing a hiddden inplane...')
    try
        vw = initHiddenInplane;
    catch
        disp('Couldn''t start a hidden inplane -- not in a mrVista session!')
    end
    return
end

% check if gcf is a view handle
for i = cellfind(INPLANE)
    if checkfields(INPLANE{i}, 'ui', 'windowHandle') && ...
            isequal(INPLANE{i}.ui.windowHandle, gcf)
        vw = INPLANE{i};
        return
    end
end
for i = cellfind(VOLUME)
    if checkfields(VOLUME{i}, 'ui', 'windowHandle') && ...
            isequal(VOLUME{i}.ui.windowHandle, gcf)
        vw = VOLUME{i};
        return
    end
end
for i = cellfind(FLAT)
    if checkfields(FLAT{i}, 'ui', 'windowHandle') && ...
            isequal(FLAT{i}.ui.windowHandle, gcf)
        vw = FLAT{i};
        return
    end
end

% None of the above worked; try to get selected inplane/volume/flat
if isempty(vw), vw = getSelectedInplane; end
if isempty(vw), vw = getSelectedVolume;  end
if isempty(vw), vw = getSelectedFlat;    end

% Report on failure
if isempty(vw)
    disp('Failed to find any views ... returning empty')
end

return


% uiputfile2() - same as uigputfile but remember folder location.
%
% Usage: >> uiputfile2(...)
%
% Inputs: Same as uiputfile
%
% Author: Arnaud Delorme & Hilit Serby, Scott Makeig, SCCN, UCSD, 2004
%         Thanks to input from Bas Kortmann
%
% Copyright (C) Arnaud Delorme & Hilit Serby, Scott Makeig, SCCN, UCSD, 2004

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

function varargout = uiputfile2(varargin);

    if nargin < 1
        help uiputfile2;
        return;
    end;

    % remember old folder
    %% search for the (mat) file which contains the latest used directory
    % -------------------
    olddir = pwd;
    try,
        eeglab_options;
        if option_rememberfolder
            tmp_fld = getenv('TEMP');
            if isempty(tmp_fld) & isunix
                if exist('/tmp') == 7
                    tmp_fld = '/tmp';
                end;
            end;
            if exist(fullfile(tmp_fld,'eeglab.cfg'))
                load(fullfile(tmp_fld,'eeglab.cfg'),'Path','-mat');
                s = ['cd([''' Path '''])'];
                if exist(Path) == 7, eval(s); end;
            end;
        end;
    catch, end;

    %% Show the open dialog and save the latest directory to the file
    % ---------------------------------------------------------------
    [varargout{1} varargout{2}] = uiputfile(varargin{:});
    try,
        if option_rememberfolder
            if varargout{1} ~= 0
                Path = varargout{2};
                try, save(fullfile(tmp_fld,'eeglab.cfg'),'Path','-mat','-V6'); % Matlab 7
                catch,
                    try,  save(fullfile(tmp_fld,'eeglab.cfg'),'Path','-mat');
                    catch, error('uigetfile2: save error, out of space or file permission problem');
                    end
                end
                if isunix
                    eval(['cd ' tmp_fld]);
                    system('chmod 777 eeglab.cfg');
                end
            end;
        end;
    catch, end;
    cd(olddir)


function initialized = fgrabm_isinit()
%initialized = FGRABM_ISINIT() FrameGrabM Tell if initialized
%   FGRABM_ISINIT will return true if FrameGrabM and the underlying
%   LTI-CIVIL library is already initialized.
%
%   Version 0.8 - 06 March 2012
global FGRABM

% Had we initialized?
if isempty(FGRABM)
    initialized = false;
    return;
end

initialized = FGRABM.class.getState();


function print_same_line(string)

% This code has been taken from Les Schaffer on comp.soft-sys.matlab
% Hope he will not mind having this sudden fame.
% Send any comment to lerouxni@iro.umontreal.ca

% small function to print a string starting from the beginning of the
% actual line

%%  the ascii code for starting an escape sequence
esc_code = 27;

%% clear to end of line
%% ESC [2K
er = [ char(esc_code) '[' '2' 'K' ];

%% goto beginning of line
%% ESC [1G
bl = [ char(esc_code) '[' '1' 'G' ];

new_string = strcat(bl, er, string);
fprintf(1, new_string);