%-----------------------------------------------------------------------
% Job configuration created by cfg_util (rev $Rev: 7703 $)
%-----------------------------------------------------------------------
matlabbatch{1}.spm.meeg.source.headmodel.D = {'C:\Users\gbarnes\Documents\simdata_peakomatic\simdata_1dip_5mm_0pcamp2_amp10\simdata.mat'};
matlabbatch{1}.spm.meeg.source.headmodel.val = 1;
matlabbatch{1}.spm.meeg.source.headmodel.comment = '';
matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshes.template = 1;
matlabbatch{1}.spm.meeg.source.headmodel.meshing.meshres = 2;
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).fidname = 'nas';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(1).specification.select = 'nas';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).fidname = 'lpa';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(2).specification.select = 'FIL_CTF_L';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).fidname = 'rpa';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.fiducial(3).specification.select = 'FIL_CTF_R';
matlabbatch{1}.spm.meeg.source.headmodel.coregistration.coregspecify.useheadshape = 0;
matlabbatch{1}.spm.meeg.source.headmodel.forward.eeg = 'EEG BEM';
matlabbatch{1}.spm.meeg.source.headmodel.forward.meg = 'Single Shell';
matlabbatch{2}.spm.tools.beamforming.data.dir = {'C:\Users\gbarnes\Documents\batchtest\'};
matlabbatch{2}.spm.tools.beamforming.data.D(1) = cfg_dep('M/EEG head model specification: M/EEG dataset(s) with a forward model', substruct('.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','D'));
matlabbatch{2}.spm.tools.beamforming.data.val = 1;
matlabbatch{2}.spm.tools.beamforming.data.space = 'MNI-aligned';
matlabbatch{3}.spm.tools.beamforming.sources.BF(1) = cfg_dep('Prepare data: BF.mat file', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.resolution = 5;
matlabbatch{3}.spm.tools.beamforming.sources.plugin.grid.space = 'MNI template';
matlabbatch{4}.spm.tools.beamforming.features.BF(1) = cfg_dep('Define sources: BF.mat file', substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{4}.spm.tools.beamforming.features.whatconditions.all = 1;
matlabbatch{4}.spm.tools.beamforming.features.woi = [-Inf Inf];
matlabbatch{4}.spm.tools.beamforming.features.foi = [0 0];
matlabbatch{4}.spm.tools.beamforming.features.plugin.regcov.lambda = 0;
matlabbatch{5}.spm.tools.beamforming.inverse.BF(1) = cfg_dep('Covariance features: BF.mat file', substruct('.','val', '{}',{4}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{5}.spm.tools.beamforming.inverse.plugin.lcmv = struct([]);
matlabbatch{6}.spm.tools.beamforming.output.BF(1) = cfg_dep('Inverse solution: BF.mat file', substruct('.','val', '{}',{5}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.whatconditions.all = 1;
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.woi = [-Inf Inf];
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.contrast = 1;
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.result = 'singleimage';
matlabbatch{6}.spm.tools.beamforming.output.plugin.image_power.modality = 'MEG';
matlabbatch{7}.spm.tools.beamforming.write.BF(1) = cfg_dep('Output: BF.mat file', substruct('.','val', '{}',{6}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','BF'));
matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.normalise = 'separate';
matlabbatch{7}.spm.tools.beamforming.write.plugin.nifti.space = 'mni';


function [document, scores] = report_failures(context, experiment, trackers, sequences, varargin)
% report_failures Generate a statistic overview of occurences of failures
%
% Generate a statistic overview of occurences of failures in individual sequences.
%
% Input:
% - context (structure): Report context structure.
% - experiment (struct): An experiment structure.
% - trackers (cell): An array of tracker structures.
% - sequences (cell): An array of sequence structures.
%
% Output:
% - document (structure): Resulting document structure.
%

scores = [];

document = create_document(context, 'failures', 'title', 'Failure overview');

for i = 1:2:length(varargin)
    switch lower(varargin{i})
        otherwise
            error(['Unknown switch ', varargin{i},'!']) ;
    end
end

tracker_labels = cellfun(@(x) iff(isfield(x.metadata, 'verified') && x.metadata.verified, [x.label, '*'], x.label), trackers, 'UniformOutput', 0);

sequences_hash = md5hash(strjoin((cellfun(@(x) x.name, sequences, 'UniformOutput', false)), '-'), 'Char', 'hex');
trackers_hash = md5hash(strjoin((cellfun(@(x) x.identifier, trackers, 'UniformOutput', false)), '-'), 'Char', 'hex');

if ~strcmp(experiment.type, 'supervised')
   error('Failure analysis only suitable for supervised experiments!');
end

cache_identifier = sprintf('failures_%s_%s_%s.mat', experiment.name, trackers_hash, sequences_hash);

histograms = report_cache(context, cache_identifier, @analyze_failures, ...
    experiment, trackers, sequences);

document.subsection('Experiment %s', experiment.name);

experiment_sequences = convert_sequences(sequences, experiment.converter);

for s = 1:length(experiment_sequences)

    if numel(experiment_sequences{s}.tags.names) == 0
        continue
    end

    document.subsection('Sequence %s',  experiment_sequences{s}.name);

    document.raw('
\n');

    hf = figure('Visible', 'off');
    imagesc(histograms{s});
    set(gca,'ytick',(1:numel(trackers)),'yticklabel', tracker_labels);

    document.figure(hf, sprintf('failures_%s_%s_individual', experiment.name, experiment_sequences{s}.name), ...
        sprintf('Sequence %s, individual trackers', experiment_sequences{s}.name));

    hf = figure('Visible', 'off');
    tags = experiment_sequences{s}.tags.data;
    tagsplit = mat2cell(tags, size(tags, 1), ones(1, size(tags, 2)));
    starts = cellfun(@(x) find(diff([0; x; 0]) > 0), tagsplit, 'UniformOutput', 0);
    ends = cellfun(@(x) find(diff([0; x; 0]) < 0), tagsplit, 'UniformOutput', 0);

    hold on;
    plot_timeline(experiment_sequences{s}.tags.names, starts, ends);
    combined_histogram = sum(histograms{s}, 1);
    combined_histogram = (combined_histogram / max(combined_histogram)) * numel(experiment_sequences{s}.tags.names);
    plot(combined_histogram);
    set(gca, 'XLim', [1, experiment_sequences{s}.length]);
    hold off;

    document.figure(hf, sprintf('failures_%s_%s_combined', experiment.name, experiment_sequences{s}.name), ...
        sprintf('Sequence %s, combined failures with properties', experiment_sequences{s}.name));

    document.raw('
\n');
end;

document.write();


% Author: James A. Douthwaite

classdef agent_2D_formation_HRVO < agent_2D_formation_RVO & agent_2D_HRVO
%% INITIALISE THE AGENT SPECIFIC PARAMETERS
    properties
        % PROPERTITIES UNIQUE TO AGENT CLASS
    end
    %% ///////////////////////// MAIN METHODS /////////////////////////////
    methods
        % Constructor
        function obj = agent_2D_formation_HRVO(varargin)
            % CALL THE SUPERCLASS CONSTRUCTOR
            obj = obj@agent_2D_formation_RVO(varargin);

            % //////////////// Check for user overrides ///////////////////
            [obj] = obj.ApplyUserOverrides(varargin); % Recursive overrides
            % /////////////////////////////////////////////////////////////
        end
        % NOTES:
        % This class simply overrides the 'process_timeCycle' function of
        % the superclass 'agent_2D_formation_RVO' such that it considers the
        % 'avoidanceCorrection' of the second super class 'agent_2D_HRVO'.
    end
end


% eeg_mergelocs() - merge channel structure while preserving channel
%                   order
%
%      >> mergedlocs = eeg_mergelocs(loc1, loc2, loc3, ...);
%
% Inputs:
%     loc1     - EEGLAB channel location structure
%     loc2     - second EEGLAB channel location structure
%
% Output:
%     mergedlocs - merged channel location structure
%
% Author: Arnaud Delorme, August 2006

% Copyright (C) Arnaud Delorme, CERCO, 2006, 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

function alllocs = eeg_mergelocs(varargin)

persistent warning_shown;

% sort by length
% --------------
len = cellfun(@length, varargin);
[tmp so] = sort(len, 2, 'descend');
varargin = varargin(so);

alllocs = varargin{1};
for index = 2:length(varargin)

    % fuse while preserving order (assumes the same channel order)
    % ------------------------------------------------------------
    tmplocs = varargin{index};
    newlocs = myunion(alllocs, tmplocs);

    if length(newlocs) > length(union({ alllocs.labels }, { tmplocs.labels }))

        if isempty(warning_shown)
            disp('Warning: different channel montage order for the different datasets');
            warning_shown = 1;
        end;

        % trying to preserve order of the longest array
        %----------------------------------------------
        if length(alllocs) < length(tmplocs)
            tmp     = alllocs;
            alllocs = tmplocs;
            tmplocs = tmp;
        end;
        allchans = { alllocs.labels tmplocs.labels };
        [uniquechan ord1 ord2 ]  = unique( allchans );

        [tmp rminds] = intersect( uniquechan, { alllocs.labels });
        ord1(rminds) = [];
        tmplocsind = ord1-length(alllocs);

        newlocs = concatlocs(alllocs, tmplocs(tmplocsind));

    end;
    alllocs = newlocs;
end;

% union of two channel location structure
% without loosing the order information
% ---------------------------------------
function alllocs = myunion(locs1, locs2)

   labs1 = { locs1.labels };
   labs2 = { locs2.labels };

   count1 = 1;
   count2 = 1;
   count3 = 1;
   alllocs = locs1; alllocs(:) = [];
   while count1 <= length(locs1) | count2 <= length(locs2)

       if count1 > length(locs1)
           alllocs = copyfields(alllocs, count3, locs2(count2));
           %alllocs(count3) = locs2(count2);
           count2 = count2 + 1;
           count3 = count3 + 1;
       elseif count2 > length(locs2)
           alllocs = copyfields(alllocs, count3, locs1(count1));
           %alllocs(count3) = locs1(count1);
           count1 = count1 + 1;
           count3 = count3 + 1;
       elseif strcmpi(labs1{count1}, labs2{count2})
           alllocs = copyfields(alllocs, count3, locs1(count1));
           %alllocs(count3) = locs1(count1);
           count1 = count1 + 1;
           count2 = count2 + 1;
           count3 = count3 + 1;
       elseif isempty(strmatch(labs1{count1}, labs2, 'exact'))
           alllocs = copyfields(alllocs, count3, locs1(count1));
           %alllocs(count3) = locs1(count1);
           count1 = count1 + 1;
           count3 = count3 + 1;
       else
           alllocs = copyfields(alllocs, count3, locs2(count2));
           %alllocs(count3) = locs2(count2);
           count2 = count2 + 1;
           count3 = count3 + 1;
       end;

   end;

% concatenate channel structures with different fields
function loc3 = concatlocs(loc1, loc2);

    fields1 = fieldnames(loc1);
    fields2 = fieldnames(loc2);
    if isequal(fields1, fields2)
        loc3 = [ loc1 loc2 ];
    else
        loc3 = loc1;
        for index = 1:length(loc2)
            loc3 = copyfields(loc3, length(loc1)+index, loc2(index));
        end;
    end;

% copy fields of a structure to another one
function [struct1] = copyfields(struct1, index1, struct2)

    fields1 = fieldnames(struct1);
    fields2 = fieldnames(struct2);

    if isequal(fields1, fields2)
        struct1(index1) = struct2;
    else
        for index = 1:length(fields2)
            struct1 = setfield(struct1, {index1}, fields2{index}, getfield(struct2, fields2{index}));
        end;
    end;


function [inpts,volpts]=mrUndoAPoint(inpts,volpts)
%function [inpts,volpts]=mrUndoAPoint(inpts,volpts)
%
%Removes the last selected pair of alignment points from the list

%6/16/96	gmb	wrote it.

npoints = size(volpts,1);

inpts=inpts(1:npoints-1,:);
volpts=volpts(1:npoints-1,:);

npoints = size(volpts,1);
disp([num2str(npoints),' pairs of points selected.']);


%  Expand a multiple-scan NIFTI file into multiple single-scan NIFTI files
%
%  Usage: expand_nii_scan(multi_scan_filename, [img_idx], [path_to_save])
%
%  NIFTI data format can be found on: http://nifti.nimh.nih.gov
%
%  - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
%
function expand_nii_scan(filename, img_idx, newpath)

   v = version;

   %  Check file extension. If .gz, unpack it into temp folder
   %
   if length(filename) > 2 & strcmp(filename(end-2:end), '.gz')

      if ~strcmp(filename(end-6:end), '.img.gz') & ...
	 ~strcmp(filename(end-6:end), '.hdr.gz') & ...
	 ~strcmp(filename(end-6:end), '.nii.gz')

         error('Please check filename.');
      end

      if str2num(v(1:3)) < 7.1 | ~usejava('jvm')
         error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.');
      else
         gzFile = 1;
      end
   end

   if ~exist('newpath','var') | isempty(newpath), newpath = pwd; end
   if ~exist('img_idx','var') | isempty(img_idx), img_idx = 1:get_nii_frame(filename); end

   for i=img_idx
      nii_i = load_untouch_nii(filename, i);

      fn = [nii_i.fileprefix '_' sprintf('%04d',i)];
      pnfn = fullfile(newpath, fn);

      if exist('gzFile', 'var')
         pnfn = [pnfn '.nii.gz'];
      end

      save_untouch_nii(nii_i, pnfn);
   end

   return;					% expand_nii_scan


function [] = lexmkpackage(fileSpec,varargin)
%
% lexmkpackage.m--Makes a software package by lexically checking the
% dependencies of the specified m-file(s). Uses the lexdepfun.m function,
% rather than Mathwork's depfun.m program, so can be used for assembling
% packages for GUI applications (Matlab's depfun.m does not detect callback
% dependencies).
%
% The package created by lexmkpackage.m is placed in a directory named
% "mkpackageDir" under the current working directory.
%
% The user specifies the m-files whose dependencies are to be searched
% using the input argument "fileSpec". fileSpec can be the fully-qualified
% filename of an m-file. Alternatively, if the m-file is on Matlab's search
% path, then just the name of the m-file (without path information) can be
% provided instead.
%
% Multiple filenames can be specified either as a cell array of strings or
% using the '*' wildcard character.
%
% lexdepfun.m detects only user-defined m-files.
%
% lexdepfun.m cannot detect dependant functions whose m-file names are
% generated dynamically at runtime with, for example, eval.m.
%
% Options:
%
%    LEXMKPACKAGE(fileSpec,...,'-quiet') suppresses progress output.
%
%    LEXMKPACKAGE(fileSpec,...,'-preserve') preserves the directory
%    structure of the dependent m-files when creating the package. This,
%    the default behaviour, is necessary to avoid namespace collisions when
%    multiple m-files with the same name are encountered or when "private"
%    directories contain special, modified versions of standard Matlab
%    routines. An additional m-file, package_path.m is created. Running
%    package_path.m will add the paths of the package sub-directories to
%    Matlab's search path.
%
%    LEXMKPACKAGE(fileSpec,...,'-consolidate') puts all dependent m-files
%    into the same directory. This method gives more convenient results
%    than the '-preserve' method, but will fail if multiple m-files with
%    the same name are encountered.
%
%    LEXMKPACKAGE(fileSpec,...,'-file') puts the code from all dependent
%    m-files into a single m-file. This method will only work if the
%    fileSpec input argument refers to a single "root" m-file. Note that
%    this method should not be used for GUI packages, as GUI callback
%    routines must be visible from the root workspace. The '-file' method
%    will not produce a useable file when any of the dependent m-files are
%    scripts, rather than functions.
%
% N.B., the package created by lexmkpackage.m will frequently contain extra
% files in addition to the ones actually needed. This is an unavoidable
% side-effect of the lexical dependency search algorithm.
%
% Syntax: lexmkpackage(fileSpec,<'-file'>,<'-preserve'>,<'-consolidate'>,<'-quiet'>,)
%
% e.g.,   lexmkpackage('/home/bartlett/matlab/units/*.m')
% e.g.,   lexmkpackage('date2yearday','-file','-quiet')
% e.g.,   lexmkpackage('acquire_vmp')
% e.g.,   lexmkpackage({'lsm' 'newfig'},'-consolidate')
% e.g.,   lexmkpackage({'/home/bartlett/matlab/FileOps/lsm.m' '/home/bartlett/matlab/plotting/newfig.m'})

% Developed in Matlab 7.3.0.298 (R2006b) on GLNX86.
% Kevin Bartlett (kpb@uvic.ca), 2007-04-27
%-------------------------------------------------------------------------

% Handle input arguments.
makeSingleFileSpecified = 0;
preserveSpecified = 0;
consolidateSpecified = 0;
isQuiet = 0;

if nargin > 1

    for arg = varargin

        arg = lower(arg);

        if strcmp(arg,'-file') == 1
            %doMakeSingleFile = 1;
            makeSingleFileSpecified = 1;
        elseif strcmp(arg,'-preserve') == 1
            preserveSpecified = 1;
        elseif strcmp(arg,'-consolidate') == 1
            consolidateSpecified = 1;
        elseif strcmp(arg,'-quiet') == 1
            isQuiet = 1;
        else
            error([mfilename '.m--Unrecognised input argument ''' varargin{1}  '''.'])
        end % if

    end % for

end % if

% Determine whether directory structure is to be preserved or whether
% dependent mfiles will be consolidated in a single directory or m-file.
% Preservation, consolidation and single-file output are mutually
% exclusive.
doPreserve = 1;
doMakeSingleFile = 0;
doConsolidate = 0;

if consolidateSpecified == 1
    doPreserve = 0;
    doMakeSingleFile = 0;
    doConsolidate = 1;
end % if

if makeSingleFileSpecified == 1
    doPreserve = 0;
    doMakeSingleFile = 1;
    doConsolidate = 0;
end % if

% Make the new directory to contain the package.
mkpackageDirName = 'mkpackageDir';
mkpackageDir = fullfile(pwd,mkpackageDirName);

if exist(mkpackageDir,'dir')==7

    %disp([mfilename '.m--Directory ' mkpackageDir ' already exists.']);
    disp([mfilename '.m--Directory already exists:']);
    disp(mkpackageDir);
    resp = input('Delete it and start over? Y/N:   ','s');

    if ~isempty(strmatch(lower(resp),'yes'))

        [rmdir_success,rmdir_mssg,rmdir_mssgID] = rmdir(mkpackageDir,'s');

        if rmdir_success == 0
            error([mfilename '.m--Failed to remove existing directory: ' mkpackageDir '.']);
        end % if

    else
        disp([mfilename '.m--Execution halted; package not created.']);
        return;
    end % if

end % if

% List the files specified by the user.

% % ...If fileSpec was entered as a cell array, assume it consists of m-file
% % names.
% if iscell(fileSpec)
%     rootFileList = fileSpec;
% else
%     % Otherwise, treat fileSpec as a string indicating the location of an
%     % m-file or files (either a filename or a wildcard-containing file
%     % specifier).
%     rootFileList = list_root_files(fileSpec);
% end % if
%

% Convert fileSpec to a cell array if necessary.
if ~iscell(fileSpec)
    fileSpec = {fileSpec};
end % if

% Assemble list of "root" files to search.
rootFileList = {};

for iFile = 1:length(fileSpec)

    thisFileSpec = fileSpec{iFile};

    % Treat this file specifier string as a sort of regular expression, and
    % look for files that match it.
    thisRootFileList = list_root_files(thisFileSpec);

    % If no file was found to match the file specifier as a regular
    % expression, assume that the user has entered the basename of an
    % m-file and look for it on the Matlab search path.
    if isempty(thisRootFileList)
        thisRootFileList = {which(thisFileSpec)};
    end % if

    % Append any mfiles found with this file specifier to the list of root
    % files.
    if ~isempty(thisRootFileList)
        %rootFileList{end+1} = thisRootFileList;
        [rootFileList{length(rootFileList)+1:length(rootFileList)+length(thisRootFileList)}] = deal(thisRootFileList{:});
    end % if

end % for

if isempty(rootFileList)
    %error([mfilename '.m--Must specify m-file(s) on Matlab''s search path.'])
    error([mfilename '.m--fileSpec argument matched no m-file or any function on Matlab''s search path. Package not created.'])
end % if

% Creating a package inside an m-file is only allowed when a single m-file
% has been specified by the user. This is because if multiple m-files are
% consolidated into a single m-file, only one of the functions is
% accessible from the root workspace, making it pointless to include
% multiple files unless they are dependents of the main function.
if doMakeSingleFile == 1 & length(rootFileList)>1
    error([mfilename '.m--Cannot create a single-file package for multiple m-files.'])
end % if

numFiles = length(rootFileList);

% Find the dependencies for the specified m-files.
depList = {};

for iFile = 1:numFiles

    if ~isQuiet
        disp([mfilename '.m--Finding dependencies of m-file ' num2str(iFile) ' of ' num2str(numFiles)]);
    end % if

    thisFile = rootFileList{iFile};

    [dummy,thisBaseName] = fileparts(thisFile);

    % Find the dependents of this m-file.
    if isQuiet
        thisDepList = lexdepfun(thisFile,'-quiet');
    else
        thisDepList = lexdepfun(thisFile);
    end % if

    % Combine with previous dependencies. It is okay to use union.m here
    % because the dependency list contains fully-qualified mfile names, so
    % the only duplicates that will be removed are TRUE duplicates (not
    % just mfiles with the same basenames).
    depList = union(depList,thisDepList);

end % for

% Test for duplicate mfile basenames. Duplicate names are not necessarily a
% problem if the directory structure is being preserved. If all the m-files
% are going to be consolidated in a single directory or in a single, large
% m-file, on the other hand, duplicate mfilenames will have unpredictable
% results.
[dummy,depBaseNames] = mfileparts(depList);
duplicatesExist = length(unique(depBaseNames)) ~= length((depBaseNames));

if duplicatesExist & (doMakeSingleFile == 1 | doPreserve == 0)
    error([mfilename '.m--Cannot consolidate all dependent m-files in a single directory or single m-file because there are duplicate m-file names.'])
end % if

% Create directory to contain package.

% Mkdir uses only 2 output arguments on linux version of matlab.
%[mkdir_success,mkdir_mssg,mkdir_mssgID] = mkdir(pwd,mkpackageDirName);
[mkdir_success,mkdir_mssg] = mkdir(pwd,mkpackageDirName);

if mkdir_success ~= 1
    error([mfilename '.m--Error creating directory: ' mkdir_mssg]);
end % if

% The list of dependencies contains the name(s) of the root file(s), but
% they may be mixed up with the dependent files. Create a new file list
% containing both the root file(s) and the dependent files, but with the
% root file(s) at the start of the list.
depList = setdiff(depList,rootFileList);
numSourceFiles = length(rootFileList) + length(depList);
[sourceFiles{1:numSourceFiles}] = deal(rootFileList{:},depList{:});
[sourceDirs,sourceBaseNames,sourceExts] = mfileparts(sourceFiles);

% Output the package.
if doMakeSingleFile == 1

    % Output package in the form of a single m-file containing (possibly)
    % multiple functions.

    % There is only one root file allowed when putting all the dependent
    % functions in a single mfile.
    rootFile = rootFileList{1};

    [dummy,rootBaseName,rootExt,dummy] = fileparts(rootFile);
    rootFileName = [rootBaseName rootExt];
    outFile = fullfile(mkpackageDir,rootFileName);
    outFid = fopen(outFile,'at');

    if outFid < 0
        error([mfilename '.m--Failed to open output file for writing.']);
    end % if

    % Output the code from the source files into the output m-file.
    for iSource = 1:length(sourceFiles)

        thisSource = sourceFiles{iSource};

        sourceFid = fopen(thisSource,'rt');

        if thisSource < 0
            error([mfilename '.m--Failed to open mfile for reading.']);
        end % if

        % Specify empty character for whitespace parameter when calling
        % textscan.m, or leading whitespace is discarded.
        %sourceCode = textscan(sourceFid,'%s','delimiter','\n');
        sourceCode = textscan(sourceFid,'%s','delimiter','\n','whitespace','');
        sourceCode = sourceCode{1};

        for iLine = 1:length(sourceCode)
            fprintf(outFid,'%s\n',sourceCode{iLine});
        end % for

        fclose(sourceFid);

        % Print out a divider line to separate functions.
        if iSource < length(sourceFiles)
            fprintf(outFid,'%s\n\n','%-------------------------------------------------------------------------');
        end % if

    end % for each dependent file

    fclose(outFid);

elseif doPreserve == 1

    % Separate the root path from the subdirectory for all the
    % directories to be copied (if all the files are in, say,
    % /home/bartlett/matlab/oceanography/mapping/, can copy them all to
    % a directory named "mapping"; there is no need to preserve the
    % /home/bartlett/matlab/oceanography/ part).

    %for i = 1:144, if strfind(sourceFiles{i},'private'),disp(sourceFiles{i}),end,end
    %[depDirs,depBaseNames,depExts] = mfileparts(sourceFiles);
    [parentPath,sourceSubDirs] = find_parent_path(sourceDirs);

    for iSource = 1:length(sourceFiles)

        thisSource = sourceFiles{iSource};
        thisSubDir = sourceSubDirs{iSource};
        thisBaseName = sourceBaseNames{iSource};
        thisExt = sourceExts{iSource};
        thisTargDir = fullfile(mkpackageDir,thisSubDir);

        if exist(thisTargDir,'dir') == 0

            mkdirSuccess = mkdir(thisTargDir);

            if mkdirSuccess ~= 1
                error([mfilename '.m--Failed to make directory ' thisTargDir '.']);
            end % if

        end % if

        thisTarget = fullfile(thisTargDir,[thisBaseName thisExt]);
        copySuccess = copyfile(thisSource,thisTarget);

        if copySuccess ~= 1
            error([mfilename '.m--Failed to copy file ' thisTarget '.']);
        end % if

    end % for each dependent file

    % Create m-file, package_path.m, to contain code for adding the package
    % contents to Matlab's path.
    pathFileFid = fopen(fullfile(mkpackageDir,'package_path.m'),'wt');

    if pathFileFid < 0
        error([mfilename '.m--Failed to open ''package_path.m'' file for writing.']);
    end % if

    fprintf(pathFileFid,'%s\n','function [] = package_path()');
    fprintf(pathFileFid,'%s\n','%');
    fprintf(pathFileFid,'%s\n','% package_path.m--Adds the package to the Matlab path.');
    fprintf(pathFileFid,'%s\n','%');
    fprintf(pathFileFid,'%s\n',['% Created automatically by ' mfilename '.m, ' datestr(now,31)]);
    fprintf(pathFileFid,'%s\n','%');
    fprintf(pathFileFid,'%s\n','%-------------------------------------------------------------------------');
    fprintf(pathFileFid,'%s\n','');
    fprintf(pathFileFid,'%s\n','% Get absolute path to package_path.m.');
    fprintf(pathFileFid,'%s\n','thisMFile = mfilename(''fullpath'');');
    fprintf(pathFileFid,'%s\n','thisDir = fileparts(thisMFile);');
    fprintf(pathFileFid,'%s\n','');
    fprintf(pathFileFid,'%s\n','% Add the paths of the mfiles in the package to the Matlab path.');

    pathsToAdd = unique(sourceSubDirs);

    for iPath = 1:length(pathsToAdd)

        thisPartialPath = pathsToAdd{iPath};

        % "Private" directories are not allowed in Matlab's search path.
        [dummy,bottomDirName] = fileparts(thisPartialPath);

        if strcmp(bottomDirName,'private') == 0
            thisFullPathStr = ['[thisDir ''' filesep thisPartialPath ''']'];
            addPathStr = ['addpath(' thisFullPathStr ');'];
            fprintf(pathFileFid,'%s\n',addPathStr);
        end % if

    end % for

    fclose(pathFileFid);

elseif doConsolidate == 1

    % Consolidate all mfiles in one directory.
    for iSource = 1:length(sourceFiles)

        thisSource = sourceFiles{iSource};
        thisBaseName = sourceBaseNames{iSource};
        thisExt = sourceExts{iSource};

        thisTarget = fullfile(mkpackageDirName,[thisBaseName thisExt]);
        copySuccess = copyfile(thisSource,thisTarget);

        if copySuccess ~= 1
            error([mfilename '.m--Failed to copy file ' thisTarget '.']);
        end % if

    end % for each dependent file

end % if making single file package

if isQuiet == 0
    disp([mfilename '.m--Package created.']);
end % if

%------------------------------------------------------------------------------
function fileList = list_root_files(fileSpec)
%
% list_root_files.m--Makes a list of the "root" files from the
% file-specifier string provided by the user and returns it as a CELL
% array.
%
% LIST_ROOT_FILES(fileSpec) returns a list of files according to the string
% found in fileSpec. fileSpec may include the wildcard character "*" and/or
% path information.
%
% Syntax: fileList = list_root_files(fileSpec);
%
% e.g., fileList = list_root_files('D:\MATLAB\toolbox\matlab\graph2d\plot*.m')

% Developed in Matlab 6.5.0.180913a (R13) on SUN OS 5.8.
% Kevin Bartlett(kpb@hawaii.edu), 2003/12/18, 11:04
%------------------------------------------------------------------------------

% If path not specified, default to current directory.
[filePath,name,extension,ver] = fileparts(fileSpec);

if isempty(filePath),
    filePath = pwd;
    fileSpec = fullfile(filePath,[name,extension,ver]);
end % if

% If fileSpec represents an existing directory with no file name or wild
% cards appended to it, then return an empty list.
if exist(fileSpec,'dir') == 7
    fileList = {};
else

    % Get list of files conforming to file specifier string.
    eval(['dirStruct = dir(''' fileSpec ''');'])
    fileList = char(dirStruct.name);

    % Exit if no files.
    if isempty(fileList)
        fileList = {};
        return;
    end % if

    % Discard directories from the list.
    isDir = {};
    [isDir{1:length(dirStruct),1}] = deal(dirStruct.isdir);
    isDir = cat(1,isDir{:});
    fileList = fileList(isDir == 0,:);

    % Convert to cell array.
    if isempty(fileList)
        fileList = {};
    else
        fileList = cellstr(fileList);
    end % if

    % Prepend path information to the list.
    numFiles = length(fileList);

    newFileList = cell(numFiles,1);

    for iFile = 1:numFiles
        newFileList{iFile} = fullfile(filePath,fileList{iFile});
    end % for

    fileList = newFileList;
    clear newFileList;

    % Sort the file list to get consistent file order.
    fileList = sort(fileList);

end % if

%-------------------------------------------------------------------------
function [pathStr,baseName,ext,versn] = mfileparts(fileList)
%
% mfileparts.m--Runs Mathworks' fileparts.m function on multiple filenames
% (fileparts.m only works on one file at a time). Result is returned in the
% form of cell arrays.
%
% If input argument is a single filename in the form of a string, rather
% than a cell array, mfileparts.m acts just like fileparts.m and
% returns strings rather than cell arrays.
%
% Syntax: [pathStr,baseName,ext,versn] = mfileparts(fileList)
%
% e.g.,   fileList = {'/home/bartlett/matlab/FileOps/where.m',...
%                     '/home/bartlett/matlab/bearings/count_rots.m',...
%                     '/home/bartlett/matlab/bearings/plot_rots.m',...
%                     '/home/bartlett/matlab/colours/getcolours.m',...
%                     '/home/bartlett/matlab/filters/decimate_me.m'};
%         [pathStr,baseName,ext,versn] = mfileparts(fileList)
%
% e.g.,   [pathStr,baseName,ext,versn] = mfileparts('/home/bartlett/matlab/FileOps/where.m')

% Developed in Matlab 7.3.0.298 (R2006b) on GLNX86.
% Kevin Bartlett (kpb@uvic.ca), 2007-04-27 16:08
%-------------------------------------------------------------------------

if iscell(fileList)
    isCellInput = 1;
elseif isstr(fileList)
    isCellInput = 0;
    fileList = cellstr(fileList);
else
    error([mfilename '.m--Input must be a cell array of strings or a single string.']);
end % if

nFiles = length(fileList);

[pathStr{1:nFiles}] = deal('');
baseName = pathStr;
ext = pathStr;
versn = pathStr;

for iFile = 1:nFiles
    thisFile = fileList{iFile};
    [thisPathStr,thisBaseName,thisExt,thisVersn] = fileparts(thisFile);
    pathStr{iFile} = thisPathStr;
    baseName{iFile} = thisBaseName;
    ext{iFile} = thisExt;
    versn{iFile} = thisVersn;
end % for

% If input was a string, make output just like fileparts.m.
if ~isCellInput
    pathStr = pathStr{1};
    baseName = baseName{1};
    ext = ext{1};
    versn = versn{1};
end % if

%-------------------------------------------------------------------------
function [parentPath,relativePaths] = find_parent_path(fileList)
%
% find_parent_path.m--Given a list of files (or directories),
% find_parent_path.m returns their shared parent path and their individual,
% relative paths.
%
% This program was developed on a Unix machine, but could presumably be
% adapted to Windows fairly easily.
%
% Syntax: [parentPath,relativePaths] = find_parent_path(fileList)
%
% e.g.,   fileList = {'/home/bartlett/matlab/FileOps/where.m',...
%                     '/home/bartlett/matlab/bearings/count_rots.m',...
%                     '/home/bartlett/matlab/bearings/plot_rots.m',...
%                     '/home/bartlett/matlab/colours/getcolours.m',...
%                     '/home/bartlett/matlab/colours/modcolours/redshift.m',...
%                     '/home/bartlett/matlab/filters/decimate_me.m'};
%         [parentPath,relativePaths] = find_parent_path(fileList)
%
% e.g., (Windows):
%        fileList = {'C:\Documents and Settings\bartlett\filesFileOps\where.m',...
%                    'C:\Documents and Settings\bartlett\bearings\count_rots.m',...
%                    'C:\Documents and Settings\bartlett\bearings\plot_rots.m',...
%                    'C:\Documents and Settings\bartlett\colours\getcolours.m',...
%                    'C:\Documents and Settings\bartlett\colours\redshift.m',...
%                    'C:\Documents and Settings\bartlett\filters\decimate_me.m'}
%         [parentPath,relativePaths] = find_parent_path(fileList)

% Developed in Matlab 7.3.0.298 (R2006b) on GLNX86.
% Kevin Bartlett (kpb@uvic.ca), 2007-04-27 16:32
%-------------------------------------------------------------------------

fileSep = filesep;

if strcmp(fileSep,'\')
   textscan_fileSep = '\\';
else
   textscan_fileSep = fileSep;
end % if

parentPathComponents = {};
nFiles = length(fileList);

% If any of the filenames is an empty string, then there is no shared
% parent directory.
for iFile = 1:nFiles

    thisFile = fileList{iFile};

    if isempty(thisFile)
        parentPath = '';
        relativePaths = fileList;
        return;
    end % if

end % for

% Make a cell array, with each cell containing the path components of one
% member of the file list.
%[pathComponents{1:nFiles}] = deal('');
pathComponents = cell(nFiles,1);

for iFile = 1:nFiles
    thisFile = fileList{iFile};
    pathComponents(iFile) = textscan(thisFile,'%s','delimiter',textscan_fileSep);
end % for

% Find the common parent directories.
commonParentExists = 1;

while commonParentExists

    [currTopLevelDir{1:nFiles}] = deal('');

    for iFile = 1:nFiles

        thisFilePathComponents = pathComponents{iFile};

        if length(thisFilePathComponents) > 0
            currTopLevelDir{iFile} = thisFilePathComponents{1};
        end % if

    end % for

    % If all the directories share a leading directory name, strip it
    % off each of the filenames.
    if length(unique(currTopLevelDir)) == 1

        for iFile = 1:nFiles

            thisFilePathComponents = pathComponents{iFile};

            if length(thisFilePathComponents) == 1
                thisFilePathComponents = {};
                pathComponents{iFile} = thisFilePathComponents;
            elseif length(thisFilePathComponents) > 1
                thisFilePathComponents = thisFilePathComponents(2:end);
                pathComponents{iFile} = thisFilePathComponents;
            end % if

            % If there are no remaining path components for this filename,
            % then it cannot share a common parent with the other
            % filenames.
            if isempty(thisFilePathComponents)
                commonParentExists = 0;
            end % if

        end % for

        % If the string giving the current top level is not empty, add it
        % to the components of the parent path (in unix file systems, the
        % first element returned by textscan.m is an empty string).
        if ~isempty(currTopLevelDir{1})
            parentPathComponents{end+1} = currTopLevelDir{1};
        end % if

    else
        commonParentExists = 0;
    end % if

end % while

% Assemble the components of the shared parent path into a single string.
if length(parentPathComponents) == 0
    parentPath = '';
elseif length(parentPathComponents) == 1
    %parentPath = [filesep parentPathComponents{1}];
    parentPath = [parentPathComponents{1}];
else
    %parentPath = [filesep fullfile(parentPathComponents{:})];
    parentPath = [fullfile(parentPathComponents{:})];
end % if

if isunix
    parentPath = [filesep parentPath];
end % if

% Assemble the components of each relative path into a single string.
relativePaths = cell(nFiles,1);

for iFile = 1:nFiles

    thisFilePathComponents = pathComponents{iFile};

    if length(thisFilePathComponents) == 0
        relativePaths{iFile} = '';
    elseif length(thisFilePathComponents) == 1
        relativePaths{iFile} = thisFilePathComponents{:};
    else
        relativePaths{iFile} = fullfile(thisFilePathComponents{:});
    end % if

end % for


function [sensor,num_Lst,InputFile,main_meta] = LoadSensorType(path_data)
%LOADSENSORTYPE Basic metadata should be loaded first to see which sensor
%here.
% Add Landsat 9 , Feb., 17, 2022

%% Search metadate file for Landsat 4-8
    main_meta=dir(fullfile(path_data,'L*MTL.txt'));
    existMTL=size(main_meta);
    InputFile=[];
    if existMTL(1)==0
        main_meta=dir(fullfile(path_data, 'S*MTD*TL*.xml'));
        if isempty(main_meta)
            main_meta=dir(fullfile(path_data, 'MTD*TL*.xml'));
        end
        if ~isempty(main_meta)
            txtstart = strfind(path_data,'S2A') ;
            num_Lst='2A';
            if isempty(txtstart)
                txtstart = strfind(path_data,'S2B') ;    % S2A or S2B  by Shi 10/18/2017
                num_Lst='2B';
            end
            txtend   = strfind(path_data,'.SAFE')-1 ;
            InputFile.DataStrip = path_data(txtstart:txtend) ;

            InputFile.Dmain = path_data(1:txtstart-1) ;

            txtstart = strfind(path_data,'GRANULE')+8 ;

            InputFile.InspireXML=path_data(1:txtstart-10); % extra add to read inspire xml.

            txtend   =  length(path_data);
            InputFile.Granule = path_data(txtstart:txtend) ;
            InputFile.pathh = path_data ;
            main_meta.name=InputFile.Granule;% return file name fro Fmask results.
        else
%             fprintf('No available data in the current folder!\n');
            sensor=[]; % no supported image.
            num_Lst=[];
            InputFile=[];
            main_meta=[];
            return;
        end
    else
        % determine sensor type
        % open and read hdr file
        fid_in=fopen(fullfile(path_data,main_meta.name),'r');
        geo_char=fscanf(fid_in,'%c',inf);
        fclose(fid_in);
        geo_char=geo_char';
        geo_str=strread(geo_char,'%s');

        % Identify Landsat Number (Lnum = 4, 5, 7, or 8)
        LID=char(geo_str(strmatch('SPACECRAFT_ID',geo_str)+2));
%         num_Lst=str2double(LID(end-1));
        num_Lst=(LID(end-1));
    end
    % define Landsat sensor.
    sensor='';
    if strcmp(num_Lst,'8') | strcmp(num_Lst,'9')
        sensor='L_OLI_TIRS';
    else
        if strcmp(num_Lst,'4')||strcmp(num_Lst,'5')||strcmp(num_Lst,'6')
            sensor='L_TM';
        else
            if strcmp(num_Lst,'7')
                sensor='L_ETM_PLUS';
            end
        end
    end
    if strcmp(num_Lst,'2A')||strcmp(num_Lst,'2B')
        sensor='S_MSI';
    end
end


function obj = prtUiSubplot(inputSpec,constructorFun)
% obj = prtUiSubplot(varargin)
%
% obj = prtUiSubplot({{subplot one inputs}, {subplot two inputs},...},{prtGuiManagerAxesType1, prtGuiMangerAxesType2,...});
% obj = prtUiSubplot([2,2,1:2],prtUiManagerAxesType1);
% obj = prtUiSubplot([2,2],prtUiManagerAxesType1);

obj = prtUiManagerMultiAxes;

if nargin < 2 || isempty(constructorFun)
    constructorFun = @prtUiManagerPlot;
end

if iscell(inputSpec)
    if ~iscell(constructorFun)
        constructorFun = repmat({constructorFun},length(inputSpec));
        assert(isa(constructorFun,'function_handle'),'constructorFun must be a function handle');
    else
        assert(length(constructorFun)==length(inputSpec),'length of specified prtGuiManager*s must match the number of specified subplots');
        assert(isa(constructorFun{1},'function_handle'),'constructorFun must be or contain a function handle');
    end

    nAxes = length(inputSpec);
    for iAxes = 1:nAxes
        cInputSpec = inputSpec{iAxes};

        if iscell(cInputSpec)
            assert(length(cInputSpec)==3,'prtUiSubplot inputs must be a cell');
            axesManagers(iAxes) = constructorFun{iAxes}('managedHandle',subplot(cInputSpec{1},cInputSpec{2},cInputSpec{3}, 'parent', obj.managedHandle)); %#ok<AGROW>
        else
            assert(prtUtilIsPositiveInteger(cInputSpec) & numel(cInputSpec)==3,'prtUiSubplot inputs must be a cell or a length(3) vector of positive integers');
            axesManagers(iAxes) = constructorFun{iAxes}('managedHandle',subplot(cInputSpec(1),cInputSpec(2),cInputSpec(3), 'parent', obj.managedHandle)); %#ok<AGROW>
        end
    end
else
    assert(prtUtilIsPositiveInteger(inputSpec) & ismember(numel(inputSpec),[2 3]),'prtUiSubplot inputs must be vector of positive integers');

    if ~iscell(constructorFun)
        assert(length(constructorFun)==1,'length of specified prtGuiManager*s must match the number of specified subplots');
    end

    switch numel(inputSpec)
        case 2
            nAxes = prod(inputSpec);
            if iscell(constructorFun)
                assert(numel(constructorFun)==nAxes,'length of specified prtGuiManager*s must match the number of specified subplots');
            end
            for iAxes = 1:nAxes
                if iscell(constructorFun)
                    cConstructorFun = constructorFun{iAxes};
                else
                    cConstructorFun = constructorFun;
                end

                axesManagers(iAxes) = cConstructorFun('managedHandle',subplot(inputSpec(1),inputSpec(2),iAxes, 'parent', obj.managedHandle)); %#ok<AGROW>
            end

        case 3
            axesManagers = constructorFun('managedHandle', subplot(inputSpec(1), inputSpec(2), inputSpec(3), 'parent', obj.managedHandle));
    end
end

obj.axesManagers = axesManagers;


function skullStruct = readLeksellSkullFile(filename)
%"readLeksellSkullFile"
%   Uses the docodeLeksellData function to decode the data from the Leksell
%   files and places the data into meaningful structures. This
%   information is not currently used in CERR.
%
%KRK 05/30/07
%
%Usage:
%   function skullStruct = readLeksellSkullFile(filename)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
% CERR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
% without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with CERR.  If not, see <http://www.gnu.org/licenses/>.

fid = fopen(filename, 'r', 'b');

data = decodeLeksellData(fid);

fclose(fid);

% If data only has one cell, it's empty since there is always one cell that
%   contains no meaningful data
if length(data) < 2
    skullStruct = [];
    return;
end

% Get meaningful data
skullData = data{1};

% Get the row size of the skull data
skullStruct.colLen = skullData{1};
% Get the column size of the skull data
skullStruct.rowLen = skullData{2};
% Get the spherical coordinate angles (theta = colAngles, phi =
%   rowAngles).  Ex: rowAngles(2) corresponds to the entire 2nd row
%   in the skullStruct.radii matrix
skullStruct.rowAngles = skullData{3};
skullStruct.colAngles = skullData{4};
% Get the sphereical coordinate radii (rho)
skullStruct.radii = reshape(skullData{5}, [skullData{2}, skullData{1}])';
% skullData{6} is unknown, it is the same size as skullData{5}, but is
%   filled with small floating point numbers.
skullStruct.mystery_value_1 = reshape(skullData{6}, [skullData{2}, skullData{1}])';


%
% These are the functions to import and export an SBML model into a
% MATLAB_SBML structure and back to an SBML file.
%
% FUNCTIONS include:
%
% TranslateSBML(varargin)
%
% - translates a sbml file into a matlab structure
%
% OutputSBML(varargin)
%
% - translates a appropriate matlab structure back into sbml and writes
%   out the file
%
% addLevelVersion.m
%
% - a script used by TranslateSBML to add a level and version field to all
%   parts of a structure
%
% applyUserValidation.m
%
% - a script that can be customized by the user to add additional
%   validation to the isSBML_Model function
%
% CheckAndConvert.m
%
% - a script used by TranslateSBML to change some mathematical function names
%   to those used by MATLAB
%
% ConvertFormulaToMathML.m
%
% - a script used by OutputSBML to change some mathematical function names
%   to those used by MathML
%
% getDefaultValues.m
%
% - a script used to retreive the default values for a given SBMLStructure
%
% getStructureFieldnames.m
%
% - a script used to retreive the fieldnames for a given SBMLStructure
%
% getValueType.m
%
% - a script used to retreive the value types for a given SBMLStructure
%
% isSBML_Model.m
%
% - a script used by OutputSBML to check that a structure is an appropriate
%   MATLAB_SBML structure for conversion to SBML
%
% isoctave.m
%
% - a script to determine if octave or matlab is being used
%

% Description : This is the binding to translate
%				 sbml models into a MATLAB structure
% Author(s)   : SBML Team <sbml-team@googlegroups.com>
%
% This file is part of libSBML.  Please visit http://sbml.org for more
% information about SBML, and the latest version of libSBML.
%
% Copyright (C) 2013-2018 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
%     3. University of Heidelberg, Heidelberg, Germany
%
% Copyright (C) 2009-2013 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
%
% Copyright (C) 2006-2008 by the California Institute of Technology,
%     Pasadena, CA, USA
%
% Copyright (C) 2002-2005 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. Japan Science and Technology Agency, Japan
%
% This library 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.  A copy of the license agreement is provided
% in the file named "LICENSE.txt" included with this software distribution
% and also available online as http://sbml.org/software/libsbml/license.html
%
% The original code contained here was initially developed by:
%
%      Sarah Keating
%      Science and Technology Research Centre
%      University of Hertfordshire
%      Hatfield, AL10 9AB
%      United Kingdom
%
%      http://www.sbml.org
%      mailto:sbml-team@googlegroups.com
%
% Contributor(s):
%
%
%


function [x0,nss] = sofa_get_secondary_sources(sofa,idx,coordinate_system)
%SOFA_GET_SECONDARY_SOURCES returns x0 from the given SOFA data set
%
%   Usage: [x0,nss] = sofa_get_secondary_sources(sofa,[idx],[coordinate_system])
%
%   Input parameters:
%       sofa              - impulse response data set (SOFA struct/file)
%       idx               - index of secondary sources that should be returned
%                           (default: return all secondary sources).
%       coordinate_system - coordinate system the position and direction of the
%                           secondary sources should be specified in:
%                             'cartesian' (default)
%                             'spherical'
%
%   Output parameters:
%       x0      - secondary source matrix [n 7]
%       nss     - number of secondary sources
%
%   SOFA_GET_SECONDARY_SOURCES(sofa,idx,coordinate_system) returns secondary
%   sources as defined in the given SOFA file or struct, specified by idx.  If
%   no idx is specified all secondary sources are returned. The coordinate
%   system the position and direction of the secondary sources are specified in
%   can be given by the string 'coordinate_system', 'cartesian' is assumed as
%   default.
%
%   see also: sofa_get_header, secondary_source_positions

%*****************************************************************************
% The MIT License (MIT)                                                      *
%                                                                            *
% Copyright (c) 2010-2019 SFS Toolbox Developers                             *
%                                                                            *
% Permission is hereby granted,  free of charge,  to any person  obtaining a *
% copy of this software and associated documentation files (the "Software"), *
% to deal in the Software without  restriction, including without limitation *
% the rights  to use, copy, modify, merge,  publish, distribute, sublicense, *
% and/or  sell copies of  the Software,  and to permit  persons to whom  the *
% Software is furnished to do so, subject to the following conditions:       *
%                                                                            *
% The above copyright notice and this permission notice shall be included in *
% all copies or substantial portions of the Software.                        *
%                                                                            *
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
% IMPLIED, INCLUDING BUT  NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY, *
% FITNESS  FOR A PARTICULAR  PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL *
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
% LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT  OR OTHERWISE, ARISING *
% FROM,  OUT OF  OR IN  CONNECTION  WITH THE  SOFTWARE OR  THE USE  OR OTHER *
% DEALINGS IN THE SOFTWARE.                                                  *
%                                                                            *
% The SFS Toolbox  allows to simulate and  investigate sound field synthesis *
% methods like wave field synthesis or higher order ambisonics.              *
%                                                                            *
% https://sfs.readthedocs.io                            sfstoolbox@gmail.com *
%*****************************************************************************

%% ===== Checking of input  parameters ==================================
nargmin = 1;
nargmax = 3;
narginchk(nargmin,nargmax)
if nargin==nargmax-2
    idx = ':';
    coordinate_system = 'cartesian';
elseif nargin==nargmax-1
    if ischar(idx)
        coordinate_system = idx;
        idx = ':';
    else
        coordinate_system = 'cartesian';
    end
else
    isargvector(idx);
    isargchar(coordinate_system);
end

%% ===== Computation ====================================================
header = sofa_get_header(sofa);

if strcmp('SimpleFreeFieldHRIR',header.GLOBAL_SOFAConventions)
    % For free field HRTFs the source positions are equivalent to the apparent
    % positons of the sources
    apparent_directions = SOFAcalculateAPV(header);
    [apparent_positions(:,1) apparent_positions(:,2) apparent_positions(:,3)] = ...
        sph2cart(rad(apparent_directions(:,1)), ...
                 rad(apparent_directions(:,2)), ...
                 apparent_directions(:,3));
    x0 = [apparent_positions(idx,:) ...
          direction_vector(apparent_positions(idx,:), ...
                           zeros(size(apparent_positions,1),3)) ...
          ones(size(apparent_positions(idx,1)))];

elseif strcmp('SingleRoomDRIR',header.GLOBAL_SOFAConventions)
    to_be_implemented;

elseif strcmp('MultiSpeakerBRIR',header.GLOBAL_SOFAConventions)
    source_position = SOFAconvertCoordinates( ...
        header.SourcePosition,header.SourcePosition_Type,'cartesian');
    emitter_positions = SOFAconvertCoordinates( ...
        header.EmitterPosition,header.EmitterPosition_Type,'cartesian');
    emitter_directions = SOFAconvertCoordinates( ...
        header.EmitterView,header.EmitterView_Type,'cartesian');
    x0 = [bsxfun(@minus,emitter_positions(idx,:),source_position) ...
          emitter_directions(idx,:) ...
          ones(size(emitter_positions(idx,1)))];

else
    error('%s: %s convention currently not supported.', ...
        upper(mfilename),header.GLOBAL_SOFAConventions);
end

nss = size(x0,1);

if strcmp('cartesian',coordinate_system)
    return;
elseif strcmp('spherical',coordinate_system)
    [x0(:,1) x0(:,2) x0(:,3)] = cart2sph(x0(:,1),x0(:,2),x0(:,3));
else
    error('%s: %s is not a supported coordinate system.', ...
        upper(mfilename),coordinate_system);
end