function main_image = PTKGetMainRegionExcludingPaddingBorder(original_image, threshold_image, minimum_region_volume_mm3, include_interior_regions, reporting)
    % PTKGetMainRegionExcludingPaddingBorder. Finds the largest connected region in a
    % binary 3D volume, excluding any regions which touch an inner border
    % created by extending an inner padding ring from the top and bottom of the image and growing horizontally.
    %
    % This is a heuristic that find the lung region while excluding regions exterior to the body even
    % if they are connected to the exterior through the airways or by the
    % lung extending beyond the image limits.
    %
    % Syntax:
    %     main_image = PTKGetMainRegionExcludingPaddingBorder(threshold_image, reporting)
    %
    % Inputs:
    %     threshold_image - a binary 3D volume as a PTKImage.
    %
    %     minimum_region_volume_mm3 (optional) - ignore any regions below this
    %         threshold
    %
    %     include_interior_regions - if true, the segmentation will include
    %         interior disconnected regions within the ROI even though they
    %         might not be part of the lungs and airways. Generally this
    %         might be set to true when finding a mask for airway
    %         segmentation, but set to false when finding a mask for lung
    %         segmentation
    %
    %     reporting (optional) - an object implementing the CoreReporting
    %         interface for reporting progress and warnings
    %
    % Outputs:
    %     main_image - a PTKImage binary volume of the found region
    %
    %
    %     Licence
    %     -------
    %     Part of the TD Pulmonary Toolkit. https://github.com/tomdoel/pulmonarytoolkit
    %     Author: Tom Doel, 2012.  www.tomdoel.com
    %     Distributed under the GNU GPL v3 licence. Please see website for details.
    %

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

    if nargin < 2 || isempty(minimum_region_volume_mm3)
        minimum_region_volume_mm3 = 0;
    end

    if nargin < 3
        reporting = CoreReportingDefault;
    end

    reporting.ShowProgress('Finding lung region');

    if ~isempty(threshold_image.PaddingValue)
        padding_image = original_image.RawImage == threshold_image.PaddingValue;
    else
        padding_image = false(original_image.ImageSize);
    end
    padding_image(1, :, :) = true;
    padding_image(end, :, :) = true;
    padding_image(:, 1, :) = true;
    padding_image(:, end, :) = true;
    threshold_excluding_padding = threshold_image.RawImage > 0;
    threshold_excluding_padding(padding_image) = false;

    % Find an inner border of the padding at the top of the image
    top_slice_padding = padding_image(:, :, 1);
    top_slice_padding = imdilate(top_slice_padding, strel([0 1 0; 1 1 1; 0 1 0]), 'same');
    top_slice_connect_points = top_slice_padding & threshold_excluding_padding(:, :, 1);

    % Find an inner border of the padding at the bottom of the image
    bottom_slice_padding = padding_image(:, :, 1);
    bottom_slice_padding = imdilate(bottom_slice_padding, strel([0 1 0; 1 1 1; 0 1 0]));
    bottom_slice_connect_points = bottom_slice_padding & threshold_excluding_padding(:, :, end);

    vert_con = zeros([3,3,3]);
    vert_con(:,:,1) = [0 0 0; 0 1 0; 0 0 0];
    vert_con(:,:,2) = [0 0 0; 0 1 0; 0 0 0];
    vert_con(:,:,3) = [0 0 0; 0 1 0; 0 0 0];
    vert_cc = bwconncomp(threshold_excluding_padding, vert_con);
    lm_vert = labelmatrix(vert_cc);
    lm_vert_top = lm_vert(:, :, 1);
    lm_vert_bottom = lm_vert(:, :, end);
    top_border_indices = lm_vert_top(top_slice_connect_points(:));
    bottom_border_indices = lm_vert_bottom(bottom_slice_connect_points(:));
    vert_border_indices = unique([top_border_indices; bottom_border_indices]);

    % We extend each point of the inner border from the top and bottom of
    % the image vertically until they encounter non-air voxels. The
    % resulting set of voxels we define as border points.
    is_border_point = ismember(lm_vert, vert_border_indices);

    % Now get horizontal connected components
    hor_con = zeros([3,3,3]);
    hor_con(:,:,2) = [0 1 0; 1 1 1; 0 1 0];
    cc_hor = bwconncomp(threshold_excluding_padding, hor_con);
    lm_hor = labelmatrix(cc_hor);

    % Remove horizontal components that are connected to the border points
    % we determined earlier
    hor_border_indices = unique(lm_hor(is_border_point(:)));
    remove_points = ismember(lm_hor, hor_border_indices);

    threshold_excluding_padding(remove_points) = false;

    bordered_image = true(threshold_image.ImageSize + [2 2 2]);
    bordered_image(2:end-1, 2:end-1, 2:end-1) = threshold_excluding_padding;
    bordered_image(2:end-1, 2:end-1, 1) = false;
    bordered_image(2:end-1, 2:end-1, end) = false;

    image_opening_params_mm = [0, 2, 4, 6];
    image_opening_index = 1;
    still_searching = true;
    if max(threshold_image.VoxelSize) >= 2
        connectivity = 6;
    else
        connectivity = 26;
    end

    last_ball_element = -1;

    while still_searching

        opening_mm = image_opening_params_mm(image_opening_index);
        if opening_mm > 0
            ball_element = CoreImageUtilities.CreateBallStructuralElement(threshold_image.VoxelSize, opening_mm);
        else
            ball_element = [];
        end
        if isequal(ball_element, last_ball_element)
            % We skip the next opening if the structural element is
            % the same as last time (which could happen with large voxel
            % sizes)
            results = [];
        else
            if include_interior_regions
                max_num_regions = 10000;
            else
                max_num_regions = 2;
            end
            [results, CC] = OpenAndGetRegions(bordered_image, ball_element, connectivity, threshold_image.VoxelSize, minimum_region_volume_mm3, max_num_regions, ~include_interior_regions, reporting);
        end
        if numel(results) > 0 || image_opening_index == numel(image_opening_params_mm)
            still_searching = false;
        else
            image_opening_index = image_opening_index + 1;
            last_ball_element = ball_element;
        end
    end

    if numel(results) == 0
        reporting.Error('PTKGetMainRegionExcludingPaddingBorder:Failed', 'Unable to extract the main image region');
    end

    if ~include_interior_regions
        % Unless we include all interior regions, then determine whether to
        % combine the two results or only choose one of them
        if numel(results) > 1
            % If more than one region was found (after excluding boundary-touching
            % regions), then check if they are disconnected left and right lungs
            bounding_boxes = regionprops(CC, 'BoundingBox');
            bb_1 = bounding_boxes(results(1)).BoundingBox;
            bb_1 = bb_1([2,1,3,5,4,6]); % Bounding box is [xyz] but Matlab indices are [yxz]
            bb_2 = bounding_boxes(results(2)).BoundingBox;
            bb_2 = bb_2([2,1,3,5,4,6]); % Bounding box is [xyz] but Matlab indices are [yxz]
            image_centre = round(size(bordered_image)/2);

            image_centre_j = image_centre(2);
            centre_offset = round(image_centre_j/2);

            use_both_regions = false;
            if (bb_1(2) >= image_centre_j - centre_offset) && (bb_2(5) + bb_2(2) < image_centre_j + centre_offset)
                reporting.LogVerbose('I appear to have found 2 disconnected lungs. I am connecting them.');
                use_both_regions = true;
            end

            if (bb_2(2) >= image_centre_j - centre_offset) && (bb_1(5) + bb_1(2) < image_centre_j + centre_offset)
                reporting.LogVerbose('I appear to have found 2 disconnected lungs. I am connecting them.');
                use_both_regions = true;
            end
        else
            use_both_regions = false;
        end
    end

    bordered_image(:) = false;
    if include_interior_regions
        % Include ALL regions
        for index = 1 : numel(results)
            bordered_image(CC.PixelIdxList{results(index)}) = true;
        end
    else
        % Include the main or the main two regions
        bordered_image(CC.PixelIdxList{results(1)}) = true;
        if use_both_regions
            bordered_image(CC.PixelIdxList{results(2)}) = true;
        end
    end

    main_image = threshold_image.BlankCopy;
    main_image.ChangeRawImage(bordered_image(2:end-1, 2:end-1, 2:end-1));
end

function [results, CC] = OpenAndGetRegions(bordered_image_input, ball_element, connectivity, voxel_size, minimum_region_volume_mm3, max_num_regions, exclude_out_of_roi, reporting)

    bordered_image = bordered_image_input;
    if ~isempty(ball_element)
        bordered_image = imopen(bordered_image_input > 0, ball_element);
    end

    % Borders are marked as segmented - this ensures all components
    % touching the border are connected and allows us to eliminate them
    % when extracting the lung

    % Obtain connected component matrix
    CC = bwconncomp(bordered_image, connectivity);
    stats = regionprops(CC, 'BoundingBox');

    % Find largest region
    num_pixels = cellfun(@numel, CC.PixelIdxList);
    [sorted_largest_areas, sorted_largest_areas_indices] = sort(num_pixels, 'descend');

    % Remove regions that are below the volume threshold - NOTE we must
    % reduce the size due to possible gaps due to noise
    pixel_volume = prod(voxel_size);

    small_area_mask = pixel_volume*sorted_largest_areas >= minimum_region_volume_mm3/100;
    sorted_largest_areas_indices = sorted_largest_areas_indices(small_area_mask);
    sorted_largest_areas = sorted_largest_areas(small_area_mask);

    result_index = 1;
    results = [];
    index_in_sorted_array = 1;
    while (result_index <= max_num_regions && index_in_sorted_array <= length(sorted_largest_areas_indices))
        current_region_being_checked = sorted_largest_areas_indices(index_in_sorted_array);
        bordered_image(:) = false;
        bordered_image(CC.PixelIdxList{current_region_being_checked}) = true;
        if (bordered_image(1) || bordered_image(end))
            % This region is connected to the edge
%             reporting.ShowMessage('PTKGetMainRegionExcludingBorder:LargestROIConnectedToExterior', 'The largest region connected with the edge of the volume. I''m assuming this region is outside the body so choosing the next largest region');
        else
            bb = stats(current_region_being_checked).BoundingBox;
            if exclude_out_of_roi && (bb(2) > (5/9)*size(bordered_image_input, 2))
                disp('removed');
                % ToDo
            else
                results(result_index) = current_region_being_checked;
                result_index = result_index + 1;
            end
        end
        index_in_sorted_array = index_in_sorted_array + 1;
    end
end


function line = extractAreaLine(area_data)

% EXTRACTS THE LINE STYLE USED FOR MATLAB OBJECTS
% OF TYPE "LINE". THESE OBJECTS ARE USED IN LINESERIES,
% STAIRSERIES, STEMSERIES, BASELINESERIES, AND BOXPLOTS

%-------------------------------------------------------------------------%

%-INITIALIZE OUTPUT-%
line = struct();

%-------------------------------------------------------------------------%

%-AREA LINE COLOR-%

if(~strcmp(area_data.LineStyle,'none'))

    % marker edge color
    LineColor = area_data.EdgeColor;

    if isnumeric(LineColor)
        col = 255*LineColor;
        linecolor = ['rgb(' num2str(col(1)) ',' num2str(col(2)) ',' num2str(col(3)) ')'];
    else
        linecolor = 'rgba(0,0,0,0)';
    end

    line.color = linecolor;

%-------------------------------------------------------------------------%

    %-PATCH LINE WIDTH (STYLE)-%
    line.width = area_data.LineWidth;

%-------------------------------------------------------------------------%

    %-PATCH LINE DASH (STYLE)-%
    switch area_data.LineStyle
        case '-'
            LineStyle = 'solid';
        case '--'
            LineStyle = 'dash';
        case ':'
            LineStyle = 'dot';
        case '-.'
            LineStyle = 'dashdot';
    end

    line.dash = LineStyle;

%-------------------------------------------------------------------------%

end
end


function value = p15_i4 ( action, name, value )

%*****************************************************************************80
%
%% P15_I4 sets or gets I4 parameters for problem 15.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string ACTION,
%    'D' to set a parameter to its default value.
%    'S' to set a parameter,
%    'G' to get a parameter,
%    'I' to increment a parameter.
%
%    Input, string NAME, the name of the variable.
%    '#' is the number of calls to the integrand routine.
%    'N' is the number of factors to multiply in the integrand.
%
%    Input/output, integer VALUE.
%    * If ACTION = 'I', then VALUE is an input quantity, and is the
%      new value to be added to NAME.
%    * If ACTION = 'S', then VALUE is an input quantity, and is the
%      new value to be assigned to NAME.
%    * If ACTION = 'G', then VALUE is an output quantity, and is the
%      current value of NAME.
%
  persistent calls;
  persistent n;

  if ( action == 'D' | action == 'd' )

    if ( name == '#' | name == '*' )
      calls = 0;
    end

    if ( name == 'n' | name == 'N' | name == '*' )
      n = 1;
    end

  elseif ( action == 'G' | action == 'g' )

    if ( name == '#' )
      value = calls;
    elseif ( name == 'n' | name == 'N' )
      value = n;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P15_I4 - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized name = "%s".\n', name );
      error ( 'P15_I4 - Fatal error!' );
    end

  elseif ( action == 'I' | action == 'i' )

    if ( name == '#' )
      calls = calls + value;
    elseif ( name == 'n' | name == 'N' )
      n = n + value;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P15_I4 - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized name = "%s".\n', name );
      error ( 'P15_I4 - Fatal error!' );
    end

  elseif ( action == 'S' | action == 's' )

    if ( name == '#' )
      calls = value;
    elseif ( name == 'n' | name == 'N' )
      n = value;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P15_I4 - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized name = "%s".\n', name );
      error ( 'P15_I4 - Fatal error!' );
    end

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'P15_I4 - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized action = "%s".\n', action );
    error ( 'P15_I4 - Fatal error!' );

  end

  return
end


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


function option_num = p16_option_num ( )

%*****************************************************************************80
%
%% P16_OPTION_NUM returns the number of options for problem 16.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer OPTION_NUM, the number of options.
%
  option_num = 1;

  return
end


function title = p23_title ( )

%*****************************************************************************80
%
%% P23_TITLE returns a title for problem 23.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 December 2000
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, a title for the problem.
%
  title = 'The De Jong Function F2';

  return
end


load cameraRTxj.mat

addpath /n/fs/vision/www/pvt/
addpath /n/fs/vision/www/pvt/drawCamera/

scale = 0.0001;

drawCameraPly('~/Downloads/cam1.ply',extrinsicsC2WframeTestDevice{1},scale);
drawCameraPly('~/Downloads/cam2.ply',extrinsicsC2WframeTestDevice{2},scale);
drawCameraPly('~/Downloads/cam3.ply',extrinsicsC2WframeTestDevice{3},scale);
drawCameraPly('~/Downloads/cam4.ply',extrinsicsC2WframeTestDevice{4},scale);


% pop_compareerps() - Compare the (ERP) averages of two datasets.
%
% Usage:
%       >> pop_compareerps( ALLEEG, datasetlist, chansubset, title);
% Inputs:
%   ALLEEG      - array of datasets
%   datasetlist - list of datasets
%   chansubset  - vector of channel subset
%   title       - plot title
%
% Author: Arnaud Delorme, CNL / Salk Institute, 2001
%
% See also: eeglab(), plottopo()

% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% 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

% 01-25-02 reformated help & license -ad
% 03-11-02 added empty ALLEEG check -ad
% 03-18-02 added channel subset -ad
% 03-18-02 added title -ad & sm
function com = pop_compareerps( ALLEEG, setlist, chansubset, plottitle);

com = '';
if nargin < 1
   help pop_compareerps;
   return;
end;
if isempty(ALLEEG)
    error('pop_compareerps: cannot process empty sets of data');
end;
if exist('plottitle') ~= 1
	plottitle = '';
end;
if nargin < 2
   % which set to save
	% -----------------
	promptstr    = { 'List of datasets to compare (ex: 1 3 4):' ...
	                 'Channels subset to consider ([]=all):' ...
	                 'Plot title ([]=automatic):' };
	inistr       = { '1' '' '' };
	result       = inputdlg2( promptstr, 'Compare dataset ERPs -- pop_compareerps()', 1,  inistr, 'pop_compareerps');
	if length(result) == 0 return; end;
	setlist   	 = eval( [ '[' result{1} ']' ] );
	chansubset   = eval( [ '[' result{2} ']' ] );
	if isempty( chansubset ), chansubset = 1:ALLEEG(setlist(1)).nbchan; end;
	plottitle    = result{3};
    if isempty(plottitle)
        plottitle = [ 'Compare datasets number (blue=first; red=sec.)' int2str(setlist) ];
    end;
    figure;
end;
try, icadefs; set(gcf, 'color', BACKCOLOR); catch, end;
tracing = [];
for setindex = setlist
	tracing  = [ tracing squeeze(mean(ALLEEG(setindex).data,3))];
end;

% save channel names
% ------------------
plottopo( tracing, ALLEEG(setlist(1)).chanlocs, ALLEEG(setlist(1)).pnts, [ALLEEG(setlist(1)).xmin ALLEEG(setlist(1)).xmax 0 0]*1000, plottitle, chansubset );

com = sprintf('figure; pop_compareerps( %s, [%s], [%s], ''%s'');', inputname(1), num2str(setlist), num2str(chansubset), plottitle);
return;


function varargout = animation(varargin)
% ANIMATION M-file for animation.fig
%      ANIMATION, by itself, creates a new ANIMATION or raises the existing
%      singleton*.
%
%      H = ANIMATION returns the handle to a new ANIMATION or the handle to
%      the existing singleton*.
%
%      ANIMATION('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in ANIMATION.M with the given input arguments.
%
%      ANIMATION('Property','Value',...) creates a new ANIMATION or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before animation_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to animation_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 animation
% Last Modified by GUIDE v2.5 09-Jul-2013 19:10:43
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file is part of OLPS: http://OLPS.stevenhoi.org/
% Original authors: Doyen Sahoo
% Contributors: Bin LI, Steven C.H. Hoi
% Change log:
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

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

    handles.portfolio = varargin{1};
    handles.windowAnimation = varargin{2};
    handles.status = 1;
    [r c] = size(handles.portfolio);
    handles.nframes = r;
    handles.c = c;
    guidata(hObject, handles);

    startAnimating(hObject, eventdata, handles, varargin);

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

    % Update handles structure
    guidata(hObject, handles);
% UIWAIT makes animation wait for user response (see UIRESUME)
% uiwait(handles.animationGui);

function startAnimating(hObject, eventdata, handles, varargin)
    c = handles.c;
    handles.status = 1;

    try
        for i = 1:handles.nframes
            start = max(1, i-handles.windowAnimation+1);
            finish = i;
            toPlot = mean(handles.portfolio(start:finish,:));
            bar(handles.animationGraph,toPlot);
            axis([0.5 (c+0.5) 0 1]);
            grid on;
            if ishandle(handles.animationGui)
                M(i) = getframe;
                set(handles.time,'String',strcat('Time Period: ', int2str(i)));
            else
                return;
            end
            if handles.status == 0
                return;
            end
        end
    catch exception
    end

    handles.output = hObject;

% --- Outputs from this function are returned to the command line.
function varargout = animation_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 closeAnimation.
function closeAnimation_Callback(hObject, eventdata, handles)
% hObject    handle to closeAnimation (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    handles.status = 0;
    guidata(hObject, handles);
    close(handles.animationGui);


load uav1u
a1 = A;
load uav2u
a2 = A;
load uav3u
a3 = A;

n1 = 3890;
plot3(a1(1:n1,2), a1(1:n1,3),a1(1:n1,4)); hold on;
plot3(a2(1:n1,2), a2(1:n1,3),a2(1:n1,4)); hold on;
plot3(a3(1:n1,2), a3(1:n1,3),a3(1:n1,4)); hold on;
axis equal


function ic = ic(icfh, x_struct,p_struct,x,p, userdata)
% initial condition function
icHandler = ocl.Constraint(userdata);
x = ocl.Variable.create(x_struct,x);
p = ocl.Variable.create(p_struct,p);
icfh(icHandler,x,p)
ic = icHandler.values;
assert(all(icHandler.lowerBounds==0) && all(icHandler.upperBounds==0),...
  'In initial condition are only equality constraints allowed.');


function varargout = KUKA_GUI(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @KUKA_GUI_OpeningFcn, ...
                   'gui_OutputFcn',  @KUKA_GUI_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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%                                                                        %%
%%%                  Written by Rohit Mishra                               %%
%%%                  A.C. Patil College of Engg.                                            %%
%%%                  March 2013                                            %%
%%%                  Simulation of six axis kuka kr6.                      %%
%%%                                                                        %%
%%%      The purpose of this program is to simulate a six axis kuka kr6    %%
%%%      robot located in the DRHR DEPT. at BARC MUMBAI .  This            %%
%%%      program simulates Forward Kinematics of this robot.               %%
%%%      To operate this program:                                          %%
%%%           1)     Make sure that KUKA.WRL, KUKA_GUI.fig, KUKA_GUI.m     %%
%%%                  are in the appropriate path.                          %%
%%%           2)     Execute KUKA_GUI.m                                    %%
%%%           4)     Have fun!                                             %%
%%%      If you have question about this program email Rohit Mishra        %%
%%%      <mishra.rohit2410@gmail.com> .  Rohit Mishra is Final Year Student%%
%%%      from Mumbai University(ACPCE, TRONIX 2013)has developed this      %%
%%%      project with the help of his friends Tejas Mahadik, Kaushik       %%
%%%      Natrajan and  Siddhesh Chavan .                                   %%
%%%      We are thankful to our project guide and HOD Dr. V.N. Pawar for   %%
%%%      his unwavering support and guidance in helping us with this       %%
%%%      project and also to Mrs. Varsha Shirwalkar at Barc, Mumbai.       %%
%%%                                                                        %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function KUKA_GUI_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
KUKA = vrworld('KUKA.wrl');
open(KUKA)
view(KUKA)

    radian=0
    KUKA.shoulder.rotation = [0, 1, 0, radian];

    KUKA.elbow.rotation = [0, 0, 1, radian];

    KUKA.pitch.rotation = [0, 0, 1, radian];

    KUKA.roll.rotation = [1, 0, 0, radian];

    KUKA.yaw.rotation = [0, 0, 1, radian];

    KUKA.drill.rotation = [1, 0, 0, radian];

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T1=get(handles.slider1,'value');
set(handles.edit57,'String',num2str(T1));
guidata(hObject, handles);
    radian=T1*pi/180;
    q1=radian;
    KUKA.shoulder.rotation = [0, 1, 0, radian];

% --- Executes on slider movement.
function slider2_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T2=get(handles.slider2,'value');
set(handles.edit58,'String',num2str(T2));
guidata(hObject, handles);
    radian=T2*pi/180;
    q2=radian;
    KUKA.elbow.rotation = [0, 0, 1, radian];

% --- Executes on slider movement.
function slider3_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T3=get(handles.slider3,'value');
set(handles.edit59,'String',num2str(T3));
guidata(hObject, handles);
    radian=T3*pi/180;
    q3=radian;
    KUKA.pitch.rotation = [0, 0, 1, radian];

% --- Executes on slider movement.
function slider4_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T4=-get(handles.slider4,'value');
set(handles.edit60,'String',num2str(T4));
guidata(hObject, handles);
    radian=T4*pi/180;
    q4=radian;
    KUKA.roll.rotation = [1, 0, 0, radian];

% --- Executes on slider movement.
function slider5_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T5=-get(handles.slider5,'value');
    set(handles.edit61,'String',num2str(T5));
    guidata(hObject, handles);
    radian=T5*pi/180;
    q5=radian;
    KUKA.yaw.rotation = [0, 0, 1, radian];

    % --- Executes on slider movement.
function slider6_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T6=-get(handles.slider6,'value');
set(handles.edit62,'String',num2str(T6));
guidata(hObject, handles);
    radian=T6*pi/180;
    q6=radian;
    KUKA.drill.rotation = [1, 0, 0, radian];

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)

% % % GIVEN JOINT VARIABLES

d=[335   0   0   -295    0   -80];
a=[75    270 90  0   0   0];

% % TRANSFORMATION MATRIX 1.
q1=get(handles.slider1,'Value');
T1=[    cos(q1)     0       -sin(q1) a(1)*cos(q1)
        sin(q1)     0       -cos(q1) a(1)*sin(q1)
        0           -1          0       d(1)
        0           0           0        1      ];

% % TRANSFORMATION MATRIX 2.
q2=get(handles.slider2,'Value');
T2=[    cos(q2)     -sin(q2)    0   a(2)*cos(q2)
        sin(q2)     cos(q2)     0   a(2)*sin(q2)
        0               0       1       0
        0               0       0       1   ];

% % TRANSFORMATION MATRIX 3.
q3=get(handles.slider3,'Value');
T3=[    cos(q3)         0    sin(q3)   a(3)*cos(q3)
        sin(q3)         0    -cos(q3)   a(3)*sin(q3)
        0               0       0       0
        0               0       0       1   ];
% % TRANSFORMATION MATRIX 4.
q4=get(handles.slider4,'Value');
T4=[    cos(q4)         0   -sin(q4)    0
        sin(q4)         0    cos(q4)    0
        0              -1       0      d(4)
        0               0       0       1   ];

% % TRANSFORMATION MATRIX 5.
q5=get(handles.slider5,'Value');
T5=[    cos(q5)     0       sin(q5)           0
        sin(q5)     0       -cos(q5)          0
        0           1          0               0
        0           0          0               1       ];

% % TRANSFORMATION MATRIX 6.
q6=get(handles.slider6,'Value');
T6=[    cos(q6)     -sin(q6)        0           0
        sin(q6)     cos(q6)     0               0
        0           0           1           0
        0           0           0               1   ];

A=T1*T2*T3*T4*T5*T6;

set(handles.edit42,'String',num2str(A(13)));
set(handles.edit43,'String',num2str(A(14)));
set(handles.edit44,'String',num2str(A(15)));
set(handles.edit48,'String',num2str(A(1)));
set(handles.edit49,'String',num2str(A(5)));
set(handles.edit50,'String',num2str(A(9)));
set(handles.edit51,'String',num2str(A(2)));
set(handles.edit52,'String',num2str(A(6)));
set(handles.edit53,'String',num2str(A(10)));
set(handles.edit54,'String',num2str(A(3)));
set(handles.edit55,'String',num2str(A(7)));
set(handles.edit56,'String',num2str(A(11)));
guidata(hObject, handles);


classdef ScalarNodalPrinter < ScalarPrinter

    properties (Access = private)
        nDecimalPositions = 12
    end

    methods (Access = public)

        function obj = ScalarNodalPrinter(d)
            obj.init(d);
            obj.createFieldRepresenter();
            obj.print();
        end

    end

    methods (Access = private)

        function init(obj,d)
            fieldsNames = fieldnames(d);
            for ifield = 1:length(fieldsNames)
                fieldName = fieldsNames{ifield};
                fieldValue = d.(fieldName);
                obj.(fieldsNames{ifield}) = fieldValue;
            end
        end

        function roundFieldValues(obj)
            obj.fieldValues = round(obj.fieldValues,obj.nDecimalPositions);
        end

        function createFieldRepresenter(obj)
            s.fileID        = obj.fileID;
            s.fieldName     = obj.fieldName;
            s.simulationStr = obj.simulationStr;
            s.iter          = obj.iter;
            s.fieldType     = obj.fieldType;
            s.fieldPosition = obj.fieldPosition;
            s.fieldValues   = obj.fieldValues;
            s.nComp         = 1;
            obj.fieldRepresenter = NodalFieldPrinter(s);
        end

    end

end


function test_bug2032

% WALLTIME 00:20:00
% MEM 2gb
% DEPENDENCY

% read each of the atlasses and ensure that it specifies the units and coordsys

[ftver, ftpath] = ft_version;

%%

filename = {
  'template/atlas/aal/ROI_MNI_V4.nii'
  'template/atlas/afni/TTatlas+tlrc.BRIK'
  'template/atlas/brainweb/brainweb_discrete.mat'
  'template/atlas/brainweb/brainweb_fuzzy.mat'
  'template/atlas/spm_anatomy/AllAreas_v17.img'
  'template/atlas/spm_anatomy/AllAreas_v18.img'
  'template/atlas/vtpm/vtpm.mat'
  };

for i=1:numel(filename)
  atlas = ft_read_atlas(fullfile(ftpath, filename{i}));
  assert(isfield(atlas, 'unit'), sprintf('unit missing in %s', filename{i}));
  assert(isfield(atlas, 'coordsys'), sprintf('coordsys missing in %s', filename{i}));
end

%%

% the inflated ones do not have a coordsys
%  'template/anatomy/surface_inflated_both.mat'
%  'template/anatomy/surface_inflated_both_caret.mat'
%  'template/anatomy/surface_inflated_left.mat'
%  'template/anatomy/surface_inflated_left_caret.mat'
%  'template/anatomy/surface_inflated_right.mat'
%  'template/anatomy/surface_inflated_right_caret.mat'

filename = {
  'template/anatomy/surface_pial_both.mat'
  'template/anatomy/surface_pial_left.mat'
  'template/anatomy/surface_pial_right.mat'
  'template/anatomy/surface_white_both.mat'
  'template/anatomy/surface_white_left.mat'
  'template/anatomy/surface_white_right.mat'
  };

for i=1:numel(filename)
  surface = ft_read_headshape(fullfile(ftpath, filename{i}));
  assert(isfield(surface, 'unit'), sprintf('unit missing in %s', filename{i}));
  assert(isfield(surface, 'coordsys'), sprintf('coordsys missing in %s', filename{i}));
end


function title = p09_title ( )

%*****************************************************************************80
%
%% P09_TITLE returns the title of problem 09.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 August 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, the title of the problem.
%
  title = 'Sunspot data, 1700-1960.';

  return
end


%MetabolicReaction
%
% @wholeCellModelID State_MetabolicReaction
% @name             Metabolic reaction
% @description
%
% Author: Jonathan Karr, jkarr@stanford.edu
% Affilitation: Covert Lab, Department of Bioengineering, Stanford University
% Last updated: 1/5/2011
classdef MetabolicReaction < edu.stanford.covert.cell.sim.CellState
    %property annotations
    properties (Constant)
        optionNames             = {   %names of properties that are options
            'verbosity';
            'seed';
            };
        fixedConstantNames      = {}; %names of process properties that are considered fixed constants
        fittedConstantNames     = {}; %names of process properties that are considered fitted constants, and should be stored with the simulation as such
        stateNames              = {   %names of properties which are part of the simulation's state
            'growth';
            'fluxs';
            };
        dependentStateNames     = {   %names of properties which can be calculated from the simulation's state
            'doublingTime'
            };
    end

    %constants
    properties
        reactionWholeCellModelIDs  %reaction whole cell model ids
        growth0                    %target growth rate
        initialGrowthFilterWidth   %tolerance of initial growth rate
        meanInitialGrowthRate      %mean initial growth rate
    end

    %state
    properties
        growth  %growth rate (cell/s)
        fluxs   %flux of each reaction, size: [length(reactionWholeCellModelIDs) X 1 X time] (rxn/s)
    end

    %dependent state
    properties (Dependent = true, SetAccess = protected)
        doublingTime  %doubling time (s)
    end

    %dependent state
    properties (Constant)
        dryWeight = 0; %dry weight of this class' state properties
    end

    %constructor
    methods
        function this = MetabolicReaction(wholeCellModelID, name)
            this = this@edu.stanford.covert.cell.sim.CellState(wholeCellModelID, name);
        end
    end

    methods
        function initializeConstants(this, knowledgeBase, simulation)
            this.initializeConstants@edu.stanford.covert.cell.sim.CellState(knowledgeBase, simulation);

            m = findobj(knowledgeBase.processes, 'wholeCellModelID', 'Process_Metabolism');
            this.reactionWholeCellModelIDs = {m.reactions.wholeCellModelID}';
        end
    end

    %allocate memory for state
    methods
        function allocateMemory(this, numTimePoints)
            this.growth = zeros(1, 1, numTimePoints);
            this.fluxs  = zeros(numel(this.reactionWholeCellModelIDs), 1, numTimePoints);
        end
    end

    %initialize state
    methods
        function initialize(~)
        end
    end

    %getters
    methods
        %doubling time (seconds/cell)
        function value = get.doublingTime(this)
            value = 1 ./ this.growth;
        end
    end
end


% longitudinally_register_scans_multi_series.m
% dirName = 'L:\Aditya\SPIdemoProject\CERRfiles';
% filesC = {'05_19_2010.mat', '08_25_2010.mat', '02_09_2011.mat', '06_04_2011.mat',...
% '11_26_2011.mat', '03_17_2012.mat', '07_21_2012.mat'};

%dirName = '/mnt/RadShared2/Aditya/cerr_data';
dirS = dir(dirName);
dirS(1:2) = [];
fileNamesC = {dirS.name};

% Get accession numbers, dates, seried id's of all files
[mrnC,remC] = strtok(fileNamesC,'~');
[accessionC,remC] = strtok(remC,'~');
[seriesC,remC] = strtok(remC,'~');
[dateC,remC] = strtok(remC,'~');

% Sort filesC by exam dates
[~,indSortV] = sort(datenum(dateC,'yyyymmdd'));
dateAllV = datenum(dateC,'yyyymmdd');
dateAllV = dateAllV(indSortV);
fileNamesC = fileNamesC(indSortV);
accessionC = accessionC(indSortV);
seriesC = seriesC(indSortV);
dateC = dateC(indSortV);

% Group Scans by accession number
[dateV, indV, uniqueIndexV] = unique(dateAllV);
dateC = dateC(indV);

for i=1:length(dateV)
    scanLesions{i} = [];
    scanXDims{i} = [];
    scanYDims{i} = [];
    scanZDims{i} = [];
    scanFileNames{i} = [];
end

% Find and Record Lesions, scan dates and scan uids on all Scans
for i=1:length(fileNamesC)
    filename = fullfile(dirName,fileNamesC{i});

    planC = loadPlanC(filename,tempdir);
    [planC, isUIDCreated] = updatePlanFields(planC);
    planC = quality_assure_planC(filename, planC, isUIDCreated);
    indexS = planC{end};
    seriesDescription = planC{indexS.scan}.scanInfo(1).DICOMHeaders.SeriesDescription;
    if ~strncmp('CORONAL', seriesDescription,7) && ...
            ~strncmp('SAGITTAL', seriesDescription,8)
        scanNum = 1;
        lesionS = findLesions(scanNum,planC);
        scanLesions{uniqueIndexV(i)} = [scanLesions{uniqueIndexV(i)} lesionS];
        planC = segmentLesions(planC,lesionS);
        planC = save_planC(planC,[],'passed',filename);
        scanFileNames{uniqueIndexV(i)} = [scanFileNames{uniqueIndexV(i)}, {filename}];
        [xV,yV,zV] = getScanXYZVals(planC{indexS.scan},planC);
        scanXDims{uniqueIndexV(i)} = [scanXDims{uniqueIndexV(i)}; min(xV) max(xV)];
        scanYDims{uniqueIndexV(i)} = [scanYDims{uniqueIndexV(i)}; min(yV) max(yV)];
        scanZDims{uniqueIndexV(i)} = [scanZDims{uniqueIndexV(i)}; min(zV) max(zV)];
        filename
        seriesDescription
    else
        filename
        seriesDescription
    end
    scanNum = 1;
    scanDatesV(i) = datenum(planC{indexS.scan}.scanInfo(1).scanDate,'yyyymmdd');
    scanUIDc{i} = planC{indexS.scan}.scanUID;
end

% ---- Code to filter out same annotations. Bugy... use volume-matching in future.
% for scanNum = 1:length(scanLesions)
%     currentScanLesions = scanLesions{scanNum};
%     % Find lesions that are close to each other and combine them as one
%     hausdorffDistM = [];
%     meanDistM = [];
%     for lesionNum = 1:length(currentScanLesions)
%         xV = currentScanLesions(lesionNum).xV;
%         yV = currentScanLesions(lesionNum).yV;
%         zV = currentScanLesions(lesionNum).zV;
%         xyzLesion = [xV yV zV];
%         for remLes = 1:length(currentScanLesions)
%             xRemV = currentScanLesions(remLes).xV;
%             yRemV = currentScanLesions(remLes).yV;
%             zRemV = currentScanLesions(remLes).zV;
%             xyzMatchedLesion = [xRemV yRemV zRemV];
%             hausdorffDistC{scanNum}(lesionNum,remLes) = hausdorff(xyzLesion,xyzMatchedLesion);
%             meanDistC{scanNum}(lesionNum,remLes) = sqrt(sum((mean(xyzLesion)-mean(xyzMatchedLesion)).^2));
%         end
%     end
% end
%
% for scanNum = 1:length(scanLesions)
%     maskM = hausdorffDistC{scanNum} < 3 | meanDistC{scanNum} < 3;
%     lesionsToDeleteV = [];
%     for lesionNum = 1:length(scanLesions{scanNum})
%         indSameLesionV = find(maskM(lesionNum,:));
%         if length(indSameLesionV) > 1
%             [~,indToKeep] = min(sum(hausdorffDistC{scanNum}(indSameLesionV,indSameLesionV)));
%             lesionsToDeleteV = [lesionsToDeleteV setdiff(indSameLesionV,indSameLesionV(indToKeep))];
%         end
%     end
%     lesionsToDeleteV = unique(lesionsToDeleteV);
%     scanLesions{scanNum}(lesionsToDeleteV) = [];
% end

% Figure out the file that needs to be used for registration. Assume there
% exists a file that encompasses all lesions. e.g. whole BODY scan
for i=1:length(dateV)
    minXval = min(scanXDims{i}(:,1));
    minLocX = find(abs(scanXDims{i}(:,1)-minXval) < 0.005);
    minYval = min(scanYDims{i}(:,1));
    minLocY = find(abs(scanYDims{i}(:,1)-minYval) < 0.005);
    minZval = min(scanZDims{i}(:,1));
    minLocZ = find(abs(scanZDims{i}(:,1)-minZval) < 0.005);
    maxXval = max(scanXDims{i}(:,2));
    maxLocX = find(abs(scanXDims{i}(:,2)-maxXval) < 0.005);
    maxYval = max(scanYDims{i}(:,2));
    maxLocY = find(abs(scanYDims{i}(:,2)-maxYval) < 0.005);
    maxZval = max(scanZDims{i}(:,2));
    maxLocZ = find(abs(scanZDims{i}(:,2)-maxZval) < 0.005);
    fileIndex = intersect(intersect(intersect(intersect(intersect(minLocX,minLocY),minLocZ),maxLocX),maxLocY),maxLocZ);
    if ~isempty(fileIndex)
        filesC{i} = scanFileNames{i}{fileIndex};
    else
        filesC{i} = [];
    end
end

% Register scans
for i=1:length(filesC)-1
%     filename1 = fullfile(dirName,filesC{i});
%     filename2 = fullfile(dirName,filesC{i+1});
    filename1 = filesC{i};
    filename2 = filesC{i+1};
    scan1PlanC = loadPlanC(filename1,tempdir);
    indexSscan1 = scan1PlanC{end};
    scan1PlanC{indexSscan1.deform}(1:end) = [];
    scan2PlanC = loadPlanC(filename2,tempdir);
    indexSscan2 = scan2PlanC{end};
    scan2PlanC{indexSscan2.deform}(1:end) = [];
    % Create annotations mask from all scans at base date.
    baseMask3M = [];
    filesToCopy = find(~ismember(scanFileNames{i},filename1));
    scan1PlanC = copyStructsFromFilesToPlanC(scanFileNames{i}(filesToCopy), scan1PlanC);
    annotROIIndV = strncmp('Annotation ROI',...
        {scan1PlanC{indexSscan1.structures}.structureName},length('Annotation ROI'));
    annotStrV = find(annotROIIndV);
    if ~isempty(annotStrV)
        baseMask3M = getUniformStr(annotStrV,scan1PlanC);
    end

    % Create annotations mask from all scans at follow-up date.
    movMask3M = [];
    filesToCopy = find(~ismember(scanFileNames{i+1},filename2));
    scan2PlanC = copyStructsFromFilesToPlanC(scanFileNames{i+1}(filesToCopy), scan2PlanC);
    annotROIIndV = strncmp('Annotation ROI',...
        {scan2PlanC{indexSscan2.structures}.structureName},length('Annotation ROI'));
    annotStrV = find(annotROIIndV);
    if ~isempty(annotStrV)
        movMask3M = getUniformStr(annotStrV,scan2PlanC);
    end

    baseScanNum = 1;
    movScanNum = 1;
    algorithm = 'BSPLINE PLASTIMATCH';
    threshold_bone = 100;
    [scan1PlanC, scan2PlanC] = register_scans(scan1PlanC, scan2PlanC, baseScanNum, movScanNum, algorithm, baseMask3M, movMask3M, threshold_bone);
    scan1PlanC = save_planC(scan1PlanC,[],'passed',filename1);
    scan2PlanC = save_planC(scan2PlanC,[],'passed',filename2);
    clear scan1PlanC scan2PlanC
end

% Match Lesions
for i=1:length(filesC)-1
%     filename1 = fullfile(dirName,filesC{i});
%     filename2 = fullfile(dirName,filesC{i+1});
    filename1 = filesC{i};
    filename2 = filesC{i+1};
    scan1PlanC = loadPlanC(filename1,tempdir);
    scan2PlanC = loadPlanC(filename2,tempdir);
    %scan1PlanC = updatePlanFields(scan1PlanC);
    %scan2PlanC = updatePlanFields(scan2PlanC);
    % Quality assure
    %scan1PlanC = quality_assure_planC(filename1, scan1PlanC);
    %scan2PlanC = quality_assure_planC(filename2, scan2PlanC);

    baseScanNum = 1;
    movScanNum = 1;
    scan1LesionS = scanLesions{i}; %findLesions(baseScanNum,scan1PlanC);
    scan2LesionS = scanLesions{i+1}; %findLesions(movScanNum,scan2PlanC);
    try
        [lesionMapping{i}, scanLesions{i+1}] = matchLesions(scan1LesionS, scan2LesionS, baseScanNum, movScanNum, scan1PlanC, scan2PlanC);
    catch
        disp('error')
    end
    clear scan1PlanC scan2PlanC
end

lesionMappingOriginal = lesionMapping;

for scanNum = 1:length(scanLesions)
    lesionsToUse{scanNum} = 1:length(scanLesions{scanNum});
end

% % Find lesions that map to same lesion on the next scan and decide which one to retain
% for scanNum = 1:length(lesionMapping)
%     lesionMap = lesionMapping{scanNum};
%     lesionsToUse{scanNum} = 1:size(lesionMap,1);
%     nextLesionIndicesV = [];
%     for lesionNum = 1:size(lesionMap,1)
%         %if ~isnan(lesionMap(lesionNum,2))
%         if ~ismember(lesionNum,nextLesionIndicesV)
%             nextLesionIndices = find(lesionMap(:,2) == lesionMap(lesionNum,2));
%             nextLesionIndicesV = [nextLesionIndicesV nextLesionIndices'];
%             if length(nextLesionIndices) > 1
%                 [~,indToKeep] = min(lesionMap(nextLesionIndices,3));
%                 indToDelete = setdiff(nextLesionIndices,nextLesionIndices(indToKeep));
%                 %lesionMapping{scanNum}(indToDelete,:) = [];
%                 %scanLesions{scanNum}(indToDelete) = [];
%                 lesionsToUse{scanNum}(indToDelete) = [];
%             end
%         end
%     end
% end
% lesionsToUse{length(scanLesions)} = 1:length(scanLesions{end});

% Track Lesions
lesionStory = {}; % (indexed by lesionNum): Start Scan, End Scan, lesion indices on scans from start:end
lesionsCountedFor = {}; % (indexed by ScanNum): LesionNums
for lesionNum=1:length(scanLesions)
    lesionsCountedFor{lesionNum} = [];
end
for scanNum = 1:length(scanLesions)
    currentScanLesions = scanLesions{scanNum};
    lesionsToIgnore = lesionsCountedFor{scanNum};
    for lesionNum = lesionsToUse{scanNum}
        if ismember(lesionNum, lesionsToIgnore)
            continue;
        end
        lesionsCountedFor{scanNum} = lesionNum;
        lesionHistoryV = lesionNum;
        currentLesionNum = lesionNum;
        endScanNum = scanNum;
        for longitScanNum = scanNum:length(scanLesions)-1
            currentLesionmap = lesionMapping{longitScanNum};
            currentLesionNum = currentLesionmap(currentLesionNum,2);
            if isnan(currentLesionNum)
                break;
            end
            endScanNum = longitScanNum + 1;
            lesionsCountedFor{endScanNum} = [lesionsCountedFor{endScanNum} currentLesionNum];
            lesionHistoryV = [lesionHistoryV currentLesionNum];
        end
        lesionStory{end+1} = [scanNum endScanNum lesionHistoryV];
    end
end

save('local_vars.mat','lesionStory','scanLesions','scanUIDc','fileNamesC','dateV','dateAllV')

return;

% Generate Longitudinal Images for lesions
absolutePathForImageFiles = '/mnt/RadShared2/Aditya/SPIdemoProject';
for lesionNum = 1:length(lesionStory)
    currentLesionStory = lesionStory{lesionNum};
    startScan = currentLesionStory(1);
    endScan = currentLesionStory(2);
    longitLesionNumsV = currentLesionStory(3:end);
    scanCount = 1;
    currentLesionLongitLenV = [];
    for scanNum = startScan:endScan
        currentLesionNum = longitLesionNumsV(scanCount);
        xV = scanLesions{scanNum}(currentLesionNum).xV;
        yV = scanLesions{scanNum}(currentLesionNum).yV;
        zV = scanLesions{scanNum}(currentLesionNum).zV;
        if isempty(scanLesions{scanNum}(currentLesionNum).assocAnnotUID)
            annotColor = 'y';
        else
            annotColor = 'r';
        end
        [~,fileIndex] = ismember(scanLesions{scanNum}(currentLesionNum).assocScanUID,scanUIDc);
        lenV = [];
        for segNum = 1:2:length(xV)
            x1 = xV(segNum);
            y1 = yV(segNum);
            z1 = zV(segNum);
            x2 = xV(segNum+1);
            y2 = yV(segNum+1);
            z2 = zV(segNum+1);
            lenV = [lenV sqrt((x1-x2)^2+(y1-y2)^2)];
        end
        currentLesionLongitLenV = [currentLesionLongitLenV max(lenV)];

        % Load scan, go to slice and take snapshot of annotation
        %cerrFileName = fullfile(dirName,filesC{fileIndex});
        cerrFileName = fullfile(dirName,fileNamesC{fileIndex});
        write_annotation_images_to_disk(absolutePathForImageFiles,cerrFileName,scanNum,[xV(:) yV(:) zV(:)],lesionNum,annotColor)

        scanCount = scanCount + 1;
    end
    longitLen{lesionNum} = currentLesionLongitLenV;
end

% Generate Report for each lesion
optS.format = 'html';
% optS.figureSnapMethod = 'getframe';
optS.showCode = false;
optS.codeToEvaluate = '';
optS.outputDir = fullfile(absolutePathForImageFiles,'report');
optS.maxHeight = 300;
optS.maxWidth = 300;
file = publish('publish_results.m',optS);


clear;
%Note that I add original val to train
%and then redefine the train/test split.
%5000 val, 5000 test  https://cs.stanford.edu/people/karpathy/cvpr2015.pdf.
txt = fileread('./annotations/captions_val2014.json');
json = jsondecode(txt);  %jsondecode is not available on 2015b. I use Matlab2016b.

file_path_val = {json.images.file_name};
img_id_val = [json.images.id];

caption_val = {json.annotations.caption};
caption_img_id_val = [json.annotations.image_id];

%train
txt = fileread('./annotations/captions_train2014.json');
json = jsondecode(txt);  %jsondecode is not available on 2015b. I use Matlab2016b.

file_path = {json.images.file_name};
img_id = [json.images.id];

caption = {json.annotations.caption};
caption_img_id = [json.annotations.image_id];

% change full path
data = cat(2,...
    cellfun(@(x) sprintf('/home/zzd/Image-Text-Embedding/dataset/MSCOCO-prepare/image_256/train2014/%sjpg',x(1:end-3)), file_path,'UniformOutput',false),...
    cellfun(@(x) sprintf('/home/zzd/Image-Text-Embedding/dataset/MSCOCO-prepare/image_256/val2014/%sjpg',x(1:end-3)), file_path_val,'UniformOutput',false));
img_label = cat(2,img_id,img_id_val);
caption = cat(2,caption,caption_val);
caption_label = cat(2,caption_img_id,caption_img_id_val);

% final 5000 images as test
rng(1);
num = numel(data);
set = ones(1,num);
val_test_id = randperm(num,10000);
set(1,val_test_id) = 2; %val+test
test_id = val_test_id(randperm(10000,5000));
set(1,test_id) = 3; %test

%assign image label
new_label = zeros(1,numel(img_label));
new_label(set==1) = 1:sum(set==1);
train_img_label = img_label;
train_img_label(set~=1) = 0;
%assign text label
for i=1:numel(caption_label)
    now = caption_label(i);
    index = find(train_img_label==now);
    if(isempty(index))
        caption_label(i) = 0;
    else
        caption_label(i) = new_label(index);%update
    end
end

% dataset
imdb.images.set = set;
imdb.images.data = data;
imdb.images.label = new_label;
imdb.images.label2 = caption_label;
%resize_image; % resize image to 256, return mean.
imdb.rgbMean = [119.8557, 113.9346, 103.9336];
save('url_data.mat','imdb');  % only train data

caption_train = caption(caption_label~=0);
caption_dic = caption_train;

save('caption_train.mat','caption_dic');

save('caption.mat','caption');

caption_label = cat(2,caption_img_id,caption_img_id_val);
img_label = cat(2,img_id,img_id_val);

test_img_label = img_label(set==3);
%assign text label
parfor i=1:numel(caption_label)
    now = caption_label(i);
    index = find(test_img_label==now);
    if(isempty(index))
        caption_label(i) = 0;
    end
end
test_id = [];
test_id.txt_id = caption_label; % test left
test_label = img_label;
test_label(set~=3) = 0;
test_id.img_id = test_label;

save('test_id.mat','test_id');


function combine_box_region_nets(box_net, region_net, pi_net)
if(~exist(box_net, 'file'))
    fprintf('Box net does not exist!\n'); return;
end
if(~exist(region_net, 'file'))
    fprintf('Region net does not exist!\n');return;
end
caffe('init', 'prototxts/rcnn_extract_fc7.prototxt', box_net);
box_layers=caffe('get_weights');
caffe('init', 'prototxts/rcnn_extract_fc7.prototxt', region_net);
region_layers=caffe('get_weights');

for i=1:numel(box_layers)
    box_layers(i).layer_names=[box_layers(i).layer_names '_1'];
end
for i=1:numel(box_layers)
    region_layers(i).layer_names=[region_layers(i).layer_names '_2'];
end
layers=[box_layers; region_layers];
caffe('read_prototxt', 'prototxts/pinetwork_extract_fc7.prototxt');
caffe('change_weights', layers);
caffe('save_net', pi_net);


function vis_benchmark(timing)
% display results of benchmarking (timing)

fprintf('\n\n------------------------------\n');
fnames = fieldnames(timing);
ttot = 0; % total sum of timing
for k=1:length(fnames);
    tsec = timing.(fnames{k});
    if isnan(tsec), continue; end;
    fprintf('%s\t: %0.5g\n',fnames{k},tsec);
    ttot = ttot+tsec;
end
fprintf('Total\t: %0.5g\n',ttot);
fprintf('------------------------------\n\n');


function hmObj = hlp_validateHeadModelObject(hmObj)
% helper function to check the head model object, and
% load from base workspace if necessary
% Author: Tim Mullen, SCCN/INC/UCSD 2013

if isempty(hmObj)
    hmObj = 'hmObj'; % default name of variable in base wkspace
end
if ischar(hmObj)
    % load variable from base workspace
    try
       hmObj = evalin('base',hmObj);
    catch err1
        % try to open it as a file names
        try
            hmObj = hlp_microcache('headmodels',@headModel.loadFromFile,env_translatepath(hmObj));
        catch err2
            if ~strcmp(err2.identifier,'MATLAB:UndefinedFunction')
                disp_once(['Note: The head model named "' hmObj '" was neither found in the base workspace nor could it be loaded as a file.']); end
            hmObj = '';
            return;
        end
    end
end

% check that the object is a valid head model object
if ~isobject(hmObj)
    warning('You did not supply a valid head model object');
    hmObj = '';
    return;
end
if ~isprop(hmObj,'leadFieldFile') || isempty(hmObj.leadFieldFile)
    warning('Head model object does not appear to be valid. The lead field matrix does not exist.');
    hmObj = '';
    return;
end


function DIC_3Djoined_results = joinPairs_old(DIC3DAllPairsResults)
%% function for joining multiple 3D-DIC pair results into one structure (plotting in step3)
%
% Inputs:
% * DIC3DAllPairsResults
%
% Outputs:
% * DIC_3Djoined_results
%

%%
nPairs=numel(DIC3DAllPairsResults);
nFrames=size(DIC3DAllPairsResults{1}.Points3D,1);

% create cells with all the variables for joining
Fi=cell(nPairs,1);
FCi=cell(nPairs,1);
Fisoi=cell(nPairs,1);
Vi=cell(nPairs,nFrames);
corrCombi=cell(nPairs,nFrames);
FaceCorrCombi=cell(nPairs,nFrames);
DispVi=cell(nPairs,nFrames);
DispMi=cell(nPairs,nFrames);
VFci=cell(nPairs,nFrames);
VFcTi=cell(nPairs,nFrames);
Ji=cell(nPairs,nFrames);
Lamda1i=cell(nPairs,nFrames);
Lamda2i=cell(nPairs,nFrames);
Emgni=cell(nPairs,nFrames);
emgni=cell(nPairs,nFrames);
Epc1i=cell(nPairs,nFrames);
Epc2i=cell(nPairs,nFrames);
Epc1veci=cell(nPairs,nFrames);
Epc1vecCuri=cell(nPairs,nFrames);
Epc2veci=cell(nPairs,nFrames);
Epc2vecCuri=cell(nPairs,nFrames);
epc1i=cell(nPairs,nFrames);
epc2i=cell(nPairs,nFrames);
epc1veci=cell(nPairs,nFrames);
epc2veci=cell(nPairs,nFrames);

for ip=1:nPairs
    DIC_3Dpair_struct=DIC3DAllPairsResults{ip};

    Fi{ip}=DIC_3Dpair_struct.Faces;
    FCi{ip}=DIC_3Dpair_struct.FaceColors;

    for it=1:nFrames
        Vi{ip,it}=DIC_3Dpair_struct.Points3D{it};
        corrCombi{ip,it}=DIC_3Dpair_struct.corrComb{it};
        FaceCorrCombi{ip,it}=DIC_3Dpair_struct.FaceCorrComb{it};
        DispVi{ip,it}=DIC_3Dpair_struct.Disp.DispVec{it};
        DispMi{ip,it}=DIC_3Dpair_struct.Disp.DispMgn{it};
        VFci{ip,it}=DIC_3Dpair_struct.FaceCentroids{it};
        Ji{ip,it}=DIC_3Dpair_struct.Deform.J{it};
        Lamda1i{ip,it}=DIC_3Dpair_struct.Deform.Lamda1{it};
        Lamda2i{ip,it}=DIC_3Dpair_struct.Deform.Lamda2{it};
        Emgni{ip,it}=DIC_3Dpair_struct.Deform.Emgn{it};
        emgni{ip,it}=DIC_3Dpair_struct.Deform.emgn{it};
        Epc1i{ip,it}=DIC_3Dpair_struct.Deform.Epc1{it};
        Epc2i{ip,it}=DIC_3Dpair_struct.Deform.Epc2{it};
        Epc1veci{ip,it}=DIC_3Dpair_struct.Deform.Epc1vec{it};
        Epc1vecCuri{ip,it}=DIC_3Dpair_struct.Deform.Epc1vecCur{it};
        Epc2veci{ip,it}=DIC_3Dpair_struct.Deform.Epc2vec{it};
        Epc2vecCuri{ip,it}=DIC_3Dpair_struct.Deform.Epc2vecCur{it};
        epc1i{ip,it}=DIC_3Dpair_struct.Deform.epc1{it};
        epc2i{ip,it}=DIC_3Dpair_struct.Deform.epc2{it};
        epc1veci{ip,it}=DIC_3Dpair_struct.Deform.epc1vec{it};
        epc2veci{ip,it}=DIC_3Dpair_struct.Deform.epc2vec{it};
        Fisoi{ip,it}=DIC_3Dpair_struct.FaceIsoInd{it};
    end

end

% join variables that are time invariant
[Fj,~,~]=joinElementSets(Fi,Vi(:,1),[]);
[~,~,FCj]=joinElementSets(Fi,Vi(:,1),FCi);

for it=1:nFrames
    % join variables that are time variant and scalar

    [~,Vj{1,it},DispMj{1,it}]=joinElementSets(Fi,Vi(:,it),DispMi(:,it));
    [~,~,corrCombj{1,it}]=joinElementSets(Fi,Vi(:,it),corrCombi(:,it));
    [~,~,FaceCorrCombj{1,it}]=joinElementSets(Fi,Vi(:,it),FaceCorrCombi(:,it));
    [~,~,Jj{1,it}]=joinElementSets(Fi,Vi(:,it),Ji(:,it));
    [~,~,Lamda1j{1,it}]=joinElementSets(Fi,Vi(:,it),Lamda1i(:,it));
    [~,~,Lamda2j{1,it}]=joinElementSets(Fi,Vi(:,it),Lamda2i(:,it));
    [~,~,Emgnj{1,it}]=joinElementSets(Fi,Vi(:,it),Emgni(:,it));
    [~,~,emgnj{1,it}]=joinElementSets(Fi,Vi(:,it),emgni(:,it));
    [~,~,Epc1j{1,it}]=joinElementSets(Fi,Vi(:,it),Epc1i(:,it));
    [~,~,Epc2j{1,it}]=joinElementSets(Fi,Vi(:,it),Epc2i(:,it));
    [~,~,epc1j{1,it}]=joinElementSets(Fi,Vi(:,it),epc1i(:,it));
    [~,~,epc2j{1,it}]=joinElementSets(Fi,Vi(:,it),epc2i(:,it));
    [~,~,Fisoj{1,it}]=joinElementSets(Fi,Vi(:,it),Fisoi(:,it));

    % join variables that are time variant and vectors
    DispVj{1,it}=DispVi{1,it};
    VFcj{1,it}=VFci{1,it};
    Epc1vecj{1,it}=Epc1veci{1,it};
    Epc1vecCurj{1,it}=Epc1vecCuri{1,it};
    Epc2vecj{1,it}=Epc2veci{1,it};
    Epc2vecCurj{1,it}=Epc2vecCuri{1,it};
    epc1vecj{1,it}=epc1veci{1,it};
    epc2vecj{1,it}=epc2veci{1,it};
    for ip=2:nPairs
        DispVj{1,it}=[DispVi{1,it}; DispVi{ip,it}];
        VFcj{1,it}=[VFcj{1,it}; VFci{ip,it}];
        Epc1vecj{1,it}=[Epc1vecj{1,it}; Epc1veci{ip,it}];
        Epc1vecCurj{1,it}=[Epc1vecCurj{1,it}; Epc1vecCuri{ip,it}];
        Epc2vecj{1,it}=[Epc2vecj{1,it}; Epc2veci{ip,it}];
        Epc2vecCurj{1,it}=[Epc2vecCurj{1,it}; Epc2vecCuri{ip,it}];
        epc1vecj{1,it}=[epc1vecj{1,it}; epc1veci{ip,it}];
        epc2vecj{1,it}=[epc2vecj{1,it}; epc2veci{ip,it}];
    end
end

DIC_3Djoined_results=struct;
DIC_3Djoined_results.Faces=Fj;
DIC_3Djoined_results.FaceColors=FCj;
DIC_3Djoined_results.FaceIsoInd=Fisoj;
DIC_3Djoined_results.FaceCentroids=VFcj;
DIC_3Djoined_results.Points3D=Vj;
DIC_3Djoined_results.corrComb=corrCombj;
DIC_3Djoined_results.FaceCorrComb=FaceCorrCombj;

DIC_3Djoined_results.Disp.DispVec=DispVj;
DIC_3Djoined_results.Disp.DispMgn=DispMj;

DIC_3Djoined_results.Deform.J=Jj;
DIC_3Djoined_results.Deform.Lamda1=Lamda1j;
DIC_3Djoined_results.Deform.Lamda2=Lamda2j;
DIC_3Djoined_results.Deform.Emgn=Emgnj;
DIC_3Djoined_results.Deform.emgn=emgnj;
DIC_3Djoined_results.Deform.Epc1=Epc1j;
DIC_3Djoined_results.Deform.Epc2=Epc2j;
DIC_3Djoined_results.Deform.Epc1vec=Epc1vecj;
DIC_3Djoined_results.Deform.Epc1vecCur=Epc1vecCurj;
DIC_3Djoined_results.Deform.Epc2vec=Epc2vecj;
DIC_3Djoined_results.Deform.Epc2vecCur=Epc2vecCurj;
DIC_3Djoined_results.Deform.epc1=epc1j;
DIC_3Djoined_results.Deform.epc2=epc2j;
DIC_3Djoined_results.Deform.epc1vec=epc1vecj;
DIC_3Djoined_results.Deform.epc2vec=epc2vecj;

end

%%
% MultiDIC: a MATLAB Toolbox for Multi-View 3D Digital Image Correlation
%
% License: <https://github.com/MultiDIC/MultiDIC/blob/master/LICENSE.txt>
%
% Copyright (C) 2018  Dana Solav
%
% If you use the toolbox/function for your research, please cite our paper:
% <https://engrxiv.org/fv47e>


function [molStr,molTable] = getMolFormulaVMH(metabolite,metaboliteTable)
% This function returns the molecular formula of a given vmh metabolite.
%
% USAGE:
%       1) [molStr,molTable] = getMolFormulaVMH(metabolite)
%       2) [molStr,molTable] = getMolFormulaVMH(metabolite,metaboliteTable)
%
% INPUT:
%   metabolite:         a metabolite in the vmh database
%
% OPTIONAL INPUT:
%   metaboliteTable:    a metabolite table containing all vmh metabolites.
%                       This optional input is recommended if the function
%                       is run repetitively in a loop to eliminate
%                       readtable time.
%
% OUTPUT:
%   molStr:             a string containing the molecular formula of the
%                       metabolite
%   molTable:           a cellular array containing a breakdown of the
%                       frequency of each element in the molecule
%
% AUTHORS:
%       Bronson R. Weston, 2022

if ~exist('metaboliteTable','Var')
    metaboliteTable=readtable('MetaboliteDatabase.txt');
end
%try metabolite abreviation
ind=find(strcmp(metaboliteTable.Var1,metabolite));
if isempty(ind)
    %try metabolite full name
    ind=find(strcmp(metaboliteTable.Var2,metabolite));
    if isempty(ind)
        error('Invalid input metabolite!')
    elseif length(ind)>1
        ind=ind(1);
    end
end

%Get metabolite formula
molStr=metaboliteTable.Var4{ind};
uC=isstrprop(molStr,'upper');
tracker={};
ind=0;

%Break down metabolite by element and create molTable
for i=1:length(uC)
    if uC(i)==1
        ind=ind+1;
        tracker{ind}=molStr(i);

    else
        tracker{ind}=[tracker{ind},molStr(i)];
    end
end

molTable={};
for i=1:length(tracker)
    unit=tracker{i};
    num=isstrprop(unit,'digit');
    if ~any(num==1)
        molTable(i,:)={tracker{i} , 1};
    else
        molTable{i,1}=unit(num~=1);
        molTable{i,2}=str2num(unit(num==1));
    end
end
end


%kkbitor 'Output = Input 1 OR (Input 2 or Constant)'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kbitor.pane file
%
% Parameters:
% InputFile: i1 'Input 1', required: 'First input data object'
% OutputFile: o 'Output', required: 'Resulting output data object'
% InputFile: i2 'Input 2', optional: 'Second input data object'
% Integer: real 'Constant', default: 0: 'Constant value'
%
% Example: o = kkbitor({i1, i2}, {'i1','';'o','';'i2','';'real',0})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kbitor - Output = Input 1  OR  (Input 2 or Constant)
%
%  DESCRIPTION
% The bitwise OR operator performs a bitwise OR between each point in
% \fBInput 1" and either \fBInput 2\fP or the \fBConstant\fP value, which
% ever is specified by the user.
%
%  "Data Type - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_1input
%
%  "Data Type - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_2input
% The bitwise operators will not operate on float or complex data types.
%
%  "Map Data" 5
% The bitwise operations have not been written to be fully polymorphic yet.
% They does not
% check for map data, and will therefore always operate on the value data,
% even if a map exists.  This will most likely corrupt indexing into the map.
% In the case of a single input, it is recommended to use the "Copy to
% Value" (kcptoval) segment operator to temporarily move the map data into
% the value segment, run the bitwise operation on the data, then move it
% back to the map with the "Copy from Value" (kcpfromval) operator.
% When operating with two input objects, where at least one of the objects
% contains map data, data should be mapped prior to running the bitwise
% operator.  The "Map Data" operator (kmapdata) can be used to perform
% the mapping operation.
%
%  "Validity Mask - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/mask_1input
%
%  "Validity Mask - Two Input Objects" 5
% Masking has not been implemented yet for the bitwise operators.  Therefore,
% only the mask from the first input object will be transferred to the output.
%
%  "Input Objects of Different Sizes" 5
% .cI $DATAMANIP/repos/shared/man/sections/resize_2input
% The value used to pad the data when the input files are not the same size is
% zero.
%
%  "Explicit Location and Time Data - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_1input
%
%  "Explicit Location and Time Data - Two Input Objects" 5
% The bitwise operations have not been extended to understand location and
% time data.  Therefore, only location and time data present in the first input
% object will be transferred to the output.
%
% Executing \fBOR" runs the program "kbitwise\fP with the -or flag.
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
% DATAMANIP::kbitwise
%
%  RESTRICTIONS
%
% THIS ROUTINE is still under development, and has not been modified to fully
% support the polymorphic data model.  See paragraphs above for discussions
% concerning the polymorphic data segments.
%
% All processing is currently performed as UNSIGNED long, so the operations
% may not work properly on negative values.
%
% The bitwise operators will not operate on float or complex data types.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

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

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


function nbytes = slstructsize(S, fields, types)
%SLSTRUCTSIZE Compute the size of a struct
%
% $ Syntax $
%   - nbytes = slstructsize(S)
%   - nbytes = slstructsize(S, fields)
%   - nbytes = slstructsize(S, fields, types)
%
% $ Arguments $
%   - nbytes:            the number of bytes in the specified parts of the struct
%   - fields:            the fields that are counted in the computation
%   - types:             the types of the fields when output
%
% $ Description $
%
%   - nbytes = slstructsize(S) computes the bytes of the struct occupied
%     if S is a struct-array, then the resultant nbytes is sum of all sizes
%     of struct entries.
%
%   - nbytes = slstructsize(S, fields) only computes the specified fields.
%     If some specified fields are not in S, an error will be raised.
%
%   - nbytes = slstructsize(S, fields, types) the computation will
%     use the types for computing the size instead of using original types.
%
% $ History $
%   - Created by Dahua Lin on Dec 10th, 2005
%

%% parse and verify input arguments
if ~isstruct(S)
    error('S is not a struct');
end
if nargin < 2 || isempty(fields)
    fields = fieldnames(S);
end
if nargin < 3 || isempty(types)
    use_origin_types = true;
else
    use_origin_types = false;
end

%% compute
n = numel(S);
if n == 1

    nbytes = 0;
    nterms = length(fields);

    for t = 1 : nterms
        cur_term = S.(fields{t});
        if isempty(cur_term)
            continue;
        elseif isstruct(cur_term)
            cur_nbytes = slstructsize(cur_term);
        else
            if use_origin_types || isempty(types{t})
                cur_elem_bytes = sltypesize(class(cur_term));
            else
                cur_elem_bytes = sltypesize(types{t});
            end
            cur_nbytes = cur_elem_bytes * numel(cur_term);
        end

        nbytes = nbytes + cur_nbytes;
    end

else

    nbytes = 0;
    for i = 1 : n
        if use_origin_types
            nbytes = nbytes + slstructsize(S(i), fields);
        else
            nbytes = nbytes + slstructsize(S(i), fields, types);
        end
    end

end


function varargout=subsref(obj,subs)
% SUBSREF Subscripted reference
% An overloaded function...
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

%
% $Id: subsref.m 4136 2010-12-09 22:22:28Z guillaume $

if isempty(subs), return; end

switch subs(1).type
    case '{}'
        error('Cell contents reference from a non-cell array object.');
    case '.'
        varargout = access_fields(obj,subs);
        return;
end

if numel(subs)~=1, error('Expression too complicated'); end;

dim  = [size(obj) ones(1,16)];
nd   = find(dim>1,1,'last')-1;
sobj = struct(obj);

if ~numel(subs.subs)
    [subs.subs{1:nd+1}] = deal(':');
elseif length(subs.subs) < nd
    l   = length(subs.subs);
    dim = [dim(1:(l-1)) prod(dim(l:end))];
    if numel(sobj) ~= 1
        error('Can only reshape simple file_array objects.');
    else
        if numel(sobj.scl_slope)>1 || numel(sobj.scl_inter)>1
            error('Can not reshape file_array objects with multiple slopes and intercepts.');
        end
        sobj.dim = dim;
    end
end

di   = ones(16,1);
args = cell(1,length(subs.subs));
for i=1:length(subs.subs)
    if ischar(subs.subs{i})
        if ~strcmp(subs.subs{i},':'), error('This shouldn''t happen....'); end
        if length(subs.subs) == 1
            args{i} = 1:prod(dim); % possible overflow when int32()
            k = 0;
            for j=1:length(sobj)
                sobj(j).dim = [prod(sobj(j).dim) 1];
                sobj(j).pos = [k+1 1];
                k           = k + sobj(j).dim(1);
            end
        else
            args{i} = 1:dim(i);
        end
    else
        args{i} = subs.subs{i};
    end
    di(i) = length(args{i});
end

if length(sobj)==1
    t = subfun(sobj,args{:});
else
    dt  = datatypes;
    dt  = dt([dt.code]==sobj(1).dtype); % assuming identical datatypes
    t = zeros(di',func2str(dt.conv));
    for j=1:length(sobj)
        ps = [sobj(j).pos ones(1,length(args))];
        dm = [sobj(j).dim ones(1,length(args))];
        for i=1:length(args)
            msk      = find(args{i}>=ps(i) & args{i}<(ps(i)+dm(i)));
            args2{i} = msk;
            args3{i} = double(args{i}(msk))-ps(i)+1;
        end

        t  = subsasgn(t,struct('type','()','subs',{args2}),subfun(sobj(j),args3{:}));
    end
end
varargout = {t};

%==========================================================================
% function t = subfun(sobj,varargin)
%==========================================================================
function t = subfun(sobj,varargin)

%sobj.dim = [sobj.dim ones(1,16)];
try
    args = cell(size(varargin));
    for i=1:length(varargin)
        args{i} = int32(varargin{i});
    end
    t = file2mat(sobj,args{:});
catch
    t = multifile2mat(sobj,varargin{:});
end
if ~isempty(sobj.scl_slope) || ~isempty(sobj.scl_inter)
    slope = 1;
    inter = 0;
    if ~isempty(sobj.scl_slope), slope = sobj.scl_slope; end
    if ~isempty(sobj.scl_inter), inter = sobj.scl_inter; end
    if numel(slope)>1
        slope = resize_scales(slope,sobj.dim,varargin);
        t     = double(t).*slope;
    else
        t     = double(t)*slope;
    end
    if numel(inter)>1
        inter = resize_scales(inter,sobj.dim,varargin);
    end;
    t = t + inter;
end

%==========================================================================
% function c = access_fields(obj,subs)
%==========================================================================
function c = access_fields(obj,subs)

sobj = struct(obj);
c    = cell(1,numel(sobj));
for i=1:numel(sobj)
    %obj = class(sobj(i),'file_array');
    obj = sobj(i);
    switch(subs(1).subs)
        case 'fname',      t = fname(obj);
        case 'dtype',      t = dtype(obj);
        case 'offset',     t = offset(obj);
        case 'dim',        t = dim(obj);
        case 'scl_slope',  t = scl_slope(obj);
        case 'scl_inter',  t = scl_inter(obj);
        case 'permission', t = permission(obj);
        otherwise
            error(['Reference to non-existent field "' subs(1).subs '".']);
    end
    if numel(subs)>1
        t = subsref(t,subs(2:end));
    end
    c{i} = t;
end

%==========================================================================
% function val = multifile2mat(sobj,varargin)
%==========================================================================
function val = multifile2mat(sobj,varargin)

% Convert subscripts into linear index
[indx2{1:length(varargin)}] = ndgrid(varargin{:},1);
ind = sub2ind(sobj.dim,indx2{:});

% Work out the partition
dt  = datatypes;
dt  = dt([dt.code]==sobj.dtype);
sz  = dt.size;
try
    mem = spm('Memory'); % in bytes, has to be a multiple of 16 (max([dt.size]))
catch
    mem = 200 * 1024 * 1024;
end
s   = ceil(prod(sobj.dim) * sz / mem);

% Assign indices to partitions
[x,y] = ind2sub([mem/sz s],ind(:));
c     = histc(y,1:s);
cc    = [0 reshape(cumsum(c),1,[])];

% Read data in relevant partitions
obj = sobj;
val = zeros(length(x),1,func2str(dt.conv));
for i=reshape(find(c),1,[])
    obj.offset = sobj.offset + mem*(i-1);
    obj.dim = [1 min(mem/sz, prod(sobj.dim)-(i-1)*mem/sz)];
    val(cc(i)+1:cc(i+1)) = file2mat(obj,int32(1),int32(x(y==i)));
end
r   = cellfun('length',varargin);
if numel(r) == 1, r = [r 1]; end
val = reshape(val,r);


% PLOT THE COLLISION EVENT DESCRIPTION FIGURES
function [currentFigure,figureSet] = GetFigure_objectCollision(SIM,objectIndex,DATA,currentFigure)
% This function is designed to move through the collsion event history and
% generate figure for each of the collisions.

figureSet = [];
% CHECK COLLISIONS OCCURED
if ~isfield(DATA,'uniqueCollisions') || isempty(DATA.uniqueCollisions)
    fprintf('[%s]\t...No collision data available.\n',SIM.phase);
    return
end

for collisionNumber = 1:numel(DATA.uniqueCollisions)
    [currentFigure,figureSet(collisionNumber)] = BuildObjectCollisionFigure(...
        SIM,...
        objectIndex,...
        DATA,...
        currentFigure,...
        DATA.uniqueCollisions(collisionNumber));
end

% ASSEMBLE TABBED FIGURE
windowHandle = GetTabbedFigure(figureSet,'OpenMAS Collision Overview');
set(windowHandle,'Position',DATA.figureProperties.windowSettings);        % Maximise the figure in the tab
savefig(windowHandle,[SIM.outputPath,'collision-overview']);              % Save the output figure
end

% Build the collision figure for the event
function [currentFigure,figureHandle] = BuildObjectCollisionFigure(SIM,objectIndex,DATA,currentFigure,collisionEvent)

% Generate the figure
figureHandle = figure('Name',sprintf('[t=%.0fs] %s & %s',collisionEvent.time,collisionEvent.name_A,collisionEvent.name_B));
set(figureHandle,'Position', DATA.figureProperties.windowSettings);        % [x y width height]
set(figureHandle,'Color',DATA.figureProperties.figureColor);               % Background colour
ax = axes(figureHandle);
hold on;
view([70 25]);
titlestr = sprintf('Collision Event between %s and %s at t=%s',...         % Declare title string for figure
           collisionEvent.name_A,collisionEvent.name_B,num2str(collisionEvent.time));

% /////////////////////////// ENTITY DATA /////////////////////////////////
% EVENT, OBJECT AND META DATA
META_A = SIM.OBJECTS(SIM.globalIDvector == collisionEvent.objectID_A);
META_B = SIM.OBJECTS(SIM.globalIDvector == collisionEvent.objectID_B);     % The associated META datas
object_A = objectIndex{SIM.globalIDvector == collisionEvent.objectID_A};
object_B = objectIndex{SIM.globalIDvector == collisionEvent.objectID_B};   % The associated object structures
geometry_A = object_A.GEOMETRY;
geometry_B = object_B.GEOMETRY;
[objectAStates] = OMAS_getTrajectoryData_mex(DATA.globalTrajectories,SIM.globalIDvector,META_A.objectID,inf);
[objectBStates] = OMAS_getTrajectoryData_mex(DATA.globalTrajectories,SIM.globalIDvector,META_B.objectID,inf);

% We need to plot:
% - The object geometries
% - The object hitboxes

% ////////////////////// PLOT THE OBJECT GEOMETRY /////////////////////////
% SUBSTITUTE A'S GEOMETRY IF NECESSARY
if size(object_A.GEOMETRY.vertices,1) < 1
    [geometry_A] = OMAS_graphics.defineSphere(zeros(3,1),META_A.radius,10);
end
% GET A'S ROTATIONS
R_A = OMAS_geometry.quaternionToRotationMatrix(collisionEvent.state_A(7:10));
% OBJECT A'S GEOMETRY
patch(ax,...
    'Vertices',(geometry_A.vertices*R_A + collisionEvent.state_A(1:3)'),...
    'Faces',geometry_A.faces,...
    'FaceColor',META_A.colour,...
    'EdgeColor','k',...
    'EdgeAlpha',DATA.figureProperties.edgeAlpha,...
    'FaceAlpha',DATA.figureProperties.faceAlpha,...
    'FaceLighting','gouraud',...
    'LineWidth',DATA.figureProperties.lineWidth);

% SUBSTITUTE B'S GEOMETRY IF NECESSARY
if size(object_B.GEOMETRY.vertices,1) < 1
    [geometry_B] = OMAS_graphics.defineSphere(zeros(3,1),META_B.radius,10);
end
% GET B'S ROTATIONS
R_B = OMAS_geometry.quaternionToRotationMatrix(collisionEvent.state_B(7:10));
% OBJECT B'S GEOMETRY
patch(ax,...
    'Vertices',(geometry_B.vertices*R_B + collisionEvent.state_B(1:3)'),...
    'Faces',geometry_B.faces,...
    'FaceColor',META_B.colour,...
    'EdgeColor','k',...
    'EdgeAlpha',DATA.figureProperties.edgeAlpha,...
    'FaceAlpha',DATA.figureProperties.faceAlpha,...
    'FaceLighting','gouraud',...
    'LineWidth',DATA.figureProperties.lineWidth);

% ////////////////////// PLOT THE OBJECT'S HITBOX /////////////////////////
% Get the hit-box geometry
[hitBoxGeometry_A] = OMAS_graphics.getHitBoxGeometry(object_A.GetGLOBAL(),object_A.GEOMETRY);
% DEFINE A's HITBOX
patch(ax,...
    'Vertices',(hitBoxGeometry_A.vertices + collisionEvent.state_A(1:3)'),...
    'Faces',hitBoxGeometry_A.faces,...
    'FaceColor','r',...
    'EdgeColor','k',...
    'EdgeAlpha',DATA.figureProperties.edgeAlpha*0.8,...
    'FaceAlpha',DATA.figureProperties.faceAlpha*0.8,...
    'FaceLighting','gouraud',...
    'LineWidth',DATA.figureProperties.lineWidth);

% Get the hit-box geometry
[hitBoxGeometry_B] = OMAS_graphics.getHitBoxGeometry(object_B.GetGLOBAL(),object_B.GEOMETRY);
% DEFINE B's HITBOX
patch(ax,...
    'Vertices',(hitBoxGeometry_B.vertices + collisionEvent.state_B(1:3)'),...
    'Faces',hitBoxGeometry_B.faces,...
    'FaceColor','r',...
    'EdgeColor','k',...
    'EdgeAlpha',DATA.figureProperties.edgeAlpha*0.8,...
    'FaceAlpha',DATA.figureProperties.faceAlpha*0.8,...
    'FaceLighting','gouraud',...
    'LineWidth',DATA.figureProperties.lineWidth);

% ////////////////////// PLOT THE TRAJECTORY TRAILS ///////////////////////
plot3(ax,objectAStates(1,:),objectAStates(2,:),objectAStates(3,:),...
    'LineStyle',DATA.figureProperties.lineStyle,...
    'LineWidth',DATA.figureProperties.lineWidth,...
    'Color',META_A.colour);
plot3(ax,objectBStates(1,:),objectBStates(2,:),objectBStates(3,:),...
    'LineStyle',DATA.figureProperties.lineStyle,...
    'LineWidth',DATA.figureProperties.lineWidth,...
    'Color',META_B.colour);

% ////////////////////// PLOT THE VELOCITY VECTORS ////////////////////////
% PLOT THE OBJECT VELOCITY VECTORS
q = quiver3(collisionEvent.state_A(1),...
    collisionEvent.state_A(2),...
    collisionEvent.state_A(3),...
    collisionEvent.state_A(4),...
    collisionEvent.state_A(5),...
    collisionEvent.state_A(6),'r');
q.AutoScaleFactor = 1;
q.LineWidth = DATA.figureProperties.lineWidth;
q = quiver3(collisionEvent.state_B(1),...
    collisionEvent.state_B(2),...
    collisionEvent.state_B(3),...
    collisionEvent.state_B(4),...
    collisionEvent.state_B(5),...
    collisionEvent.state_B(6),'g');
q.AutoScaleFactor = 1;
q.LineWidth = DATA.figureProperties.lineWidth;

% ///////////////////////// ADD LABEL ANNOTATIONS /////////////////////////
annotationText = sprintf('    %s [ID-%d]',META_A.name,META_A.objectID);
text(collisionEvent.state_A(1),collisionEvent.state_A(2),collisionEvent.state_A(3),annotationText);
annotationText = sprintf('    %s [ID-%d]',META_B.name,META_B.objectID);
text(collisionEvent.state_B(1),collisionEvent.state_B(2),collisionEvent.state_B(3),annotationText);

% DEFINE THE PLOT LAYOUT
% Title
title(ax,titlestr,...
    'Interpreter',DATA.figureProperties.interpreter,...
    'fontname',DATA.figureProperties.fontName,...
    'Fontweight',DATA.figureProperties.fontWeight,...
    'FontSize',DATA.figureProperties.titleFontSize,...
    'FontSmoothing','on');
% X-label
xlabel(ax,'x(m)',...
    'Interpreter',DATA.figureProperties.interpreter,...
    'fontname',DATA.figureProperties.fontName,...
    'Fontweight',DATA.figureProperties.fontWeight,...
    'FontSize',DATA.figureProperties.axisFontSize,...
    'FontSmoothing','on');
% Y-Label
ylabel(ax,'y(m)',...
    'Interpreter',DATA.figureProperties.interpreter,...
    'fontname',DATA.figureProperties.fontName,...
    'Fontweight',DATA.figureProperties.fontWeight,...
    'FontSize',DATA.figureProperties.axisFontSize,...
    'FontSmoothing','on');
% Z-Label
zlabel(ax,'z(m)',...
    'Interpreter',DATA.figureProperties.interpreter,...
    'fontname',DATA.figureProperties.fontName,...
    'Fontweight',DATA.figureProperties.fontWeight,...
    'FontSize',DATA.figureProperties.axisFontSize,...
    'FontSmoothing','on');
% Axes
set(ax,...
    'TickLabelInterpreter',DATA.figureProperties.interpreter,...
    'fontname',DATA.figureProperties.fontName,...
    'Fontweight',DATA.figureProperties.fontWeight,...
    'FontSize',DATA.figureProperties.axisFontSize,...
    'FontSmoothing','on',...
    'Color',DATA.figureProperties.axesColor,...
    'GridLineStyle','--',...
    'GridAlpha',0.25,...
    'GridColor','k');
axisLimit = (DATA.figureProperties.objectMaximalRadii + DATA.figureProperties.maxAbsPosition);
xlim(ax,[-axisLimit,axisLimit]);
ylim(ax,[-axisLimit,axisLimit]);
zlim(ax,[-axisLimit,axisLimit]);
axis vis3d equal;
grid on;  box on;
hold off;

% SAVE THE OUTPUT FIGURE
figurePath = [SIM.outputPath,...
    sprintf('collision-event-id-%d-%s-id-%d-%s.fig',...
    collisionEvent.objectID_A,collisionEvent.name_A,...
    collisionEvent.objectID_B,collisionEvent.name_B)];

savefig(figureHandle,figurePath);
% ITERATE PLOT
currentFigure = currentFigure + 1;
end


function b = ne(v1,v2,varargin)
% ? v1 == v2

b = ~eq(v1,v2,varargin{:});


function new_files = remove_disdaq_vols(img_files, num_vols_per_run, num_disdaq_vols, varargin)
% :Usage:
% ::
%
%     new_files = remove_disdaq_vols(img_files, num_vols_per_run, num_disdaq_vols, ['overwrite', 0|1], ['FSLOUTPUTTYPE', fsl_output_type], ['strict', 0|1])
%
% :Inputs:
%
%   **img_files:**
%        cellstr of files to remove disdaqs from - each cell represents a run
%
%   **num_vols_per_run:**
%        vector of volume counts per run, *not* including disdaq vols
%
%   **num_disdaq_vols:**
%        constant describing how many data points to remove from the beginning of each run
%
%   **'overwrite':**
%        if set, will overwriting images in place - defaults to 0
%
%   **'FSLOUTPUTTYPE':**
%        outputfile type - defaults to 'NIFTI'
%
%   **'strict':**
%        if set, will error out unless data given to it is
%        exactly proper length - defaults to 1 - turn off ONLY with good reason
%
% :Output:
%
%   **new_files:**
%        input files, but with a 'd' prepended, unless 'overwriting' was specified
%
% NB: Not set up for 3d files yet!!!
%
% :Examples:
% ::
%
%    % for an experiment
%    num_vols_per_run = [124 140 109];  % NOT including disdaqs
%    num_disdaq_vols = 4;

    global FSLDIR;
    scn_setup();

    % Flags
    strict = 1;
    overwriting = 0;
    return_char = 0;
    fsl_output_type = 'NIFTI';

    % Check inputs
    if ~isempty(varargin)
        for i = 1:length(varargin)
            if ischar(varargin{i})
                switch(varargin{i})
                    case {'overwrite' 'overwriting'}
                        overwriting = varargin{i+1};
                    case 'strict'
                        strict = varargin{i+1};
                    case {'fsl_output_type', 'FSLOUTPUTTYPE'}
                        fsl_output_type = varargin{i+1};
                end
            end
        end
    end

    if(ischar(img_files))
        disp('Cellstr not passed in, changing...')
        img_files = cellstr(img_files);
        return_char = 1;
    end

    % Use FSL to remove disdaqs
    new_files = cell(size(img_files));
    for i=1:length(img_files)
        current_file = img_files{i};
        num_frames = scn_num_volumes(current_file);

        if(strict && (num_frames ~= num_vols_per_run(i) + num_disdaq_vols(i)))
            error('The number of vols (%d) + disdaqs (%d) don''t add up to the length (%d) of the file (''%s'') passed in.', num_vols_per_run, num_disdaq_vols, num_frames, current_file);
        else
            if(overwriting)
                output_file = current_file;
            else
                [d f e] = fileparts(current_file);
                output_file = fullfile(d, ['d' f]);
            end

            fslroi_command = sprintf('export FSLDIR=%s && . %s/etc/fslconf/fsl.sh && FSLOUTPUTTYPE=%s && %s/bin/fslroi %s %s %d %d', ...
                FSLDIR, FSLDIR, fsl_output_type, FSLDIR, current_file, output_file, num_disdaq_vols, num_vols_per_run);
            disp(fslroi_command);
            system(fslroi_command);
        end

        new_files{i} = [output_file e];
    end

    % Convert output back to char is only a single file was passed in
    if(return_char)
        new_files = char(new_files);
    end
end


function dStates = rhs(~,States,Phase,P)

%This function is a wrapper for the controller and dynamics functions that
%makes them easier to call from ode45.

Actuators = Controller_PD(States,P.Control,Phase);

switch Phase
    case 'F'
        dStates = dynamics_flight(States,Actuators,P.Dyn);
    case 'D'
        dStates = dynamics_doubleStance(States,Actuators,P.Dyn);
    case 'S1'
        dStates = dynamics_singleStanceOne(States,Actuators,P.Dyn);
    case 'S2'
        dStates = dynamics_singleStanceTwo(States,Actuators,P.Dyn);
    otherwise
        error('Invalid phase, must be element of {''F'',''D'',''S1'',''S2''}');
end

end


function [lrp] = ft_lateralizedpotential(cfg, avgL, avgR)

% FT_LATERALIZEDPOTENTIAL computes lateralized potentials such as the
% lateralized readiness potential (LRP)
%
% Use as
%   [lrp] = ft_lateralizedpotential(cfg, avgL, avgR)
%
% where the input datasets should come from FT_TIMELOCKANALYSIS
% and the configuration should contain
%   cfg.channelcmb = Nx2 cell-array
%
% An example channelcombination containing the homologous channels
% in the 10-20 standard system is
%    cfg.channelcmb = {'Fp1'   'Fp2'
%                      'F7'    'F8'
%                      'F3'    'F4'
%                      'T7'    'T8'
%                      'C3'    'C4'
%                      'P7'    'P8'
%                      'P3'    'P4'
%                      'O1'    'O2'}
%
% The lateralized potential is computed on combinations of channels and
% not on indivudual channels. However, if you want to make a topographic
% plot with e.g. FT_MULTIPLOTER, you can replace the output lrp.label
% with lrp.plotlabel.
%
% The concept for the LRP was introduced approximately simultaneously in the
% following two papers
% - M. G. H. Coles. Modern mind-brain reading - psychophysiology,
%   physiology, and cognition. Psychophysiology, 26(3):251-269, 1988.
% - R. de Jong, M. Wierda, G. Mulder, and L. J. Mulder. Use of
%   partial stimulus information in response processing. J Exp Psychol
%   Hum Percept Perform, 14:682-692, 1988.
% and it is discussed in detail on a technical level in
% - R. Oostenveld, D.F. Stegeman, P. Praamstra and A. van Oosterom.
%   Brain symmetry and topographic analysis of lateralized event-related
%   potentials. Clin Neurophysiol. 114(7):1194-202, 2003.
%
% 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_TIMELOCKANALYSIS, FT_MULTIPLOTER

% Copyright (C) 2004, 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 avgL avgR
ft_preamble provenance avgL avgR

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

% check if the input data is valid for this function
avgL = ft_checkdata(avgL, 'datatype', 'timelock');
avgR = ft_checkdata(avgR, 'datatype', 'timelock');

% check if the input cfg is valid for this function
cfg = ft_checkconfig(cfg, 'forbidden',  {'channels'}); % prevent accidental typos, see issue 1729

% set the defaults
if ~isfield(cfg, 'channelcmb')
  cfg.channelcmb = {
    'Fp1'   'Fp2'
    'F7'    'F8'
    'F3'    'F4'
    'T7'    'T8'
    'C3'    'C4'
    'P7'    'P8'
    'P3'    'P4'
    'O1'    'O2'
    };
end

if ~isequal(avgL.time, avgR.time)
  ft_error('the time axes are not the same');
end

% start with an empty output structure
lrp.label     = {};
lrp.plotlabel = {};
lrp.avg       = [];
lrp.time      = avgL.time;

% add timelock signature
if isfield(avgL, 'dimord') && isfield(avgR, 'dimord')
    if ~strcmp(avgL.dimord, avgR.dimord)
        ft_error('The input data are of different dimord types');
    else
        lrp.dimord = avgL.dimord;
    end
else
    ft_error('''dimord'' not found. The function expects timelock data');
end

% compute the lateralized potentials
Nchan = size(cfg.channelcmb,1);
for i=1:Nchan
  % here the channel names "C3" and "C4" are used to clarify the
  % computation of the lateralized potential on all channel pairs
  C3R = strcmp(cfg.channelcmb{i,1}, avgR.label);
  C4R = strcmp(cfg.channelcmb{i,2}, avgR.label);
  C3L = strcmp(cfg.channelcmb{i,1}, avgL.label);
  C4L = strcmp(cfg.channelcmb{i,2}, avgL.label);
  if any(C3R) && any(C4R) && any(C3L) && any(C4L)
    lrp.label{end+1}     = sprintf('%s/%s', cfg.channelcmb{i,1}, cfg.channelcmb{i,2});
    lrp.plotlabel{end+1} = cfg.channelcmb{i,1};
    erpC3L = avgL.avg(C3L,:);
    erpC4L = avgL.avg(C4L,:);
    erpC3R = avgR.avg(C3R,:);
    erpC4R = avgR.avg(C4R,:);
    lrp.avg(end+1,:) = 1/2 * ((erpC3R - erpC4R) + (erpC4L - erpC3L));
  end
end

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble previous   avgL avgR
ft_postamble provenance lrp
ft_postamble history    lrp
ft_postamble savevar    lrp


function [mem]=tt_mem(tt)
% Memory required to store the tensor TT
%   [MEM]=TT_MEM(TT) Computes the total number of elements in the TT-tensor
%   in the TT1.0 format. Please avoid its usage: it will be removed in
%   future releases. Use mem() from the object-oriented version.
%
%
% TT-Toolbox 2.2, 2009-2012
%
%This is TT Toolbox, written by Ivan Oseledets et al.
%Institute of Numerical Mathematics, Moscow, Russia
%webpage: http://spring.inm.ras.ru/osel
%
%For all questions, bugs and suggestions please mail
%ivan.oseledets@gmail.com
%---------------------------
mem=0;
d=size(tt,1);
for k=1:d
    mem=mem+numel(tt{k});
end
end