function res = hlp_checkeegset(EEG,checks)
%
% Check whether EEG dataset(s) contains one or more substructures.
%
% Inputs:
%
%   EEG         EEG dataset or array of datasets
%   checks      Cell vector containing one or more checks to perform
%               Possible checks: {'cat','conn','model','stats','pconn','pnull','surogdist','configs','validation','ic'}.
% Outputs:
%
%   res         cell array containing results of checks where res{i} is the
%               result of checking for checks{i}
%
% Note: hlp_checkeegset('supported_checks'), returns a list of supported
%       checks
%
% References:
%
% [1] Mullen T (2010) The Source Information Flow Toolbox (SIFT):
%   Theoretical Handbook and User Manual.
%   Available at: http://www.sccn.ucsd.edu/wiki/Sift/
%
%
% Author: Tim Mullen 2010, SCCN/INC, UCSD.
% Email:  tim@sccn.ucsd.edu

% This function is part of the Source Information Flow Toolbox (SIFT)
%
% 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 3 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

res = {};

supported_checks = {'cat','conn','model','stats','pconn','pnull','surogdist','configs','validation','ic'};
if ischar(EEG) && strcmpi(EEG,'supported_checks');
    res = supported_checks;
    return;
end
if nargin<2
    checks = {'cat','conn','model'};
end

if ~iscell(checks)
    checks = {checks};
end

if isempty(EEG)
    res = {sprintf('SIFT: \nEEG structure is empty')};
    return;
end

for cnd=1:length(EEG)
    for i=1:length(checks)
        switch lower(checks{i})
            case 'cat'
                if ~isfield(EEG(cnd),'CAT') || isempty(EEG(cnd).CAT)
                    res = [res, sprintf(['SIFT: \nEEG must contain CAT structure\n' ...
                        'You probably need to complete the pre-processing step first'])];
                end
            case 'conn'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'Conn') ...
                    || isempty(EEG(cnd).CAT.Conn)

                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain Conn structure\n' ...
                        'You need to estimate connectivity first'])];
                end
            case 'model'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'MODEL') ...
                    || isempty(EEG(cnd).CAT.MODEL)
                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain MODEL structure\n' ...
                        'You need to fit a model first'])];
                end
            case 'validation'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'VALIDATION') ...
                    || isempty(EEG(cnd).CAT.VALIDATION)
                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain VALIDATION structure\n' ...
                        'You need to run model validation first'])];
                end
            case 'ic'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'IC') ...
                    || isempty(EEG(cnd).CAT.IC)
                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain IC structure\n' ...
                        'You need to run model order selection first'])];
                end
            case 'surogdist'
                % either pconn OR pnull must be present
                tmpres = hlp_checkeegset(EEG(cnd),{'pnull'});
                if ~isempty(tmpres) % if no pnull, check for pconn...
                    tmpres = hlp_checkeegset(EEG(cnd),{'pconn'});
                end
                res = [res, tmpres];
            case 'pconn'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'PConn') ...
                    || isempty(EEG(cnd).CAT.PConn)

                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain PConn structure\n' ...
                        'You need to estimate connectivity distributions first.\n' ...
                        'See stat_* functions or type ''help stat''.'])];
                end
            case 'pnull'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'Pnull') ...
                    || isempty(EEG(cnd).CAT.Pnull)

                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain Pnull structure\n' ...
                        'You need to estimate a null distribution first.\n' ...
                        'See stat_* functions or type ''help stat''.'])];
                end
            case 'stats'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG(cnd).CAT,'Stats') ...
                    || isempty(EEG(cnd).CAT.Stats)

                    res = [res, sprintf(['SIFT: \nEEG.CAT must contain Stats structure\n' ...
                        'You need to estimate statistics first'])];
                end
            case 'configs'
                if ~isfield(EEG(cnd),'CAT') ...
                    || ~isfield(EEG.CAT,'configs') ...
                    || isempty(EEG.CAT.configs)
                    res = [res, sprintf('SIFT: \nEEG.CAT does not contain a configs structure\n')];
                end
            otherwise
                res = [res, sprintf('SIFT: \nUnknown field/check %s\n',checks{i})];
        end
    end
end


function mining_queue = esvm_initialize_mining_queue(imageset, ordering)
%Initialize the mining queue with ordering (random by default)
%function mining_queue = esvm_initialize_mining_queue(imageset, ordering)
% Copyright (C) 2011-12 by Tomasz Malisiewicz
% All rights reserved.
%
% This file is part of the Exemplar-SVM library and is made
% available under the terms of the MIT license (see COPYING file).
% Project homepage: https://github.com/quantombone/exemplarsvm

if ~exist('ordering','var')
  fprintf(1,'Randomizing mining queue\n');
  myRandomize;
  ordering = randperm(length(imageset));
end

mining_queue = cell(0,1);
for zzz = 1:length(ordering)
  mining_queue{zzz}.index = ordering(zzz);
  mining_queue{zzz}.num_visited = 0;
end


function testAxis()
% 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/>.

hFig = figure;
hAxis = gca;
table('init', hAxis);
table('data', hAxis, dir);
set(hAxis, 'units', 'normalized');
set(hFig, 'resizefcn', 'myResize');


function sensor_data = kspaceFirstOrder_extractSensorData(dim, sensor_data, file_index, sensor_mask_index, record, p, ux_sgx, uy_sgy, uz_sgz)
% DESCRIPTION:
%       Function to extract the required sensor data from the acoustic
%       variables at each time step. This is defined as a function rather
%       than a script to avoid the computational overhead of using scripts
%       to access variables local to another function. For k-Wave < V1.1,
%       this code was included directly in the simulation functions.
%
% ABOUT:
%       author      - Bradley Treeby
%       date        - 9th July 2013
%       last update - 6th September 2013
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2014 Bradley Treeby and Ben Cox

% This file is part of k-Wave. k-Wave 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.
%
% k-Wave 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 Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>.

% =========================================================================
% GRID STAGGERING
% =========================================================================

% shift the components of the velocity field onto the non-staggered
% grid if required for output
if (...
        record.u_non_staggered || ...
        record.I || ...
        record.I_avg)

    switch dim
        case 1
            ux_shifted = real(ifft(bsxfun(@times, record.x_shift_neg, fft(ux_sgx, [], 1)), [], 1));
        case 2
            ux_shifted = real(ifft(bsxfun(@times, record.x_shift_neg, fft(ux_sgx, [], 1)), [], 1));
            uy_shifted = real(ifft(bsxfun(@times, record.y_shift_neg, fft(uy_sgy, [], 2)), [], 2));
        case 3
            ux_shifted = real(ifft(bsxfun(@times, record.x_shift_neg, fft(ux_sgx, [], 1)), [], 1));
            uy_shifted = real(ifft(bsxfun(@times, record.y_shift_neg, fft(uy_sgy, [], 2)), [], 2));
            uz_shifted = real(ifft(bsxfun(@times, record.z_shift_neg, fft(uz_sgz, [], 3)), [], 3));
    end
end

% =========================================================================
% BINARY SENSOR MASK
% =========================================================================

if record.binary_sensor_mask

    % store the time history of the acoustic pressure
    if record.p || record.I || record.I_avg
        if ~record.compute_directivity
            sensor_data.p(:, file_index) = p(sensor_mask_index);
        end
    end

    % store the maximum acoustic pressure
    if record.p_max
        if file_index == 1
            sensor_data.p_max = p(sensor_mask_index);
        else
            sensor_data.p_max = max(sensor_data.p_max, p(sensor_mask_index));
        end
    end

    % store the minimum acoustic pressure
    if record.p_min
        if file_index == 1
            sensor_data.p_min = p(sensor_mask_index);
        else
            sensor_data.p_min = min(sensor_data.p_min, p(sensor_mask_index));
        end
    end

    % store the rms acoustic pressure
    if record.p_rms
        sensor_data.p_rms = sqrt((sensor_data.p_rms.^2*(file_index - 1) + p(sensor_mask_index).^2)./file_index);
    end

    % store the time history of the particle velocity on the staggered grid
    if record.u
        switch dim
            case 1
                sensor_data.ux(:, file_index) = ux_sgx(sensor_mask_index);
            case 2
                sensor_data.ux(:, file_index) = ux_sgx(sensor_mask_index);
                sensor_data.uy(:, file_index) = uy_sgy(sensor_mask_index);
            case 3
                sensor_data.ux(:, file_index) = ux_sgx(sensor_mask_index);
                sensor_data.uy(:, file_index) = uy_sgy(sensor_mask_index);
                sensor_data.uz(:, file_index) = uz_sgz(sensor_mask_index);
        end
    end

    % store the time history of the particle velocity
    if record.u_non_staggered || record.I || record.I_avg
        switch dim
            case 1
                sensor_data.ux_non_staggered(:, file_index) = ux_shifted(sensor_mask_index);
            case 2
                sensor_data.ux_non_staggered(:, file_index) = ux_shifted(sensor_mask_index);
                sensor_data.uy_non_staggered(:, file_index) = uy_shifted(sensor_mask_index);
            case 3
                sensor_data.ux_non_staggered(:, file_index) = ux_shifted(sensor_mask_index);
                sensor_data.uy_non_staggered(:, file_index) = uy_shifted(sensor_mask_index);
                sensor_data.uz_non_staggered(:, file_index) = uz_shifted(sensor_mask_index);
        end
    end

    % store the maximum particle velocity
    if record.u_max
        if file_index == 1
            switch dim
                case 1
                    sensor_data.ux_max = ux_sgx(sensor_mask_index);
                case 2
                    sensor_data.ux_max = ux_sgx(sensor_mask_index);
                    sensor_data.uy_max = uy_sgy(sensor_mask_index);
                case 3
                    sensor_data.ux_max = ux_sgx(sensor_mask_index);
                    sensor_data.uy_max = uy_sgy(sensor_mask_index);
                    sensor_data.uz_max = uz_sgz(sensor_mask_index);
            end
        else
            switch dim
                case 1
                    sensor_data.ux_max = max(sensor_data.ux_max, ux_sgx(sensor_mask_index));
                case 2
                    sensor_data.ux_max = max(sensor_data.ux_max, ux_sgx(sensor_mask_index));
                    sensor_data.uy_max = max(sensor_data.uy_max, uy_sgy(sensor_mask_index));
                case 3
                    sensor_data.ux_max = max(sensor_data.ux_max, ux_sgx(sensor_mask_index));
                    sensor_data.uy_max = max(sensor_data.uy_max, uy_sgy(sensor_mask_index));
                    sensor_data.uz_max = max(sensor_data.uz_max, uz_sgz(sensor_mask_index));
            end
        end
    end

    % store the minimum particle velocity
    if record.u_min
        if file_index == 1
            switch dim
                case 1
                    sensor_data.ux_min = ux_sgx(sensor_mask_index);
                case 2
                    sensor_data.ux_min = ux_sgx(sensor_mask_index);
                    sensor_data.uy_min = uy_sgy(sensor_mask_index);
                case 3
                    sensor_data.ux_min = ux_sgx(sensor_mask_index);
                    sensor_data.uy_min = uy_sgy(sensor_mask_index);
                    sensor_data.uz_min = uz_sgz(sensor_mask_index);
            end
        else
            switch dim
                case 1
                    sensor_data.ux_min = min(sensor_data.ux_min, ux_sgx(sensor_mask_index));
                case 2
                    sensor_data.ux_min = min(sensor_data.ux_min, ux_sgx(sensor_mask_index));
                    sensor_data.uy_min = min(sensor_data.uy_min, uy_sgy(sensor_mask_index));
                case 3
                    sensor_data.ux_min = min(sensor_data.ux_min, ux_sgx(sensor_mask_index));
                    sensor_data.uy_min = min(sensor_data.uy_min, uy_sgy(sensor_mask_index));
                    sensor_data.uz_min = min(sensor_data.uz_min, uz_sgz(sensor_mask_index));
            end
        end
    end

    % store the rms particle velocity
    if record.u_rms
        switch dim
            case 1
                sensor_data.ux_rms(:) = sqrt((sensor_data.ux_rms(:).^2*(file_index - 1) + ux_sgx(sensor_mask_index).^2)./file_index);
            case 2
                sensor_data.ux_rms(:) = sqrt((sensor_data.ux_rms(:).^2*(file_index - 1) + ux_sgx(sensor_mask_index).^2)./file_index);
                sensor_data.uy_rms(:) = sqrt((sensor_data.uy_rms(:).^2*(file_index - 1) + uy_sgy(sensor_mask_index).^2)./file_index);
            case 3
                sensor_data.ux_rms(:) = sqrt((sensor_data.ux_rms(:).^2*(file_index - 1) + ux_sgx(sensor_mask_index).^2)./file_index);
                sensor_data.uy_rms(:) = sqrt((sensor_data.uy_rms(:).^2*(file_index - 1) + uy_sgy(sensor_mask_index).^2)./file_index);
                sensor_data.uz_rms(:) = sqrt((sensor_data.uz_rms(:).^2*(file_index - 1) + uz_sgz(sensor_mask_index).^2)./file_index);
        end
    end

% =========================================================================
% CARTESIAN SENSOR MASK
% =========================================================================

% extract data from specified Cartesian coordinates using interpolation
% (record.record.tri and record.record.bc are the Delaunay triangulation
% and Barycentric coordinates returned by gridDataFast3D)
else

    % store the time history of the acoustic pressure
    if record.p || record.I || record.I_avg
        if dim == 1
            sensor_data.p(:, file_index) = interp1(record.grid_x, p, record.sensor_x);
        else
            sensor_data.p(:, file_index) = sum(p(record.tri) .* record.bc, 2);
        end
    end

    % store the maximum acoustic pressure
    if record.p_max
        if dim == 1
            if file_index == 1
                sensor_data.p_max = interp1(record.grid_x, p, record.sensor_x);
            else
                sensor_data.p_max = max(sensor_data.p_max, interp1(record.grid_x, p, record.sensor_x));
            end
        else
            if file_index == 1
                sensor_data.p_max = sum(p(record.tri) .* record.bc, 2);
            else
                sensor_data.p_max = max(sensor_data.p_max, sum(p(record.tri) .* record.bc, 2));
            end
        end
    end

    % store the minimum acoustic pressure
    if record.p_min
        if dim == 1
            if file_index == 1
                sensor_data.p_min = interp1(record.grid_x, p, record.sensor_x);
            else
                sensor_data.p_min = min(sensor_data.p_min, interp1(record.grid_x, p, record.sensor_x));
            end
        else
            if file_index == 1
                sensor_data.p_min = sum(p(record.tri) .* record.bc, 2);
            else
                sensor_data.p_min = min(sensor_data.p_min, sum(p(record.tri) .* record.bc, 2));
            end
        end
    end

    % store the rms acoustic pressure
    if record.p_rms
        if dim == 1
            sensor_data.p_rms = sqrt((sensor_data.p_rms.^2*(file_index - 1) + (interp1(record.grid_x, p, record.sensor_x)).^2)./file_index);
        else
            sensor_data.p_rms(:) = sqrt((sensor_data.p_rms(:).^2*(file_index - 1) + (sum(p(record.tri) .* record.bc, 2)).^2)./file_index);
        end
    end

    % store the time history of the particle velocity on the staggered grid
    if record.u
        switch dim
            case 1
                sensor_data.ux(:, file_index) = interp1(record.grid_x, ux_sgx, record.sensor_x);
            case 2
                sensor_data.ux(:, file_index) = sum(ux_sgx(record.tri) .* record.bc, 2);
                sensor_data.uy(:, file_index) = sum(uy_sgy(record.tri) .* record.bc, 2);
            case 3
                sensor_data.ux(:, file_index) = sum(ux_sgx(record.tri) .* record.bc, 2);
                sensor_data.uy(:, file_index) = sum(uy_sgy(record.tri) .* record.bc, 2);
                sensor_data.uz(:, file_index) = sum(uz_sgz(record.tri) .* record.bc, 2);
        end
    end

    % store the time history of the particle velocity
    if record.u_non_staggered || record.I || record.I_avg
        switch dim
            case 1
                sensor_data.ux_non_staggered(:, file_index) = interp1(record.grid_x, ux_shifted, record.sensor_x);
            case 2
                sensor_data.ux_non_staggered(:, file_index) = sum(ux_shifted(record.tri) .* record.bc, 2);
                sensor_data.uy_non_staggered(:, file_index) = sum(uy_shifted(record.tri) .* record.bc, 2);
            case 3
                sensor_data.ux_non_staggered(:, file_index) = sum(ux_shifted(record.tri) .* record.bc, 2);
                sensor_data.uy_non_staggered(:, file_index) = sum(uy_shifted(record.tri) .* record.bc, 2);
                sensor_data.uz_non_staggered(:, file_index) = sum(uz_shifted(record.tri) .* record.bc, 2);
        end
    end

    % store the maximum particle velocity
    if record.u_max
        if file_index == 1
            switch dim
                case 1
                    sensor_data.ux_max = interp1(record.grid_x, ux_sgx, record.sensor_x);
                case 2
                    sensor_data.ux_max = sum(ux_sgx(record.tri) .* record.bc, 2);
                    sensor_data.uy_max = sum(uy_sgy(record.tri) .* record.bc, 2);
                case 3
                    sensor_data.ux_max = sum(ux_sgx(record.tri) .* record.bc, 2);
                    sensor_data.uy_max = sum(uy_sgy(record.tri) .* record.bc, 2);
                    sensor_data.uz_max = sum(uz_sgz(record.tri) .* record.bc, 2);
            end
        else
            switch dim
                case 1
                    sensor_data.ux_max = max(sensor_data.ux_max, interp1(record.grid_x, ux_sgx, record.sensor_x));
                case 2
                    sensor_data.ux_max = max(sensor_data.ux_max, sum(ux_sgx(record.tri) .* record.bc, 2));
                    sensor_data.uy_max = max(sensor_data.uy_max, sum(uy_sgy(record.tri) .* record.bc, 2));
                case 3
                    sensor_data.ux_max = max(sensor_data.ux_max, sum(ux_sgx(record.tri) .* record.bc, 2));
                    sensor_data.uy_max = max(sensor_data.uy_max, sum(uy_sgy(record.tri) .* record.bc, 2));
                    sensor_data.uz_max = max(sensor_data.uz_max, sum(uz_sgz(record.tri) .* record.bc, 2));
            end
        end
    end

    % store the minimum particle velocity
    if record.u_min
        if file_index == 1
            switch dim
                case 1
                    sensor_data.ux_min = interp1(record.grid_x, ux_sgx, record.sensor_x);
                case 2
                    sensor_data.ux_min = sum(ux_sgx(record.tri) .* record.bc, 2);
                    sensor_data.uy_min = sum(uy_sgy(record.tri) .* record.bc, 2);
                case 3
                    sensor_data.ux_min = sum(ux_sgx(record.tri) .* record.bc, 2);
                    sensor_data.uy_min = sum(uy_sgy(record.tri) .* record.bc, 2);
                    sensor_data.uz_min = sum(uz_sgz(record.tri) .* record.bc, 2);
            end
        else
            switch dim
                case 1
                    sensor_data.ux_min = min(sensor_data.ux_min, interp1(record.grid_x, ux_sgx, record.sensor_x));
                case 2
                    sensor_data.ux_min = min(sensor_data.ux_min, sum(ux_sgx(record.tri) .* record.bc, 2));
                    sensor_data.uy_min = min(sensor_data.uy_min, sum(uy_sgy(record.tri) .* record.bc, 2));
                case 3
                    sensor_data.ux_min = min(sensor_data.ux_min, sum(ux_sgx(record.tri) .* record.bc, 2));
                    sensor_data.uy_min = min(sensor_data.uy_min, sum(uy_sgy(record.tri) .* record.bc, 2));
                    sensor_data.uz_min = min(sensor_data.uz_min, sum(uz_sgz(record.tri) .* record.bc, 2));
            end
        end
    end

    % store the rms particle velocity
    if record.u_rms
        switch dim
            case 1
                sensor_data.ux_rms = sqrt((sensor_data.ux_rms.^2*(file_index - 1) + (interp1(record.grid_x, ux_sgx, record.sensor_x)).^2)./file_index);
            case 2
                sensor_data.ux_rms(:) = sqrt((sensor_data.ux_rms(:).^2*(file_index - 1) + (sum(ux_sgx(record.tri) .* record.bc, 2)).^2)./file_index);
                sensor_data.uy_rms(:) = sqrt((sensor_data.uy_rms(:).^2*(file_index - 1) + (sum(uy_sgy(record.tri) .* record.bc, 2)).^2)./file_index);
            case 3
                sensor_data.ux_rms(:) = sqrt((sensor_data.ux_rms(:).^2*(file_index - 1) + (sum(ux_sgx(record.tri) .* record.bc, 2)).^2)./file_index);
                sensor_data.uy_rms(:) = sqrt((sensor_data.uy_rms(:).^2*(file_index - 1) + (sum(uy_sgy(record.tri) .* record.bc, 2)).^2)./file_index);
                sensor_data.uz_rms(:) = sqrt((sensor_data.uz_rms(:).^2*(file_index - 1) + (sum(uz_sgz(record.tri) .* record.bc, 2)).^2)./file_index);
        end
    end
end

% =========================================================================
% RECORDED VARIABLES OVER ENTIRE GRID
% =========================================================================

% store the maximum acoustic pressure over all the grid elements
if record.p_max_all
    switch dim
        case 1
            if file_index == 1
                sensor_data.p_max_all = p(record.x1_inside:record.x2_inside);
            else
                sensor_data.p_max_all = max(sensor_data.p_max_all, p(record.x1_inside:record.x2_inside));
            end
        case 2
            if file_index == 1
                sensor_data.p_max_all = p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside);
            else
                sensor_data.p_max_all = max(sensor_data.p_max_all, p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside));
            end
        case 3
            if file_index == 1
                sensor_data.p_max_all = p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
            else
                sensor_data.p_max_all = max(sensor_data.p_max_all, p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
            end
    end
end

% store the minimum acoustic pressure over all the grid elements
if record.p_min_all
    switch dim
        case 1
            if file_index == 1
                sensor_data.p_min_all = p(record.x1_inside:record.x2_inside);
            else
                sensor_data.p_min_all = min(sensor_data.p_min_all, p(record.x1_inside:record.x2_inside));
            end
        case 2
            if file_index == 1
                sensor_data.p_min_all = p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside);
            else
                sensor_data.p_min_all = min(sensor_data.p_min_all, p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside));
            end
        case 3
            if file_index == 1
                sensor_data.p_min_all = p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
            else
                sensor_data.p_min_all = min(sensor_data.p_min_all, p(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
            end
    end
end

% store the maximum particle velocity over all the grid elements
if record.u_max_all
    switch dim
        case 1
            if file_index == 1
                sensor_data.ux_max_all = ux_sgx(record.x1_inside:record.x2_inside);
            else
                sensor_data.ux_max_all = max(sensor_data.ux_max_all, ux_sgx(record.x1_inside:record.x2_inside));
            end
        case 2
            if file_index == 1
                sensor_data.ux_max_all = ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside);
                sensor_data.uy_max_all = uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside);
            else
                sensor_data.ux_max_all = max(sensor_data.ux_max_all, ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside));
                sensor_data.uy_max_all = max(sensor_data.uy_max_all, uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside));
            end
        case 3
            if file_index == 1
                sensor_data.ux_max_all = ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
                sensor_data.uy_max_all = uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
                sensor_data.uz_max_all = uz_sgz(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
            else
                sensor_data.ux_max_all = max(sensor_data.ux_max_all, ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
                sensor_data.uy_max_all = max(sensor_data.uy_max_all, uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
                sensor_data.uz_max_all = max(sensor_data.uz_max_all, uz_sgz(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
            end
    end
end

% store the minimum particle velocity over all the grid elements
if record.u_min_all
    switch dim
        case 1
            if file_index == 1
                sensor_data.ux_min_all = ux_sgx(record.x1_inside:record.x2_inside);
            else
                sensor_data.ux_min_all = min(sensor_data.ux_min_all, ux_sgx(record.x1_inside:record.x2_inside));
            end
        case 2
            if file_index == 1
                sensor_data.ux_min_all = ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside);
                sensor_data.uy_min_all = uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside);
            else
                sensor_data.ux_min_all = min(sensor_data.ux_min_all, ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside));
                sensor_data.uy_min_all = min(sensor_data.uy_min_all, uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside));
            end
        case 3
            if file_index == 1
                sensor_data.ux_min_all = ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
                sensor_data.uy_min_all = uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
                sensor_data.uz_min_all = uz_sgz(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside);
            else
                sensor_data.ux_min_all = min(sensor_data.ux_min_all, ux_sgx(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
                sensor_data.uy_min_all = min(sensor_data.uy_min_all, uy_sgy(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
                sensor_data.uz_min_all = min(sensor_data.uz_min_all, uz_sgz(record.x1_inside:record.x2_inside, record.y1_inside:record.y2_inside, record.z1_inside:record.z2_inside));
            end
    end
end


%RGBINT2HEX Convert RGB integer into hexadecimal colour
%   HEX = RGBINT2HEX(INT) given an RGB integer, convert it into a
%   hexadecimal string.
%
%   This is a helper function which you can use when manually creating your
%   own MATLAB colour schemes. It is the inverse of COLOR2JAVARGBINT.
%
%   See also COLOR2JAVARGBINT.

% Copyright (c) 2015-2016,  Scott C. Lowe <scott.code.lowe@gmail.com>
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.

function hex = RGBint2hex(int)

% Make a Java colour object
jc = java.awt.Color(int);
% Convert R,G,B into hexadecimal
hex = sprintf('%02s', ...
    dec2hex(jc.getRed), dec2hex(jc.getGreen), dec2hex(jc.getBlue));

end


function writedb(c,dbOut,varargin)

   %WRITEDB write antelope database tables
   %  WRITEDB(C,DBOUT) writes an arrival table into the database DBOUT. The
   %  arrival contains the station and channel names. The phase arrival time
   %  is set to the trigger field in the correlation object. If the cluster
   %  field is filled in C, then the phase names are assigned as cXX where XX
   %  is the cluster number. If the cluster field is not filled, a default
   %  phase name of P is assigned. If the table DBOUT.arrival already exists,
   %  new entries are appended to it. Duplicate entries to the database will
   %  NOT be skipped.
   %
   %  WRITEDB(C,DBOUT,PHASENAME) Assign an explicit PHASENAME. PHASENAME is
   %  a cell array containing character phase names. The cell array must be
   %  of length 1 or of length N, where N is the number of traces in the
   %  corelation object.
   %
   %  WRITEDB(C,DBOUT,'detection') Writes a detection table instead of an
   %  arrival table. The filter field is left null by default. Rows for
   %  detection ON and OFF states are not included. On state='D' rows are
   %  written.
   %
   %  WRITEDB(C,DBOUT,'detection','filterString') Fills the filter field on
   %  the detection table with the string given by filterString.
   %
   %  WRITEDB checks for the Antelope toolbox for Matlab. If it does not
   %  exist, WRITEDB writes a simple text file DBOUT.txt which contains
   %  station, channel, arrival times and phase names.

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

   % READ & CHECK ARGUMENTS
   if numel(varargin)>2
      error('Wrong number of inputs');
   end;

   if ~ischar(dbOut)
      disp('Second input parameter must be a text string');
   end

   if ~isempty(c.lags)
      disp('Note: Time corrections from LAG field have not been applied to traces. Consider using ADJUSTTRIG prior to writing out');
      disp(' ');
   end;

   % SELECT TABLE TYPE
   ISDETECTION = 0;
   if numel(varargin)>=1 || ~admin.antelope_exists
      if strcmpi(varargin{1},'detection')
         ISDETECTION = 1;
      end
   end

   % ASSIGN ARGUMENTS FOR ARRIVAL TABLE
   if ~ISDETECTION
      if numel(varargin)==1
         phaseList = varargin{1};
         if numel(phaseList)== c.ntraces
            phaseList = phaseList;
         elseif numel(phaseList)~= c.ntraces && numel(phaseList)~=1
            error('phase list argument must be cell array of length 1 or N, where N is the number of traces in the correlation object');
         elseif numel(phaseList)==1
            if ischar(phaseList)
               phaseList = {phaseList};
            end
            phaseList = repmat(phaseList, c.ntraces,1);
         end
      elseif ~isempty(c.clust)
         disp('assigning phase names based on cluster field');
         clust = c.clust;
         phaseList = cell(size(clust));
         for n = 1:numel(clust)
            phaseList(n) = {['c' num2str(clust(n),'%02.0f')]};
         end
      else
         disp('assigning default phase name "P"');
         phaseList = repmat({'P'},c.ntraces,1);
      end;

   end

   % ASSIGN ARGUMENTS FOR DETECTION TABLE
   if ISDETECTION
      if numel(varargin)>=2
         if ischar(varargin{2})
            filterString = varargin(2);
         elseif iscell(varargin{2}) && (numel(varargin{2})==1)
            filterString = varargin{2};
         end
      else
         filterString = 'not_specified';
      end
   end

   % WRITE ARRIVAL TABLE OR TEXT FILE
   if ~ISDETECTION
      trig = c.trig;
      sta = c.stations; %sta = sta{1};
      chan = c.channels; %chan = chan{1};
      if admin.antelope_exists
         % TODO: check for database table
         disp(['Writing database table ' dbOut '.arrival']);
         db = dbopen(dbOut,'r+');
         db = dblookup(db,'','arrival','','');
         nMax = length(trig);
         disp('     ');
         for n = 1:nMax
            arid = dbnextid( db,'arid');
            db.record = dbaddv(db,'sta',sta{n},'chan',chan{n},'time',datenum2epoch(trig(n)),'iphase',phaseList{n},'auth','corr/writedb');
            fprintf('\b\b\b\b\b\b%5.0f%%',n/nMax*100);
         end
         fprintf('\n');
         dbclose(db);
      else
         % write out a simple text file
         disp(['Antelope toolbox not found. Writing text file ' dbOut '.txt instead']);
         fid = fopen([dbOut '.txt'],'w');
         for n = 1:numel(trig)
            fprintf(fid,'%-7s %-7s %-s %5s\n',sta,chan,datestr(trig(n),'yyyy/mm/dd HH:MM:SS.FFF'),phaseList{n});
         end
         fclose(fid);
      end
   end

   % WRITE DETECTION TABLE
   if ISDETECTION
      trig = c.trig;
      sta = c.stations;
      chan = c.channels;
      % TODO: check for database table
      disp(['Writing database table ' dbOut '.detection']);
      db = dbopen(dbOut,'r+');
      db = dblookup(db,'','detection','','');
      nMax = length(trig);
      disp('     ');
      for n = 1:nMax
         arid = dbnextid( db,'arid');
         db.record = dbaddv(db,'sta',sta{n},'chan',chan{n},'time',datenum2epoch(trig(n)),'state','D','filter',filterString);
         fprintf('\b\b\b\b\b\b%5.0f%%',n/nMax*100);
      end
      fprintf('\n');
      dbclose(db);

   end
end


function ds_info=my_gen_ds_info_egohands(ds_config)

ds_dir=fullfile('../datasets', 'EgoHands');

train_idx_file=fullfile(ds_dir, 'ImageSets/Segmentation/train.txt');
fid=fopen(train_idx_file);
train_file_names=textscan(fid, '%s');
train_file_names=train_file_names{1};
fclose(fid);

val_idx_file=fullfile(ds_dir, 'ImageSets/Segmentation/val.txt');
fid=fopen(val_idx_file);
val_file_names=textscan(fid, '%s');
val_file_names=val_file_names{1};
fclose(fid);

train_num=length(train_file_names);
img_names=cat(1, train_file_names, val_file_names);
img_num=length(img_names);

img_files=cell(img_num, 1);
mask_files=cell(img_num, 1);

for t_idx=1:img_num
    file_name=img_names{t_idx};
    img_files{t_idx}=[file_name(1:end-4) '.jpg'];
    mask_file_name = strrep(file_name,'JPEGImages','SegmentationClass');
    mask_files{t_idx}=[mask_file_name(1:end-4) '.png'];

end

train_idxes=1:train_num;
val_idxes=train_num+1:img_num;

ds_info=[];

ds_info.img_names=img_names;
ds_info.img_files=img_files;
ds_info.mask_files=mask_files;

ds_info.train_idxes=uint32(train_idxes');
ds_info.test_idxes=uint32(val_idxes');

disp('here::')
img_dir=fullfile(ds_dir, 'JPEGImages')
mask_dir=fullfile(ds_dir, 'SegmentationClass')

data_dirs=[];
data_dirs{1}=img_dir;
data_dirs{2}=mask_dir;

data_dir_idxes_img=zeros([img_num 1], 'uint8')+1;
data_dir_idxes_mask=zeros([img_num 1], 'uint8')+2;

ds_info.data_dir_idxes_img=data_dir_idxes_img;
ds_info.data_dir_idxes_mask=data_dir_idxes_mask;
ds_info.data_dirs=data_dirs;
ds_info.ds_dir=ds_dir;

ds_info.class_info=gen_class_info_ego();

ds_info.ds_name='EgoHands';

ds_info=process_ds_info_classification(ds_info, ds_config);

end


function publish_scn_session_spike_id(inputimgs, SUBJDATA,outformat)
% This function is a wrapper function to call scn_session_spike_id in
% 'multi-session' mode, using input data across the runs for a single
% subject.  It runs the program, and generates both a yaml-format text file
% for uploading into the CANlab database, and an html file with all the
% results and images for that subject embedded.
%
% :Inputs:
%
%   **inputimgs:**
%        is a cell array of images (4-D) for each run in a separate cell.
%        the cell array outside this function has to be named 'inputimgs'
%
%   **SUBJDATA:**
%        Input fields of SUBJDATA define the experiment name, subject name,
%        and directories for saving both QC images + yaml and HTML
%        - study. a string
%        - subject. another string with subject ID
%        - html_save_dir can be one directory for all subjects if format 'pdf'
%        - subject_dir. a new subdirectory qc_images will be created within
%        subject_dir. images and .yaml files will be written there.
%
%
%   **ouformat**
%       file format for the report as available in 'publish'. can be
%       'html' [default],'pdf', 'latex', etc.
%
% :Examples:
% ::
%
%    SUBJDATA.study = 'NSF';
%    SUBJDATA.subject = subjects{i};
%    SUBJDATA.html_save_dir = fullfile(output_basedir, 'html_output');
%    SUBJDATA.subject_dir = fullfile(output_basedir, 'SubjectData', 'denoised_canlab', SUBJDATA.subject);
%
% ..
%    This has been tested with SPM8 and Matlab2010a only.
%
%    Tor Wager, Aug 2010
% ..

% Programmer's Notes
%
% 8/25/2017 - Stephan Geuter
% added option to use other fileformats like PDF
%

%% check input
% default report format is html. choose pdf or other options from publish.m
if nargin<3, outformat = 'html'; end

%% Initialize yaml file for database integration
if ~exist(SUBJDATA.subject_dir, 'dir'), mkdir(SUBJDATA.subject_dir); end
cd(SUBJDATA.subject_dir)

yamlfilename = fullfile(SUBJDATA.subject_dir, 'qc_results.yaml');

SUBJDATA.unique_id = [SUBJDATA.study '_' SUBJDATA.subject];

struct2yaml(yamlfilename, SUBJDATA, 'new', 'replace');

%% housekeeping: get rid of any old .png qc images
% these will mess it up, as it checks for existing files in order to
% require minimal input to scn_session_spike_id

qcdir = fullfile(SUBJDATA.subject_dir, 'qc_images');
if exist(qcdir, 'dir')
    disp('Removing old qc png images');

    disp(['!rm ' qcdir filesep '*png'])
    eval(['!rm ' qcdir filesep '*png'])
end

%% Create .m file script to publish that will create HTML file

htmlname = ['qc_scn_session_spike_id_' SUBJDATA.subject];

if ~exist(SUBJDATA.html_save_dir, 'dir'), mkdir(SUBJDATA.html_save_dir); end

diaryfilename = fullfile(SUBJDATA.html_save_dir, [htmlname '.m']);
if exist(diaryfilename, 'file'), eval(['!rm ' diaryfilename]); end

% These commands, written in the file called diaryfilename,
% will be evaluated in the m-file, and image and text
% results published in the HTML file called htmlname.
% ------------------------------------------------------------------

diary(diaryfilename);

disp(['%% SCN session spike ID, subject ' SUBJDATA.subject]);
fprintf('%% *Experiment:* %s\n%% \n', SUBJDATA.study); % start new formatted block if two spaces
fprintf('%% *QC results stored in:* %s\n%% \n', SUBJDATA.subject_dir);
fprintf('%% spike ID, quality control step 1.  writes to ''qc_results.yaml''\n');
%%% NEED COMMAND THAT LOADS INPUTIMGS FROM DISK -- OR PASSES IN AS INPUT?
disp('scn_session_spike_id(inputimgs);')
disp('snapnow');

diary off

%%
addpath(SUBJDATA.html_save_dir)
p = struct('useNewFigure', false, 'maxHeight', 800, 'maxWidth', 500, ...
    'outputDir', SUBJDATA.html_save_dir, 'showCode', false,'format',outformat);
publish(diaryfilename, p);

fprintf('\npublished to\n%s\n\n',diaryfilename);

if strcmp(outformat,'html')
    htmlfilename = fullfile(SUBJDATA.html_save_dir, [htmlname '.html']);
    web(htmlfilename);
end

% clean up the original diary; no longer needed
eval(['!rm ' diaryfilename]);


classdef VehicleStateVectorTypeEnum < matlab.mixin.SetGet
    %VehicleStateVectorTypeEnum Summary of this class goes here
    %   Detailed explanation goes here

    enumeration
        Radial('Radial Vector');
        Velocity('Velocity Vector');
        AngularMomentum('Angular Momentum Vector');
        North('North Vector');
        East('East Vector');
        AscNode('Ascending Node Vector');
        Periapsis('Periapsis Vector');
    end

    properties
        name(1,:) char
    end

    methods
        function obj = VehicleStateVectorTypeEnum(name)
            obj.name = name;
        end
    end

    methods(Static)
        function listBoxStr = getListBoxStr()
            m = enumeration('VehicleStateVectorTypeEnum');
            [~,I] = sort({m.name});
            listBoxStr = {m(I).name};
        end

        function [ind, enum] = getIndForName(name)
            m = enumeration('VehicleStateVectorTypeEnum');
            [~,I] = sort({m.name});
            m = m(I);
            ind = find(ismember({m.name},name),1,'first');
            enum = m(ind);
        end

        function [enum, ind] = getEnumForListboxStr(nameStr)
            m = enumeration('VehicleStateVectorTypeEnum');
            ind = find(ismember({m.name},nameStr),1,'first');
            enum = m(ind);
        end
    end
end


function [ projdata ] = fiff_read_proj(fid,node)

%
% [ projdata ] = fiff_read_proj(fid,node)
%
% Read the SSP data under a given directory node
%

%
%   Author : Matti Hamalainen, MGH Martinos Center
%   License : BSD 3-clause
%
%
%   Revision 1.7  2006/05/16 00:39:32  msh
%   Fixed error in mne_ex_read_raw: All projection items were not activated.
%   List the initial states of projection items when they are loaded.
%
%   Revision 1.6  2006/04/23 15:29:40  msh
%   Added MGH to the copyright
%
%   Revision 1.5  2006/04/21 15:06:03  msh
%   Do not list projection item status because it might be confusing.
%
%   Revision 1.4  2006/04/21 14:43:59  msh
%   Report projection operators.
%   Some more checks in raw data reading.
%
%   Revision 1.3  2006/04/18 20:44:46  msh
%   Added reading of forward solution.
%   Use length instead of size when appropriate
%
%   Revision 1.2  2006/04/12 10:29:02  msh
%   Made evoked data writing compatible with the structures returned in reading.
%
%   Revision 1.1  2006/04/10 23:26:54  msh
%   Added fiff reading routines
%
%

global FIFF;
if isempty(FIFF)
    FIFF = fiff_define_constants();
end

me='MNE:fiff_read_proj';

if nargin ~= 2
    error(me,'Incorrect number of arguments');
end

projdata = struct('kind',{},'active',{},'desc',{},'data',{});
%
%   Locate the projection data
%
nodes = fiff_dir_tree_find(node,FIFF.FIFFB_PROJ);
if length(nodes) == 0
    return;
end
tag = find_tag(nodes(1),FIFF.FIFF_NCHAN);
if ~isempty(tag)
    global_nchan = tag.data;
end
items = fiff_dir_tree_find(nodes(1),FIFF.FIFFB_PROJ_ITEM);
for i = 1:length(items)
    %
    %   Find all desired tags in one item
    %
    item = items(i);
    tag = find_tag(item,FIFF.FIFF_NCHAN);
    if ~isempty(tag)
        nchan = tag.data;
    else
        nchan = global_nchan;
    end
    tag = find_tag(item,FIFF.FIFF_DESCRIPTION);
    if ~isempty(tag)
        desc = tag.data;
    else
        tag = find_tag(item,FIFF.FIFF_NAME);
        if ~isempty(tag)
            desc = tag.data;
        else
            error(me,'Projection item description missing');
        end
    end
    tag = find_tag(item,FIFF.FIFF_PROJ_ITEM_CH_NAME_LIST);
    if ~isempty(tag)
        namelist = tag.data;
    else
        error(me,'Projection item channel list missing');
    end
    tag = find_tag(item,FIFF.FIFF_PROJ_ITEM_KIND);
    if ~isempty(tag)
        kind = tag.data;
    else
        error(me,'Projection item kind missing');
    end
    tag = find_tag(item,FIFF.FIFF_PROJ_ITEM_NVEC);
    if ~isempty(tag)
        nvec = tag.data;
    else
        error(me,'Number of projection vectors not specified');
    end
    tag = find_tag(item,FIFF.FIFF_PROJ_ITEM_CH_NAME_LIST);
    if ~isempty(tag)
        names = fiff_split_name_list(tag.data);
    else
        error(me,'Projection item channel list missing');
    end
    tag = find_tag(item,FIFF.FIFF_PROJ_ITEM_VECTORS);
    if ~isempty(tag)
        data = tag.data;
    else
        error(me,'Projection item data missing');
    end
    tag = find_tag(item,FIFF.FIFF_MNE_PROJ_ITEM_ACTIVE);
    if ~isempty(tag)
        active = tag.data;
    else
        active = false;
    end
    if size(data,2) ~= length(names)
        error(me,'Number of channel names does not match the size of data matrix');
    end
    one.kind           = kind;
    one.active         = active;
    one.desc           = desc;
    %
    %   Use exactly the same fields in data as in a named matrix
    %
    one.data.nrow      = nvec;
    one.data.ncol      = nchan;
    one.data.row_names = [];
    one.data.col_names = names;
    one.data.data      = data;
    %
    projdata(i) = one;
end

if length(projdata) > 0
    fprintf(1,'\tRead a total of %d projection items:\n', ...
        length(projdata));
    for k = 1:length(projdata)
        fprintf(1,'\t\t%s (%d x %d)',projdata(k).desc, ...
            projdata(k).data.nrow,projdata(k).data.ncol);
        if projdata(k).active
            fprintf(1,' active\n');
        else
            fprintf(1,' idle\n');
        end
    end
end

return;

    function [tag] = find_tag(node,findkind)

        for p = 1:node.nent
            if node.dir(p).kind == findkind
                tag = fiff_read_tag(fid,node.dir(p).pos);
                return;
            end
        end
        tag = [];
    end

end


function [problemTypeParams, solverParams] = parseSolverParameters(problemType, varargin)
% Gets default cobra solver parameters for a problem of type problemType, unless
% overridden by cobra solver parameters provided by varagin either as parameter
% struct, or as parameter/value pairs.
%
% USAGE:
%    [problemTypeParams, solverParams] = parseSolverParameters(problemType,varargin)
%
% INPUT:
%    problemType:       The type of the problem to get parameters for
%                       ('LP','MILP','QP','MIQP','NLP','EP')
%
% OPTIONAL INPUTS:
%    varargin:          Additional parameters either as parameter struct, or as
%                       parameter/value pairs. A combination is possible, if
%                       the parameter struct is either at the beginning or the
%                       end of the optional input.
%                       All fields of the struct which are not COBRA parameters
%                       (see `getCobraSolverParamsOptionsForType`) for this
%                       problem type will be passed on to the solver in a
%                       solver specific manner.
%
% OUTPUTS:
%    problemTypeParams: The COBRA Toolbox specific parameters for this
%                       problem type given the provided parameters
%
%    solverParams:      Additional parameters provided which are not part
%                       of the COBRA parameters and are assumed to be part
%                       of direct solver input structs. For some solvers, it
%                       is essential to not include any extraneous fields that are
%                       outside the solver interface specification.

cobraSolverParameters = getCobraSolverParamsOptionsForType(problemType); % build the default Parameter Structure

% set the solver Type
eval(['global CBT_' problemType '_SOLVER;'])
eval(['defaultSolver = CBT_' problemType '_SOLVER;']);

% initialize the solver variables
solverVars = cell(numel(cobraSolverParameters),1);

% get the default variables for the correct solver.
[solverVars{:}] = getCobraSolverParams(problemType,cobraSolverParameters,struct('solver',defaultSolver));
defaultParams = [cobraSolverParameters',solverVars];

nVarargin = numel(varargin);
% parse the supplied parameters
if nVarargin > 0
    % we should have a struct at the end
    if mod(nVarargin,2) == 1
        optParamStruct = varargin{end};
        if ~isstruct(optParamStruct)
            % but it could also be at the first position, so test that as well.
            optParamStruct = varargin{1};
            varargin(1) = [];
            nVarargin = numel(varargin); %added this in case varagin{1} is the parameter structure
            if ~isstruct(optParamStruct)
                error(['Invalid Parameters supplied.\n',...
                       'Parameters have to be supplied either as parameter/Value pairs, or as struct.\n',...
                       'A combination is possible, if the last or first input argument is a struct, and all other arguments are parameter/value pairs'])
            end
        else
            varargin(end) = [];
        end
    else
        % no parameter struct. so initialize an empty one.
        optParamStruct = struct();
    end
    nVarargin = numel(varargin); %added this in case varagin{1} is the parameter structure
    % now, loop through all parameter/value pairs.
    for i = 1:2:nVarargin
        cparam = varargin{i};
        if ~ischar(cparam)
            error('Parameters have to be supplied as ''parameterName''/Value pairs');
        end
        % the param struct overrides the only use the parameter if it is
        % not a field of the parameter struct.
        if ~isfield(optParamStruct,cparam)
            try
                optParamStruct.(cparam) = varargin{i+1};
            catch
                error('All parameters have to be valid matlab field names. %s is not a valid field name',cparam);
            end
        else
            warning('Duplicate parameter %s, both supplied as a field name and a parameter/value pair!',cparam);
        end
    end
else
    % no optional parameters.
    optParamStruct = struct();
end

% set up the cobra parameters
problemTypeParams = struct();

for i = 1:numel(defaultParams(:,1))
    % if the field is part of the optional parameters (i.e. explicitly provided) use it.
    if isfield(optParamStruct,defaultParams{i,1})
        problemTypeParams.(defaultParams{i,1}) = optParamStruct.(defaultParams{i,1});
        % and remove the field from the struct for the solver specific parameters.
        optParamStruct = rmfield(optParamStruct,defaultParams{i,1});
    else
        % otherwise use the default parameter
        problemTypeParams.(defaultParams{i,1}) = defaultParams{i,2};
    end
end

% assign all remaining parameters to the solver parameter struct.
solverParams = optParamStruct;


%SETFILES Set files (directory names) for datafile
%
%   A = SETFILES(A,DIRNAMES)
%
% INPUT
%   A         - Datafile
%   DIRNAMES  - Character array with directory (or file) names
%
% OUTPUT
%   A         - Datafile
%
% DESCRIPTION
% Set the filenames for a datafile. This constructs a new datafile,
% except for the PREPROC and POSTPROC fields.
%
% SEE ALSO (PRTools Guide)
% DATAFILES


function keypointsAll = keypoints14to16(keypointsAllcell)

keypointsAll = repmat(struct('det',nan(16,3),'imgname',''),size(keypointsAllcell,1),1);

for imgidx = 1:length(keypointsAll)
    det = keypointsAllcell{imgidx};
    keypointsAll(imgidx).det(1:6,1:2) = det(1:6,1:2);
    %keypointsAll(imgidx).det(9,1:2) = det(13,1:2);
    %keypointsAll(imgidx).det(10,1:2) = det(14,1:2);
    keypointsAll(imgidx).det(9:16,1:2) = det(7:14,1:2);
end

end


function ws = wavelet_wavescale(w)
	ws = w.wavScale;


%{
 * Copyright (C) 2020-2030, The Regents of The University of Michigan.
 * All rights reserved.
 * This software was developed in the Biped Lab (https://www.biped.solutions/)
 * under the direction of Jessy Grizzle, grizzle@umich.edu. This software may
 * be available under alternative licensing terms; contact the address above.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of the Regents of The University of Michigan.
 *
 * AUTHOR: Bruce JK Huang (bjhuang[at]umich.edu)
 * WEBSITE: https://www.brucerobot.com/
%}

function line = point3DToLineForDrawing(points)
    line = [points(1,1), points(2,1), points(3,1);
        points(1,2), points(2,2), points(3,2);
        points(1,2), points(2,2), points(3,2)
        points(1,4), points(2,4), points(3,4);
        points(1,4), points(2,4), points(3,4);
        points(1,3), points(2,3), points(3,3);
        points(1,1), points(2,1), points(3,1)]';
end


function obj = sym(obj)
% the symmetric part of the tensors

for i = 1:length(obj.u)
  if  obj.rank(i) > 1
    obj.u{i} = sym(obj.u{i});
  end
end

end


function t = structn(obj)
% Convert a NIFTI-1 object into a form of struct
% _______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

%
% $Id$

if numel(obj)~=1,
    error('Too many elements to convert');
end;
fn = fieldnames(obj);
for i=1:length(fn)
    tmp = subsref(obj,struct('type','.','subs',fn{i}));
    if ~isempty(tmp)
        t.(fn{i}) = tmp;
    end;
end;
return;


function quenchWriteStateFromFiberGroup(fg,t1File,outName)
%
%   quenchWriteStateFromFiberGroup([fg],[t1File],[outName])
%
% OVERVIEW: Takes a mrDiffusion fiber group and associated t1File and
%           creates a Quench '.qst' state file using the fg.subgroup field
%           to identify different group assignments in Quench.
%
% NOTE:
%           This function saves an accompanying pathway database file
%           (.pdb) that will be loaded in quench when the state file is
%           loaded. The T1 file can be stored anywhere as the full path is
%           written to the sate file - the pdb file and the qst files are
%           saved, and should be stored, in the same directory.
%
% INPUTS:
%       fg      -  a mrDiffusion fiber structure: can be a filename (.mat)
%                  with a subgroup field wherein each distinct fiber is
%                  given an idex unique to the fibergroup it belongs to.
%                  The field fg.subgroupNames should have the names for
%                  each of the unique fiber groups indexed.
%
%       t1File  -  full path to t1 file. Important: Do not use symbolic
%                  links. If you use a symbolic link in linux then we can
%                  resovle the link, but in windows or MAC you're on your
%                  own.
%
%       outName -  the stem for the qst and pdb filenames. If not provided
%                  the name will be taken from fg.name.
%
% WEB RESOURCES:
%       mrvBrowseSVN('quenchWriteStateFromFiberGroup');
%
%
% EXAMPLE USAGE:
%
%   Default usage: Provide path to fiber group and t1 file - take name
%                  from fiber group.
%       >> fg = 'MoriGroups.mat';
%       >> t1File = '/some/Path/t1File.nii.gz';
%       >> quenchWriteStateFromFiberGroup(fg,t1File,[]);
%
% (C) Stanford University, VISTA Lab 2012
%

%% Check inputs and open file for writing

% Fiber group
if notDefined('fg')
    fg = mrvSelectFile('r','*.mat','QST: Select fiber group',pwd);
    if isempty(fg); return; end
end

% Check that fg is a struct or a file that we can read in
if ~isstruct(fg) && exist(fg,'file')
    fprintf('Reading fiber group structure from file...');
    fg = fgRead(fg);
    fprintf('done.\n')
elseif isfield(fg,'fg.fibers')
    disp('Fiber group structure already loaded.');
end

% Check for subroups and subgroup names fields. If they don't exist however
% the fiber group structure contains an array of fiber groups then convert
% it into the desired format. Otherwise exit the function
if ~isfield(fg,'subgroup') && ~isfield(fg,'subgroupNames') && length(fg) > 1
    fg = dtiFgArrayToFiberGroup(fg);
elseif ~isfield(fg,'subgroup') && length(fg) <=1
    error('No subgroup field found in fibergroup structure!');
elseif ~isfield(fg,'subgroupNames') && length(fg) <=1
    error('No subgroupNames field found in fiber structure!');
end

% T1 File
if notDefined('t1File')
    t1File = mrvSelectFile('r','*.nii*','QST: Select t1File',pwd);
    if isempty(t1File); return; end
else
    [p f e] = fileparts(t1File);
    if isempty(p)
        disp('WARNING: t1File must be a full path to the t1File - NOT A SYMBOLIC LINK!!!!');
        t1File = mrvSelectFile(r,'.nii.gz','Choose t1File',pwd);
        if isempty(t1File); return; end
    end
end

% Check that t1File is not a soft link:
if isunix
    [status t1File] = system((sprintf('readlink -f %s',t1File)));
    if status ~= 0
        disp('Could not resolve real path to t1File');
    end
else
    disp('NON-UNIX system detected: Could not verify the path of the t1File - make sure that t1File is not a symbolic Link.')
end

% If outname is not supplied then we use the fg.name field and make sure
% that the extension is not yet attached
if notDefined('outName')
    outName = fg.name;
end

[path file ext] = fileparts(outName);

if ~isempty(ext)
    outName = fullfile(path,file);
end

% Remove any spaces in the file name and replace with '_'
outName = regexprep(outName,'\W','_');

%% Set color and name assignments

% Get the information we need to do the assignments
fgInds    = fg.subgroup;
numGroups = numel(unique(fgInds));

disp([num2str(numGroups) ' fiber groups will be written to the state file:']);

% Number of unique colors used by default in Quench = 16
num       = 1:16;
cinds     = repmat(num,1,(round(numGroups/16)+1));

% Build cell array of colors for color assignments
c{1}='0.0784314 0.352941 0.784314 1';
c{2}='0.596078 0.305882 0.639216 1';
c{3}='1 1 0.2 1';
c{4}='0.301961 0.686275 0.290196 1';
c{5}='0.745098 0.156863 0.156863 1';
c{6}='1 0.498039 0 1';
c{7}='0.470588 0.705882 0.705882 1';
c{8}='0.470588 0.392157 0.196078 1';
c{9}='0.564706 0.705882 1 1';
c{10}='0.831373 0.682353 0.854902 1';
c{11}='0.964706 0.964706 0.690196 1';
c{12}='0.678431 0.87451 0.670588 1';
c{13}='0.913725 0.607843 0.607843 1';
c{14}='0.976471 0.784314 0.611765 1';
c{15}='0.756863 0.882353 0.882353 1';
c{16}='0.780392 0.737255 0.635294 1';

% Loop over the groups and assign the color
for ii = 1:numGroups
    color{ii} = c{cinds(ii)};
end

% Name assignments: Check group names field and build group name cell array
% for displaying each of the names
for ii = 1:numGroups
    if numGroups == length(fg.subgroupNames)
        gname{ii} = fg.subgroupNames(ii).subgroupName;
        % Remove any spaces in the file names and replace with '_'
        gname{ii} = regexprep(gname{ii},'\W','_');
        fprintf(' %s - %s\n',num2str(ii),gname{ii});
    else
        error('Length of subgroupNames is not == to the number of subgroups');
    end
end

%% Start writing the huge, annoying text file
%  Note that quench is INCREDIBLY picky about line endings and spaces.
%  Things have to be just as they are below or Quench will CRASH - hard.

fprintf('Writing Quench state file [%s.qst] ... ', outName);

% Open the state file for writing
qst = fopen([outName '.qst'],'wt');

        fprintf(qst,'Version 2\n');

        fprintf(qst,'--- Main Window ---\n');
        fprintf(qst,'Position 1865 52\n');
        fprintf(qst,'Size 1088 915\n');
        fprintf(qst,'Is Maximized 0\n');
        fprintf(qst,'Current background image index 0\n');

        fprintf(qst,'\n--- Volumes ---\n');
        fprintf(qst,'Num Volumes :1\n');
        fprintf(qst,'%s\n', t1File); % This has to be the full path to the t1.

        fprintf(qst,'--- PDB Info ---\n');
        fprintf(qst,'Num PDB''s: 1\n');
        fprintf(qst,'%s\n',[outName '.pdb']); % This could be the full path to the fiber group

        fprintf(qst,'--- Pathway Assignment ---\n');
        fprintf(qst,'Locked: 0\n');
        fprintf(qst,'Selected Group: 1\n');
        fprintf(qst,'Num Assigned: %s\n',num2str(numel(fgInds)));

        % Convert the fgInds matrix to a string and remove the brackets
        indstr      = mat2str(fgInds);
        indstr(1)   = [];
        indstr(end) = [];
        fprintf(qst,'%s \n',indstr); % the trailing space is important!!!

        fprintf(qst,'\n--- Pathway Groups ---\n');
        fprintf(qst,'Num Groups: %s\n',num2str(numGroups+1)); % This should be +1
        fprintf(qst,'Name: Trash\n');
        fprintf(qst,'Color: 0.501961 0.501961 0.501961 1\n');
        fprintf(qst,'Visible: 1\n');
        fprintf(qst,'Active: 1\n\n');

        % Loop over the groups and write out the unique names and colors
        for ii = 1:numGroups
            fprintf(qst,'Name: %s\n', gname{ii});
            fprintf(qst,'Color: %s\n', color{ii});
            fprintf(qst,'Visible: 1\n');
            fprintf(qst,'Active: 1\n\n');
        end

        % Not sure that these positions will work for every screen
        fprintf(qst,'Camera Position: -503.393,-16.364,26.7371\n');
        fprintf(qst,'Camera View Up: 0.0488575,-0.000488639,0.998806\n');
        fprintf(qst,'Camera Focal Point: 0.062871,-13.8796,2.11129\n');

        fprintf(qst,'--- Move tool ---\n');
        fprintf(qst,'Position: (0,0,0)\n');
        fprintf(qst,'Scale :(19.8361,19.8361,19.8361)\n');
        fprintf(qst,'Visible : 0\n');

        fprintf(qst,'--- Scale tool ---\n');
        fprintf(qst,'Position: (0,0,0)\n');
        fprintf(qst,'Scale :(19.8361,19.8361,19.8361)\n');
        fprintf(qst,'Visible : 0\n');

        fprintf(qst,'\n--- Volume State ---\n');
        fprintf(qst,'Volume Section"s Position: 0,-18,18\n');
        fprintf(qst,'Volume Section"s Visibility: 1,1,1\n');
        fprintf(qst,'Active Image :1\n');

        fprintf(qst,'\n--- Overlays ---\n');
        fprintf(qst,'Num overlay items :1\n');
        fprintf(qst,'Opacity :1\n');
        fprintf(qst,'Range :0 32767\n');
        fprintf(qst,'ColorMapIndex :0\n');
        fprintf(qst,'Visible :0\n');

        fprintf(qst,'\n--- Gesture Panel ---\n');
        fprintf(qst,'Visible :1\n');
        fprintf(qst,'Position :(755,4)\n');
        fprintf(qst,'SelectMode :0\n');

        fprintf(qst,'\n--- Selection Panel ---\n');
        fprintf(qst,'Visible :1\n');
        fprintf(qst,'Position :(857,4)\n');
        fprintf(qst,'SelectMode :0\n');

        fprintf(qst,'\n--- Refine Selection panel ---\n');
        fprintf(qst,'Position -1 -1\n');
        fprintf(qst,'Size 450 260\n');
        fprintf(qst,'Visible 0\n');
        fprintf(qst,'Num ROIs 0\n');

        fprintf(qst,'\n--- Background and overlay panel ---\n');
        fprintf(qst,'Position -1 -1\n');
        fprintf(qst,'Size 458 250\n');
        fprintf(qst,'Visible 0\n');

        fprintf(qst,'\n--- ROIs ---\n');
        fprintf(qst,'Num ROIs: 0\n\n');

fclose(qst);

fprintf('done.\n');

%% Save the fiber group struct as a pdb

fprintf('Writing pathway database [%s.pdb] ... ', outName);

fgWrite(fg,outName,'pdb')

fprintf('done! \n');

return

%%
%#ok<*ASGLU>
%#ok<*AGROW>
%#ok<*NASGU>


%%*****************************************************************************
%% sqlpmisc:
%% unscale and produce infeasibility certificates if appropriate
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004.
%%*****************************************************************************

   function [X,y,Z,termcode,resid,reldist,msg] = sqlpmisc(blk,At,C,b,X,y,Z,permZ,param);

   termcode    = param.termcode;
   iter        = param.iter;
   obj         = param.obj;
   relgap      = param.relgap;
   prim_infeas = param.prim_infeas;
   dual_infeas = param.dual_infeas;
   homRd       = param.homRd;
   homrp       = param.homrp;
   AX          = param.AX;
   ZpATynorm   = param.ZpATynorm;
   m0          = param.m0;
   indeprows   = param.indeprows;
   normX0      = param.normX0;
   normZ0      = param.normZ0;
   inftol      = param.inftol;
   maxit       = param.maxit;
   scale_data  = param.scale_data;
   printlevel  = param.printlevel;
%%
   resid = []; reldist = []; msg = [];
   if (scale_data)
      normA = param.normA; normC = param.normC; normb = param.normb;
   else
      normA = 1; normC = 1; normb = 1;
   end
   Anorm = ops(At,'norm'); xnorm = ops(X,'norm'); ynorm = norm(y);
   infeas = max(prim_infeas,dual_infeas);
%%
   if (iter >= maxit)
      termcode = -6;
      msg = 'sqlp stop: maximum number of iterations reached';
      if (printlevel); fprintf('\n  %s',msg); end
   end
   if (termcode <= 0)
      %%
      %% To detect near-infeasibility when the algorithm provides
      %% a "better" certificate of infeasibility than of optimality.
      %%
      err = max(infeas,relgap);
      iflag = 0;
      if (obj(2) > 0)
         if (homRd < 0.1*sqrt(err*inftol))
            iflag = 1;
            msg = sprintf('prim_inf,dual_inf,relgap = %3.2e, %3.2e, %3.2e',...
		  prim_infeas,dual_infeas,relgap);
            if (printlevel); fprintf('\n  %s',msg); end
            termcode = 1;
         end
      end
      if (obj(1) < 0)
         if (homrp < 0.1*sqrt(err*inftol))
            iflag = 1;
            msg = sprintf('prim_inf,dual_inf,relgap = %3.2e, %3.2e, %3.2e',...
                  prim_infeas,dual_infeas,relgap);
            if (printlevel); fprintf('\n  %s',msg); end
            termcode = 2;
         end
      end
      if (iflag == 0)
         if (scale_data == 1)
            X = ops(ops(X,'./',normA),'*',normb);
            y = y*normC;
            Z = ops(ops(Z,'.*',normA),'*',normC);
         end
      end
   end
   if (termcode == 1) & (iter > 3)
      msg = 'sqlp stop: primal problem is suspected of being infeasible';
      if (printlevel); fprintf('\n  %s',msg); end
      if (scale_data == 1)
         X = ops(X,'./',normA); b = b*normb;
      end
      rby = 1/(b'*y); y = rby*y; Z = ops(Z,'*',rby);
      resid = ZpATynorm * rby;
      reldist = ZpATynorm/(Anorm*ynorm);
   end
   if (termcode == 2) & (iter > 3)
      msg = 'sqlp stop: dual problem is suspected of being infeasible';
      if (printlevel); fprintf('\n  %s',msg); end
      if (scale_data == 1)
         C = ops(C,'.*',normC);
         Z = ops(Z,'.*',normA);
      end
      tCX = blktrace(blk,C,X);
      X = ops(X,'*',1/(-tCX));
      resid = norm(AX)/(-tCX);
      reldist = norm(AX)/(Anorm*xnorm);
   end
   if (termcode == 3)
      maxblowup = max(ops(X,'norm')/normX0,ops(Z,'norm')/normZ0);
      msg = sprintf('sqlp stop: primal or dual is diverging, %3.1e',maxblowup);
      if (printlevel); fprintf('\n  %s',msg); end
   end
   [X,Z] = unperm(blk,permZ,X,Z);
   if ~isempty(indeprows)
      ytmp = zeros(m0,1);
      ytmp(indeprows) = y;
      y = ytmp;
   end
%%*****************************************************************************
%% unperm: undo the permutations applied in validate.
%%
%% [X,Z] = unperm(blk,permZ,X,Z);
%%
%% undoes the permutation introduced in validate.
%%*****************************************************************************

  function [X,Z] = unperm(blk,permZ,X,Z);
%%
  for p = 1:size(blk,1)
     if (strcmp(blk{p,1},'s') & ~isempty(permZ{p}))
        per = permZ{p};
        X{p} = X{p}(per,per);
        Z{p} = Z{p}(per,per);
     end
  end
%%*****************************************************************************


function gmt_patch(hPatch, sOutput, sPrefix)

% Get data
mXData = get(hPatch, 'XData');
mYData = get(hPatch, 'YData');

% Transform data and save it
[nRow, nCnt] = size(mXData);
if nRow == 1
  mXData = mXData';
end
[nRow, nCnt] = size(mYData);
if nRow == 1
  mYData = mYData';
end
mXYValues = [mXData mYData];
save([sPrefix '_patch.dat'], 'mXYValues', '-ascii');

% Get attributes
vEdgeColor = get(hPatch, 'EdgeColor');
vFaceColor = get(hPatch, 'FaceColor');
fLineWidth = get(hPatch, 'LineWidth');

% Write GMT
hFile = fopen(sOutput, 'a');
fprintf(hFile, '# Plot patch\n');
sG = sprintf('-G%s/%s/%s', num2str(round(vFaceColor(1)*255)), num2str(round(vFaceColor(2)*255)), num2str(round(vFaceColor(3)*255)));
sW = sprintf('-W%s/%s/%s/%s', num2str(fLineWidth), num2str(vEdgeColor(1)*255), num2str(vEdgeColor(2)*255), num2str(vEdgeColor(3)*255));
fprintf(hFile, 'psxy %s $default %s %s -O -K >> $output\n', [sPrefix '_patch.dat'], sW, sG);
fclose(hFile);


function a = reshape(b,varargin)
% Overloaded reshape function for file_array objects
% _______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

%
% $Id: reshape.m 1143 2008-02-07 19:33:33Z spm $

if length(struct(b))~=1, error('Can only reshape simple file_array objects.'); end;

args = [];
for i=1:length(varargin),
    args = [args varargin{i}(:)'];
end;
if prod(args)~=prod(b.dim),
    error('To RESHAPE the number of elements must not change.');
end;
a = b;
a.dim = args;


function [model, globalOpt] = svargplvmReOptimiseModel(model, initVardistIters, itNo, newExperimentNo, varargin)

% SVARGPLVMREOPTIMISEMODEL Optimise an already optimised svargplvm model for more iterations
%
% SEEALSO : svargplvmOptimiseModel
%
% COPYRIGHT : Andreas C. Damianou, 2011

% VARGPLVM

globalOptOrig = model.globalOpt;
globalOpt = globalOptOrig;

if nargin < 4
    newExperimentNo = globalOpt.experimentNo;
end
globalOpt.experimentNo = newExperimentNo;

globalOpt.initVardistIters = initVardistIters;
globalOpt.itNo = itNo;
model.globalOpt = globalOpt;

model = svargplvmOptimiseModel(model, varargin{:});

globalOptOrig.initVardistIters = [globalOptOrig.initVardistIters initVardistIters];
globalOptOrig.itNo = [globalOptOrig.itNo itNo];

globalOpt = globalOptOrig;
model.globalOpt = globalOpt;


function [M_stimrange,stimrange] = GetStimRange(option,i_fish)
% Fish 1-5: 16-stim PT/Black/White
% Fish 6-7: PT/White
% Fish 8:
%     stimset(1).name = 'PT';
%     stimset(2).name = 'OMR';
%     stimset(3).name = 'Spontaneous';
%     stimset(4).name = 'PT-shock';
%     stimset(5).name = 'OMR-shock';
%     stimset(6).name = 'RB-shock';
% Fish 9-11
%     stimset(1).name = 'PT';
%     stimset(2).name = 'OMR';
%     stimset(3).name = 'Spontaneous';
%     stimset(4).name = 'Dot/prey';
%     stimset(5).name = 'Looming';
%     stimset(6).name = 'Red|Blue';
%     stimset(7).name = 'PT-shock';
%     stimset(8).name = 'OMR-shock';
%     stimset(9).name = 'RB-shock';
% Fish 12-18 except 16
%     stimset(1).name = 'PT';
%     stimset(2).name = 'OMR';
%     stimset(3).name = 'DF';
%     stimset(4).name = 'Spontaneous';
%     stimset(5).name = 'Looming';
% Fish 16
%     stimset(1).name = 'PT';
%     stimset(2).name = 'OMR';
%     [stimset(3).name = may be 'Spontaneous' but not credible, not used]

if ~exist('option','var'),
    % default range:
    M_stimrange = {1,1,1,1,1,1,1,... 1-7
        1:3,... 8
        1:5,1:5,1:5,... 9-11
        1:5,1:5,1:5,1:5,...12-15
        1:3,...16
        1:5,1:5}; % 17-18
elseif isempty(option), % same as above,
    % default range:
    M_stimrange = {1,1,1,1,1,1,1,... 1-7
        1:3,... 8
        1:5,1:5,1:5,... 9-11
        1:5,1:5,1:5,1:5,...12-15
        1:3,...16
        1:5,1:5}; % 17-18

elseif option == 'F', % full range included in data
    M_stimrange = {1,1,1,1,1,1,1,... 1-7
        1:5,... 8
        1:9,1:8,1:9,... 9-11
        1:5,1:5,1:5,1:5,...12-15
        1:3,...16
        1:5,1:5}; % 17-18

elseif option == '2', % no spont, only PT, OMR and DF
    M_stimrange = {1,1,1,1,1,1,1,... 1-7
        1:2,... 8
        1:2,1:2,1:2,... 9-11
        1:3,1:3,1:3,1:3,...12-15
        1:2,...16
        1:3,1:3}; % 17-18

% elseif option == '3', %
%     M_stimrange = {[],[],[],[],[],[],[],... 1-7
%         1:3,... 8
%         1:3,1:3,1:3,... 9-11
%         1:3,1:3,1:3,1:3,...12-15
%         1:3,...16
%         1:3,1:3}; % 17-18

elseif option == '5', % first 5, PT/Black/White
    M_stimrange = {1,1,1,1,1,[],[],... 1-7
        [],... 8
        [],[],[],... 9-11
        [],[],[],[],...12-15
        [],...16
        [],[]};  % 17-18

elseif option == 'M', % M = multistim
    M_stimrange = {[],[],[],[],[],[],[],... 1-7
        1:3,... 8
        1:5,1:5,1:5,... 9-11
        1:5,1:5,1:5,1:5,...12-15
        1:3,...16
        1:5,1:5}; % 17-18

elseif option == 'P', % PT = phototaxis
    M_stimrange = {[],[],[],[],[],1,1,... 1-7
        1,... 8
        1,1,1,... 9-11
        1,1,1,1,...12-15
        1,...16
        1,1};  % 17-18

elseif option == 'O', % OMR
    M_stimrange = {[],[],[],[],[],[],[],... 1-7
        2,... 8
        2,2,2,... 9-11
        2,2,2,2,...12-15
        2,...16
        2,2};  % 17-18
elseif option == 'S', % Spontaneuous
        M_stimrange = {[],[],[],[],[],[],[],... 1-7
        3,... 8
        3,3,3,... 9-11
        4,4,4,4,...12-15
        [],...16
        4,4};  % 17-18

elseif option == 'D', % DF, Dark flash
    M_stimrange = {1,1,1,1,1,[],[],... % [],[],[],[],[],[],[],... 1-7
        [],... 8
        [],[],[],... 9-11
        3,3,3,3,...12-15
        [],...16
        3,3};  % 17-18

elseif option == 'L', % Looming
        M_stimrange = {[],[],[],[],[],[],[],... 1-7
        [],... 8
        5,5,5,... 9-11
        5,5,5,5,...12-15
        [],...16
        5,5};  % 17-18

elseif option == 'Y', % Dot/Prey
        M_stimrange = {[],[],[],[],[],[],[],... 1-7
        [],... 8
        4,4,4,... 9-11
        [],[],[],[],...12-15
        [],...16
        [],[]};  % 17-18
end

if exist('i_fish','var'),
    stimrange = M_stimrange{i_fish};
else % dummy
    stimrange = 1;
end
end


function HeadModel = in_bst_headmodel(HeadModelFile, ApplyOrient, varargin)
% IN_BST_HEADMODEL: Read a headmodel file in Brainstorm format.
%
% USAGE:  HeadModel = in_bst_headmodel(HeadModelFile, ApplyOrient, FieldsList) : Read the specified fields
%         HeadModel = in_bst_headmodel(HeadModelFile, ApplyOrient)             : Read all the fields
%         HeadModel = in_bst_headmodel(HeadModelFile)                          : Read all the fields and do NOT constrain orientations
%
% INPUT:
%    - HeadModelFile : Absolute or relative path to the headmodel file to read
%    - ApplyOrient   : If 1, return the Gain matrix for a constrained orientation (orientations from GridOrient field)
%    - FieldsList    : List of fields to read from headmodel file

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

%% ===== PARSE INPUTS =====
if (nargin < 2) || isempty(ApplyOrient)
    ApplyOrient = 0;
end
% Get protocol folders
ProtocolInfo = bst_get('ProtocolInfo');
% Filename: Relative / absolute
if ~file_exist(HeadModelFile)
    HeadModelFile = bst_fullfile(ProtocolInfo.STUDIES, HeadModelFile);
    if ~file_exist(HeadModelFile)
        error('Head model file not found.');
    end
end
% Specfied fields
if (nargin < 3)
    % Read all fields
    HeadModel = load(HeadModelFile);
else
    % Get fields to read
    FieldsToRead = varargin;
    % If Gain is required, and ApplyOrient is set to 1, we need also the GridOrient field
    if ismember('Gain', FieldsToRead) && ~ismember('GridOrient', FieldsToRead) && ApplyOrient
        FieldsToRead{end + 1} = 'GridOrient';
    end
    % If SurfaceFile required, also add GridLoc
    if ismember('SurfaceFile', FieldsToRead) && ~ismember('GridLoc', FieldsToRead)
        FieldsToRead{end + 1} = 'GridLoc';
    end
    if ismember('GridLoc', FieldsToRead) && ~ismember('SurfaceFile', FieldsToRead)
        FieldsToRead{end + 1} = 'SurfaceFile';
    end
    % If Comment required, also add HeadModelName
    if ismember('Comment', FieldsToRead) && ~ismember('HeadModelName', FieldsToRead)
        FieldsToRead{end + 1} = 'HeadModelName';
    end
    % Read specified files only
    warning off MATLAB:load:variableNotFound
    HeadModel = load(HeadModelFile, FieldsToRead{:});
    warning on MATLAB:load:variableNotFound
end

%% ===== REMOVE CELLS =====
% In previous verisons of Brainstorm, the values were contained in cell lists
% If some values are enclosed in cells, extract them from the cells
fieldsToProcess = {'Gain', 'GridLoc', 'GridOrient'};
% Loop over all fields
for i = 1:length(fieldsToProcess)
    if isfield(HeadModel, fieldsToProcess{i}) && iscell(HeadModel.(fieldsToProcess{i}))
        HeadModel.(fieldsToProcess{i}) = HeadModel.(fieldsToProcess{i}){1};
    end
end

%% ===== READ SOURCE LOCATIONS =====
SurfaceMat = [];
% If GridLoc is a filename
if isfield(HeadModel, 'GridLoc') && ischar(HeadModel.GridLoc)
    SurfaceFile = HeadModel.GridLoc;
    % Load surface file
    SurfaceMat = in_tess_bst(SurfaceFile, 1);
    HeadModel.GridLoc    = SurfaceMat.Vertices;
    HeadModel.SurfaceFile = SurfaceFile;
elseif ~isfield(HeadModel, 'SurfaceFile')
    HeadModel.SurfaceFile = '';
end

% Clean surface filename
if isfield(HeadModel, 'SurfaceFile') && ~isempty(HeadModel.SurfaceFile)
    HeadModel.SurfaceFile = file_short(HeadModel.SurfaceFile);
end

%% ===== READ SOURCE ORIENTATIONS =====
% If GridOrient is empty
if isfield(HeadModel, 'GridOrient') && isempty(HeadModel.GridOrient) && ~isempty(HeadModel.SurfaceFile)
    if isempty(SurfaceMat)
        SurfaceMat = in_tess_bst(HeadModel.SurfaceFile);
    end
    HeadModel.GridOrient = SurfaceMat.VertNormals;
end

%% ===== READ GAIN MATRIX =====
if isfield(HeadModel, 'Gain')
    if ischar(HeadModel.Gain)
        % Get the proper gain covariance matrix
        gainfile = bst_fullfile(bst_fileparts(HeadModelFile), HeadModel.Gain);
        % If the 3 orientations are required, read the _xyz file
        if ~ApplyOrient
            gainfile = strrep(gainfile, '.bin', '_xyz.bin');
        end
        % Read full gain matrix
        HeadModel.Gain = old_read_gain(gainfile);
    else
        HeadModel.Gain = double(HeadModel.Gain);
    end

    % === APPLY ORIENTATIONS ====
    % If the gain matrix has 3 orientations per source, we need to apply the orientation
    if ApplyOrient && (size(HeadModel.Gain,2) == 3 * length(HeadModel.GridOrient))
        % Apply the fixed orientation to the Gain matrix (normal to the cortex)
        HeadModel.Gain = bst_gain_orient(HeadModel.Gain, HeadModel.GridOrient);
    end
end

%% ===== READ COMMENT =====
if isfield(HeadModel, 'HeadModelName') && ~isfield(HeadModel, 'Comment')
    HeadModel.Comment = HeadModel.HeadModelName;
end

%% ===== READ HEAD MODEL TYPE =====
if isfield(HeadModel, 'HeadModelType')
    if ~ismember(HeadModel.HeadModelType, {'surface', 'volume', 'mixed'})
        HeadModel.HeadModelType = 'surface';
    end
end

%% ===== GRID LOC =====
if isfield(HeadModel, 'GridLoc') && ~isempty(HeadModel.GridLoc)
    % Check matrix orientation
    if (size(HeadModel.GridLoc,2) ~= 3)
        HeadModel.GridLoc = HeadModel.GridLoc';
    end
end

%% ===== GRID LOC =====
if isfield(HeadModel, 'GridOrient') && ~isempty(HeadModel.GridOrient)
    % Check matrix orientation
    if (size(HeadModel.GridOrient,2) ~= 3)
        HeadModel.GridOrient = HeadModel.GridOrient';
    end
end

%% ===== ADD MISSING FIELDS =====
if (nargin >= 3)
    for i = 1:length(FieldsToRead)
        if ~isfield(HeadModel, FieldsToRead{i})
            HeadModel.(FieldsToRead{i}) = [];
        end
    end
end


% The COBRAToolbox: testVerifyModel.m
%
% Purpose:
%     - Tests the Model Verification function
%

model = getDistributedModel('ecoli_core_model.mat');

% test whether the correct "invalid" subSystem is found
modelSub = model;
modelSub.subSystems(20) = {'blubb'};

res = verifyModel(modelSub,'silentCheck',true);

assert(~isempty(res))
if isfield(res,'Errors')
    assert(isequal(res.Errors.propertiesNotMatched.subSystems, sprintf('Field does not match the required properties at the following positions: \n            20')));
end

% test whether rules are checked crrectly
modelRule = model;
modelRule.rules(3) = {'x(17) )'};
res = verifyModel(modelRule,'silentCheck',true);

assert(~isempty(res))
assert(isequal(res.Errors.propertiesNotMatched.rules, sprintf('Field does not match the required properties at the following positions: \n       3')));


classdef (Abstract) nme_load < mp.nm_element

%   MATPOWER
%   Copyright (c) 2019-2022, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%     properties
%     end     %% properties

    methods
        function name = name(obj)
            name = 'load';
        end

        function np = np(obj)
            np = 1;     %% this is a 1 port element
        end
    end     %% methods
end         %% classdef


% EEG_MULTIEEGPLOT - Produce an EEGPLOT of a the average of an epoched dataset
%                  (with optional pre-labelling of specific trials).
% Usage:
%   >> eeg_multieegplot( data,trialrej, elecrej, ...
%                                'key1', value, 'key2', value ... );
% Inputs:
%   data        - input data (channels x points or channels x points x trials).
%   trialrej    - array of 0s and 1s (depicting rejected trials) (size sweeps)
%   elecrej     - array of 0s and 1s (depicting electrodes rejected in
%                 all trials) (size nbelectrodes x sweeps )
%   oldtrialrej - array of 0s and 1s (depicting rejected trials) (size sweeps)
%   oldelecrej  - array of 0s and 1s (depicting electrodes rejected in
%                 all trials) (size nbelectrodes x sweeps )
%
% Note: 1) {'Key', value } Arguments are passed on to EEGPLOT
%       2) To ignore previous rejections simply set 'oldtrialrej' and
%          'oldelecrej' arguments to empty ([]).
%
% Author: Arnaud Delorme, CNL / Salk Institute, 2001
%
% See also: EEGPLOT, EEGPLOT2EVENT, EEGPLOT2TRIAL, EEGLAB

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

% 01-25-02 reformated help & license -ad
% 03-07-02 corrected help -ad

function eeg_multieegplot( data, rej, rejE, oldrej, oldrejE, varargin);

if nargin < 1
   help eeg_multieegplot;
   return;
end
if nargin < 4
   oldrej = [];
end
if nargin < 5
   oldrejE = [];
end
if ~exist('command')
	command = '';
end
chans = size(data,1);
pnts  = size(data,2);

colnew = [0.8 0.8 1];
colold = [0.8 1 0.8];

if ndims(data) > 2 % --------------- considering epoched EEG data
   rejeegplot = [];
   % concatenate old rejection if not empty
   % --------------------------------------
   if ~isempty( oldrej )
   		oldrej 	 = find( oldrej > 0);
   		oldrejE  = oldrejE(:, oldrej)';
   		rejeegplot = trial2eegplot( oldrej, oldrejE, pnts, colold);
   end;
   % convert for eegplot
   % -------------------
   if ~isempty(	rej )
   		rej    = find( rej > 0);
   		rejE   = rejE(:,rej)';
   		secondrejeegplot = trial2eegplot( rej, rejE, pnts, colnew); % see bottom of code for this function
   		rejeegplot = [ rejeegplot' secondrejeegplot' ]';

   		% remove duplicates
   		% -----------------
		%[tmp I] = unique_bc( rejeegplot(:,1) );
		%rejeegplot = rejeegplot(I,:);
   end
else % ---------------------------------------- considering continuous EEG
   % for continuous EEG, electrodes (rejE and oldrejE) are not considered yet
   % because there would be a format problem (these rejection are stored in
   % the event array).

   rejeegplot = [];
   if ~isempty(rej) %assuming nrejection x 2 (2 = begin end)
      s = size(rej, 1);
      rejeegplot = [ rej(3:4) colnew*ones(s,1)  zeros(s, chans) ];
   end;

   % pooling previous rejections
   if ~isempty(oldrej)
       tmp = [ oldrej(:, 3:4) colold*ones(s,1) zeros(size(oldrej,1), chans) ];
       rejeegplot = [rejeegplot; tmp];
   end
end

if isempty(varargin)
	eegplot(data, 'winlength', 5, 'position', [100 300 800 500], 'winrej', rejeegplot, 'xgrid', 'off');
else
	eegplot(data, 'winlength', 5, 'position', [100 300 800 500], 'winrej', rejeegplot, 'xgrid', 'off', varargin{:} );
end;
return;

% convert eeglab format to eeplot format of rejection window
% ----------------------------------------------------------
function rejeegplot = trial2eegplot( rej, rejE, pnts, color)
   	rejeegplot = zeros(length(rej), size(rejE,2)+5);
   	rejeegplot(:, 6:end) = rejE;
   	rejeegplot(:, 1) = (rej(:)-1)*pnts;
   	rejeegplot(:, 2) = rej(:)*pnts-1;
   	rejeegplot(:, 3:5) = ones(size(rejeegplot,1),1)*color;
return


function drawBox3D(h,occlusion,corners,face_idx,orientation)

% set styles for occlusion and truncation
occ_col    = {'w','g','y','r'};

% draw projected 3D bounding boxes
if ~isempty(corners)
  for f=1:4
    line([corners(1,face_idx(f,:)),corners(1,face_idx(f,1))]+1,...
         [corners(2,face_idx(f,:)),corners(2,face_idx(f,1))]+1,...
         'parent',h(2).axes, 'color',occ_col{occlusion+2},...
         'LineWidth',6);
    line([corners(1,face_idx(f,:)),corners(1,face_idx(f,1))]+1,...
         [corners(2,face_idx(f,:)),corners(2,face_idx(f,1))]+1,...
         'parent',h(2).axes,'color','k','LineWidth',2);
  end
end

% draw orientation vector
if ~isempty(orientation)
  line([orientation(1,:),orientation(1,:)]+1,...
       [orientation(2,:),orientation(2,:)]+1,...
       'parent',h(2).axes,'color','w','LineWidth',6);
  line([orientation(1,:),orientation(1,:)]+1,...
       [orientation(2,:),orientation(2,:)]+1,...
       'parent',h(2).axes,'color','k','LineWidth',2);
end