%KWAVEGRID   Class definition for k-Wave grid structure.
%
% DESCRIPTION:
%       See makeGrid for function arguments.
%
% ABOUT:
%       author      - Bradley Treeby
%       date        - 22nd July 2010
%       last update - 29th August 2012
%
% 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/>.

classdef kWaveGrid

    % define the private properties (these parameters are stored and cannot
    % be altered by the user after the object is created, but they can be
    % accessed)
    properties (GetAccess = public, SetAccess = private)

        % grid dimensions in grid points
        Nx = 0;
        Ny = 0;
        Nz = 0;

        % grid point spacing in metres
      	dx = 0;
        dy = 0;
        dz = 0;

        % wavenumber grids
        kx_vec = 0;
        ky_vec = 0;
        kz_vec = 0;
        k = 0;

        % maximum supported spatial frequency
        kx_max = 0;
        ky_max = 0;
        kz_max = 0;
        k_max = 0;

        % number of dimensions
        dim = 0;

        % non-uniform grid
        nonuniform = false;

    end

    % define the public properties (these parameters are stored and can be
    % both accessed and altered by the user after the object is created)
    properties (GetAccess = public, SetAccess = public)

        % time array
        t_array = 'auto';

    end

    % define the dependent properties (these parameters are not stored but
    % re-computed each time they are needed)
    properties(Dependent = true, GetAccess = public, SetAccess = private)

        % 3D plaid Cartesian spatial grids
        x;
        y;
        z;

        % 3D plaid wavenumber grids
        kx;
        ky;
        kz;

        % 1D spatial grids
        x_vec;
        y_vec;
        z_vec;

        % Cartesian grid size
        x_size;
        z_size;
        y_size;

        % time step and number of time points
        dt;
        Nt;

        % total number of grid points
        total_grid_points;

    end

    % define the staggered grid properties (these can be accessed but not
    % altered by the user after the object is created, the parameters are
    % also hidden from view)
    properties (Hidden = true, GetAccess = public, SetAccess = private)

        % position vectors for the staggered grid points in [0, 1]
        xn_vec = 0;
        yn_vec = 0;
        zn_vec = 0;
        xn_vec_sgx = 0;
        yn_vec_sgy = 0;
        zn_vec_sgz = 0;

        % transformation gradients between uniform and staggered grids
        dxudxn = 0;
        dyudyn = 0;
        dzudzn = 0;
        dxudxn_sgx = 0;
        dyudyn_sgy = 0;
        dzudzn_sgz = 0;

    end

    % define the dependent staggered grid properties (these parameters are
    % not stored but re-computed each time they are needed, the parameters
    % are also hidden from view)
    properties(Dependent = true, Hidden = true, GetAccess = public, SetAccess = private)

        % 3D plaid non-uniform spatial grids
        xn;
        yn;
        zn;

    end

    % constructor function
    methods
        function kgrid = kWaveGrid(varargin)

            % assign the input values to the grid object
            switch nargin

                case 6

                    % 3D uniform grid
                    kgrid.Nx = varargin{1};
                    kgrid.dx = varargin{2};
                    kgrid.Ny = varargin{3};
                    kgrid.dy = varargin{4};
                    kgrid.Nz = varargin{5};
                    kgrid.dz = varargin{6};

                    % set the number of dimensions
                    kgrid.dim = 3;

                case 4

                    % 2D uniform grid
                    kgrid.Nx = varargin{1};
                    kgrid.dx = varargin{2};
                    kgrid.Ny = varargin{3};
                    kgrid.dy = varargin{4};

                    % set the number of dimensions
                    kgrid.dim = 2;

                case 2

                    % 1D uniform grid
                    kgrid.Nx = varargin{1};
                    kgrid.dx = varargin{2};

                    % set the number of dimensions
                    kgrid.dim = 1;

                otherwise
                    error('Incorrect number of input arguments');
            end

            switch kgrid.dim
                case 1

                    % assign the grid parameters for the x spatial direction
                    kgrid.kx_vec = kgrid.makeDim(kgrid.Nx, kgrid.dx);

                    % define the scalar wavenumber based on the wavenumber components
                    kgrid.k = abs(kgrid.kx_vec);

                    % define maximum supported frequency
                    kgrid.kx_max = max(abs(kgrid.kx_vec(:)));
                    kgrid.k_max = kgrid.kx_max;

                case 2

                    % assign the grid parameters for the x and z spatial directions
                    kgrid.kx_vec = kgrid.makeDim(kgrid.Nx, kgrid.dx);
                    kgrid.ky_vec = kgrid.makeDim(kgrid.Ny, kgrid.dy);

                    % define the wavenumber based on the wavenumber components
                    % (using bsxfun saves memory by avoiding ndgrid)
                    kgrid.k = zeros(kgrid.Nx, kgrid.Ny);
                    kgrid.k = bsxfun(@plus, (reshape(kgrid.kx_vec, [], 1, 1).^2), kgrid.k);
                    kgrid.k = bsxfun(@plus, (reshape(kgrid.ky_vec, 1, [], 1).^2), kgrid.k);
                    kgrid.k = sqrt(kgrid.k);

                    % define maximum supported frequency
                    kgrid.kx_max = max(abs(kgrid.kx_vec(:)));
                    kgrid.ky_max = max(abs(kgrid.ky_vec(:)));
                    kgrid.k_max = min([kgrid.kx_max, kgrid.ky_max]);

                case 3

                    % assign the grid parameters for the x ,y and z spatial directions
                    kgrid.kx_vec = kgrid.makeDim(kgrid.Nx, kgrid.dx);
                    kgrid.ky_vec = kgrid.makeDim(kgrid.Ny, kgrid.dy);
                    kgrid.kz_vec = kgrid.makeDim(kgrid.Nz, kgrid.dz);

                    % define the wavenumber based on the wavenumber components
                    % (using bsxfun saves memory by avoiding ndgrid)
                    kgrid.k = zeros(kgrid.Nx, kgrid.Ny, kgrid.Nz);
                    kgrid.k = bsxfun(@plus, (reshape(kgrid.kx_vec, [], 1, 1).^2), kgrid.k);
                    kgrid.k = bsxfun(@plus, (reshape(kgrid.ky_vec, 1, [], 1).^2), kgrid.k);
                    kgrid.k = bsxfun(@plus, (reshape(kgrid.kz_vec, 1, 1, []).^2), kgrid.k);
                    kgrid.k = sqrt(kgrid.k);

                    % define maximum supported frequency
                    kgrid.kx_max = max(abs(kgrid.kx_vec(:)));
                    kgrid.ky_max = max(abs(kgrid.ky_vec(:)));
                    kgrid.kz_max = max(abs(kgrid.kz_vec(:)));
                    kgrid.k_max = min([kgrid.kx_max, kgrid.ky_max, kgrid.kz_max]);

            end
        end
    end

    % functions for dependent variables that only run when queried
    methods

        function x = get.x(obj)
            % calculate x based on kx
            x = obj.x_size*obj.kx*obj.dx/(2*pi);
        end

        function y = get.y(obj)
            % calculate y based on ky
            y = obj.y_size*obj.ky*obj.dy/(2*pi);
        end

        function z = get.z(obj)
            % calculate z based on kz
            z = obj.z_size*obj.kz*obj.dz/(2*pi);
        end

        function kx = get.kx(obj)
            % duplicate kx vector
            switch obj.dim
                case 1
                    kx = obj.kx_vec;
                case 2
                    kx = repmat(obj.kx_vec, [1, obj.Ny]);
                case 3
                    kx = repmat(obj.kx_vec, [1, obj.Ny, obj.Nz]);
            end
        end

        function ky = get.ky(obj)
            % rotate ky vector to y direction then duplicate
            switch obj.dim
                case 1
                    ky = 0;
                case 2
                    ky = repmat(obj.ky_vec.', [obj.Nx, 1]);
                case 3
                    ky = repmat(obj.ky_vec.', [obj.Nx, 1, obj.Nz]);
            end
        end

        function kz = get.kz(obj)
            % permute kz vector to z direction then duplicate
            switch obj.dim
                case 1
                    kz = 0;
                case 2
                    kz = 0;
                case 3
                    kz = repmat(permute(obj.kz_vec, [2 3 1]), [obj.Nx, obj.Ny, 1]);
            end
        end

        function x_vec = get.x_vec(obj)
            % calculate x_vec based on kx_vec
            x_vec = obj.x_size*obj.kx_vec*obj.dx/(2*pi);
        end

        function y_vec = get.y_vec(obj)
            % calculate y_vec based on ky_vec
            y_vec = obj.y_size*obj.ky_vec*obj.dy/(2*pi);
        end

        function z_vec = get.z_vec(obj)
            % calculate z_vec based on kz_vec
            z_vec = obj.z_size*obj.kz_vec*obj.dz/(2*pi);
        end

        function x_size = get.x_size(obj)
            % calculate x_size based on Nx and dx
            x_size = obj.Nx*obj.dx;
        end

        function y_size = get.y_size(obj)
            % calculate y_size based on Ny and dy
            y_size = obj.Ny*obj.dy;
        end

        function z_size = get.z_size(obj)
            % calculate z_size based on Nz and dz
            z_size = obj.Nz*obj.dz;
        end

        function dt = get.dt(obj)
            % extract dt from the time array
            if strcmp(obj.t_array, 'auto')
                dt = 'auto';
            else
                dt = obj.t_array(2) - obj.t_array(1);
            end
        end

        function Nt = get.Nt(obj)
            % extract dt from the time array
            if strcmp(obj.t_array, 'auto')
                Nt = 'auto';
            else
                Nt = length(obj.t_array);
            end
        end

        function N = get.total_grid_points(obj)
            % calculate the total number of points in the grid
            switch obj.dim
                case 1
                    N = obj.Nx;
                case 2
                    N = obj.Nx*obj.Ny;
                case 3
                    N = obj.Nx*obj.Ny*obj.Nz;
            end
        end
    end

    % functions that can only be accessed by class members
    methods (Access = 'protected', Static = true)

        % subfunction to create the grid parameters for a single spatial direction
        function kx_vec = makeDim(Nx, dx)

            % define the discretisation of the spatial dimension such that there is
            % always a DC component
            if rem(Nx, 2) == 0
                % grid dimension has an even number of points
                nx = ((-Nx/2:Nx/2-1)/Nx).';
            else
                % grid dimension has an odd number of points
                nx = ((-(Nx-1)/2:(Nx-1)/2)/Nx).';
            end

            % force middle value to be zero in case 1/Nx is a recurring
            % number and the series doesn't give exactly zero
            nx(floor(Nx/2) + 1) = 0;

            % define the wavenumber vector components
            kx_vec = (2*pi/dx).*nx;
        end

    end

    % functions for non-uniform grids
    methods

        % subfunction to return plaid xn matrix
        function xn = get.xn(obj)
            if obj.nonuniform
                % duplicate xn vector
                switch obj.dim
                    case 1
                        xn = obj.xn_vec;
                    case 2
                        xn = repmat(obj.xn_vec, [1, obj.Ny]);
                    case 3
                        xn = repmat(obj.xn_vec, [1, obj.Ny, obj.Nz]);
                end
            else
                xn = 0;
            end
        end

        % subfunction to return plaid yn matrix
        function yn = get.yn(obj)
            if obj.nonuniform
                % rotate yn vector to y direction then duplicate
                switch obj.dim
                    case 1
                        yn = 0;
                    case 2
                        yn = repmat(obj.yn_vec.', [obj.Nx, 1]);
                    case 3
                        yn = repmat(obj.yn_vec.', [obj.Nx, 1, obj.Nz]);
                end
            else
                yn = 0;
            end
        end

        % subfunction to return plaid zn matrix
        function zn = get.zn(obj)
            if obj.nonuniform
                % permute kz vector to z direction then duplicate
                switch obj.dim
                    case 1
                        zn = 0;
                    case 2
                        zn = 0;
                    case 3
                        zn = repmat(permute(obj.zn_vec, [2 3 1]), [obj.Nx, obj.Ny, 1]);
                end
            else
                zn = 0;
            end
        end

        % subfunction to set non-uniform grid parameters in specified
        % dimension
        function obj = setNUGrid(obj, dim, xn_vec, dxudxn, xn_vec_sgx, dxudxn_sgx)

            % check the dimension to set the nonuniform grid is appropriate
            if dim > obj.dim
                error(['Cannot set nonuniform parameters for dimension ' num2str(dim) ' of ' num2str(obj.dim) '-dimensional grid']);
            end

            % force non-uniform grid spacing to be column vectors, and the
            % gradients to be in the correct direction for use with bsxfun
            switch dim
                case 1
                    obj.xn_vec = reshape(xn_vec, [], 1);
                    obj.dxudxn = reshape(dxudxn, [], 1);
                    obj.xn_vec_sgx = reshape(xn_vec_sgx, [], 1);
                    obj.dxudxn_sgx = reshape(dxudxn_sgx, [], 1);
                case 2
                    obj.yn_vec = reshape(xn_vec, [], 1);
                    obj.dyudyn = reshape(dxudxn, 1, []);
                    obj.yn_vec_sgy = reshape(xn_vec_sgx, [], 1);
                    obj.dyudyn_sgy = reshape(dxudxn_sgx, 1, []);
                case 3
                    obj.zn_vec = reshape(xn_vec, [], 1);
                    obj.dzudzn = reshape(dxudxn, 1, 1, []);
                    obj.zn_vec_sgz = reshape(xn_vec_sgx, [], 1);
                    obj.dzdzn_sgz = reshape(dxudxn_sgx, 1, 1, []);
            end

            % set non-uniform flag
            obj.nonuniform = true;

        end
    end
end


classdef nme_gen_acc_nln < mp.nme_gen_acc & mp.nme_wrapper_ac_nln

%   MATPOWER
%   Copyright (c) 2019-2020, 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
        nme_class = @mp.nme_gen_acc;
    end

    methods
        function obj = nme_gen_acc_nln()
            obj@mp.nme_gen_acc();
            obj.nme_wrapper_ac_nln_init();
        end

        function build_params(obj, nm, dm)
            build_params@mp.nme_gen_acc(obj, nm, dm);
            obj.build_nln_params(nm, dm);
        end

        function nk = count(obj, dm)
            obj.nme.count(dm);
            nk = count@mp.nme_gen_acc(obj, dm);
        end
    end     %% methods
end         %% classdef


function par = fmri_ldpar(varargin)
%
% Load specified par files for multiple runs.
%
% par = fmri_ldpar(ParFileList)
% par = fmri_ldpar(ParFile1, ParFile2, ...)
%
% ParFileList is a vertical cat of parfile names (ie, each run's'
% parfile name on a different row).
%
% ParFile format is as follows:
%   Column 1: stimulus presentation time (float or int)
%   Column 2: stimulus condition number
%   Column > 2: ignored
%
% par dimensionality: nPresentations x 2 x nRuns
%
% ras, 04/05: sorts rows by onsets, so they need not
% be specified in chronological order.
% ras, 02/06: replaced w/ mrVista tools, to fix linux \n issue.
par = [];

if(nargin == 0)
    error('USAGE: par = fmri_ldpar(ParFile)');
end

if( length(varargin) == 1)
    ParFile = varargin{1};
    nRuns = size(ParFile,1);
else
    nRuns = length(varargin);
    ParFile = '';
    for r = 1:nRuns,
        ParFile = strvcat(ParFile,varargin{r});
    end
end

% Go through each run and load par %
for r=1:nRuns,
    [onsets conds] = readParFile(deblank(ParFile(r,:)));
    par = [par; onsets(:) conds(:)];
end

return


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spherical Harmonic Modeling and Analysis Toolkit (SPHARM-MAT) is a 3D
% shape modeling and analysis toolkit.
% It is a software package developed at Shenlab in Center for Neuroimaging,
% Indiana University (SpharmMat@gmail.com, http://www.iupui.edu/~shenlab/)
% It is available to the scientific community as copyright freeware
% under the terms of the GNU General Public Licence.
%
% Copyright 2009, 2010, ShenLab, Center for Neuroimaging, Indiana University
%
% This file is part of SPHARM-MAT.
%
% SPHARM-MAT 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.
%
% SPHARM-MAT 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 SPHARM-MAT. If not, see <http://www.gnu.org/licenses/>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ============================================
% patch_color.m
%
% Goal: surface rendering with color
%       need to open figure or subplot before use
%
% Li Shen
% 02/21/2006 - create

function patch_color(vertices,faces,cdata)

patches = patch('faces', faces, 'vertices', vertices, 'FaceVertexCData', cdata, ...
		'FaceColor', 'interp', 'EdgeColor', 'k', 'FaceAlpha', 1); % transparancy can be adjusted by FaceAlpha

c = [1 1 1]*0.5;
light('Position',[ 1  0 0],'Style','infinite', 'Color', c);
light('Position',[-1  0 0],'Style','infinite', 'Color', c);
light('Position',[ 0  1 0],'Style','infinite', 'Color', c);
light('Position',[ 0 -1 0],'Style','infinite', 'Color', c);
lighting gouraud

axis image; box on; view(3);

return;


% Read a dataset captured at multiple binning factors and compression
% levels from a given directory. If simulate=true, low-resolution images
% are simulated from 1x1 binning (ground truth) data via bicubic
% downscaling.
function imageDataset = readDatasetWithMultipleBinningFactors(datasetDir, factors, compress_affix, type, createGroundTruth, simulate)

    if nargin < 4
        type = 'png';
    end
    if nargin < 5
        createGroundTruth = false;
    end

    % Read data for the different binning factors.
    for binningFactorIdx = 1:length(factors)

        if factors(binningFactorIdx) == 1 % No adaptation required for compression
            if createGroundTruth
                % Create the ground truth images by averaging over sequences of
                % consecutive frames.
                imageDataset.groundTruth = createGroundTruthImages([datasetDir, '/Bin', num2str( factors(binningFactorIdx) )], type);
            else
                % Read the ground truth from the given directory.
                frames = readImageSequence([datasetDir, '/Bin1'], ['*.', type]);
                if ~isa(frames, 'double')
                    % Convert to double.
                    frames = double(frames) / 255;
                end
                imageDataset.groundTruth = frames;
            end
        else % Adaptations required for compression
            if simulate
                gt = imageDataset.groundTruth;
                frames = zeros(size(gt,1) / factors(binningFactorIdx), size(gt,2) / factors(binningFactorIdx));
                for k = 1:size(gt,3)
                    frames(:,:,k) = imresize(gt(:,:,k), 1 / factors(binningFactorIdx));
                end
                imageDataset.(['Bin', num2str( factors(binningFactorIdx) )]) = frames;
            else
                % Read image sequence associated with the current binning factor.
                frames = readImageSequence([datasetDir, '/Bin', num2str( factors(binningFactorIdx) ),compress_affix], ['*.', type]);
                if ~isa(frames, 'double')
                    % Convert to double.
                    frames = double(frames) / 255;
                end
                imageDataset.(['Bin', num2str( factors(binningFactorIdx) )]) = frames;
            end
        end

    end


%Program for creating CSV File

%Author : Athi Narayanan S
%M.E, Embedded Systems,
%K.S.R College of Engineering
%Erode, Tamil Nadu, India.
%http://sites.google.com/site/athisnarayanan/

%Program Description
%This program generates a CSV file containing the colors in the output image.
%The CSV format is as follows
%PaletteNumber  R   G   B

function writeCSV(out_map, OutCSVName)

s = size(out_map);
fid = fopen(OutCSVName,'w');
for i=1:s(1)
    fprintf(fid,'%d,',i); %Palette No.
    for j=1:s(2)
        fprintf(fid,'%d,',double(out_map(i,j)));
    end
    fprintf(fid,'\n');
end
fclose(fid);


function [f1,colors,axh] = tor_fig(varargin)
% function [f1,colors,axh] = tor_fig(varargin)
%
% Creates a figure, hold on, fontsize 18
%
% Var args are number of rows, then columns for subplot
fs=18;
if length(varargin)>2;,varargin{3}=fs;,end

f1 = figure('Color','w'); set(gca,'FontSize',18),hold on
colors = {'ro' 'go' 'bo' 'yo' 'co' 'mo' 'ko' 'r^' 'g^' 'b^' 'y^' 'c^' 'm^' 'k^'};

if length(varargin) > 0
    i = varargin{1};
    j = varargin{2};
    np = i * j;
    for k = 1:np
        axh(k) = subplot(i,j,k);
        set(gca,'FontSize',fs),hold on
    end
    axes(axh(1));
end

return


% LFSelectFromDatabase - support function for selecting white image/calibration by matching serial/zoom/focus
%
% Usage:
%
%     SelectedCamInfo = LFSelectFromDatabase( DesiredCamInfo, DatabaseFname )
%
% This helper function is used when decoding a light field to select an appropriate white image,
% and when rectifying a light field to select the appropriate calibration. It works by parsing a
% database (white image or calibration), and searching its CamInfo structure for the best match to
% the requested DesiredCamInfo. DesiredCamInfo is set based on the camera settings used in
% measuring the light field. See LFUtilDecodeLytroFolder / LFLytroDecodeImage for example usage.
%
% Selection prioritizes the camera serial number, then zoom, then focus. It is unclear whether this
% is the optimal approach.
%
% The output SelectedCamInfo includes all fields in the database's CamInfo struct, including the
% filename of the selected calibration or white image. This facilitates decoding / rectification.
%
% User guide: LFToolbox.pdf
% See also: LFUtilProcessWhiteImages, LFUtilProcessCalibrations, LFUtilDecodeLytroFolder, LFLytroDecodeImage

% Copyright (c) 2013-2020 Donald G. Dansereau

function SelectedCamInfo = LFSelectFromDatabase( DesiredCamInfo, DatabaseFname )

%---Load the database---
load(DatabaseFname, 'CamInfo');

%---Find the closest to the desired settings, prioritizing serial, then zoom, then focus---
ValidSerial = find( ismember({CamInfo.CamSerial}, {DesiredCamInfo.CamSerial}) );

% Discard non-matching serials
CamInfo = CamInfo(ValidSerial);
OrigIdx = ValidSerial;

% Find closest zoom
ZoomDiff = abs([CamInfo.ZoomStep] - DesiredCamInfo.ZoomStep);
BestZoomDiff = min(ZoomDiff);
BestZoomIdx = find( ZoomDiff == BestZoomDiff ); % generally multiple hits

% Retain the (possibly multiple) matches for the best zoom setting
% CamInfo.ZoomStep = CamInfo(BestZoomIdx).ZoomStep;
CamInfo = CamInfo(BestZoomIdx);
OrigIdx = OrigIdx(BestZoomIdx);

% Of those that are closest in zoom, find the one that's closest in focus
FocusDiff = abs([CamInfo.FocusStep] - DesiredCamInfo.FocusStep);
[~,BestFocusIdx] = min(FocusDiff);

% Retrieve the index into the original
BestOriglIdx = OrigIdx(BestFocusIdx);
SelectedCamInfo = CamInfo(BestFocusIdx);


% This M-file is to change the settings of the LMS sensor in MATLAB to do
% the following:
% 1) Change the baudrate to 500k using RS422 communication setup via Fastcom 422/2-PCI-335 board
% 2) Permanently set this baudrate as data transfer rate for the sensor (To memorize even the power is turned off)

%% Create a serial object for MATLAB to talk with the board
s=serial('COM3','BaudRate',9600);
fopen(s)
%% At this time, switch on the Sick Sensor connected to the PC either using the RS-232 or RS-422 connection
% Read the initial response message from the LMS (30sec after the unit is turned on when the LED turns GREEN)
Initial_Response = fread(s,29,'uint8');
%% Status Request Telegram
% This telegram can be sent at any time to verify if you are able to
% communicate with the sensor.
% NOTE: A response telegram from the sensor if it starts with
% 06hex (6 decimal) indicates success
% 15hex (21 decimal) indicates failure in the sense that the sensor is unable to send any response for the telegram
Status_Chk = uint8([2 0 1 0 49 21 18]);
fwrite(s,Status_Chk);
Status_Ack = fread(s,161,'uint8');
%% Change to 500K BaudRate (high-speed mode) Telegram
Bd500k = uint8([2 0 2 0 32 72 88 8]);
fwrite(s,Bd500k);
Bd500k_Ack = fread(s,10,'uint8');
% change the board rate on the PC as well before any further communications
s.BaudRate = 9600; % the board assumes 9600 would actually correspond to highest possible BaudRate for the corresponding clock rate
%% close the serial object
fclose(s);

%% At this time, change the board settings from the PC by right clicking on
% My Computer->Properties->Hardware->Device Manager->Ports and change the clock rate to 8 MHz and check the "enable custom baudrate" option

%%  Reopen the serial object
fopen(s);
%% Change to Installation mode (password is hex SICK_LMS)
Install_Mode = uint8([2 0 10 0 32 0 83 73 67 75 95 76 77 83 190 197]);
fwrite(s,Install_Mode);
InstallMode_Ack = fread(s);
%% Set the current BaudRate as permanent
Perm_BdRate = uint8([2 0 2 0 102 1 157 78]);
fwrite(s,Perm_BdRate);
Perm_BdRate_Ack = fread(s);
%% Close the serial port object in MATLAB
fclose(s);


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

    properties
        joints
        links
        transmissions
        props
        attr
        jseq
    end

    methods
        function urdf = URDF(urdffile)
            if nargin == 0
                urdffile = 'katana_400_6m180.urdf.xacro';
            end

            dom = xmlread(urdffile);

            links = dom.getElementsByTagName('link');
            joints = dom.getElementsByTagName('joint');
            properties = dom.getElementsByTagName('property');
            robot = dom.getElementsByTagName('robot');
            urdf.attr = urdf.getattr(robot.item(0))

            % get the properties
            fprintf('%d properties\n', properties.getLength);

            Props = [];
            for k = 0:properties.getLength-1
                property = properties.item(k)
                if property.hasAttributes
                    attributes = property.getAttributes;

                    att = [];
                    for i=1:attributes.getLength

                        attribute = attributes.item(i-1);
                        n = char(attribute.getName);
                        v = char(attribute.getValue);
                        att.(n) = v
                    end
                    Props = [ Props; att];
                end
            end
            urdf.props = Props;

            % get the joints
            urdf.joints = URDF.get_elements(dom, 'joint', Props);

            % get the links
            urdf.links = URDF.get_elements(dom, 'link', Props);

            % get the transmissions
            urdf.transmissions = URDF.get_elements(dom, 'transmission', Props);

            p = zeros(1, length(urdf.links));

            for j=1:length(urdf.joints)
                    i = urdf.ln2i( urdf.joints{j}.parent.link);
                    p(i) = p(i) + 1;
                    i = urdf.ln2i( urdf.joints{j}.child.link);
                    p(i) = p(i) - 1;
            end

            [~,base_link] = max(p);
            base_link_name = urdf.links{base_link}.name;
            link = base_link_name;
            for j=1:length(urdf.joints)
                jj = urdf.findnextjoint(link);
                if isempty(jj)
                    break;
                end
                urdf.jseq(j) = jj;
                link = urdf.joints{jj}.child.link;
            end
        end

        function r = robot(urdf)
            for i=1:urdf.njoints
                % create link objects
                % attach the STL model to them
            end
            r = SerialLink(links, 'name', urdf.attr.name);
        end

        function n = nlinks(urdf)
            n = length(urdf.links);
        end

        function n = njoints(urdf)
            n = length(urdf.joints);
        end

        % map joint/link name to an index

        function joint = findnextjoint(urdf, link)
            joint = [];
            for j=1:length(urdf.joints)
                if strcmp(link, urdf.joints{j}.parent.link)
                    joint = j;
                    return
                end
            end
        end

        function idx = ln2i(urdf, name)
            idx = [];
            for i=1:length(urdf.links)
                if strcmp(urdf.links{i}.name, name)
                    idx = i;
                    return
                end
            end
        end

        function display(urdf)
            for j=1:length(urdf.joints)
                joint = urdf.joints{j};
                fprintf('j%d: %s -> %s (%s)\n', j, joint.parent.link, joint.child.link, joint.type);
            end
        end
    end

    methods (Static)
        function List = get_elements(doc, elname, props)
            elements  = doc.getElementsByTagName(elname);
            % get the links
            List = {};
            fprintf('%d %s\n', elements.getLength, elname);
            % step through the list of  elements found
            for k = 1:elements.getLength
                element = elements.item(k-1);

                info = URDF.descend(element, props);
                info = URDF.getattr(element, info, props);
                List{k} = info;
            end
        end

        function t = descend(node, props)
            if node.hasChildNodes
                t = [];

                nodeChildren = node.getChildNodes;
                for i=1:nodeChildren.getLength
                    child = nodeChildren.item(i-1);
                    if child.getNodeType == 3
                        continue;
                    end
                    result = URDF.descend(child, props);
                    if ~isempty(result)
                        n = char(child.getNodeName);
                        t.(n) = result;
                    end
                end
            elseif node.hasAttributes
                t = URDF.getattr(node, [], props);
            else
                t = [];
            end
        end

        function att = getattr(node, att, props)
            if nargin < 2
                att = [];
            end
            if nargin < 3
                props = [];
            end

            attributes = node.getAttributes;
            for i=1:attributes.getLength
                attribute = attributes.item(i-1);
                n = char(attribute.getName);
                v = char(attribute.getValue);

                % skip properties with colon in them
                n = strrep(n, ':', '_');

                %do simple xacro type substitution
                %xyz="0 0 ${-base_height}"
                if ~isempty(props)

                    % is there a ${...} substring
                    [s,e] = regexp(v, '\${[^}]*');
                    if ~isempty(s)
                        macro = v(s+2:e);
                        %fprintf('XACRO: %s --> ', v);
                        % if yes, then regexprep replace within it for every property in the list
                        for k=1:length(props)
                            macro = strrep(macro, props(k).name, props(k).value);
                        end
                        % stick the macro back into the original string
                        macro = strrep(macro, ' ', '');  % remove all blanks
                        v = [v(1:s-1) macro v(e+2:end)];
                        %fprintf('%s\n', v);
                    end
                end

                % attempt to convert it to a scalar or vector, fallback is a string
                att.(n) = str2num(v);
                if isempty( att.(n) )
                    att.(n) = v;
                end
            end
        end
    end
end


typeOfMaterial = 'ISOTROPIC';
interpolation = 'SIMP_P3';
dim = '2D';


function V = tapas_uniqc_spm_create_vol_with_tr(V)
% Create a NIfTI image volume
% FORMAT V = spm_create_vol(V)
% V        - image volume information (see spm_vol.m)
%__________________________________________________________________________
% Copyright (C) 2005-2014 Wellcome Trust Centre for Neuroimaging

% John Ashburner

for i=1:numel(V)
    v = create_vol(V(i));

    f = fieldnames(v);
    for j=1:numel(f)
        V(i).(f{j}) = v.(f{j});
    end
end

%==========================================================================
%-function V = create_vol(V)
%==========================================================================
function V = create_vol(V)

if ~isstruct(V),        error('tapas:uniqc:NotStructure', ...
        'Not a structure.'); end

if ~isfield(V,'fname'), error('tapas:uniqc:MissingField', ...
        'No "fname" field'); end

if ~isfield(V,'dim'),   error('tapas:uniqc:MissingField', ...
        'No "dim" field'); end
if ~all(size(V.dim)==[1 3])
    error('tapas:uniqc:WrongFieldSizeDim', ...
        ['"dim" field is the wrong size (' num2str(size(V.dim)) ').']);
end

if ~isfield(V,'n')
    V.n = [1 1];
else
    V.n = [V.n(:)' 1 1];
    V.n =  V.n(1:2);
end
if V.n(1)>1 && V.n(2)>1
    error('tapas:uniqc:TooManyDimensions', ...
        'Can only do up to 4D data (%s).',V.fname);
end

if ~isfield(V,'dt')
    V.dt = [spm_type('float64') spm_platform('bigend')];
end
dt{1} = spm_type(V.dt(1));
if strcmp(dt{1},'unknown')
    error('tapas:uniqc:UnrecognizedDatatype', ...
        ['"' dt{1} '" is an unrecognised datatype (' num2str(V.dt(1)) ').']);
end
if V.dt(2), dt{2} = 'BE'; else dt{2} = 'LE'; end

if ~isfield(V,'pinfo'), V.pinfo      = [Inf Inf 0]'; end
if size(V.pinfo,1)==2,  V.pinfo(3,:) = 0;            end

V.fname  = deblank(V.fname);
ext      = spm_file(V.fname,'ext');

switch ext
    case {'img'}
        minoff = 0;
    case {'nii'}
        minoff = 352; % or 544 for NIfTI-2
    otherwise
        error('tapas:uniqc:InvalidFileExtension', ...
            ['".' ext '" is not a recognised extension.']);
end
bits   = spm_type(V.dt(1),'bits');
minoff = minoff + ceil(prod(V.dim(1:2))*bits/8)*V.dim(3)*(V.n(1)-1+V.n(2)-1);
V.pinfo(3,1) = max(V.pinfo(3,:),minoff);

if ~isfield(V,'descrip'), V.descrip = '';     end
if ~isfield(V,'private'), V.private = struct; end

dim    = [V.dim(1:3) V.n];
dat    = file_array(V.fname,dim,[dt{1} '-' dt{2}],0,V.pinfo(1),V.pinfo(2));
N      = nifti;
N.dat  = dat;
N.mat  = V.mat;
N.mat0 = V.mat;
N.mat_intent  = 'Aligned';
N.mat0_intent = 'Aligned';
N.descrip = V.descrip;
%% changed by Saskia Bollmann, 25/09/2015
try N.timing = V.private.timing; end %#ok<TRYNC>
%% end

try
    N0  = nifti(V.fname);

    % Just overwrite if both are single volume files.
    tmp = [N0.dat.dim ones(1,5)];
    if prod(tmp(4:end))==1 && prod(dim(4:end))==1
        N0 = [];
    end
catch
    N0  = [];
end

if ~isempty(N0)

    % If the dimensions differ, then there is the potential for things to go badly wrong.
    tmp = [N0.dat.dim ones(1,5)];
    if any(tmp(1:3) ~= dim(1:3))
        warning('tapas:uniqc', ...
            ['Incompatible x,y,z dimensions in file "' V.fname '" [' num2str(tmp(1:3)) ']~=[' num2str(dim(1:3)) '].']);
    end
    if dim(5) > tmp(5) && tmp(4) > 1
        warning('tapas:uniqc', ...
            ['Incompatible 4th and 5th dimensions in file "' V.fname '" (' num2str([tmp(4:5) dim(4:5)]) ').']);
    end
    N.dat.dim = [dim(1:3) max(dim(4:5),tmp(4:5))];

    if ~strcmp(dat.dtype,N0.dat.dtype)
        warning('tapas:uniqc', ...
            ['Incompatible datatype in file "' V.fname '" ' N0.dat.dtype ' ~= ' dat.dtype '.']);
    end
    if single(N.dat.scl_slope) ~= single(N0.dat.scl_slope) && (size(N0.dat,4)>1 || V.n(1)>1)
        warning('tapas:uniqc', ...
            ['Incompatible scalefactor in "' V.fname '" ' num2str(N0.dat.scl_slope) '~=' num2str(N.dat.scl_slope) '.']);
    end
    if single(N.dat.scl_inter) ~= single(N0.dat.scl_inter)
        warning('tapas:uniqc', ...
            ['Incompatible intercept in "' V.fname '" ' num2str(N0.dat.scl_inter) '~=' num2str(N.dat.scl_inter) '.']);
    end
    if single(N.dat.offset) ~= single(N0.dat.offset)
        warning('tapas:uniqc', ...
            ['Incompatible intercept in "' V.fname '" ' num2str(N0.dat.offset) '~=' num2str(N.dat.offset) '.']);
    end

    if V.n(1)==1

        % Ensure volumes 2..N have the original matrix
        nt = size(N.dat,4);
        if nt>1 && sum(sum((N0.mat-V.mat).^2))>1e-8
            M0 = N0.mat;
            if ~isfield(N0.extras,'mat')
                N0.extras.mat = zeros([4 4 nt]);
            else
                if size(N0.extras.mat,4)<nt
                    N0.extras.mat(:,:,nt) = zeros(4);
                end
            end
            for i=2:nt
                if sum(sum(N0.extras.mat(:,:,i).^2))==0
                    N0.extras.mat(:,:,i) = M0;
                end
            end
            N.extras.mat = N0.extras.mat;
        end

        N0.mat = V.mat;
        if strcmp(N0.mat0_intent,'Aligned'), N.mat0 = V.mat; end
        if ~isempty(N.extras) && isstruct(N.extras) && isfield(N.extras,'mat') &&...
                size(N.extras.mat,3)>=1
            N.extras.mat(:,:,V.n(1)) = V.mat;
        end
    else
        if sum(sum((N0.mat-V.mat).^2))>1e-8
            N.extras.mat(:,:,V.n(1)) = V.mat;
        end
    end

    if ~isempty(N0.extras) && isstruct(N0.extras) && isfield(N0.extras,'mat')
        N0.extras.mat(:,:,V.n(1)) = N.mat;
        N.extras                  = N0.extras;
    end
    if sum((V.mat(:)-N0.mat(:)).^2) > 1e-4
        N.extras.mat(:,:,V.n(1)) = V.mat;
    end
end

if isfield(N.extras,'mat')
    M0 = N.mat;
    for i=1:size(N.extras.mat,3)
        if sum((M0-N.extras.mat(:,:,i)).^2) < 1e-8
            N.extras.mat(:,:,i) = 0;
        end
    end
    if sum(N.extras.mat(:).^2) < 1e-8*size(N.extras.mat,3)
        N.extras = [];
        if ~isempty(N0) && ~isempty(N0.extras) && isstruct(N0.extras) && isfield(N0.extras,'mat')
            warning('tapas:uniqc', ...
                'Forcing deletion of MAT-file.');
            spm_unlink(spm_file(N.dat.fname,'ext','mat'));
        end
    end
end

create(N);
V.private = N;


function [obX,obY,obXM,obYM,lp] = mrTransByButton(numofanats,obXM,obYM,lp,curInplane,transDelta,direction)
%NAME:    [obX,obY,obXM,obYM,lp] = mrTransByButton(numofanats,obXM,obYM,lp,curInplane,direction)
%AUTHOR:  Poirson
%DATE:	  08.04.96
%PURPOSE: One of a set of routines that allows user
%         to set and select a set of oblique planes in saggital slice.
%	  The routines are mrTransInplanes.m, mrRotInplanes.m,
%	  mrClipInplanes.m, mrSelInplane.m, mrSetupInplanes.m
%         mrSpreadInplanes.m
%HISTORY: Started with mrGetOblPlane from G. Boynton 4/6/96
%NOTES:

global sagwin
figure(sagwin)

% One more pair of points for the perpendicular line
nPtPairs = numofanats + 1;

% See if the user has already been working on some inPlanes
if size(obXM,1) == 0
	disp('You must first create a candidate set of Inplanes');
	disp('Choose Set_Up_Inplanes first');
	return
end

switch direction
  case 1
    obXM = obXM - transDelta;
  case 2
    obXM = obXM + transDelta;
  case 3
    obYM = obYM - transDelta;
  case 4
    obYM = obYM + transDelta;
end

if (curInplane ~= 0)
	obX = obXM(curInplane,:);
	obY = obYM(curInplane,:);
else
	obX = [0,0];
	obY = [0,0];
end

return

for i=1:length(lp)
  delete(lp(i));
end

for i=1:nPtPairs
  if i == curInplane
    lp(i)=line(obXM(i,:),obYM(i,:),'Color','r');
    % Set obX and obY to new values.
  else
    lp(i)=line(obXM(i,:),obYM(i,:),'Color','b');
  end
end


% MatrixUser, a multi-dimensional matrix analysis software package
% https://sourceforge.net/projects/matrixuser/
%
% The MatrixUser is a matrix analysis software package developed under Matlab
% Graphical User Interface Developing Environment (GUIDE). It features
% functions that are designed and optimized for working with multi-dimensional
% matrix under Matlab. These functions typically includes functions for
% multi-dimensional matrix display, matrix (image stack) analysis and matrix
% processing.
%
% Author:
%   Fang Liu <leoliuf@gmail.com>
%   University of Wisconsin-Madison
%   Aug-30-2014

function theStruct = MU_parseXML(dnode)
%DoParseXML(XML_filename)
%convert XML file to a MATLAB structure.

try
   tree = xmlread(dnode);
catch
   error('Failed to read XML file %s.',dnode);
end

% Recurse over child nodes. This could run into problems
% with very deeply nested trees.

theStruct = parseChildNodes(tree);
theStruct.current=1;

% ----- Subfunction PARSECHILDNODES -----
function children = parseChildNodes(theNode)
% Recurse over node children.
children = [];
if theNode.hasChildNodes
   childNodes = theNode.getChildNodes;
   numChildNodes = childNodes.getLength;
   allocCell = cell(1, numChildNodes);
   children = struct('Name', allocCell,...
                     'Attributes', allocCell,...
                     'Data', allocCell,...
                     'Children', allocCell,...
                     'current', allocCell);
    i=0;
    for count = 1:numChildNodes
        theChild = childNodes.item(count-1);
        c = makeStructFromNode(theChild);
        if isempty(c)
            i=i+1;
        else
            children(count-i) = c;
        end
    end
    if i>0
        children(numChildNodes-i+1:numChildNodes)=[];
    end
end

% ----- Subfunction MAKESTRUCTFROMNODE -----
function nodeStruct = makeStructFromNode(theNode)
% Create structure of node info.

PC=parseChildNodes(theNode);
nodeStruct = struct('Name', char(theNode.getNodeName),...
                    'Attributes', parseAttributes(theNode),...
                    'Data', '',...
                    'Children', PC,...
                    'current',0);

if any(strcmp(methods(theNode), 'getData'))
   nodeStruct.Data = char(theNode.getData);
else
   nodeStruct.Data = '';
end
if strcmp(nodeStruct.Name,'#text')
   nodeStruct=[];
end

% ----- Subfunction PARSEATTRIBUTES -----
function attributes = parseAttributes(theNode)
% Create attributes structure.
attributes = [];
if theNode.hasAttributes
   theAttributes = theNode.getAttributes;
   numAttributes = theAttributes.getLength;
   allocCell = cell(1, numAttributes);
   attributes = struct('Name', allocCell,...
                       'Value', allocCell);

   for count = 1:numAttributes
      attrib = theAttributes.item(count-1);
      attributes(count).Name = char(attrib.getName);
      attributes(count).Value = char(attrib.getValue);
   end
end


classdef ScalarGaussVariablePrinter < ResultsPrinter

    properties (Access = protected)
        simulationStr
        hasGaussData = true;
    end

    properties (Access = private)
        fieldName
    end

    methods (Access = public)

        function obj = ScalarGaussVariablePrinter(d)
            obj.init(d);
            obj.fieldName = d.fieldName;
            obj.simulationStr = [d.fieldName,'Gauss'];
        end

        function printResults(obj,iter,fileID)
            field(:,1,:) = squeeze(obj.fields)';
            dS = obj.createScalarGaussDataBase(iter,fileID,field, obj.fieldName,'OnGaussPoints');
            ScalarGaussPrinter(dS);
        end

    end

    methods (Access = protected)

        function storeFieldsToPrint(obj,d)
            obj.fields = d.fields;
        end

        function createHeadPrinter(obj,d,dh)
            obj.headPrinter = GaussHeadPrinter(d,dh);
        end

    end

end


function L = lt(p1,p2)
%PREAL/lt Overloaded LT (<) operator for class preal.

global useUnitsFlag

if ~(useUnitsFlag) % If physunits is disabled...
    L=lt(double(p1),double(p2)); % ... treat as double.
    return
end

p1=preal(p1);
p2=preal(p2);
tol=0.001;
if isscalar(p1)
    p1=preal(p1.value*ones(size(p2)),p1.units);
elseif isscalar(p2)
    p2=preal(p2.value*ones(size(p1)),p2.units);
elseif ndims(p1)==ndims(p2)&size(p1)==size(p2)
    % do nothing
else
    error('Array dimensions must agree')
end

L=false(size(p1));
for k=1:numel(L)
    if any(abs(p1(k).units-p2(k).units)>tol)
        error('Attempt to compare dimensionally inconsistent preals')
    end
    L(k)=lt(p1(k).value,p2(k).value);
end


function [sFile, ChannelMat] = in_fopen_intan(DataFile)
% IN_FOPEN_INTAN Open Intan RHS/RHD recordings
%
% DESCRIPTION:
%    Intan has 3 different ways of saving the raw file (Indicated by the AcqType variable throughout the code)
%       1. One .rhd/.rhs file for saving everything
%       2. A separate file for each channel (.dat), a .rhd/.rhs header, a separate file for each pin of the parallel port (.dat)
%       3. A separate file for each type of channel (one file for all data-files, one file for aux etc.)
%    This code supports 1 and 2.
%
%    The events are read from a parallel port, and all Digital outputs are saved in seperate files as well.
%    Information for the datatypes can be found at:
%        http://intantech.com/files/Intan_RHD2000_data_file_formats.pdf
%        http://intantech.com/files/Intan_RHS2000_data_file_formats.pdf

% @=============================================================================
% 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: Konstantinos Nasiotis 2018
%          Francois Tadel, 2019

%% ===== GET FILES =====
% Get base dataset folder
[hdr.BaseFolder, isItInfo, hdr.FileExt] = bst_fileparts(DataFile);
[filePath, fileComment] = bst_fileparts(hdr.BaseFolder);

% Check the type of file
if strcmp(isItInfo,'info')
    AcqType = 2; % One separate file per channel
else
    AcqType = 1; % One file to rule them all
end

% Get extra files
if (AcqType == 2)
    % Event files (.dat) % They are collected from a parallel port and saved as board-DIN-*.dat files
    EventFiles = dir(bst_fullfile(hdr.BaseFolder, '*DIN*.dat'));
    if isempty(EventFiles)
        disp(['BST> Warning: board-DIN-*.dat files not found in folder: ' 10 hdr.BaseFolder]);
        EventFiles = [];
    end
    % Recordings (amp*.dat)
    ampFiles = dir(bst_fullfile(hdr.BaseFolder, 'amp*.dat'));
    if isempty(ampFiles)
        error(['Could not find any amp*.dat recordings in folder: ' 10 hdr.BaseFolder]);
    end
end

%% ===== READ DATA HEADERS =====
hdr.chan_headers = {};
hdr.chan_files = {};

% Read the header
switch (hdr.FileExt)
    case '.rhd'
        newHeader = read_Intan_RHD2000_bst_2022(DataFile,1,1,1,100);
    case '.rhs'
        newHeader = read_Intan_RHS2000_bst_2018(DataFile,1,1,1,100);
end
newHeader.AcqType = AcqType; % This will be used later in in_fread_intan.m

% Check for the magic Number
if newHeader.magic_number ~= hex2dec('d69127ac') && newHeader.magic_number ~= hex2dec('c6912702')
    error('Magic Number Incorrect. The Intan header was not loaded properly');
end

% Check for some important fields
if ~isfield(newHeader, 'frequency_parameters') || ~isfield(newHeader, 'amplifier_channels') || ~isfield(newHeader, 'sample_rate')
    error('Missing fields in the file header of file');
end

% Check if all the channels' files are present
if AcqType==2
    if length(ampFiles) ~= newHeader.num_amplifier_channels
        error('Missing channel files. Check if the .dat files from all channels are present');
    end
    % Check if there are missing timestamps in the file
    % Check from the time.dat file how many samples exist, and compare with
    % every amp file that was collected
    fileinfo = dir(bst_fullfile(hdr.BaseFolder, 'time.dat'));
    num_samples_time = fileinfo.bytes/4; % int32 = 4 bytes
    for iChannel = 1:newHeader.num_amplifier_channels
        num_samples_channel = ampFiles(iChannel).bytes/2; % int32 = 4 bytes
        if (num_samples_time ~= num_samples_channel)
            error(['There are some missing blocks of recordings in file: ' ampFiles(iChannel).name]);
        end
    end
    % Read the time.dat file to extract first and last timestamp
    fid = fopen(bst_fullfile(hdr.BaseFolder, 'time.dat'), 'r');
    Time = fread(fid, num_samples_time, 'int32');
    fclose(fid);
    Time = Time / newHeader.frequency_parameters.amplifier_sample_rate; % sample rate from header file

    hdr.chan_files   = ampFiles;  % I ONLY LOAD THE AMP FILES HERE. THE AUXILIARY FILES HAVE DIFFERENT SAMPLING FREQUENCY. FIX THIS ON A LATER VERSION
    hdr.ChannelCount = length(hdr.chan_files);
    hdr.NumSamples   = num_samples_time;

else
    Time             = linspace(0,newHeader.nSamples/newHeader.sample_rate,newHeader.nSamples);
    num_samples_time = newHeader.sample_rate;
    hdr.ChannelCount = newHeader.num_amplifier_channels;
    hdr.NumSamples   = newHeader.nSamples;
end

% Extract information needed for opening the file
hdr.FirstTimeStamp        = Time(1);
hdr.LastTimeStamp         = Time(end);
hdr.SamplingFrequency     = newHeader.sample_rate;
% Save all file names
hdr.chan_headers = newHeader;
hdr.DataFile     = DataFile;

%% ===== CREATE BRAINSTORM SFILE STRUCTURE =====
% Initialize returned file structure
sFile = db_template('sfile');
% Add information read from header
sFile.byteorder = 'l';
sFile.filename  = hdr.BaseFolder;
sFile.format    = 'EEG-INTAN';
sFile.device    = 'Intan';
sFile.header    = hdr;
sFile.comment   = fileComment;
sFile.condition = fileComment;
% Consider that the sampling rate of the file is the sampling rate of the first signal
sFile.prop.sfreq = hdr.SamplingFrequency;
sFile.prop.times = [0, hdr.NumSamples - 1] ./ sFile.prop.sfreq;
sFile.prop.nAvg  = 1;
% No info on bad channels
sFile.channelflag = ones(hdr.ChannelCount, 1);

%% ===== CREATE EMPTY CHANNEL FILE =====
ChannelMat = db_template('channelmat');
ChannelMat.Comment = 'Intan channels';
ChannelMat.Channel = repmat(db_template('channeldesc'), [1, hdr.ChannelCount]);
% For each channel
for i = 1:hdr.ChannelCount
    if AcqType==2
        [fPath,fName,fExt] = bst_fileparts(hdr.chan_files(i).name);
        ChannelMat.Channel(i).Name = fName;
    else
        ChannelMat.Channel(i).Name = newHeader.amplifier_channels(i).custom_channel_name;
    end
    ChannelMat.Channel(i).Loc     = [0; 0; 0];
    ChannelMat.Channel(i).Type    = 'EEG';
    ChannelMat.Channel(i).Orient  = [];
    ChannelMat.Channel(i).Weight  = 1;
    ChannelMat.Channel(i).Comment = [];
end

%% ===== READ EVENTS =====
areThereEvents = 0;

if AcqType==2
    if ~isempty(EventFiles)
        % Read blocks of BINARY INPUT channels to create events
        parallel_input = false(num_samples_time, length(EventFiles));

        for iDIN = 1:length(EventFiles)
            fid = fopen(bst_fullfile(hdr.BaseFolder, EventFiles(iDIN).name), 'r');
            temp = fread(fid, num_samples_time, 'uint16');
            parallel_input(:,iDIN) = logical(temp);
            fclose(fid);
        end
        events_vector = bst_bi2de(parallel_input,'right-msb'); % Collapse the parallel ports to a vector that shows the events
        areThereEvents = 1;
    end
else
    if isfield(newHeader,'board_dig_in_data')
        events_vector = bst_bi2de(newHeader.board_dig_in_data,'right-msb'); % Collapse the parallel ports to a vector that shows the events
        areThereEvents = 1;
    end
end

if areThereEvents
    if bst_get('UseSigProcToolbox')
        [event_labels, event_samples] = findpeaks(events_vector);
    else
        [event_samples, event_labels] = peakseek(events_vector, min(events_vector));
        event_labels = event_labels';
        event_samples = event_samples';
    end

    % Create events list
    if ~isempty(event_labels)

        % Get list of events
        event_labels_unique = unique(event_labels); % These are still numbers

        % Initialize list of events
        events = repmat(db_template('event'), 1, length(event_labels_unique));
        % Format list
        for iEvt = 1:length(event_labels_unique)
            % Fill the event fields
            events(iEvt).label      = num2str(event_labels_unique(iEvt));
            events(iEvt).color      = rand(1,3);
            events(iEvt).reactTimes = [];
            events(iEvt).select     = 1;
            events(iEvt).times      = event_samples(event_labels == event_labels_unique(iEvt))' ./ sFile.prop.sfreq;
            events(iEvt).epochs     = ones(1, length(events(iEvt).times));    % Epoch: set as 1 for all the occurrences
            events(iEvt).channels   = [];
            events(iEvt).notes      = [];
        end
        % Import this list
        sFile = import_events(sFile, [], events);
    end
end
end

function de = bst_bi2de(bi, flg)
    if nargin < 2 || isempty(flg)
        flg = 'right-msb';
    end

    % Initialize array of powers of two
    [numElems, numDecimals] = size(bi);
    pows = zeros(numDecimals, 1);
    for iDec = 1:numDecimals
        pows(iDec) = 2 ^ (iDec - 1);
    end

    % Flip if required
    if strcmp(flg, 'left-msb')
        pows = flipud(pows);
    end

    de = bi * pows;
end


%  internal function

%  - Jimmy Shen (jimmy@rotman-baycrest.on.ca)

function save_nii_hdr(hdr, fid)

   if ~isequal(hdr.hk.sizeof_hdr,348),
      error('hdr.hk.sizeof_hdr must be 348.');
   end

   write_header(hdr, fid);

   return;					% save_nii_hdr

%---------------------------------------------------------------------
function write_header(hdr, fid)

        %  Original header structures
	%  struct dsr				/* dsr = hdr */
	%       {
	%       struct header_key hk;            /*   0 +  40       */
	%       struct image_dimension dime;     /*  40 + 108       */
	%       struct data_history hist;        /* 148 + 200       */
	%       };                               /* total= 348 bytes*/

   header_key(fid, hdr.hk);
   image_dimension(fid, hdr.dime);
   data_history(fid, hdr.hist);

   %  check the file size is 348 bytes
   %
   fbytes = ftell(fid);

   if ~isequal(fbytes,348),
      msg = sprintf('Header size is not 348 bytes.');
      warning(msg);
   end

   return;					% write_header

%---------------------------------------------------------------------
function header_key(fid, hk)

   fseek(fid,0,'bof');

	%  Original header structures
	%  struct header_key                      /* header key      */
	%       {                                /* off + size      */
	%       int sizeof_hdr                   /*  0 +  4         */
	%       char data_type[10];              /*  4 + 10         */
	%       char db_name[18];                /* 14 + 18         */
	%       int extents;                     /* 32 +  4         */
	%       short int session_error;         /* 36 +  2         */
	%       char regular;                    /* 38 +  1         */
	%       char dim_info;   % char hkey_un0;        /* 39 +  1 */
	%       };                               /* total=40 bytes  */

   fwrite(fid, hk.sizeof_hdr(1),    'int32');	% must be 348.

   % data_type = sprintf('%-10s',hk.data_type);	% ensure it is 10 chars from left
   % fwrite(fid, data_type(1:10), 'uchar');
   pad = zeros(1, 10-length(hk.data_type));
   hk.data_type = [hk.data_type  char(pad)];
   fwrite(fid, hk.data_type(1:10), 'uchar');

   % db_name   = sprintf('%-18s', hk.db_name);	% ensure it is 18 chars from left
   % fwrite(fid, db_name(1:18), 'uchar');
   pad = zeros(1, 18-length(hk.db_name));
   hk.db_name = [hk.db_name  char(pad)];
   fwrite(fid, hk.db_name(1:18), 'uchar');

   fwrite(fid, hk.extents(1),       'int32');
   fwrite(fid, hk.session_error(1), 'int16');
   fwrite(fid, hk.regular(1),       'uchar');	% might be uint8

   % fwrite(fid, hk.hkey_un0(1),    'uchar');
   % fwrite(fid, hk.hkey_un0(1),    'uint8');
   fwrite(fid, hk.dim_info(1),      'uchar');

   return;					% header_key

%---------------------------------------------------------------------
function image_dimension(fid, dime)

	%  Original header structures
	%  struct image_dimension
	%       {                                /* off + size      */
	%       short int dim[8];                /* 0 + 16          */
	%       float intent_p1;   % char vox_units[4];   /* 16 + 4       */
	%       float intent_p2;   % char cal_units[8];   /* 20 + 4       */
	%       float intent_p3;   % char cal_units[8];   /* 24 + 4       */
	%       short int intent_code;   % short int unused1;   /* 28 + 2 */
	%       short int datatype;              /* 30 + 2          */
	%       short int bitpix;                /* 32 + 2          */
	%       short int slice_start;   % short int dim_un0;   /* 34 + 2 */
	%       float pixdim[8];                 /* 36 + 32         */
	%			/*
	%				pixdim[] specifies the voxel dimensions:
	%				pixdim[1] - voxel width
	%				pixdim[2] - voxel height
	%				pixdim[3] - interslice distance
	%				pixdim[4] - volume timing, in msec
	%					..etc
	%			*/
	%       float vox_offset;                /* 68 + 4          */
	%       float scl_slope;   % float roi_scale;     /* 72 + 4 */
	%       float scl_inter;   % float funused1;      /* 76 + 4 */
	%       short slice_end;   % float funused2;      /* 80 + 2 */
	%       char slice_code;   % float funused2;      /* 82 + 1 */
	%       char xyzt_units;   % float funused2;      /* 83 + 1 */
	%       float cal_max;                   /* 84 + 4          */
	%       float cal_min;                   /* 88 + 4          */
	%       float slice_duration;   % int compressed; /* 92 + 4 */
	%       float toffset;   % int verified;          /* 96 + 4 */
	%       int glmax;                       /* 100 + 4         */
	%       int glmin;                       /* 104 + 4         */
	%       };                               /* total=108 bytes */

   fwrite(fid, dime.dim(1:8),        'int16');
   fwrite(fid, dime.intent_p1(1),  'float32');
   fwrite(fid, dime.intent_p2(1),  'float32');
   fwrite(fid, dime.intent_p3(1),  'float32');
   fwrite(fid, dime.intent_code(1),  'int16');
   fwrite(fid, dime.datatype(1),     'int16');
   fwrite(fid, dime.bitpix(1),       'int16');
   fwrite(fid, dime.slice_start(1),  'int16');
   fwrite(fid, dime.pixdim(1:8),   'float32');
   fwrite(fid, dime.vox_offset(1), 'float32');
   fwrite(fid, dime.scl_slope(1),  'float32');
   fwrite(fid, dime.scl_inter(1),  'float32');
   fwrite(fid, dime.slice_end(1),    'int16');
   fwrite(fid, dime.slice_code(1),   'uchar');
   fwrite(fid, dime.xyzt_units(1),   'uchar');
   fwrite(fid, dime.cal_max(1),    'float32');
   fwrite(fid, dime.cal_min(1),    'float32');
   fwrite(fid, dime.slice_duration(1), 'float32');
   fwrite(fid, dime.toffset(1),    'float32');
   fwrite(fid, dime.glmax(1),        'int32');
   fwrite(fid, dime.glmin(1),        'int32');

   return;					% image_dimension

%---------------------------------------------------------------------
function data_history(fid, hist)

	% Original header structures
	%struct data_history
	%       {                                /* off + size      */
	%       char descrip[80];                /* 0 + 80          */
	%       char aux_file[24];               /* 80 + 24         */
	%       short int qform_code;            /* 104 + 2         */
	%       short int sform_code;            /* 106 + 2         */
	%       float quatern_b;                 /* 108 + 4         */
	%       float quatern_c;                 /* 112 + 4         */
	%       float quatern_d;                 /* 116 + 4         */
	%       float qoffset_x;                 /* 120 + 4         */
	%       float qoffset_y;                 /* 124 + 4         */
	%       float qoffset_z;                 /* 128 + 4         */
	%       float srow_x[4];                 /* 132 + 16        */
	%       float srow_y[4];                 /* 148 + 16        */
	%       float srow_z[4];                 /* 164 + 16        */
	%       char intent_name[16];            /* 180 + 16        */
	%       char magic[4];   % int smin;     /* 196 + 4         */
	%       };                               /* total=200 bytes */

   % descrip     = sprintf('%-80s', hist.descrip);     % 80 chars from left
   % fwrite(fid, descrip(1:80),    'uchar');
   pad = zeros(1, 80-length(hist.descrip));
   hist.descrip = [hist.descrip  char(pad)];
   fwrite(fid, hist.descrip(1:80), 'uchar');

   % aux_file    = sprintf('%-24s', hist.aux_file);    % 24 chars from left
   % fwrite(fid, aux_file(1:24),   'uchar');
   pad = zeros(1, 24-length(hist.aux_file));
   hist.aux_file = [hist.aux_file  char(pad)];
   fwrite(fid, hist.aux_file(1:24), 'uchar');

   fwrite(fid, hist.qform_code,    'int16');
   fwrite(fid, hist.sform_code,    'int16');
   fwrite(fid, hist.quatern_b,   'float32');
   fwrite(fid, hist.quatern_c,   'float32');
   fwrite(fid, hist.quatern_d,   'float32');
   fwrite(fid, hist.qoffset_x,   'float32');
   fwrite(fid, hist.qoffset_y,   'float32');
   fwrite(fid, hist.qoffset_z,   'float32');
   fwrite(fid, hist.srow_x(1:4), 'float32');
   fwrite(fid, hist.srow_y(1:4), 'float32');
   fwrite(fid, hist.srow_z(1:4), 'float32');

   % intent_name = sprintf('%-16s', hist.intent_name);	% 16 chars from left
   % fwrite(fid, intent_name(1:16),    'uchar');
   pad = zeros(1, 16-length(hist.intent_name));
   hist.intent_name = [hist.intent_name  char(pad)];
   fwrite(fid, hist.intent_name(1:16), 'uchar');

   % magic	= sprintf('%-4s', hist.magic);		% 4 chars from left
   % fwrite(fid, magic(1:4),           'uchar');
   pad = zeros(1, 4-length(hist.magic));
   hist.magic = [hist.magic  char(pad)];
   fwrite(fid, hist.magic(1:4),        'uchar');

   return;					% data_history


function com = pop_topohistplot( EEG, typeplot, components, topotitle, rowcols, varargin);

com = '';
if nargin < 1
    help pop_topoplot;
    return;
end;
if nargin < 2
    typeplot = 1;
end;
if typeplot == 0 & isempty(EEG.icasphere)
    disp('Error: no ICA data for this set, first run ICA or Load AMICA components'); return;
end;
if isempty(EEG.chanlocs)
    disp('Error: cannot plot topography without channel location file'); return;
end;
if ~isfield(EEG.etc,'amica') || isempty(EEG.etc.amica)
    error('No AMICA solution found. You should first load AMICA components');return;
end

if nargin < 3
    % which set to save
    % -----------------
    if typeplot
        txtwhat2plot1 = 'Plotting ERP scalp maps at these latencies';
        txtwhat2plot2 = sprintf('(range: %d to %d ms, NaN -> empty):', ...
            round(EEG.xmin*1000), round(EEG.xmax*1000));
        editwhat2plot = [''];
    else
        txtwhat2plot1 = 'Component numbers';
        txtwhat2plot2 = '(negate index to invert component polarity; NaN -> empty subplot; Ex: -1 NaN 3)';
        editwhat2plot = ['1:' int2str(size(EEG.icaweights,1))];
    end;
    allmodels = 1:EEG.etc.amica.num_models;

    if ~isfield(EEG.etc.amica,'modnames')
        EEG.etc.amica.modnames{length(allmodels)} = '';
    end

    str = [num2str(allmodels(1)) fastif(~isempty(EEG.etc.amica.modnames{1}) ,[' - ' EEG.etc.amica.modnames{1}],'')];
    for i = 2:EEG.etc.amica.num_models
        str = [str '|' num2str(allmodels(i)) fastif(~isempty(EEG.etc.amica.modnames{i}) ,[' - ' EEG.etc.amica.modnames{i}],'')];
    end
    editwhat2select = str;

    if EEG.nbchan > 64,
        elecdef = ['''electrodes'', ''off'''];
    else,
        elecdef = ['''electrodes'', ''on'''];
    end;
    cb_enable = ['set(findobj(''parent'', gcbf, ''tag'', ''block'')    , ''enable'', ''on'');'];
    cb_disable = ['set(findobj(''parent'', gcbf, ''tag'', ''block'')    , ''enable'', ''off'');'];
    cb_block = ['if get(gcbo,''value''),' cb_enable ...
        'else,' cb_disable ...
        'end;'];
    cb_chosen = ['m = get(gcbo,''value''); set(findobj(''parent'',gcbf,''tag'',''title''),''string'',[EEG.setname '', Model '' num2str(m)])'];

    %EEG.etc.amica
    uilist = { { 'style'   'text'     'string'    txtwhat2plot1 } ...
        { 'style'   'edit'     'string'    editwhat2plot } ...
        { 'style'   'text'     'string'    txtwhat2plot2 } ...
        { } ...
        {'style' 'text' 'string' 'Select AMICA model'} ...
        {'style' 'popupmenu' 'string' editwhat2select 'value' 1 'callback' cb_chosen} ...
        { 'style'   'text'     'string'    'Plot title' } ...
        { 'style'   'edit'     'tag' 'title' 'string'    fastif(~isempty(EEG.setname), [EEG.setname ', Model 1'], '') } ...
        { 'style'   'text'     'string'    'Plot geometry (rows,col.); [] -> near square' } ...
        { 'style'   'edit'     'string'    '[]' } ...
        { 'style'   'text'     'string'    'Plot associated dipole(s) (if present)' } ...
        { 'style'   'checkbox' 'string'    '' } { } ...
        { } ...
        { 'style'   'text'     'string'    [ '-> Additional topoplot()' fastif(typeplot,'',' (and dipole)') ...
        ' options (see Help)' ] } ...
        { 'style'   'edit'     'string'    elecdef } ...
        {'style' 'checkbox' 'string' 'Show IC histograms' 'value' 1 'callback' cb_block} ...
        {'style' 'checkbox' 'tag' 'block' 'string' 'Use block analysis when determining histogram range' 'enable' 'on'}};
    uigeom = { [1.5 1] [1] [1] [1 1] [1.5 1] [1.5 1] [1.55 0.2 0.8] [1] [1] [1] [1] [1]};
    if typeplot
        uilist(9:11) = [];
        uigeom(6) = [];
    end;
    guititle = fastif( typeplot, 'Plot ERP scalp maps in 2-D -- pop_topoplot()', ...
        'Plot AMICA component scalp maps in 2-D -- pop_topohistplot()');

    result = inputgui( uigeom, uilist, 'pophelp(''pop_topoplot'')', guititle, [], 'normal');
    if isempty(result)
        return;
    end

    % reading first param
    % -------------------
    components   	     = eval( [ '[' result{1} ']' ] );
    if length(components) > EEG.nbchan
        tmpbut = questdlg2(...
            ['This involves drawing ' int2str(length(components)) ' plots. Continue ?'], ...
            '', 'Cancel', 'Yes', 'Yes');
        if strcmp(tmpbut, 'Cancel'), return; end;
    end;
    if isempty(components), error('Nothing to plot; enter parameter in first edit box'); end;

    % reading other params
    % --------------------
    h = result{2}; % chosen AMICA model
    topotitle   = result{3};
    rowcols     = eval( [ '[' result{4} ']' ] );
    options = [];
    if typeplot
        plotdip = 0;
        try, options      = eval( [ '{ ' result{5} ' }' ]);
        catch, error('Invalid scalp map options'); end;
    else
        plotdip     = result{5};
        try, options      = eval( [ '{ ' result{6} ' }' ]);
        catch, error('Invalid scalp map options'); end;
    end;
    if length(components) == 1,
        figure('paperpositionmode', 'auto'); curfig=gcf;
        try, icadefs;
            set(curfig, 'color', BACKCOLOR);
        catch, end;
    end;
    showhist = result{7};
    use_block = result{8};
    options = {options{:} 'showhist' showhist 'use_block' use_block 'model' h};
else
    if ~isempty(varargin) & isnumeric(varargin{1})
        plotdip = varargin{1};
        varargin = varargin(2:end);
    else
        plotdip = 0;
    end;
    options = varargin;
end;

% additional options
% ------------------
outoptions = { options{:} }; % for command
options    = { options{:} 'masksurf' 'on' };

% find maplimits
% --------------
maplimits = [];
for i=1:2:length(options)
    if isstr(options{i})
        if strcmpi(options{i}, 'maplimits')
            maplimits = options{i+1};
            options(i:i+1) = [];
            break;
        end;
    end;
end;

%--------------Added for IC histogram plotting--------------------------
for i=1:2:length(options)
    if isstr(options{i})
        if strcmpi(options{i}, 'showhist')
            showhist = options{i+1};
            options(i:i+1) = [];
            break;
        end;
    end;
end;

for i=1:2:length(options)
    if isstr(options{i})
        if strcmpi(options{i}, 'use_block')
            use_block = options{i+1};
            options(i:i+1) = [];
            break;
        end;
    end;
end;

for i=1:2:length(options)
    if isstr(options{i})
        if strcmpi(options{i}, 'model')
            h = options{i+1};
            options(i:i+1) = [];
            break;
        end;
    end;
end;
if ~exist('h','var')
    h = 1;
end
% ----------------------------------------------------------------------

nbgraph = size(components(:),1);
if ~exist('topotitle')
    topotitle = '';
end;
if ~exist('rowcols') | isempty(rowcols) | rowcols == 0
    rowcols(2) = ceil(sqrt(nbgraph));
    rowcols(1) = ceil(nbgraph/rowcols(2));
end;

SIZEBOX = 150;

fprintf('Plotting...\n');
if isempty(EEG.chanlocs)
    fprintf('Error: set has no channel location file\n');
    return;
end;

% Check if pop_topoplot input 'colorbar' was called, and don't send it to topoplot
loc = strmatch('colorbar', options(1:2:end), 'exact');
loc = loc*2-1;
if ~isempty(loc)
    colorbar_switch = strcmp('on',options{ loc+1 });
    options(loc:loc+1) = [];
else
    colorbar_switch = 1;
end

% determine the scale for plot of different times (same scales)
% -------------------------------------------------------------
if typeplot
    SIGTMP = reshape(EEG.data, EEG.nbchan, EEG.pnts, EEG.trials);
    pos = round( (components/1000-EEG.xmin)/(EEG.xmax-EEG.xmin) * (EEG.pnts-1))+1;
    nanpos = find(isnan(pos));
    pos(nanpos) = 1;
    SIGTMPAVG = mean(SIGTMP(:,pos,:),3);
    SIGTMPAVG(:, nanpos) = NaN;
    if isempty(maplimits)
        maxlim = max(SIGTMPAVG(:));
        minlim = min(SIGTMPAVG(:));
        maplimits = [ -max(maxlim, -minlim) max(maxlim, -minlim)];
    end;
else
    if isempty(maplimits)
        maplimits = 'absmax';
    end;
end;

if plotdip
    if strcmpi(EEG.dipfit.coordformat, 'CTF')
        disp('Cannot plot dipole on scalp map for CTF MEG data');
    end;
end;

%Calculate the winv matrix for the model chosen
A = pinv(EEG.etc.amica.W(:,:,h)*EEG.etc.amica.S);
%------------------------------------------------

% plot the graphs
% ---------------
counter = 1;
countobj = 1;
allobj = zeros(1,1000);
curfig = get(0, 'currentfigure');
if isfield(EEG, 'chaninfo'), options = { options{:} 'chaninfo' EEG.chaninfo }; end

if showhist

    alpha = EEG.etc.amica.alpha;
    sbeta = EEG.etc.amica.sbeta;
    rho = EEG.etc.amica.rho;
    mu = EEG.etc.amica.mu;
    nbgraph = length(components);
    mn = EEG.etc.amica.data_mean;
    x = EEG.data;

    models = EEG.etc.amica;
    if EEG.trials>1
        x = reshape(x,EEG.nbchan,EEG.trials*EEG.pnts);
        models.LLt = reshape(models.LLt,EEG.etc.amica.num_models,size(models.LLt,2)*size(models.LLt,3));
    end
    if max(size(models.LLt)) > 1
        indx = find(models.LLt(1,:)~=0);
        lim = find(indx>size(x,2));
        if ~isempty(lim)
            indx = indx(1:lim(1)-1);
        end
        x = x(:,indx);
        models.LLt = models.LLt(:,indx);
    end
    [nx,N] = size(x);
    n = size(models.c,1);
    B = 1000;
    num_blocks = floor(N/B);
    nbins = min(100,sqrt(N));
    [mval,mind] = max(models.LLt);
    n = size(models.c,1);
    s = zeros(n,N);
    disp('Sphering the data...')
    if use_block

        % sphere the data

        for k = 1:num_blocks
            xstrt = (k-1)*B + 1;
            if k < num_blocks
                xstp = k*B;
            else
                xstp = N;
            end
            for i = 1:nx
                x(i,xstrt:xstp) = x(i,xstrt:xstp) - mn(i);
                %x(i,xstrt:xstp) = s(1,xstrt:xstp) - mn(i);
            end
            x(1:n,xstrt:xstp) = models.S(1:n,:) * x(:,xstrt:xstp);
        end

        for k = 1:num_blocks
            xstrt = (k-1)*B + 1;
            if k < num_blocks
                xstp = k*B;
            else
                xstp = N;
            end
            s(components,xstrt:xstp) = models.W(components,:,h) * x(1:n,xstrt:xstp);
            for i = components
                s(i,xstrt:xstp) = s(i,xstrt:xstp) - models.c(i,h);
            end
        end

    else
        for i = 1:nx
            x(i,:) = x(i,:) - mn(i);
            %x(i,xstrt:xstp) = s(1,xstrt:xstp) - mn(i);
        end

        x(1:n,:) = models.S(1:n,:) * x(:,:);

        s(components,:) = models.W(components,:,h) * x(1:n,:);
        for i = components
            s(i,:) = s(i,:) - models.c(i,h);
        end

    end

end

for index = 1:size(components(:),1)
    if nbgraph > 1
        if mod(index, rowcols(1)*rowcols(2)) == 1

            if index> 1, figure(curfig); a = textsc(0.5, 0.05, topotitle); set(a, 'fontweight', 'bold'); end;
            curfig = figure('paperpositionmode', 'auto');
            pos = get(curfig,'Position');

            posx = max(0, pos(1)+(pos(3)-SIZEBOX*rowcols(2))/2);

            posy = pos(2)+pos(4)-SIZEBOX*rowcols(1);
            if showhist

                set(curfig,'Position', [posx posy  2*SIZEBOX*rowcols(2)  SIZEBOX*rowcols(1)]);
            else
                set(curfig,'Position', [posx posy  SIZEBOX*rowcols(2)  SIZEBOX*rowcols(1)]);
            end
            try, icadefs; set(curfig, 'color', BACKCOLOR); catch, end;
        end;

        if showhist
            curax = subplot( rowcols(1), 2*rowcols(2), 2*mod(index-1, rowcols(1)*rowcols(2))+1,'parent',curfig);
        else
            curax = subplot( rowcols(1), rowcols(2), mod(index-1, rowcols(1)*rowcols(2))+1,'parent',curfig);
        end
        set(curax, 'visible', 'off')
        if index == 1
            constantPosition = get(curax,'position');
        end

    else
        if showhist
            curax = subplot(1,2,1);
            set(curax,'visible','off')
        end

    end

    % add dipole location if present
    % ------------------------------
    dipoleplotted = 0;
    if plotdip && typeplot == 0
        if isfield(EEG, 'dipfit') & isfield(EEG.dipfit, 'model')
            if length(EEG.dipfit.model) >= index & ~strcmpi(EEG.dipfit.coordformat, 'CTF')
                %curpos = EEG.dipfit.model(components(index)).posxyz/EEG.dipfit.vol.r(end);
                curpos = EEG.dipfit.model(components(index)).posxyz;
                curmom = EEG.dipfit.model(components(index)).momxyz;
                try,
                    select = EEG.dipfit.model(components(index)).select;
                catch ,
                    select = 0;
                end;
                if ~isempty(curpos)
                    if strcmpi(EEG.dipfit.coordformat, 'MNI') % from MNI to sperical coordinates
                        transform = pinv( sph2spm );
                        tmpres = transform * [ curpos(1,:) 1 ]'; curpos(1,:) = tmpres(1:3);
                        tmpres = transform * [ curmom(1,:) 1 ]'; curmom(1,:) = tmpres(1:3);
                        try, tmpres = transform * [ curpos(2,:) 1 ]'; curpos(2,:) = tmpres(1:3); catch, end;
                        try, tmpres = transform * [ curmom(2,:) 1 ]'; curmom(2,:) = tmpres(1:3); catch, end;
                    end;
                    curpos = curpos / 85;
                    if size(curpos,1) > 1 && length(select) == 2

                        dipole_index = find(strcmpi('dipole',options),1);
                        if  ~isempty(dipole_index) % if 'dipoles' is already defined in options{:}
                            options{dipole_index+1} = [ curpos(:,1:2) curmom(:,1:3) ];
                        else
                            options = { options{:} 'dipole' [ curpos(:,1:2) curmom(:,1:3) ] };
                        end
                        dipoleplotted = 1;
                    else
                        if any(curpos(1,:) ~= 0)
                            dipole_index = find(strcmpi('dipole',options),1);
                            if  ~isempty(dipole_index) % if 'dipoles' is already defined in options{:}
                                options{dipole_index+1} = [ curpos(1,1:2) curmom(1,1:3) ];
                            else
                                options = { options{:} 'dipole' [ curpos(1,1:2) curmom(1,1:3) ] };
                            end
                            dipoleplotted = 1;
                        end
                    end

                end
                if nbgraph ~= 1
                    dipscale_index = find(strcmpi('dipscale',options),1);
                    if ~isempty(dipscale_index) % if 'dipscale' is already defined in options{:}
                        options{dipscale_index+1} = 0.6;
                    else
                        options = {  options{:} 'dipscale' 0.6 };
                    end
                end
                %options = { options{:} 'dipsphere' max(EEG.dipfit.vol.r) };
            end
        end
    end
    %curax = subplot( rowcols(1), 2*rowcols(2), 2*mod(index-1, rowcols(1)*rowcols(2))+1);
    % plot scalp map
    % --------------
    if index == 1
        addopt = { 'verbose', 'on' };
    else
        addopt = { 'verbose', 'off' };
    end;
    %fprintf('Printing to figure %d.\n',curfig);
    options = {  'maplimits' maplimits options{:} addopt{:} };
    if ~isnan(components(index))
        if typeplot
            if nbgraph > 1, axes(curax); end;
            tmpobj = topoplot( SIGTMPAVG(:,index), EEG.chanlocs, options{:});
            if nbgraph == 1,
                figure(curfig); if nbgraph > 1, axes(curax); end;
                title( [ 'Latency ' int2str(components(index)) ' ms from ' topotitle]);
            else
                figure(curfig); if nbgraph > 1, axes(curax); end;
                title([int2str(components(index)) ' ms'] );
            end;
        else
            if components(index) < 0
                figure(curfig);  if nbgraph > 1, axes(curax); end;
                tmpobj = topoplot( -A(:, -components(index)), EEG.chanlocs, options{:} );
            else
                figure(curfig);  if nbgraph > 1, axes(curax); end;
                tmpobj = topoplot( A(:, components(index)), EEG.chanlocs, options{:} );
            end;
            if nbgraph == 1, texttitle = [ 'IC ' int2str(components(index)) ' from ' topotitle];
            else             texttitle = ['' int2str(components(index))];
            end;
            if dipoleplotted, texttitle = [ texttitle ' (' num2str(EEG.dipfit.model(components(index)).rv*100,2) '%)']; end;
            figure(curfig);  if nbgraph > 1, axes(curax); end; title(texttitle);
        end;
        allobj(countobj:countobj+length(tmpobj)-1) = tmpobj;
        countobj = countobj+length(tmpobj);
        pos = get(curax,'position');

        set(curax,'position',[pos(1) pos(2) constantPosition(3) constantPosition(4)]);
        drawnow;
        axis square;
    else
        axis off
    end;

    % plot IC histogram
    % --------------------------

    if showhist

        if EEG.etc.amica.num_models > 1
            inds = find(mind == h);
            if ~isempty(inds)
                smn = mean(s(components(index),inds));
                [~,b] = hist(s(components(index),inds)-smn,nbins);

            else
                b = -10:0.01:10;

            end
        else
            [~,b] = hist(s(components(index),:),nbins);
        end

        if nbgraph > 1
            subplot(rowcols(1),2*rowcols(2),2*index,'parent',curfig);
        else
            subplot(1,2,2,'parent',curfig);
        end
        hold on
        sum = 0;
        for j = 1:size(alpha,1)
            mixtpdf = alpha(j,components(index),h)*sbeta(j,components(index),h)*(1/(2*gamma(1+1/rho(j,components(index),h))))*exp(-abs(sbeta(j,components(index),h)*(b-mu(j,components(index),h))).^rho(j,components(index),h));
            if ~isnan(mixtpdf)
                sum = mixtpdf + sum;
                plot(b,mixtpdf,'g');
            end
        end

        plot(b,sum,'b');

        drawnow;
    end
    % ---------------------------------------------
end

% Draw colorbar
if colorbar_switch
    if nbgraph == 1
        if ~isstr(maplimits)
            ColorbarHandle = cbar(0,0,[maplimits(1) maplimits(2)]);
        else
            ColorbarHandle = cbar(0,0,get(gca, 'clim'));
        end;
        pos = get(ColorbarHandle,'position');  % move left & shrink to match head size
        if showhist %if IC histogram is also plotted
            set(ColorbarHandle,'position',[pos(1)+.02 pos(2)+0.13 pos(3)*0.7 pos(4)-0.26]);
        else
            set(ColorbarHandle,'position',[pos(1)-.05 pos(2)+0.13 pos(3)*0.7 pos(4)-0.26]);
        end
    elseif ~isstr(maplimits)
        cbar('vert',0,[maplimits(1) maplimits(2)]);
    else cbar('vert',0,get(gca, 'clim'));
    end
    if ~typeplot    % Draw '+' and '-' instead of numbers for colorbar tick labels
        tmp = get(gca, 'ytick');
        set(gca, 'ytickmode', 'manual', 'yticklabelmode', 'manual', 'ytick', [tmp(1) tmp(end)], 'yticklabel', { '-' '+' });
    end
end

if nbgraph> 1,
    figure(curfig); a = textsc(0.5, 0.05, topotitle);
    set(a, 'fontweight', 'bold');
end;
if nbgraph== 1,
    com = 'figure;';
end;
set(allobj(1:countobj-1), 'visible', 'on');

figure(curfig);
axcopy(curfig, 'set(gcf, ''''units'''', ''''pixels''''); postmp = get(gcf, ''''position''''); set(gcf, ''''position'''', [postmp(1) postmp(2) 560 420]); clear postmp;');

com = [com sprintf('pop_topohistplot(%s,%d, %s);', ...
    inputname(1), typeplot, vararg2str({components topotitle rowcols plotdip outoptions{:} }))];
disp('Done.');
return;


% Authors: A. Iscen, G. Tolias, Y. Avrithis, T. Furon, O. Chum. 2017.
% find index for the truncated affinity
function f = findtrunc(v, qv, k, imids)

   [knn, ~] = knn_wrap(v, qv, k,100);
   f = find(ismember(imids,knn));


% The COBRAToolbox: testSimpleOptKnock.m
%
% Purpose:
%     - test the simpleOptKnock function
%
% Authors:
%     - Jacek Wachowiak
global CBTDIR
% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testSimpleOptKnock'));
cd(fileDir);

% test variables
model = getDistributedModel('ecoli_core_model.mat');
targetRxn = model.rxns(20); % 'EX_ac(e)'

% function outputs
[wtRes, delRes] = simpleOptKnock(model, targetRxn);
[wtRes2, delRes2] = simpleOptKnock(model, targetRxn, model.genes(1), 1, 0.5, 1);

% tests
assert(abs(12.1585 - delRes.maxProd(23)) < 1e-4); % 'EX_co2(e)'
assert(abs(14.3123 - delRes.maxProd(12)) < 1e-4);% 'ATPS4r'
assert(abs(12.1584 - delRes.minProd(14)) < 1e-4);% 'CO2t'
assert(abs(8.5036 - delRes.minProd(16)) < 1e-4);% 'CYTBD'
assert(abs(0.8739 - wtRes.growth) < 1e-4);% always the same
%for gene deletions
assert(abs(0.8739 - wtRes2.growth) < 1e-4);% always the same
assert(abs(3e-07 - delRes2.maxProd) < 1e-4);
assert(abs(delRes2.minProd) < 1e-4);

% change to old directory
cd(currentDir);


%  INTERNAL FUNCTION: makes to vectors have the same minimum and maximum
%
%  ::
%
%    new=apply_range(type,refv,newv)
%
%  Args:
%
%     - **refv** [vector]: reference vector
%     - **newv** [vector]: vector to modify
%
%  Returns:
%     :
%
%     - **newv** [vector]: modified vector
%
%


function showsolutionP2(node,elem,u)

[node,elem] = uniformrefine(node,elem);
showsolution(node,elem,u);


function images = loadPRFsize(vw, images, curSlice)
%
% load 'ecc' into images.M1 and 'pRF size' into images.M3 field (ecc is
% reloaded since it was scaled to 0-2pi at the initial loading)
%
% images = loadPRFsize(vw, images, curSlice)

global dataTYPES

if notDefined('vw'), vw=getCurView;  end
if notDefined('images'), error('images should be defined');  end
if notDefined('curSlice'), curSlice = viewGet(vw, 'Current Slice'); end

for i=1:size(dataTYPES,2)
    if strcmp(dataTYPES(i).name, 'Averages')
        vw.curDataType = i;
    end
end
vw = selectDataType(vw,vw.curDataType);
vw = loadCorAnal(vw);

% reload ecc (initially loaded ecc was scaled into the range
% between 0 and 2*pi for atlas fitting)
images.M1=vw.map{1}(:,:,curSlice);
% load pRF size
images.M3=vw.amp{1}(:,:,curSlice);


% KEVALS - Returns the number of kernel evaluations
%
% Syntax: kernel_evals = kevals();
%
% Version 3.22e -- Comments to diehl@alumni.cmu.edu
%

function kernel_evals = kevals();

global kernel_evals;

if (isempty(kernel_evals))
   kernel_evals = 0;
end;


%% housekeeping
close all
clear
clc

%% It just amounts to adding a keyword in the parameter list

he=rise('hybrid_expect');

%%
he=solve(he);


function so = subStreams(s1,s2)
% SUBSTREAMS  Subtract streams
so = streamCompose({s1,s2},@subVals);

function ris = subVals(v1,v2)
ris = v1-v2;


% fixedSegmentation = removeBridgesMex(segmentation, anatomicalData,
%			 averageWhiteIntensity, thresholdIntensity, averageGrayIntensity)
%
% Mex function implementing the bridge removal algorithm described
% in Kriegeskorte & Goebel (2001) An Efficient Algorithm for
% Topologically Correct Segmentation of the Cortical Sheet in Anatomical
% MR Volumes. Neuroimage, 14, 329-346.
%
% To compile, try:
% mex removeBridgesMex.cpp CRemoveBridges.cpp
%
% On linux, this might make faster code:
% mex -O COPTIMFLAGS='-O3 -march=i686 -DNDEBUG' removeBridgesMex.cpp CRemoveBridges.cpp
%
% HISTORY (from the source code):
% 2002.08.?? Niko & Rainer kindly gave us their code from BrainVoyager.
% 2002.09.?? Ian Spiro modified the BV code to build a DLL that takes
%            data rather than filenames. He also wrote a simple mex wrapper
%            to call this DLL.
% 2002.11.13 Bob Dougherty: overhauled the code to make it cleaner (no more
%            globals!) and platform-independent. To do this, I had to remove
%            all the GUI stuff and the threading. The code now runs serially
%            and uses printf for progress reporting (although this can be
%            easily changed by modifying the updateProgress method). I also
%            wrote a mex wrapper for this class.