function CPD = root_CPD(bnet, self, val)
% ROOT_CPD Make a conditional prob. distrib. which has no parameters.
% CPD = ROOT_CPD(BNET, NODE_NUM, VAL)
%
% The node must not have any parents and is assumed to always be observed.
% It is a way of modelling exogenous inputs to a model.
% VAL is the value to which the root is clamped (default: [])

if nargin==0
  % This occurs if we are trying to load an object from a file.
  CPD = init_fields;
  CPD = class(CPD, 'root_CPD', generic_CPD(1));
  return;
elseif isa(bnet, 'root_CPD')
  % This might occur if we are copying an object.
  CPD = bnet;
  return;
end
CPD = init_fields;

if nargin < 3, val = []; end

ns = bnet.node_sizes;
ps = parents(bnet.dag, self);
if ~isempty(ps)
  error('root CPDs should have no parents')
end

CPD.self = self;
CPD.val = val;
CPD.sizes = ns(self);

clamped = 1;
CPD = class(CPD, 'root_CPD', generic_CPD(clamped));

%%%%%%%%%%%

function CPD = init_fields()
% This ensures we define the fields in the same order
% no matter whether we load an object from a file,
% or create it from scratch. (Matlab requires this.)

CPD.self = [];
CPD.val = [];
CPD.sizes = [];


function S3G = copy(S3G,ind)
% copy nodes by indece
%
% Input
%  S3G    - @SO3Grid
%  indece - int32
%
% See also
%  EBSD/delete EBSD/subGrid

 S3G.a = S3G.a(ind);
 S3G.b = S3G.b(ind);
 S3G.c = S3G.c(ind);
 S3G.d = S3G.d(ind);
 S3G.i = S3G.i(ind);

 S3G.gamma = subGrid(S3G.gamma,ind);
 S3G.alphabeta  = subGrid(S3G.alphabeta,GridLength(S3G.gamma)>0);
 S3G.gamma(GridLength(S3G.gamma)==0) = [];


function [pvec, pstruct] = tapas_bayes_optimal_categorical_transp(r, ptrans)
% --------------------------------------------------------------------------------------------------
% Copyright (C) 2012-2013 Christoph Mathys, TNU, UZH & ETHZ
%
% This file is part of the HGF toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

% This is a dummy function

pvec    = [];
pstruct = struct;

return;


function imdb_cnn_train(imdb, opts, varargin)
% Train a CNN model on a dataset supplied by imdb

opts.lite = false ;
opts.numFetchThreads = 0 ;
opts.train.batchSize = opts.batchSize ;
opts.train.numEpochs = 25 ;
opts.train.continue = true ;
opts.train.useGpu = true ;
opts.train.prefetch = false ;
opts.train.learningRate = [0.001*ones(1, 10) 0.0001*ones(1, 10) 0.00001*ones(1,10)] ;
opts.train.expDir = opts.expDir ;
opts = vl_argparse(opts, varargin) ;

% -------------------------------------------------------------------------
%                                                    Network initialization
% -------------------------------------------------------------------------

net = initializeNetwork(imdb, opts) ;

% Initialize average image
if isempty(net.meta.normalization.averageImage),
    % compute the average image
    averageImagePath = fullfile(opts.expDir, 'average.mat') ;
    if exist(averageImagePath, 'file')
      load(averageImagePath, 'averageImage') ;
    else
      train = find(imdb.images.set == 1) ;
      bs = 256 ;
      fn = getBatchWrapper(net.meta.normalization, opts.numFetchThreads) ;
      for t=1:bs:numel(train)
        batch_time = tic ;
        batch = train(t:min(t+bs-1, numel(train))) ;
        fprintf('computing average image: processing batch starting with image %d ...', batch(1)) ;
        temp = fn(imdb, batch) ;
        im{t} = mean(temp, 4) ;
        batch_time = toc(batch_time) ;
        fprintf(' %.2f s (%.1f images/s)\n', batch_time, numel(batch)/ batch_time) ;
      end
      averageImage = mean(cat(4, im{:}),4) ;
      save(averageImagePath, 'averageImage') ;
    end

    net.meta.normalization.averageImage = averageImage ;
    clear averageImage im temp ;
end

% -------------------------------------------------------------------------
%                                               Stochastic gradient descent
% -------------------------------------------------------------------------
fn = getBatchWrapper(net.meta.normalization, opts.numFetchThreads) ;
[net,info] = cnn_train(net, imdb, fn, opts.train, 'conserveMemory', true) ;

% Save model
net = vl_simplenn_move(net, 'cpu');
saveNetwork(fullfile(opts.expDir, 'final-model.mat'), net);

% -------------------------------------------------------------------------
function saveNetwork(fileName, net)
% -------------------------------------------------------------------------
layers = net.layers;

% Replace the last layer with softmax
layers{end}.type = 'softmax';
layers{end}.name = 'prob';

% Remove fields corresponding to training parameters
ignoreFields = {'filtersMomentum', ...
                'biasesMomentum',...
                'filtersLearningRate',...
                'biasesLearningRate',...
                'filtersWeightDecay',...
                'biasesWeightDecay',...
                'class'};
for i = 1:length(layers),
    layers{i} = rmfield(layers{i}, ignoreFields(isfield(layers{i}, ignoreFields)));
end
classes = net.meta.classes;
normalization = net.meta.normalization;
save(fileName, 'layers', 'classes', 'normalization');

% -------------------------------------------------------------------------
function fn = getBatchWrapper(opts, numThreads)
% -------------------------------------------------------------------------
fn = @(imdb,batch) getBatch(imdb,batch,opts,numThreads) ;

% -------------------------------------------------------------------------
function [im,labels] = getBatch(imdb, batch, opts, numThreads)
% -------------------------------------------------------------------------
images = strcat([imdb.imageDir '/'], imdb.images.name(batch)) ;
im = imdb_get_batch(images, opts, ...
                            'numThreads', numThreads, ...
                            'prefetch', nargout == 0);
labels = imdb.images.label(batch) ;

% -------------------------------------------------------------------------
function net = initializeNetwork(imdb, opts)
% -------------------------------------------------------------------------
scal = 1 ;
init_bias = 0.1;
numClass = length(imdb.classes.name);
if ~isempty(opts.model)
    net = load(fullfile('data/models', opts.model)); % Load model if specified
    net.meta.normalization.keepAspect = opts.keepAspect;
    fprintf('Initializing from model: %s\n', opts.model);

    % Replace the last but one layer with random weights
    net.layers{end-1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(1,1,4096,numClass,'single'), ...
                           'biases', zeros(1, numClass, 'single'), ...
                           'stride', 1, ...
                           'pad', 0, ...
                           'filtersLearningRate', 10, ...
                           'biasesLearningRate', 20, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0);

    % Last layer is softmaxloss (switch to softmax for prediction)
    net.layers{end} = struct('type', 'softmaxloss') ;

    % Rename classes
    net.meta.classes.name = imdb.classes.name;
    net.meta.classes.description = imdb.classes.name;

    % TODO: add dropout layers if initializing from previous models
    return;
end

% Else initial model randomly
net.layers = {} ;

% Block 1
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(11, 11, 3, 96, 'single'), ...
                           'biases', zeros(1, 96, 'single'), ...
                           'stride', 4, ...
                           'pad', 0, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'pool', ...
                           'method', 'max', ...
                           'pool', [3 3], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'normalize', ...
                           'param', [5 1 0.0001/5 0.75]) ;

% Block 2
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(5, 5, 48, 256, 'single'), ...
                           'biases', init_bias*ones(1, 256, 'single'), ...
                           'stride', 1, ...
                           'pad', 2, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'pool', ...
                           'method', 'max', ...
                           'pool', [3 3], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'normalize', ...
                           'param', [5 1 0.0001/5 0.75]) ;

% Block 3
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(3,3,256,384,'single'), ...
                           'biases', init_bias*ones(1,384,'single'), ...
                           'stride', 1, ...
                           'pad', 1, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;

% Block 4
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(3,3,192,384,'single'), ...
                           'biases', init_bias*ones(1,384,'single'), ...
                           'stride', 1, ...
                           'pad', 1, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;

% Block 5
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(3,3,192,256,'single'), ...
                           'biases', init_bias*ones(1,256,'single'), ...
                           'stride', 1, ...
                           'pad', 1, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'pool', ...
                           'method', 'max', ...
                           'pool', [3 3], ...
                           'stride', 2, ...
                           'pad', 0) ;

% Block 6
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(6,6,256,4096,'single'),...
                           'biases', init_bias*ones(1,4096,'single'), ...
                           'stride', 1, ...
                           'pad', 0, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'dropout', ...
                           'rate', 0.5) ;

% Block 7
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(1,1,4096,4096,'single'),...
                           'biases', init_bias*ones(1,4096,'single'), ...
                           'stride', 1, ...
                           'pad', 0, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'dropout', ...
                           'rate', 0.5) ;

% Block 8
net.layers{end+1} = struct('type', 'conv', ...
                           'filters', 0.01/scal * randn(1,1,4096,numClass,'single'), ...
                           'biases', zeros(1, numClass, 'single'), ...
                           'stride', 1, ...
                           'pad', 0, ...
                           'filtersLearningRate', 1, ...
                           'biasesLearningRate', 2, ...
                           'filtersWeightDecay', 1, ...
                           'biasesWeightDecay', 0) ;

% Block 9
net.layers{end+1} = struct('type', 'softmaxloss') ;

% Other details
net.meta.normalization.imageSize = [227, 227, 3] ;
net.meta.normalization.interpolation = 'bicubic' ;
net.meta.normalization.border = 256 - net.meta.normalization.imageSize(1:2) ;
net.meta.normalization.averageImage = [] ;
net.meta.normalization.keepAspect = true ;


% clc; clear all; close all;

%% hydro data
hydro = struct();
hydro = readAQWA(hydro, 'cubes.AH1', 'cubes.LIS');
hydro = radiationIRF(hydro,40,[],[],[],[]);
hydro = radiationIRFSS(hydro,[],[]);
hydro = excitationIRF(hydro,50,[],[],[],[]);
writeBEMIOH5(hydro)

%% Plot hydro data
% plotBEMIO(hydro)


function varargout = dsxy2figxy(varargin)
if length(varargin{1}) == 1 && ishandle(varargin{1}) ...
                            && strcmp(get(varargin{1},'type'),'axes')
    hAx = varargin{1};
    varargin = varargin(2:end);
else
    hAx = gca;
end;
if length(varargin) == 1
    pos = varargin{1};
else
    [x,y] = deal(varargin{:});
end
axun = get(hAx,'Units');
set(hAx,'Units','normalized');
axpos = get(hAx,'Position');
axlim = axis(hAx);
axwidth = diff(axlim(1:2));
axheight = diff(axlim(3:4));
if exist('x','var')
    varargout{1} = (x - axlim(1)) * axpos(3) / axwidth + axpos(1);
    varargout{2} = (y - axlim(3)) * axpos(4) / axheight + axpos(2);
else
    pos(1) = (pos(1) - axlim(1)) / axwidth * axpos(3) + axpos(1);
    pos(2) = (pos(2) - axlim(3)) / axheight * axpos(4) + axpos(2);
    pos(3) = pos(3) * axpos(3) / axwidth;
    pos(4) = pos(4) * axpos(4 )/ axheight;
    varargout{1} = pos;
end
set(hAx,'Units',axun)


function ChannelMat = in_channel_eeglab_set(ChannelFile, isFixUnits)
% IN_CHANNEL_EEGLAB_SET:  Read 3D cartesian positions from an .SET EEGLAB file.
%
% USAGE:  ChannelMat = in_channel_eeglab_set(ChannelFile, isFixUnits=[ask])
%         ChannelMat = in_channel_eeglab_set(SetFileMat,  isFixUnits=[ask])
%
% INPUTS:
%     - ChannelFile  : Full path to the file (either .ela or .eps file)
%     - SetFileMat   : Structure contained in an EEGLAB .set file
%     - isFixUnit    : If 1: If the positions of the electrodes are normalized, try to convert them to something acceptable by brainstorm
%                            Otherwise, tries to convert the distance units to meters automatically
%                      If 0, does not apply  any correction
%                      If [], ask for use input

% @=============================================================================
% 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-2017

% Parse inputs
if (nargin < 2) || isempty(isFixUnits)
    isFixUnits = [];
end
% Load initial file (Matlab .mat format)
if ischar(ChannelFile)
    SetFileMat = load(ChannelFile, '-mat');
else
    SetFileMat = ChannelFile;
    ChannelFile = '';
end
% Convert Channel locations to Brainstorm format
if isfield(SetFileMat.EEG, 'chanlocs') && ~isempty(SetFileMat.EEG.chanlocs)
    % Check coordinates sytem
    isLoc = isfield(SetFileMat.EEG.chanlocs(1), 'X');
    if isLoc
        isNormalizedCs = (max([SetFileMat.EEG.chanlocs.X]) <= 1);
        if isempty(isNormalizedCs)
            isNormalizedCs = 0;
        elseif isNormalizedCs && isempty(isFixUnits)
            isFixUnits = java_dialog('confirm', ['The EEGLAB file you selected contains 3D electrodes positions, but they' 10 ...
                                               'seem to be spherical projections in a normalized coordinates system.' 10 ...
                                               'Brainstorm needs real 3D positions, you may need to import them separately.' 10 10 ...
                                               'Would you like Brainstorm to try to convert these positions ?'], 'EEGLAB electrodes positions');
        end
    end
    % Initialize returned structure
    nbChannels = SetFileMat.EEG.nbchan;
    ChannelMat = db_template('channelmat');
    ChannelMat.Comment = 'EEGLAB channels';

    % Copy channel data
    for iChan = 1:nbChannels
        % Electrode type and name
        if isfield(SetFileMat.EEG.chanlocs(iChan), 'type') && ~isempty(SetFileMat.EEG.chanlocs(iChan).type) && ischar(SetFileMat.EEG.chanlocs(iChan).type) && ismember(SetFileMat.EEG.chanlocs(iChan).type(1), 'abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
            ChannelMat.Channel(iChan).Type = upper(SetFileMat.EEG.chanlocs(iChan).type);
        else
            ChannelMat.Channel(iChan).Type = 'EEG';
        end
        ChannelMat.Channel(iChan).Name = SetFileMat.EEG.chanlocs(iChan).labels;
        % Electrode location
        if isLoc
            if isempty(SetFileMat.EEG.chanlocs(iChan).X) || isempty(SetFileMat.EEG.chanlocs(iChan).Y) || isempty(SetFileMat.EEG.chanlocs(iChan).Z)
                ChannelMat.Channel(iChan).Loc = [];
                if strcmpi(ChannelMat.Channel(iChan).Type, 'EEG') && ~isempty([SetFileMat.EEG.chanlocs.X])
                    ChannelMat.Channel(iChan).Type = 'Misc';
                end
            elseif ~isNormalizedCs
                ChannelMat.Channel(iChan).Loc = [SetFileMat.EEG.chanlocs(iChan).X; ...
                                                 SetFileMat.EEG.chanlocs(iChan).Y; ...
                                                 SetFileMat.EEG.chanlocs(iChan).Z] ./ 1000;
            elseif isFixUnits
                ChannelMat.Channel(iChan).Loc = [SetFileMat.EEG.chanlocs(iChan).X / 9.4 + 0.007; ...
                                                 SetFileMat.EEG.chanlocs(iChan).Y / 11.5; ...
                                                 SetFileMat.EEG.chanlocs(iChan).Z / 8.7 + 0.042];
            else
                ChannelMat.Channel(iChan).Loc = [SetFileMat.EEG.chanlocs(iChan).X; ...
                                                 SetFileMat.EEG.chanlocs(iChan).Y; ...
                                                 SetFileMat.EEG.chanlocs(iChan).Z] / 10;
            end
        else
            ChannelMat.Channel(iChan).Loc = [];
        end
        ChannelMat.Channel(iChan).Orient  = [];
        ChannelMat.Channel(iChan).Comment = '';
        ChannelMat.Channel(iChan).Weight  = 1;
    end

    % Check distance units
    if isLoc && ~isNormalizedCs && ~isequal(isFixUnits, 0)
        if isempty(isFixUnits)
            isConfirmFix = 1;
        else
            isConfirmFix = 0;
        end
        ChannelMat = channel_fixunits(ChannelMat, 'mm', isConfirmFix);
    end
else
    ChannelMat = [];
end


function boolvec = artifact2boolvec(artifact, varargin)

% ARTIFACT2BOOLVEC converts between two representations of events or trials.
%
% FieldTrip uses a number of representations for events that are conceptually very similar
%   event    = structure with type, value, sample, duration and offset
%   trl      = Nx3 numerical array with begsample, endsample, offset
%   trl      = table with 3 columns for begsample, endsample, offset
%   artifact = Nx2 numerical array with begsample, endsample
%   artifact = table with 2 columns for begsample, endsample
%   boolvec  = 1xNsamples boolean vector with a thresholded TTL/trigger sequence
%   boolvec  = MxNsamples matrix vector with a thresholded TTL/trigger sequence
%
% If trl or artifact are represented as a MATLAB table, they can have additional
% columns. These additional columns have to be named and are not restricted to
% numerical values.
%
% This function makes a Boolean vector (or matrix when artifact is a cell-array of
% multiple artifact definitions) with 0 for artifact free sample and 1 for sample
% containing an artifact according to artifact specification. The length of the
% vector matches the last sample in the artifact definition, or endsample when
% specified.
%
% See also ARTIFACT2BOOLVEC, ARTIFACT2EVENT, ARTIFACT2TRL, BOOLVEC2ARTIFACT, BOOLVEC2EVENT, BOOLVEC2TRL, EVENT2ARTIFACT, EVENT2BOOLVEC, EVENT2TRL, TRL2ARTIFACT, TRL2BOOLVEC, TRL2EVENT

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

% trl and artifact are similar, except for the offset column
trl = artifact2trl(artifact);
boolvec = trl2boolvec(trl, varargin{:});


classdef TestImreadmulti
    %TestImreadmulti

    methods (Static)
        function test_read_pages
            filename = which('mri.tif');
            if isempty(filename)
                error('mexopencv:testskip', 'missing data');
            end

            imgs = cv.imreadmulti(filename);
            validateattributes(imgs, {'cell'}, {'vector', 'nonempty'});
            cellfun(@(im) validateattributes(im, {'uint8'}, ...
                {'nonempty', 'ndims',2}), imgs);
        end

        function test_compare
            % TIFF file with 27 grayscale images
            filename = which('mri.tif');
            if isempty(filename)
                error('mexopencv:testskip', 'missing data');
            end

            % number of pages
            info = imfinfo(filename);
            num_pages = numel(info);

            % read all pages
            imgs1 = cv.imreadmulti(filename, 'AnyColor',true, 'AnyDepth',true);
            validateattributes(imgs1, {'cell'}, {'vector', 'numel',num_pages});

            % compare against imread from MATLAB
            imgs2 = cell(1,num_pages);
            for i=1:num_pages
                % (convert indexed images to grayscale)
                [X,map] = imread(filename, 'Info',info, 'Index',i);
                imgs2{i} = ind2gray(X, map);
            end
            assert(isequal(imgs1(:), imgs2(:)), 'Images are not equal');
        end

        function test_single_page
            filename = fullfile(mexopencv.root(),'test','fruits.jpg');
            imgs = cv.imreadmulti(filename);
            validateattributes(imgs, {'cell'}, {'vector', 'numel',1});
        end

        function test_error_non_existant_file
            try
                cv.imreadmulti('non_existant_image.tif');
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
        function test_error_argnum
            try
                cv.imreadmulti();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function imdb = setupScene67(datasetDir, varargin)
% SETUPSCENE67    Setup MIT Scene 67 dataset
%    This is similar to SETUPGENERIC(), with modifications to setup
%    MIT Scene 67 according to the standard evaluation protocols. The
%    function supports only the LITE option.
%
%    See: SETUPGENERIC().

% Author: Andrea Vedaldi

% Copyright (C) 2013 Andrea Vedaldi
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

opts.lite = false ;
opts = vl_argparse(opts, varargin) ;

% Download and unpack
vl_xmkdir(datasetDir) ;
if exist(fullfile(datasetDir, 'Images', 'airport_inside'))
  % ok
else
  url = 'http://groups.csail.mit.edu/vision/LabelMe/NewImages/indoorCVPR_09.tar' ;
  trainImagesUrl = 'http://web.mit.edu/torralba/www/TrainImages.txt' ;
  testImagesUrl = 'http://web.mit.edu/torralba/www/TestImages.txt' ;
  fprintf('Downloading MIT Scene 67 data to ''%s''. This will take a while.', datasetDir) ;
  urlwrite(trainImagesUrl, fullfile(datasetDir, 'TrainImages.txt')) ;
  urlwrite(testImagesUrl, fullfile(datasetDir, 'TestImages.txt')) ;
  untar(url, datasetDir) ;
end

% Construct image database imdb structure
imdb.meta.sets = {'train', 'val', 'test'} ;

trainNames = textread(fullfile(datasetDir, 'TrainImages.txt'),'%s','delimiter','\n') ;
testNames = textread(fullfile(datasetDir, 'TestImages.txt'),'%s','delimiter','\n') ;
names = [trainNames; testNames]' ;
sets = [ones(1,numel(trainNames)), 3*ones(1,numel(testNames))] ;
imdb.images.id = 1:numel(names) ;
[imdb.images.name,perm] = sort(names) ;
imdb.images.set = sets(perm) ;

a = regexp(imdb.images.name, '^([^/]+)*/.*$', 'tokens') ;
for i = 1:numel(names)
  a{i} = a{i}{1}{1} ;
end
[imdb.meta.classes, ~, imdb.images.class] = unique(a) ;
imdb.images.class = imdb.images.class(:)' ;
imdb.imageDir = fullfile(datasetDir, 'Images') ;

if opts.lite
  ok = {} ;
  for c = 1:3
    ok{end+1} = vl_colsubset(find(imdb.images.class == c & imdb.images.set == 1), 5) ;
    ok{end+1} = vl_colsubset(find(imdb.images.class == c & imdb.images.set == 3), 5) ;
  end
  ok = cat(2, ok{:}) ;
  imdb.meta.classes = imdb.meta.classes(1:3) ;
  imdb.images.id = imdb.images.id(ok) ;
  imdb.images.name = imdb.images.name(ok) ;
  imdb.images.set = imdb.images.set(ok) ;
  imdb.images.class = imdb.images.class(ok) ;
end


function teacher_stats(varargin)
%TEACHER_STATS - compute the distribution of teacher predictions
%   TEACHER_STATS(VARARGIN) computes the distribution of emotion predictions
%   made by the teahcer model on the EmoVoxCeleb dataset and the Afew6.0
%   dataset [1] and combines them in a figure.
%
%   TEACHER_STATS(..'name', value) accepts the following options:
%
%   `figurePath` :: fullfile(vl_rootnn, 'data/xEmo18/emovoxceleb-figure.pdf')
%    Path to location where figure will be stored.
%
%    References:
%     [1] Dhall, Abhinav, et al. "Collecting large, richly annotated
%       facial-expression databases from movies." IEEE multimedia 19.3%
%       (2012): 34-41.
%
% Copyright (C) 2018 Samuel Albanie, Arsha Nagrani
% Licensed under The MIT License [see LICENSE.md for details]

  opts.figurePath = fullfile(vl_rootnn, ...
                       'data/emoVoxCeleb/emovoxceleb-figure.pdf') ;
  opts.afewLogits = fullfile(vl_rootnn, 'data/emoVoxCeleb/afew-logits.mat') ;
  opts = vl_argparse(opts, varargin) ;

  fprintf('loading imdb of predictions on EmoVoxCeleb...') ; tic ;
  opts.teacher = 'senet50-ferplus' ;
  imdb = fetch_emovoxceleb_imdb(opts.teacher) ;
  allLogits = vertcat(imdb.wavLogits{:}) ;
  [~, emoVoxPreds] = max(allLogits, [], 2) ;
  fprintf('done in %g (s) \n', toc) ;

  fprintf('loading imdb of teacher predictions on AFEW...') ; tic ;
  % Note: These are stored online as a convenience but can be recomputed
  % if desired.
  if ~exist(fileparts(opts.afewLogits), 'dir')
		mkdir(fileparts(opts.afewLogits)) ;
	end
	fetchLogitsFromInternet(opts.afewLogits, 'afew-logits') ;
  xx = load(opts.afewLogits) ;
  emos = vertcat(xx.faceLogits{:}) ;
  [~, afewPreds] = max(emos, [], 2) ;
  fprintf('done in %g (s) \n', toc) ;
  plotHistogram(emoVoxPreds, afewPreds, opts.figurePath) ;
end

% --------------------------------------------------------------------
function plotHistogram(emoVoxPreds, afewPreds, figurePath)
% --------------------------------------------------------------------

  ferPlusEmotions = {'Neutral', 'Happiness', 'Surprise', 'Sadness', ...
                    'Anger', 'Disgust', 'Fear', 'Contempt'} ;

  olive = [ 125 ; 168 ; 50 ] / 255 ; % pick a colour scheme
  set(0,'defaulttextinterpreter','latex') ;

  h = figure(1) ;
  [emoCeleb, ~] = histcounts(emoVoxPreds, 0.5:8.5) ;
  [compared, edges] = histcounts(afewPreds, 0.5:8.5) ;
  label1 = 'EmoVoxCeleb' ;
  label2 = 'Afew 6.0' ;
	ctrs = edges(1)+(1:length(edges)-1).*diff(edges);   % Create Centres
	b = bar(ctrs, [emoCeleb ; compared]', 1, 'BarWidth', 1) ;
  b(1).EdgeColor = olive ; b(1).FaceColor = olive ; b(1).FaceAlpha = 0.8 ;
  b(2).EdgeColor = 'red'; b(2).FaceColor = 'red'; b(2).FaceAlpha = 0.8 ;

	set(gca,'YScale','log') ; grid on ;
	set(gca, 'xtick', ctrs, 'xticklabel', ferPlusEmotions) ;
  ylabel('Number of frames') ;
  set(groot, 'defaultAxesTickLabelInterpreter','latex') ;
  set(groot, 'defaultLegendInterpreter','latex') ;
  legend({label1, label2}) ;
  a = get(gca,'XTickLabel') ;
  set(gca,'XTickLabel', a, 'fontsize', 15) ;
  xlim([1 9]) ;
	xtickangle(60) ;

  if exist('zs_dispFig', 'file'), zs_dispFig ; end

  set(h,'Units','Inches');
  pos = get(h,'Position');
  set(h,'PaperPositionMode', 'Auto', ...
         'PaperUnits', 'Inches', 'PaperSize',[pos(3), pos(4)]) ;
  print(figurePath, '-dpdf','-r0') ;
end

% -------------------------------------------------
function fetchLogitsFromInternet(destPath, imdbName)
% -------------------------------------------------

  waiting = true ;
  prompt = sprintf(...
        strcat('Logits were not found at %s\nWould you like to ', ...
        ' download them from THE INTERNET (y/n)?\n'), destPath) ;

  baseUrl = 'http://www.robots.ox.ac.uk/~albanie/data/cross-modal-emotions' ;

  switch imdbName
    case 'afew-logits'
      url = [baseUrl '/afew-logits.mat'] ;
    otherwise
      error('did not recognise imdb name %s\n', imdbName) ;
  end

  if exist(destPath, 'file')
    fprintf('file already exists at destination, skipping...\n') ;
    return
  end

  while waiting
    str = input(prompt,'s') ;
    switch str
      case 'y'
        if ~exist(fileparts(destPath), 'dir'), mkdir(fileparts(destPath)) ; end
        fprintf('VoxCelebImdb ... \n') ;
        urlwrite(url, destPath) ;
        return ;
      case 'n', throw(exception) ;
      otherwise, fprintf('input %s not recognised, please use `y/n`\n', str) ;
    end
  end
end


function exact = p00_exact ( problem )

%*****************************************************************************80
%
%% P00_EXACT returns the exact integral for any problem.
%
%  Discussion:
%
%    This routine provides a "generic" interface to the exact integral
%    routines for the various problems, and allows a problem to be called
%    by index (PROBLEM) rather than by name.
%
%    In most cases, the "exact" value of the integral is not given;
%    instead a "respectable" approximation is available.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the index of the problem.
%
%    Output, real EXACT, the exact value of the integral.
%
  if ( problem == 1 )
    exact = p01_exact ( );
  elseif ( problem == 2 )
    exact = p02_exact ( );
  elseif ( problem == 3 )
    exact = p03_exact ( );
  elseif ( problem == 4 )
    exact = p04_exact ( );
  elseif ( problem == 5 )
    exact = p05_exact ( );
  elseif ( problem == 6 )
    exact = p06_exact ( );
  elseif ( problem == 7 )
    exact = p07_exact ( );
  elseif ( problem == 8 )
    exact = p08_exact ( );
  elseif ( problem == 9 )
    exact = p09_exact ( );
  elseif ( problem == 10 )
    exact = p10_exact ( );
  elseif ( problem == 11 )
    exact = p11_exact ( );
  elseif ( problem == 12 )
    exact = p12_exact ( );
  elseif ( problem == 13 )
    exact = p13_exact ( );
  elseif ( problem == 14 )
    exact = p14_exact ( );
  elseif ( problem == 15 )
    exact = p15_exact ( );
  elseif ( problem == 16 )
    exact = p16_exact ( );
  elseif ( problem == 17 )
    exact = p17_exact ( );
  elseif ( problem == 18 )
    exact = p18_exact ( );
  elseif ( problem == 19 )
    exact = p19_exact ( );
  elseif ( problem == 20 )
    exact = p20_exact ( );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_EXACT - Fatal error!\n' );
    fprintf ( 1, '  Illegal problem number = %d\n', problem );
    error ( 'P00_EXACT - Fatal error!' );
  end

  return
end


% 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 Tz < ETS3

    methods
        function obj = Tz(varargin)
            obj@ETS3('Tz', varargin{:});

        end

        % function s = char(ets)
        %     s = ets.what;
        % end
    end
end


function value = s_begin ( s1, s2 )

%*****************************************************************************80
%
%% S_BEGIN is TRUE if one string matches the beginning of the other.
%
%  Discussion:
%
%    The strings are compared, ignoring blanks and capitalization.
%
%  Example:
%
%     S1              S2      S_BEGIN
%
%    'Bob'          'BOB'     TRUE
%    '  B  o b '    ' bo b'   TRUE
%    'Bob'          'Bobby'   TRUE
%    'Bobo'         'Bobb'    FALSE
%    ' '            'Bob'     FALSE    (Do not allow a blank to match
%                                       anything but another blank string.)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character S1(*), S2(*), the strings to be compared.
%
%    Output, logical S_BEGIN, is TRUE if the strings match up to
%    the end of the shorter string, ignoring case.
%
  len1 = s_len_trim ( s1 );
  len2 = s_len_trim ( s2 );
%
%  If either string is blank, then both must be blank to match.
%  Otherwise, a blank string matches anything, which is not
%  what most people want.
%
  if ( len1 == 0 || len2 == 0 )

    if ( len1 == 0 && len2 == 0 )
      value = 1;
    else
      value = 0;
    end

    return

  end

  i1 = 0;
  i2 = 0;
%
%  Find the next nonblank in S1.
%
  while ( 1 )

    while ( 1 )

      i1 = i1 + 1;

      if ( len1 < i1 )
        value = 1;
        return
      end

      if ( s1(i1) ~= ' ' )
        break
      end

    end
%
%  Find the next nonblank in S2.
%
    while ( 1 )

      i2 = i2 + 1;

      if ( len2 < i2 )
        value = 1;
        return
      end

      if ( s2(i2) ~= ' ' )
        break
      end

    end
%
%  If the characters match, get the next pair.
%
    if ( ~ch_eqi ( s1(i1), s2(i2) ) )
      break
    end

  end

  value = 0;

  return
end


function labelfolder(HOMEIMAGES, HOMEANNOTATIONS)
% bb = labelimage(img)
%
% It returns bounding boxes. It does not ask for object names.
% Simple script to label bounding boxes on an image.
%
% Use the online tool for labeling!
%
% Output:
%   bb = bounding boxes. Each row is [xmin ymin width height]

objectname = 'building';

folders = folderlist(HOMEIMAGES);

%f = 4; n = 218;

for f = 5:length(folders)
    imgfiles = dir(fullfile(HOMEIMAGES, folders{f}, '*.jpg'));

    for n = 1:length(imgfiles)
        disp([f n])
        anofile = fullfile(HOMEANNOTATIONS, folders{f}, strrep(imgfiles(n).name, '.jpg', '.xml'));

        todo = 1;
        M = 0;

        % if annotation already exists, skip image
        if exist(anofile, 'file')
            % read annotation file
            clear v
            v = LMread(anofile);

            % check if already annotated
            jc = LMobjectindex(v, objectname);
            if ~isempty(jc)
                todo = 0;
            else
                if isfield(v, 'object')
                    M = length(v.object);
                else
                    M = 0;
                end
            end
        else
            clear v
            v.filename = imgfiles(n).name;
            v.folder = folders{f};
            M = 0;
        end

        if todo
            % check if annotation folder exists
            if ~exist(fullfile(HOMEANNOTATIONS, folders{f}), 'dir')
                mkdir(fullfile(HOMEANNOTATIONS, folders{f}))
            end

            % label image
            img = imread(fullfile(HOMEIMAGES, folders{f}, imgfiles(n).name));
            bb = labelimage(img, v);
            close
            % bb = bounding boxes. Each row is [xmin ymin width height]

            % create annotation struct
            for m = 1:size(bb,1)
                b = bb(m,:);
                x = [b(1) b(1)+b(3) b(1)+b(3) b(1)      b(1)];
                y = [b(2) b(2)      b(2)+b(4) b(2)+b(4) b(2)];
                v.object(M+m).name = objectname;
                v.object(M+m).deleted = '0';
                v.object(M+m).polygon = setLMpolygon(x',y');
            end

            clear xml
            xml.annotation = v;

            % save annotation
            writeXML(anofile, xml);
        end
    end
end