THE AUDITORY MODELING TOOLBOX

This documentation page applies to an outdated major AMT version. We show it for archival purposes only.
Click here for the documentation menu and here to download the latest AMT (1.6.0).

View the help

Go to function

EXP_REIJNIERS2014 - - Experiments of Reijniers et al. (2014)

Program code:

function varargout = exp_reijniers2014(varargin)
%EXP_REIJNIERS2014 - Experiments of Reijniers et al. (2014)
%   Usage: [] = exp_reijniers2014(flag) 
%
%   EXP_REIJNIERS2014(flag) reproduces figures of the study from 
%   Reijniers et al. (2014). Note that HRTFs from the ARI database
%   are used for Fig. 4-6, which is most probably different to the HRTFs 
%   used for the calculations in the paper. For Fig. 2 and 3 HRTFs from the
%   Symare database are used, which are also most probably non original.
%
%
%   The following flags can be specified
%   
%     'fig2a'          Reproduce Fig. 2 (a):
%                      The results for simulated trial of a locali-
%                      zation experiment for subject 1 [see also Fig. 3(a)] 
%                      in front Theta = (-34,45)deg (a)  is shown. The
%                      figures show the simulated posterior angular
%                      probabilities and the templates corresponding to the
%                      original direction Theta (solid black line) and
%                      estimated direction Theta_est (dotted black line).
%                      The simulated auditory input is shown as the solid 
%                      red line.
%
%     'fig2b'          Reproduce Fig. 2 (b):
%                      The results for simulated trial of a locali-
%                      zation experiment for subject 1 [see also Fig. 3(a)] 
%                      in back Theta = (14,171)deg (b) is shown. The figures 
%                      show the simulated posterior angular probabilities
%                      and the templates corresponding to the original 
%                      direction Theta (solid black line) and estimated
%                      direction Theta_est (dotted black line). The
%                      simulated auditory input is shown as the solid red
%                      line.
%
%     'fig3'           Reproduce Fig. 3:
%                      The simulated mean spherical error as function
%                      of the source position for 3 different subjects. The
%                      average was taken over 500 localization trials for  
%                      each source position.
%
%     'fig4'           Reproduce Fig. 4(a):                    
%                      The mean localization performance when the
%                      simulation results are averaged over 100 subjects.
%                      Superimposed arrows indicate the size and direction 
%                      of local population response biases for different
%                      source positions.  
%
%     'fig5'           Reproduce Fig. 5:
%                      Sensitivity analysis of the Bayesian localization
%                      model. The simulated mean spherical error is shown 
%                      as function of the source position, when each of the
%                      model parameters is varied separately. The average 
%                      was taken over 500 localization trials for each 
%                      source position and 100 subjects were pooled.
%                      (a) The model with input parameters as described in
%                      the main text. The standard deviation is doubled,
%                      respectively for (b) the noise on the ITD, (c) the 
%                      internal noise and the variation on (d) the source
%                      spectrum. In (e), the bandwidth of the source is 
%                      reduced to [300Hz-8kHz].  
%
%     'fig6'           Reproduce Fig. 6:
%                      The mean spherical error for different values of the
%                      SNR. SNR=75dB corresponds to the control situation,
%                      see Fig.5(a), as the magnitude in all frequency 
%                      channels is above the system noise level.
%
%     'tab1_barumerli2020aes'           Reproduce Tab. 1:
%                      Comparison between actual (majdak2010) and simulated,
%                      performances by relying on different perceptual
%                      metrics (middlebrooks1999b). The variable 'multiplier'
%                      allows to tune the internal noise.
%
%     'fig2_barumerli2020forum'    Reproduce Fig.2 of Barumerli et al. (2020):
%                                  comparison between virtual estimations
%                                  and real data (see
%                                  data_middlebrooks1999()) for individual
%                                  and non-individual DTFs
%
%     'fig3_barumerli2020forum'    Reproduce Fig.3 of Barumerli et al. (2020):
%                                  estimations' evaluation with band limited spectra.
%                                  See Best et al. 2005 and Fig 11 baumgartner2014
%
%     'fig4_barumerli2020forum'    Reproduce Fig.4 of Barumerli et al. (2020):
%                                  estimations' evaluation with rippled
%                                  spectra. See Macpherson and Middlebrooks 2003
%                                  and Fig 10 baumgartner2014
%
%   Further, cache flags (see amt_cache) and plot flags can be specified
%   (Warning: Enforcing recalculation of cached data might take several
%   hours).
%     'no_plot'        Do not compute plots. Flag for cluster execution.
%
%     'interp'         Plot scattered interpolated data (default).
%   
%     'scatter'        Plot only discrete scattered data instead of inter-
%                      polated scattered data.
%
%     'redo_fast'      Quickly recalculate data for figures without using
%                      cache. To speed up computation the amount of locali-
%                      zation trials for Fig. 3 is reduced to 20 and the 
%                      amount of subjects for Fig. 4-6 is reduced to 12.
%
%   Requirements: 
%   -------------
%
%   1) SOFA API v1.1 or higher from 
%      http://sourceforge.net/projects/sofacoustics for Matlab (e.g. in 
%      thirdparty/SOFA)
%
%   Examples:
%   ---------
%
%   To display right part of Fig. 2 (a) use :
%
%     exp_reijniers2014('fig2a');
%
%   To display Fig. 3 and do a quick recalcultaion use :
%
%     exp_reijniers2014('fig3','redo_fast');
%
%   To display Fig. 6 and show a scatter plot :
%
%     exp_reijniers2014('fig6','scatter','redo_fast');
%
%
%   See also: reijniers2014 plot_reijniers2014 reijniers2014_preproc
%   
%   References:
%     R. Barumerli, P. Majdak, R. Baumgartner, J. Reijniers, M. Geronazzo,
%     and F. Avanzini. Predicting directional sound-localization of human
%     listeners in both horizontal and vertical dimensions. In Audio
%     Engineering Society Convention 148. Audio Engineering Society, 2020.
%     
%     R. Barumerli, P. Majdak, R. Baumgartner, M. Geronazzo, and F. Avanzini.
%     Evaluation of a human sound localization model based on bayesian
%     inference. In Forum Acusticum, 2020.
%     
%     J. Reijniers, D. Vanderleist, C. Jin, C. S., and H. Peremans. An
%     ideal-observer model of human sound localization. Biological
%     Cybernetics, 108:169--181, 2014.
%     
%
%   Url: http://amtoolbox.sourceforge.net/amt-0.10.0/doc/experiments/exp_reijniers2014.php

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

%   AUTHOR: Jonas Reijniers
%   Modified and adapted for amtoolbox by 
%   Roberto Barumerli and Michael Sattler,
%   Acoustics Research Institute, Vienna, Austria, 2019


%% ------ Check input options ---------------------------------------------
definput.import = {'amt_cache'};
definput.keyvals.MarkerSize = 6;
definput.keyvals.FontSize = 12;

definput.flags.type = {'missingflag', 'fig2a','fig2b', ...
                        'fig3','fig4','fig5','fig6', ...
                        'tab1_barumerli2020aes', ...
                        'fig2_barumerli2020forum', ...
                        'fig3_barumerli2020forum',...
                        'fig4_barumerli2020forum'};
definput.flags.plot = {'plot', 'no_plot'};
definput.flags.plot_type = {'interp','scatter'};
definput.flags.redo = {'no_redo_fast','redo_fast'};

[flags,kv]  = ltfatarghelper({},definput,varargin);

if flags.do_missingflag
  flagnames=[sprintf('%s, ',definput.flags.type{2:end-2}),...
             sprintf('%s or %s',definput.flags.type{end-1},...
             definput.flags.type{end})];
  error('%s: You must specify one of the following flags: %s.', ...
      upper(mfilename),flagnames);
end


%% ------ fig2a -----------------------------------------------------------
if flags.do_fig2a  
    if flags.do_redo_fast || flags.do_redo
        num_exp = 1;
        fig2a = [];
    else
        num_exp = 1; % definedin case of flag 'redo' 
        fig2a = amt_cache('get','fig2a',flags.cachemode);
    end
               
    if isempty(fig2a)
        % Load SOFA file 
        filename='HA01.sofa';  
        path = ['db://reijniers2014/',filename];
        SOFA_obj=SOFAload(path);

        % Get index of closest directions to Theta shown in Fig. 2(a) 
        az = -34;
        el = 45;
        % Preprocessing source information for both directions
        [template, target] = reijniers2014_preproc(SOFA_obj, ... 
                                        'targ_az', az, 'targ_el', el);
        
        [fig2a.doa, fig2a.params] = ...
            reijniers2014(template, target, 'num_exp', num_exp);
        amt_cache('set','fig2a',fig2a);
    end

    if flags.do_plot
        % plot left side of Fig. 2 (a)   
        plot_reijniers2014(fig2a.params.template_coords, ...
                           squeeze(fig2a.params.post_prob), ...
                           'target', fig2a.doa.real, ...
                           flags.plot_type,flags.type);
        title('Fig. 2(a), posterior probability density');  

        % plot right side of fig 2(a)
        figure('NumberTitle', 'off', 'Name', 'Fig. 2 (a) templates');
        set(gcf, 'Position',  [100,150, 1100, 550]);
        s1 = subplot(1,3,1);
        set(s1, 'position', [0.07, 0.11, 0.05, 0.8] );
        plot(0, fig2a.params.T_target(fig2a.params.Tidx.itd),'k.', ...
             0, fig2a.params.T_template(fig2a.params.Tidx.itd),'b.', ...
             0, fig2a.params.X(fig2a.params.Tidx.itd),'r.','MarkerSize',20);    
        set(gca,'Color',[0.99,0.95,0.93]);
        ylim([-10,10]);
        xlim([-0.2,0.2]);
        ax1 = gca;
        title('ITD','FontSize', 14);
        ylabel('itd (jnd)','FontSize', 13);
        set(ax1,'xticklabel',[]);

        s2 = subplot(1,3,2);
        set(s2, 'position', [0.19, 0.11, 0.35, 0.8] );
        plot(fig2a.params.freq_channels,...
             fig2a.params.T_template(fig2a.params.est_idx, fig2a.params.Tidx.Hm),'k', ...
             fig2a.params.freq_channels,fig2a.params.T_target(fig2a.params.Tidx.Hm),'k:', ...
             fig2a.params.freq_channels,squeeze(fig2a.params.X(1,1,fig2a.params.Tidx.Hm)),'r', ...
             fig2a.params.freq_channels,squeeze(fig2a.params.X(1,1,fig2a.params.Tidx.Hm)),'r.', ...
             'MarkerSize',20,'LineWidth',1.5);
        legend({'$T_{-}(\Theta)$','$T_{-}(\widehat{\Theta})$', ... 
                '$X_{-}(\Theta)$'},'Interpreter','latex','FontSize',13);
        title('spectral difference','FontSize', 14);
        ylabel('logmagnitude (dB)','FontSize',13);
        xlabel('log_{10}(f) (Hz)','Interpreter','tex','FontSize',13);
        ylim([-20,30]);
        xlim([min(fig2a.params.freq_channels) max(fig2a.params.freq_channels)]);
        set(gca,'Xscale','log')

        s3 = subplot(1,3,3); 
        set(s3, 'position', [0.61, 0.11, 0.35, 0.8] );
        plot(fig2a.params.freq_channels,...
             fig2a.params.T_template(fig2a.params.est_idx, fig2a.params.Tidx.Hp),'k', ...
             fig2a.params.freq_channels,fig2a.params.T_target(fig2a.params.Tidx.Hp),'k:', ...
             fig2a.params.freq_channels,squeeze(fig2a.params.X(1,1,fig2a.params.Tidx.Hp)),'r', ...
             fig2a.params.freq_channels,squeeze(fig2a.params.X(1,1,fig2a.params.Tidx.Hp)),'r.', ...
             'MarkerSize',20,'LineWidth',1.5);
        legend({'$T_{+}(\Theta)$','$T_{+}(\widehat{\Theta})$',  ...
                '$X_{+}(\Theta)$'},'Interpreter','latex','FontSize',13);
        title('spectral sum','FontSize', 14);
        ylabel('logmagnitude (dB)','FontSize',13);
        xlabel('log_{10}(f) (Hz)','Interpreter','tex','FontSize',13);
        ylim([-20,30]);
        xlim([min(fig2a.params.freq_channels) max(fig2a.params.freq_channels)]);
        set(gca,'Xscale','log');
    end
end

%% ------ fig2b -----------------------------------------------------------
if flags.do_fig2b  
    if flags.do_redo_fast || flags.do_redo
        num_exp = 1;
        fig2b = [];
    else
        num_exp = 1; 
        fig2b = amt_cache('get','fig2b',flags.cachemode);
    end
               
    if isempty(fig2b)
        % Load SOFA file 
        filename='HA01.sofa';  
        path = ['db://reijniers2014/',filename];
        SOFA_obj=SOFAload(path);

        % Get index of closest directions to Theta shown in Fig. 2(a) 
        az = 14;
        el = 171;
       
        % Preprocessing source information for both directions
        [template, target] = reijniers2014_preproc(SOFA_obj, ... 
                            'targ_az', az, 'targ_el', el);
        
        % Model
        [fig2b.doa, fig2b.params] = ...
            reijniers2014(template, target, 'num_exp', num_exp);
        amt_cache('set','fig2b',fig2b);
    end
    
    if ~flags.do_no_plot
        % plot left side of Fig. 2b   
        plot_reijniers2014(fig2b.params.template_coords, ...
                           squeeze(fig2b.params.post_prob), ...
                           'target', fig2b.doa.real, ...
                           flags.plot_type,flags.type);
        title('Fig. 2(b), posterior probability density');    
        % plot right side of fig 2(b)
        figure('NumberTitle', 'off', 'Name', 'Fig. 2 (b) templates');
        set(gcf, 'Position',  [100,150, 1100, 550]);
        s1 = subplot(1,3,1);
        set(s1, 'position', [0.07, 0.11, 0.05, 0.8] );
        plot(0, fig2b.params.T_target(fig2b.params.Tidx.itd),'k.', ...
             0, fig2b.params.T_template(fig2b.params.Tidx.itd),'b.', ...
             0, fig2b.params.X(fig2b.params.Tidx.itd),'r.','MarkerSize',20); 
        set(gca,'Color',[0.99,0.95,0.93]);
        ylim([-10,10]);
        xlim([-0.2,0.2]);
        ax1 = gca;
        title('ITD','FontSize', 14);
        ylabel('itd (jnd)','FontSize', 13);
        set(ax1,'xticklabel',[]);

        s2 = subplot(1,3,2);
        set(s2, 'position', [0.19, 0.11, 0.35, 0.8] );
        plot(fig2b.params.freq_channels,...
             fig2b.params.T_template(fig2b.params.est_idx, fig2b.params.Tidx.Hm),'k', ...
             fig2b.params.freq_channels,fig2b.params.T_target(fig2b.params.Tidx.Hm),'k:', ...
             fig2b.params.freq_channels,squeeze(fig2b.params.X(1,1,fig2b.params.Tidx.Hm)),'r', ...
             fig2b.params.freq_channels,squeeze(fig2b.params.X(1,1,fig2b.params.Tidx.Hm)),'r.', ...
             'MarkerSize',20,'LineWidth',1.5);
        legend({'$T_{-}(\Theta)$','$T_{-}(\widehat{\Theta})$',...
                '$X_{-}(\Theta)$'},'Interpreter','latex','FontSize',13);
        title('spectral difference','FontSize', 14);
        ylabel('logmagnitude (dB)','FontSize',13);
        xlabel('log_{10}(f) (Hz)','Interpreter','tex','FontSize',13);
        ylim([-20,30]);
        xlim([min(fig2b.params.freq_channels) max(fig2b.params.freq_channels)]);
        set(gca,'Xscale','log');

        s3 = subplot(1,3,3); 
        set(s3, 'position', [0.61, 0.11, 0.35, 0.8] );
        plot(fig2b.params.freq_channels,...
             fig2b.params.T_template(fig2b.params.est_idx, fig2b.params.Tidx.Hp),'k', ...
             fig2b.params.freq_channels,fig2b.params.T_target(fig2b.params.Tidx.Hp),'k:', ...
             fig2b.params.freq_channels,squeeze(fig2b.params.X(1,1,fig2b.params.Tidx.Hp)),'r', ...
             fig2b.params.freq_channels,squeeze(fig2b.params.X(1,1,fig2b.params.Tidx.Hp)),'r.', ...
             'MarkerSize',20,'LineWidth',1.5);
        legend({'$T_{+}(\Theta)$','$T_{+}(\widehat{\Theta})$', ... 
                '$X_{+}(\Theta)$'},'Interpreter','latex','FontSize',13);
        title('spectral sum','FontSize', 14);
        ylabel('logmagnitude (dB)','FontSize',13);
        xlabel('log_{10}(f) (Hz)','Interpreter','tex','FontSize',13);
        ylim([-20,30]);
        xlim([min(fig2b.params.freq_channels) max(fig2b.params.freq_channels)]);
        set(gca,'Xscale','log');
    end
end

%% ------ fig3 ------------------------------------------------------------
if flags.do_fig3
    if flags.do_redo_fast
        num_exp = 20;
        fig3 = [];
    else
        num_exp = 500;
        fig3 = amt_cache('get','fig3',flags.cachemode);
    end
        
    if isempty(fig3)
        filenames={'HA03.sofa'; 'HA01.sofa';'HA06.sofa'};
        for i = 1:length(filenames)
            path = ['db://reijniers2014/',filenames{i}];
            SOFA_obj(i)=SOFAload(path);
        end
        % Preallocation
        fig3 = struct('metrics', struct([]), 'err',struct([]), 'doa_real',struct([]));
        fig3 = repmat(fig3,length(filenames),1);
        
        amt_disp('Processing three subjects in parallel...','progress');
        
        parfor i = 1:length(filenames)
            amt_disp(['Processing subject #' num2str(i)],'progress');
            % Get directions from SOFA files
            [template, target] = reijniers2014_preproc(SOFA_obj(i));
            doa = reijniers2014(template, target,'num_exp',num_exp);
            
            fig3(i).err = reijniers2014_metrics(doa);
            fig3(i).doa_real = doa.real;
            fig3(i).metrics = reijniers2014_metrics(doa, 'middle_metrics'); 
        end
        
        if ~flags.do_redo_fast
             amt_cache('set','fig3',fig3);
        end
    end
    
    if flags.do_plot
        % plot for each subject
        for i = 1:length(fig3)
            [~, cbar] = plot_reijniers2014(fig3(i).doa_real, ...
                                    fig3(i).err, ...
                                    flags.plot_type, flags.type);
            title(sprintf('Fig. 3(a), Subject %i', i));
            caxis([0,20]);
            cbar.Label.String = 'Mean spherical error [^\circ]';
            cbar.Label.FontSize = 12;    
            ct1=get(cbar,'TickLabels');
            for k=1:numel(ct1)
                ct1{k}=sprintf('%s',ct1{k});
            end
            set(cbar,'xticklabel',ct1);
        end
    end
    
    for i = 1:length(fig3)
        amt_disp(sprintf('\nSUBJECT %i', i))
        amt_disp(sprintf('\t\t\tSIM'))
        amt_disp(sprintf('lateral_bias [deg]:\t%0.2f', ...
            mean([fig3(i).metrics.accL])))
        amt_disp(sprintf('lateral_rms_error [deg]:\t%0.2f', ...
            mean([fig3(i).metrics.rmsL])))
        amt_disp(sprintf('elevation_bias [deg]:\t%0.2f', ...
            mean([fig3(i).metrics.accE])))
        amt_disp(sprintf('local_rms_polar [deg]:\t%0.2f', ...
            mean([fig3(i).metrics.rmsP])))
        amt_disp(sprintf('quadrant_err [%%]:\t%0.2f', ...
            mean([fig3(i).metrics.querr])))
    end
end

%% ------ fig4 ------------------------------------------------------------
if flags.do_fig4
    if flags.do_redo_fast
        num_exp = 20;
        num_sub = 12;
        fig4 = [];
    else
        num_exp = 500;
        num_sub = 100;
        fig4 = amt_cache('get','fig4',flags.cachemode);
    end
    
    if isempty(fig4)
        offset = 13; % start at 14th file in folder 
        % Get names of all used hrtfs
        x=amt_load('reijniers2014','hrtfnames.mat');  
        % Load SOFA files  
        for i=1:num_sub             
            path = ['db://reijniers2014/',x.hrtfnames{i+offset}];
            SOFA_obj(i)=SOFAload(path);
        end
        % Preallocation
        fig4 = struct('exp',struct(), ...
                      'err',struct([]), ...
                      'bias',struct([]), ...
                      'doa_real',struct([]));
        fig4 = repmat(fig4,num_sub,1);
        
        % Compute mean spherical error for all subjects 
        amt_disp(['Processing ' num2str(num_sub) ...
                  ' subjects in parallel...'],'progress');
        parfor i = 1:num_sub
            amt_disp(['Processing subject #' num2str(i)],'progress');
            % Get directions from SOFA files
            [template, target] = reijniers2014_preproc(SOFA_obj(i));
            doa = reijniers2014(template, target,'num_exp',num_exp);
            
            [fig4(i).err, fig4(i).bias] = reijniers2014_metrics(doa);
            fig4(i).doa_real = doa.real;
            fig4(i).exp = reijniers2014_metrics(doa, 'middle_metrics');
        end
        
        if ~flags.do_redo_fast
            amt_cache('set','fig4',fig4);
        end
    end
 
    % remove ill formed hrtf
    if(length(fig4(51).err) ~= length(fig4(1).err))
        fig4(51) = [];
    end
    if flags.do_plot
        % Calculate averages
        mean_error = zeros(size(fig4(1).doa_real, 1), 1);
        mean_bias = zeros(size(fig4(1).doa_real, 1), 3);
        
        for k = 1:length(fig4)
            mean_error = mean_error + fig4(k).err;
            mean_bias = mean_bias + fig4(k).bias;
        end
        
        mean_error = abs(mean_error/length(fig4)); 
        mean_bias = mean_bias/length(fig4); 
        
        [~, cbar] = plot_reijniers2014(fig4(1).doa_real, ... % assuming same dirs
                                mean_error,'bias', ...
                                mean_bias,flags.plot_type,flags.type);                        
        title('Fig. 4(a), simulation');
        caxis([0,35]);
        cbar.Label.String = 'Mean spherical error [^\circ]';
        cbar.Label.FontSize = 12;    
        ct1=get(cbar,'TickLabels');
        for k=1:numel(ct1)
            ct1{k}=sprintf('%s',ct1{k});
        end
        set(cbar,'xticklabel',ct1);
    end
    
    metrics =  struct2cell(fig4);
    metrics = cell2mat(metrics(1,:));
    amt_disp(sprintf('\t\t\tSIM'))
    amt_disp(sprintf('lateral_bias [dg]:\t%0.2f', ...
        mean([metrics.accL], 'all')))
    amt_disp(sprintf('lateral_rms_error [deg]:\t%0.2f', ...
        mean([metrics.rmsL], 'all')))
    amt_disp(sprintf('elevation_bias [deg]:\t%0.2f', ...
        mean([metrics.accE], 'all')))
    amt_disp(sprintf('local_rms_polar [deg]:\t%0.2f', ...
        mean([metrics.rmsP], 'all')))
    amt_disp(sprintf('quadrant_err [%%]:\t%0.2f', ...
        mean([metrics.querr], 'all')))
end

%% ------ fig5 ------------------------------------------------------------
if flags.do_fig5
    if flags.do_redo_fast
        num_exp = 20;
        num_sub = 12;
        fig5 = [];
    else
        num_exp = 500;
        num_sub = 100;
        fig5 = amt_cache('get','fig5',flags.cachemode);
    end
    
    if isempty(fig5) 
        offset = 13; % start at 14th file in folder 
        % Get names of all used hrtfs
        x=amt_load('reijniers2014','hrtfnames.mat');  
        % Load SOFA files  
        for i=1:num_sub             
            path = ['db://reijniers2014/',x.hrtfnames{i+offset}];
            SOFA_obj(i)=SOFAload(path);
        end
        
        % preallocation
        fig5 = struct('a',struct('err',[], 'exp', struct([])), ...
                      'b',struct('err',[], 'exp', struct([])), ...
                      'c',struct('err',[], 'exp', struct([])), ...
                      'd',struct('err',[], 'exp', struct([])), ...
                      'e',struct('err',[], 'exp', struct([])), ...
                      'doa_real', []);
        fig5 = repmat(fig5,num_sub,1);

        amt_disp(['Processing ' num2str(num_sub) ...
                  ' subjects in parallel...'],'progress');
        % Compute mean sphercial error for all subjects
        parfor i = 1:num_sub       
            %% Preprocessing source and template information 
            amt_disp(['Processing subject #' num2str(i)],'progress');
            [template, target] = reijniers2014_preproc(SOFA_obj(i));

            % Model
            % Fig. 5 (a)
            amt_disp('Doing control','progress');
            doa = reijniers2014(template, target, ...
                                    'num_exp',num_exp);
            fig5(i).a.err = reijniers2014_metrics(doa);
            fig5(i).a.exp = reijniers2014_metrics(doa, 'middle_metrics');
            
            % Fig. 5 (b)
            amt_disp('Doing sigma_itd doubled','progress');
            doa = reijniers2014(template, target, ...
                                    'sig_itd',0.569*2, 'num_exp',num_exp);                         
            fig5(i).b.err = reijniers2014_metrics(doa);
            fig5(i).b.exp = reijniers2014_metrics(doa, 'middle_metrics');

            % Fig. 5 (c)
            amt_disp('Doing sigma_I doubled','progress');
            doa = reijniers2014(template, target, ...
                                    'sig_I',3.5*2,'num_exp',num_exp); 
            fig5(i).c.err = reijniers2014_metrics(doa);
            fig5(i).c.exp = reijniers2014_metrics(doa, 'middle_metrics');

            % Fig. 5 (d)
            amt_disp('Doing sigma_S doubled','progress');
            doa = reijniers2014(template, target, ...
                                    'sig_S',3.5*2,'num_exp',num_exp);                         
            fig5(i).d.err = reijniers2014_metrics(doa);
            fig5(i).d.exp = reijniers2014_metrics(doa, 'middle_metrics');

            % Fig. 5 (e)
            amt_disp('Doing LPF','progress');
            [templpf, targlpf] = reijniers2014_preproc(SOFA_obj(i), ...
                                     'fb_low', 3e2, 'fb_high', 8e3);
            doa = reijniers2014(templpf, targlpf, ...
                                     'num_exp',num_exp);
            fig5(i).e.err = reijniers2014_metrics(doa);
            fig5(i).e.exp = reijniers2014_metrics(doa, 'middle_metrics');

            fig5(i).doa_real = doa.real;
        end
                    
        if ~flags.do_redo_fast
            amt_cache('set','fig5',fig5);
        end
    end
    
    graphs_lb = {'a', 'b', 'c', 'd', 'e'};

    if flags.do_plot
        % remove anomalous subject
        fig5(51) = [];
        num_sub = length(fig5);
        % Calculate averages and plot
        mean_error = zeros(length(fig5(1).a.err), length(graphs_lb));

        titles = {'Fig. 5 (a), control', ...
                  'Fig. 5 (b), $2\sigma_{itd}$', ...
                  'Fig. 5 (c), $2\sigma_{I}$',...
                  'Fig. 5 (d), $2\sigma_{S}$',...
                  'Fig. 5 (e), LPF'};

        for j =1:length(graphs_lb)
            for k = 1:num_sub
                mean_error(:,j) = mean_error(:,j) + fig5(k).(graphs_lb{j}).err;
            end

            mean_error(:,j) = abs((mean_error(:,j)/num_sub)); 

            [~, cbar] = plot_reijniers2014(fig5(1).doa_real, ...
                                mean_error(:,j),flags.plot_type,flags.type);                        
            title(titles{j},'Interpreter','Latex');
            caxis([0,20]);
            cbar.Label.String = 'Mean spherical error [^\circ]';
            cbar.Label.FontSize = 12;    
            ct1=get(cbar,'TickLabels');
            for k=1:numel(ct1)
                ct1{k}=sprintf('%s',ct1{k});
            end
            set(cbar,'xticklabel',ct1);
        end
    end
    
    accL = zeros(length(fig5(1).a.err), length(graphs_lb));
    rmsL = zeros(length(fig5(1).a.err), length(graphs_lb));
    accE = zeros(length(fig5(1).a.err), length(graphs_lb));
    rmsP = zeros(length(fig5(1).a.err), length(graphs_lb));
    querr = zeros(length(fig5(1).a.err), length(graphs_lb));
    
    for j =1:length(graphs_lb)
        for k = 1:num_sub
            accL(k,j) = accL(k,j) + fig5(k).(graphs_lb{j}).exp.accL;
            rmsL(k,j) = rmsL(k,j) + fig5(k).(graphs_lb{j}).exp.rmsL;
            accE(k,j) = accE(k,j) + fig5(k).(graphs_lb{j}).exp.accE;
            rmsP(k,j) = rmsP(k,j) + fig5(k).(graphs_lb{j}).exp.rmsP;
            querr(k,j) = querr(k,j) + fig5(k).(graphs_lb{j}).exp.querr;
        end

        amt_disp(sprintf('\n EXP %s', graphs_lb{j}))
        amt_disp(sprintf('\t\t\tSIM'))
        amt_disp(sprintf('lateral_bias [deg]:\t%0.3f', ...
            mean(accL(:,j), 'all')))
        amt_disp(sprintf('lateral_rms_error [deg]:\t%0.3f', ...
            mean(rmsL(:,j), 'all')))
        amt_disp(sprintf('elevation_bias [deg]:\t%0.3f', ...
            mean(accE(:,j), 'all')))
        amt_disp(sprintf('local_rms_polar [deg]:\t%0.3f', ...
            mean(rmsP(:,j), 'all')))
        amt_disp(sprintf('quadrant_err [%%]:\t%0.3f', ...
            mean(querr(:,j), 'all')))
    end
end

%% ------ fig6 ------------------------------------------------------------
if flags.do_fig6 
    if flags.do_redo_fast
        num_exp = 20;
        num_sub = 12;
        fig6 = [];
    else
        num_exp = 500;
        num_sub = 100;
        fig6 = amt_cache('get','fig6',flags.cachemode);
    end
    
    SNRs = [75, 50, 40, 30];
    graphs_lb = {'a', 'b', 'c', 'd'};

    if isempty(fig6) 
        offset = 13; % start at 14th file in folder 
        % Get names of all used hrtfs
        x=amt_load('reijniers2014','hrtfnames.mat');
        % Load SOFA files
        for i=1:num_sub   
            path = ['db://reijniers2014/',x.hrtfnames{i+offset}];
            SOFA_obj(i)=SOFAload(path);
        end

        % preallocation
        fig6 = struct('a',struct('err',[], 'exp', struct([])), ...
                      'b',struct('err',[], 'exp', struct([])), ...
                      'c',struct('err',[], 'exp', struct([])), ...
                      'd',struct('err',[], 'exp', struct([])), ...
                      'doa_real', []);
        fig6 = repmat(fig6,num_sub,1);
        
        % Compute mean sphercial error for all subjects 
        amt_disp(['Processing ' num2str(num_sub) ...
                  ' subjects in parallel...'],'progress');
        parfor i = 1:num_sub
            amt_disp(['Processing subject #' num2str(i)],'progress');
            [template, target] = reijniers2014_preproc(SOFA_obj(i));

            for j = 1:length(SNRs)
                amt_disp(sprintf('Doing SNR=%idB', SNRs(j)),'progress');
                doa = reijniers2014(template, target, ...
                                    'SNR',SNRs(j),'num_exp',num_exp);
                fig6(i).(graphs_lb{j}).err = reijniers2014_metrics(doa);
                fig6(i).(graphs_lb{j}).exp = reijniers2014_metrics(doa, 'middle_metrics');
                fig6(i).doa_real = doa.real;
            end
        end

        if ~flags.do_redo_fast
            amt_cache('set','fig6',fig6);
        end
    end
    
    if flags.do_plot
        num_sub = length(fig6);
        % Calculate averages and plot
        mean_error = zeros(length(fig6(1).doa_real), length(graphs_lb));

        for j =1:length(graphs_lb)
            for k = 1:num_sub
                mean_error(:,j) = mean_error(:,j) + fig6(k).(graphs_lb{j}).err;
            end
            mean_error(:,j) = abs((mean_error(:,j)/num_sub)); 

            [~, cbar] = plot_reijniers2014(fig6(1).doa_real, ...
                                mean_error(:,j),flags.plot_type,flags.type);                        
            title(sprintf('Fig.6 (%c), SNR=%idB',graphs_lb{j}, SNRs(j)),...
                        'Interpreter','Latex');
            caxis([0,20]);
            cbar.Label.String = 'Mean spherical error [^circ]';
            cbar.Label.FontSize = 12;    
            ct1=get(cbar,'TickLabels');
            for k=1:numel(ct1)
                ct1{k}=sprintf('%s',ct1{k});
            end
            set(cbar,'xticklabel',ct1);
        end     
    end
    
    accL = zeros(length(fig6(1).a.err), length(graphs_lb));
    rmsL = zeros(length(fig6(1).a.err), length(graphs_lb));
    accE = zeros(length(fig6(1).a.err), length(graphs_lb));
    rmsP = zeros(length(fig6(1).a.err), length(graphs_lb));
    querr = zeros(length(fig6(1).a.err), length(graphs_lb));
    
    for j =1:length(graphs_lb)
        for k = 1:num_sub
            accL(:,j) = accL(:,j) + fig6(k).(graphs_lb{j}).exp.accL;
            rmsL(:,j) = rmsL(:,j) + fig6(k).(graphs_lb{j}).exp.rmsL;
            accE(:,j) = accE(:,j) + fig6(k).(graphs_lb{j}).exp.accE;
            rmsP(:,j) = rmsP(:,j) + fig6(k).(graphs_lb{j}).exp.rmsP;
            querr(:,j) = querr(:,j) + fig6(k).(graphs_lb{j}).exp.querr;
        end

        amt_disp(sprintf('\n EXP %s', graphs_lb{j}))
        amt_disp(sprintf('\t\t\tSIM'))
        amt_disp(sprintf('lateral_bias [deg]:\t%0.2f', ...
            mean([accL], 'all')))
        amt_disp(sprintf('lateral_rms_error [deg]:\t%0.2f', ...
            mean([rmsL], 'all')))
        amt_disp(sprintf('elevation_bias [deg]:\t%0.2f', ...
            mean([accE], 'all')))
        amt_disp(sprintf('local_rms_polar [deg]:\t%0.2f', ...
            mean([rmsP], 'all')))
        amt_disp(sprintf('quadrant_err [%%]:\t%0.2f', ...
            mean([querr], 'all')))
    end
end

%% ------ tab1_barumerli2020aes ----------------------------------------------
if flags.do_tab1_barumerli2020aes
    data_baseline = data_majdak2010('Learn_M');
    % remove subjects with no data
    data_baseline(1:5) = [];

    % uncertainties tuner 
    multiplier = 3;
    amt_disp(sprintf('Uncertanties multiplied by a factor: %i\n', multiplier));
    
    tab1_barumerli2020aes = [];
    
    if ~flags.do_redo
        tab1_barumerli2020aes = amt_cache('get','tab1_barumerli2020aes',flags.cachemode);
    end
    
    if isempty(tab1_barumerli2020aes)
        amt_disp('Loading SOFA files');

        parfor i = 1:length(data_baseline)
            data_baseline(i).sofa = ...
                SOFAload(['https://sofacoustics.org/data/database/ari/',...
                'dtf_' lower(data_baseline(i).id) '.sofa']);
        end

        % Preallocation
        tab1_barumerli2020aes = struct('doa', struct([]));
        tab1_barumerli2020aes = repmat(tab1_barumerli2020aes,length(data_baseline),1);

        parfor i = 1:length(data_baseline)
            amt_disp(['Processing subject #' num2str(i)],'progress');
            % Get directions from SOFA files
            targ_az = data_baseline(i).mtx(:,1);
            targ_el = data_baseline(i).mtx(:,2);
            % preprocessing
            [template, target] = ...
                reijniers2014_preproc(data_baseline(i).sofa, ...
                'targ_az', targ_az, 'targ_el', targ_el);

            % model esecution
            [tab1_barumerli2020aes(i).doa] = ... 
                reijniers2014(template, target, 'num_exp', 1, ...
                            'sig_itd', 0.569*multiplier, ...
                            'sig_I', 3.5*multiplier, ...
                            'sig_S', 3.5*multiplier, ...
                            'sig', 5*multiplier);
        end

        amt_cache('set','tab1_barumerli2020aes',tab1_barumerli2020aes);
    end
        
    for i = 1:length(tab1_barumerli2020aes)
        % lateral_bias 
        exp(i).accL = reijniers2014_metrics(tab1_barumerli2020aes(i).doa, 'accL'); 
        % lateral_rms_error
        exp(i).rmsL = reijniers2014_metrics(tab1_barumerli2020aes(i).doa, 'rmsL'); 
        % elevation_bias
        exp(i).accE = reijniers2014_metrics(tab1_barumerli2020aes(i).doa, 'accE'); 
        % local_rms_polar
        exp(i).rmsP = ... 
            reijniers2014_metrics(tab1_barumerli2020aes(i).doa, 'rmsPmedianlocal'); 
        % quadrant_err
        exp(i).querr = ...
            reijniers2014_metrics(tab1_barumerli2020aes(i).doa, 'querrMiddlebrooks'); 

        real(i).accL = localizationerror(data_baseline(i).mtx, 'accL');
        real(i).rmsL = localizationerror(data_baseline(i).mtx, 'rmsL');
        real(i).accE = localizationerror(data_baseline(i).mtx, 'accE');
        real(i).rmsP = ...
            localizationerror(data_baseline(i).mtx, 'rmsPmedianlocal');
        real(i).querr = ...
            localizationerror(data_baseline(i).mtx, 'querrMiddlebrooks');
    end
    
    amt_disp(sprintf('\t\t\tSIM\t\tREAL'))
    amt_disp(sprintf('lateral_bias [deg]:\t%0.2f\t\t%0.2f', ...
        mean([exp.accL]), mean([real.accL])))
    amt_disp(sprintf('lateral_rms_error [deg]:\t%0.2f\t\t%0.2f', ...
        mean([exp.rmsL]), mean([real.rmsL])))
    amt_disp(sprintf('elevation_bias [deg]:\t%0.2f\t\t%0.2f', ...
        mean([exp.accE]), mean([real.accE])))
    amt_disp(sprintf('local_rms_polar [deg]:\t%0.2f\t\t%0.2f', ...
        mean([exp.rmsP]), mean([real.rmsP])))
    amt_disp(sprintf('quadrant_err [%%]:\t%0.2f\t\t%0.2f', ...
        mean([exp.querr]), mean([real.querr])))
end


%% ------ fig2_barumerli2020forum -------------------------------------
if flags.do_fig2_barumerli2020forum
    fig2_barumerli2020forum = [];

    if ~flags.do_redo
        fig2_barumerli2020forum = amt_cache('get', ...
            'fig2_barumerli2020forum',flags.cachemode);
    end
    
    if isempty(fig2_barumerli2020forum)
        % load 23 DTFs from baumgartner2014         
        amt_disp('Loading SOFA files');
        sbj_dtf = data_baumgartner2014('pool','cached');

        % preprocess templates for each user
        amt_disp('Processing subjects'' templates');
        
        for i = 1:length(sbj_dtf)
            amt_disp(['Pre-processing subject #' num2str(i)],'progress');
            [sbj_template(i), sbj_target(i)] = reijniers2014_preproc(sbj_dtf(i).Obj);
        end
        
        % preallocation for results
        amt_disp('Allocating memory for results');
        estimations = struct('doa', struct([]));
        estimations = repmat(estimations, ...
            length(sbj_dtf),length(sbj_dtf)); % all vs all

        for i = 1:length(sbj_dtf)
            amt_disp(['Processing subject #' num2str(i)],'progress');
            parfor j = 1:length(sbj_dtf)
                amt_disp(num2str(j));
                %TODO: select points in the sphere grid
                estimations(i, j).doa = ... 
                    reijniers2014(sbj_template(i), sbj_target(j), 'num_exp', 1);
            end
        end

        % compute metrics
        for i = 1:size(estimations, 1)
            for j = 1:size(estimations, 2)
                % lateral bias
                metrics(i, j).accL = reijniers2014_metrics(estimations(i, j).doa, 'accL'); 
                % lateral_rms_error
                metrics(i, j).rmsL = reijniers2014_metrics(estimations(i, j).doa, 'rmsL'); 
                % elevation_bias
                metrics(i, j).accE = reijniers2014_metrics(estimations(i, j).doa, 'accE'); 
                % polar bias
                metrics(i, j).accP = ... 
                    reijniers2014_metrics(estimations(i, j).doa, 'accP'); 
                % local rms polar
                metrics(i, j).rmsP = ... 
                    reijniers2014_metrics(estimations(i, j).doa, 'rmsPmedianlocal'); 
                % quadrant_err
                metrics(i, j).querr = ...
                    reijniers2014_metrics(estimations(i, j).doa, 'querrMiddlebrooks'); 
            end
        end
        
        fig2_barumerli2020forum = metrics;
        
        amt_cache('set','fig2_barumerli2020forum',fig2_barumerli2020forum);
    end
    
    metrics = fig2_barumerli2020forum;

    % aggregate metrics
    ns = size(metrics,1);
    own = logical(eye(ns));
    other = not(own);
    quants = [0,0.05,0.25,0.5,0.75,0.95,1];
    % code similar to baumgartner2014 - fig9
    le_own.quantiles = quantile([metrics(own).rmsL], quants);
    lb_own.quantiles = quantile([metrics(own).accL], quants);
    qe_own.quantiles = quantile([metrics(own).querr], quants);
    pe_own.quantiles = quantile([metrics(own).rmsP], quants);
    pb_own.quantiles = quantile([metrics(own).accP], quants);
    le_own.mean = mean([metrics(own).rmsL]);
    lb_own.mean = mean([metrics(own).accL]);
    qe_own.mean = mean([metrics(own).querr]);
    pe_own.mean = mean([metrics(own).rmsP]);
    pb_own.mean = mean([metrics(own).accP]);

    le_other.quantiles = quantile([metrics(other).rmsL], quants);
    lb_other.quantiles = quantile([metrics(other).accL], quants);
    qe_other.quantiles = quantile([metrics(other).querr], quants);
    pe_other.quantiles = quantile([metrics(other).rmsP], quants);
    pb_other.quantiles = quantile([metrics(other).accP], quants);
    le_other.mean = mean([metrics(other).rmsL]);
    lb_other.mean = mean([metrics(other).accL]);
    qe_other.mean = mean([metrics(other).querr]);
    pe_other.mean = mean([metrics(other).rmsP]);
    pb_other.mean = mean([metrics(other).accP]);
    
    data = data_middlebrooks1999;
    
    % baumgartner data
    data_baum_temp = exp_baumgartner2014('fig9', 'noplot');
    data_baum.qe_pool = data_baum_temp(1).qe;
    data_baum.pe_pool = data_baum_temp(1).pe;
    data_baum.pb_pool = data_baum_temp(1).pb;
    
    ns = size(data_baum.pe_pool,1);
    own = eye(ns) == 1;
    other = not(own);
    data_baum.pb_pool = abs(data_baum.pb_pool);
    data_baum.qe_own.quantiles = quantile(data_baum.qe_pool(own),[0,0.05,0.25,0.5,0.75,0.95,1]);
    data_baum.pe_own.quantiles = quantile(data_baum.pe_pool(own),[0,0.05,0.25,0.5,0.75,0.95,1]);
    data_baum.pb_own.quantiles = quantile(data_baum.pb_pool(own),[0,0.05,0.25,0.5,0.75,0.95,1]);
    data_baum.qe_own.mean = mean(data_baum.qe_pool(own));
    data_baum.pe_own.mean = mean(data_baum.pe_pool(own));
    data_baum.pb_own.mean = mean(data_baum.pb_pool(own));

    data_baum.qe_other.quantiles = quantile(data_baum.qe_pool(other),[0,0.05,0.25,0.5,0.75,0.95,1]);
    data_baum.pe_other.quantiles = quantile(data_baum.pe_pool(other),[0,0.05,0.25,0.5,0.75,0.95,1]);
    data_baum.pb_other.quantiles = quantile(data_baum.pb_pool(other),[0,0.05,0.25,0.5,0.75,0.95,1]);
    data_baum.qe_other.mean = mean(data_baum.qe_pool(other));
    data_baum.pe_other.mean = mean(data_baum.pe_pool(other));
    data_baum.pb_other.mean = mean(data_baum.pb_pool(other));
  
    % plot
    if flags.do_plot
        dx = 0.22;
        dx_lat = 0.15;
        Marker = 's-';
        LineColor = [0 0.4470 0.7410];
        data.Marker = 'ko-';
        data.LineColor = [1 1 1]*0.3;
        data_baum.Marker = 'd-';
        data_baum.LineColor = [0.8500 0.3250 0.0980];
        
        mFig = figure;
        mFig.Units = 'centimeters';
        mFig.Position = [5,5,35,10];
        subplot(1, 5, 1)
        middlebroxplot(1-dx_lat,data.le_own.quantiles,kv.MarkerSize, data.LineColor)
        plot(1-dx_lat,data.le_own.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(1+dx_lat,le_own.quantiles,kv.MarkerSize, LineColor)
        plot(1+dx_lat,le_own.mean,Marker,'MarkerSize', kv.MarkerSize, 'MarkerFaceColor', LineColor, 'MarkerEdgeColor', LineColor)
        
        middlebroxplot(2-dx_lat,data.le_other.quantiles,kv.MarkerSize, data.LineColor)
        plot(2-dx_lat,data.le_other.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(2+dx_lat,le_other.quantiles,kv.MarkerSize, LineColor)
        plot(2+dx_lat,le_other.mean,Marker,'MarkerSize',kv.MarkerSize, 'MarkerFaceColor', LineColor, 'MarkerEdgeColor', LineColor)
        
        ylabel('RMS Lateral Error [deg]','FontSize',kv.FontSize)
        set(gca,'YLim',[-10 60],'XLim',[0.5 2.5],...
          'XTick',1:2,'XTickLabel',{'Own' 'Other'},'FontSize',kv.FontSize,...
            'TickLength',2*get(gca,'TickLength'))

        subplot(1, 5, 2)
        middlebroxplot(1-dx_lat,data.lb_own.quantiles,kv.MarkerSize, data.LineColor)
        plot(1-dx_lat,data.lb_own.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(1+dx_lat,lb_own.quantiles,kv.MarkerSize, LineColor)
        plot(1+dx_lat,lb_own.mean,Marker,'MarkerSize',kv.MarkerSize, 'MarkerFaceColor', LineColor, 'MarkerEdgeColor', LineColor)
        
        middlebroxplot(2-dx_lat,data.lb_other.quantiles,kv.MarkerSize, data.LineColor)
        plot(2-dx_lat,data.lb_other.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(2+dx_lat,lb_other.quantiles,kv.MarkerSize, LineColor)
        plot(2+dx_lat,lb_other.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor', LineColor, 'MarkerEdgeColor', LineColor)
        ylabel('Magnitude Lateral Bias [deg]','FontSize',kv.FontSize)
        set(gca,'YLim',[-10 60],'XLim',[0.5 2.5],...
          'XTick',1:2,'XTickLabel',{'Own' 'Other'},'FontSize',kv.FontSize,...
            'TickLength',2*get(gca,'TickLength'))

        subplot(1, 5, 3)
        middlebroxplot(1-dx,data.qe_own.quantiles,kv.MarkerSize, data.LineColor)
        midd = plot(1-dx,data.qe_own.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor);
        middlebroxplot(1,qe_own.quantiles,kv.MarkerSize, LineColor)
        reij = plot(1,qe_own.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor', LineColor, 'MarkerEdgeColor', LineColor);
        middlebroxplot(1+dx,data_baum.qe_own.quantiles,kv.MarkerSize, data_baum.LineColor)
        baum = plot(1+dx,data_baum.qe_own.mean,data_baum.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor', data_baum.LineColor, 'MarkerEdgeColor', data_baum.LineColor);
        
        middlebroxplot(2-dx,data.qe_other.quantiles,kv.MarkerSize, data.LineColor)
        plot(2-dx,data.qe_other.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(2,qe_other.quantiles,kv.MarkerSize, LineColor)
        plot(2,qe_other.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor', LineColor, 'MarkerEdgeColor', LineColor)
        middlebroxplot(2+dx,data_baum.qe_other.quantiles,kv.MarkerSize, data_baum.LineColor)
        plot(2+dx,data_baum.qe_other.mean,data_baum.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor', data_baum.LineColor, 'MarkerEdgeColor', data_baum.LineColor)
        
        ylabel('Quadrant Errors (%)','FontSize',kv.FontSize)
        set(gca,'YLim',[0 50],'XLim',[0.5 2.5],...
          'XTick',1:2,'XTickLabel',{'Own' 'Other'},'FontSize',kv.FontSize,...
            'TickLength',2*get(gca,'TickLength'))
        leg = legend([midd, reij, baum], {'Actual', 'SA', 'SP'}, 'Location', 'none');
        leg.Units = 'normalized';
        leg.Position = [0.4745,0.831536390309064,0.097524379329044,0.159029645257883];

        subplot(1, 5, 4)
        middlebroxplot(1-dx,data.pe_own.quantiles,kv.MarkerSize, data.LineColor)
        plot(1-dx,data.pe_own.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(1,pe_own.quantiles,kv.MarkerSize, LineColor)
        plot(1,pe_own.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',LineColor, 'MarkerEdgeColor', LineColor)
        middlebroxplot(1+dx,data_baum.pe_own.quantiles,kv.MarkerSize, data_baum.LineColor)
        plot(1+dx,data_baum.pe_own.mean,data_baum.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data_baum.LineColor, 'MarkerEdgeColor', data_baum.LineColor)
        
        middlebroxplot(2-dx,data.pe_other.quantiles,kv.MarkerSize, data.LineColor)
        plot(2-dx,data.pe_other.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(2,pe_other.quantiles,kv.MarkerSize, LineColor)
        plot(2,pe_other.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',LineColor, 'MarkerEdgeColor', LineColor)
        middlebroxplot(2+dx,data_baum.pe_other.quantiles,kv.MarkerSize, data_baum.LineColor)
        plot(2+dx,data_baum.pe_other.mean,data_baum.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data_baum.LineColor, 'MarkerEdgeColor', data_baum.LineColor)
        
        ylabel('Local Polar RMS Error (deg)','FontSize',kv.FontSize)
        set(gca,'YLim',[-10 60],'XLim',[0.5 2.5],...
          'XTick',1:2,'XTickLabel',{'Own' 'Other'},'FontSize',kv.FontSize,...
            'TickLength',2*get(gca,'TickLength'))

        subplot(1, 5, 5)
        middlebroxplot(1-dx,data.pb_own.quantiles,kv.MarkerSize, data.LineColor)
        plot(1-dx,data.pb_own.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(1,pb_own.quantiles,kv.MarkerSize, LineColor)
        plot(1,pb_own.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',LineColor, 'MarkerEdgeColor', LineColor)
        middlebroxplot(1+dx,data_baum.pb_own.quantiles,kv.MarkerSize, data_baum.LineColor)
        plot(1+dx,data_baum.pb_own.mean,data_baum.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data_baum.LineColor, 'MarkerEdgeColor', data_baum.LineColor)
        
        middlebroxplot(2-dx,data.pb_other.quantiles,kv.MarkerSize, data.LineColor)
        plot(2-dx,data.pb_other.mean,data.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',data.LineColor)
        middlebroxplot(2,pb_other.quantiles,kv.MarkerSize, LineColor)
        plot(2,pb_other.mean,Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor',LineColor, 'MarkerEdgeColor', LineColor)
        middlebroxplot(2+dx,data_baum.pb_other.quantiles,kv.MarkerSize, data_baum.LineColor)
        plot(2+dx,data_baum.pb_other.mean,data_baum.Marker,'MarkerSize',kv.MarkerSize,'MarkerFaceColor', data_baum.LineColor, 'MarkerEdgeColor', data_baum.LineColor)
        
        ylabel('Magnitude of Elevation Bias (deg)','FontSize',kv.FontSize)
        set(gca,'YLim',[-10 60],'XLim',[0.5 2.5],...
          'XTick',1:2,'XTickLabel',{'Own' 'Other'},'FontSize',kv.FontSize,...
            'TickLength',2*get(gca,'TickLength'))
    end
end

%% ------ fig3_barumerli2020forum -------------------------------------
if flags.do_fig3_barumerli2020forum
    fig3_barumerli2020forum = [];

    if ~flags.do_redo
        fig3_barumerli2020forum = amt_cache('get', ...
            'fig3_barumerli2020forum',flags.cachemode);
    end
    
    if isempty(fig3_barumerli2020forum)
        % Settings
        num_exp = 1;

        % Load Data
        % Speech Samples from Harvard Word list
        speechsample = amt_cache('get','../experiments%2Fexp_baumgartner2014.m/best2005speechSamples');
        samples_num = length(speechsample);
        % FIR Low-pass filters at 8kHz
        % Brick-wall (aka sinc-filter): fir1(200,1/3) -> -60 dB
        x=amt_load('baumgartner2014','highfreqatten_filters.mat');
        LP{1} = [1 zeros(1,100)];
        LP{2} = x.fir20db;
        LP{3} = x.fir40db;
        LP{4} = x.fir60db;

        % Model Data
        sbj_dtf = data_baumgartner2014('pool', 'cached');

        estimations = struct('doa', struct([]));
        est_expflat = repmat(estimations, length(sbj_dtf), 1); 

        est_expLP = repmat(estimations, ...
            length(sbj_dtf),length(LP),length(speechsample)); 
        
        % Simulations
        amt_disp('Processing subjects HRIR');
        for i = 1:length(sbj_dtf)
            amt_disp(['Pre-processing subject #' num2str(i)],'progress');

            % noise stimulus
            [sbj_template(i), sbj_target_flat(i)] = ...
                reijniers2014_preproc(sbj_dtf(i).Obj);

            % flat spectrum estimations
            est_expflat(i, 1).doa = ... 
                reijniers2014(sbj_template(i), sbj_target_flat(i), 'num_exp', num_exp);

            amt_disp('Computing localization');
            for f = 1:length(LP)
                amt_disp(sprintf('Filter %i\n', f))
                parfor s = 1:samples_num
                    stim = filter(LP{f},1,speechsample{s});

                    [~, trgt] = ...
                            reijniers2014_preproc(sbj_dtf(i).Obj, ...
                            'source_ir', stim);
                    est_expLP(i, f, s).doa = ... 
                            reijniers2014(sbj_template(i), trgt, 'num_exp', num_exp);
                end
            end
        end

        % metrics
        % allocate memory for results
        % aggregate over different lateral angles
        ale_expflat = zeros(length(sbj_dtf),1);
        ale_expLP = zeros(length(sbj_dtf),length(LP), samples_num);
        ape_expflat = zeros(length(sbj_dtf),1);
        ape_expLP = zeros(length(sbj_dtf),length(LP), samples_num);
        qe_expflat = zeros(length(sbj_dtf),1);
        qe_expLP = zeros(length(sbj_dtf),length(LP), samples_num);

        for i = 1:length(sbj_dtf)
            amt_disp(['Computing metrics #' num2str(i)],'progress');

            % flat spectrum estimations
            ale_expflat(i,1) = reijniers2014_metrics(est_expflat(i, 1).doa, 'accabsL');
            ape_expflat(i,1) = reijniers2014_metrics(est_expflat(i, 1).doa, 'accabsP');
            qe_expflat(i,1) = reijniers2014_metrics(est_expflat(i, 1).doa, 'querr');

            for f = 1:length(LP)
                for s = 1:samples_num
                    ale_expLP(i, f, s) = reijniers2014_metrics(est_expLP(i, f, s).doa, 'accabsL');
                    ape_expLP(i, f, s) = reijniers2014_metrics(est_expLP(i, f, s).doa, 'accabsP');
                    qe_expLP(i, f, s) = reijniers2014_metrics(est_expLP(i, f, s).doa, 'querr');
                end
            end
        end

        % save cache
        fig3_barumerli2020forum.ale_expflat = ale_expflat;
        fig3_barumerli2020forum.ale_expLP   = ale_expLP;
        fig3_barumerli2020forum.ape_expflat = ape_expflat;
        fig3_barumerli2020forum.ape_expLP   = ape_expLP;        
        fig3_barumerli2020forum.qe_expflat  = qe_expflat;
        fig3_barumerli2020forum.qe_expLP    = qe_expLP;
        
        amt_cache('set','fig3_barumerli2020forum', fig3_barumerli2020forum);
    end
    varargout{1} = [fig3_barumerli2020forum];
    
    ale_expflat = fig3_barumerli2020forum.ale_expflat;
    ale_expLP = fig3_barumerli2020forum.ale_expLP;
    ape_expflat = fig3_barumerli2020forum.ape_expflat;
    ape_expLP = fig3_barumerli2020forum.ape_expLP;        
    qe_expflat = fig3_barumerli2020forum.qe_expflat;
    qe_expLP = fig3_barumerli2020forum.qe_expLP;
    
    % load real and baum2014 data
    data = data_best2005;

    % DCN enabled
    [baum_temp, ~] = exp_baumgartner2014('fig11', 'noplot'); 
    data_baum.ape = zeros(size(ape_expLP));
    data_baum.qe = zeros(size(qe_expLP));
    
    for i = 1:size(ape_expLP,3)
        data_baum.ape(:,:,i) = transpose(baum_temp{1}(:,:,i));
        data_baum.qe(:,:,i) = transpose(baum_temp{2}(:,:,i));
    end

    data_baum.ape_expflat = baum_temp{3};
    data_baum.qe_expflat = baum_temp{4};
     
    % Pool Samples
    ale_pooled = mean(ale_expLP,3);
    ape_pooled = mean(ape_expLP,3);
    qe_pooled = mean(qe_expLP,3);
    data_baum.ape_pooled = mean(data_baum.ape,3);
    data_baum.qe_pooled = mean(data_baum.qe,3);
    
    % Confidence Intervals or standard errors
    % reijniers model 
    df_speech = size(ale_expLP,1)-1;
    tquant_speech = 1;
    seale_speech = std(ale_pooled,0,1)*tquant_speech/(df_speech+1);
    df_noise = size(ale_expflat,1)-1;
    tquant_noise = 1;
    seale_noise = std(ale_expflat)*tquant_noise/(df_noise+1);
    seale = [seale_noise, seale_speech];
    
    df_speech = size(ape_expLP,1)-1;
    tquant_speech = 1;
    seape_speech = std(ape_pooled,0,1)*tquant_speech/(df_speech+1);
    df_noise = size(ape_expflat,1)-1;
    tquant_noise = 1;
    seape_noise = std(ape_expflat)*tquant_noise/(df_noise+1);
    seape = [seape_noise, seape_speech];
    
    % baumgartner2014 model
    df_speech = size(data_baum.ape,1)-1;
    tquant_speech = 1;
    seape_speech = std(data_baum.ape_pooled,0,1)*tquant_speech/(df_speech+1);
    df_noise = size(data_baum.ape_expflat,1)-1;
    tquant_noise = 1;
    seape_noise = std(data_baum.ape_expflat)*tquant_noise/(df_noise+1);
    data_baum.seape = [seape_noise, seape_speech];
    
    % averages
    % reij2014
    ale = mean([ale_expflat, ale_pooled],1);
    ape = mean([ape_expflat, ape_pooled],1);
    qe = mean([qe_expflat, qe_pooled],1);

    % baum2014
    data_baum.ape = mean([data_baum.ape_expflat', data_baum.ape_pooled],1);
    data_baum.qe = mean([data_baum.qe_expflat', data_baum.qe_pooled],1);

    if flags.do_plot
        MarkerSize = kv.MarkerSize;
        FontSize = kv.FontSize;
        LineColor = [0 0.4470 0.7410];
        Marker = 's-';
        data.Marker = 'o-';
        data.LineColor = [1 1 1]*0.3;
        data_baum.Marker = 'd--';
        data_baum.LineColor = [0.8500 0.3250 0.0980];
        
        mFig = figure;
        mFig.Units = 'centimeters';
        mFig.Position = [5,5,13.5,15];
        
        dx = 0;
        xticks = 0:size(ale_pooled,2);
        subplot(3,1,1)
        plot(xticks-dx,data.ale, data.Marker,'Color', data.LineColor, 'MarkerFaceColor',data.LineColor,'MarkerSize',MarkerSize)
        hold on
        plot(xticks-dx,ale, Marker,'Color', LineColor, 'MarkerFaceColor',LineColor,'MarkerSize',MarkerSize)
        ylabel('Lateral Error (deg)','FontSize',FontSize)
        set(gca,'XTick',xticks,'XTickLabel',[],'FontSize',FontSize)
        set(gca,'XLim',[-0.5 4.5],'YLim',[0 75],'YMinorTick','on')

        subplot(3,1,2)
        plot(xticks,data.ape,data.Marker,'Color', data.LineColor, 'MarkerFaceColor',data.LineColor,'MarkerSize',MarkerSize)
        hold on
        plot(xticks-dx,ape, Marker,'Color', LineColor, 'MarkerFaceColor',LineColor,'MarkerSize',MarkerSize)
        plot(xticks,data_baum.ape, data_baum.Marker,'Color', data_baum.LineColor, 'MarkerFaceColor',data_baum.LineColor,'MarkerSize',MarkerSize)
        ylabel('Polar Error (deg)','FontSize',FontSize)
        set(gca,'XTick',xticks,'XTickLabel',[],'FontSize',FontSize)
        set(gca,'XLim',[-0.5 4.5],'YLim',[0 75],'YMinorTick','on')

        subplot(3,1,3)
        best = plot(xticks([1 2 5]),data.qe([1 2 5]), data.Marker,'Color', data.LineColor, 'MarkerFaceColor',data.LineColor,'MarkerSize',MarkerSize);
        hold on
        reij = plot(xticks-dx,qe, Marker,'Color', LineColor, 'MarkerFaceColor',LineColor,'MarkerSize',MarkerSize);
        baum = plot(xticks,data_baum.qe, data_baum.Marker,'Color', data_baum.LineColor, 'MarkerFaceColor',data_baum.LineColor,'MarkerSize',MarkerSize);
        ylabel('Quadrant Err. (%)','FontSize',FontSize)
        set(gca,'XTick',xticks,'XTickLabel',data.meta,'FontSize',FontSize,...
        'XLim',[-0.5 4.5],'YLim',[-3 54],'YMinorTick','on')
        
        leg = legend([best, reij, baum], {'Actual', 'SA', 'SP'});
        leg.FontSize = FontSize - 1;
        leg.Units = 'centimeters';
        leg.Position = [9.281,12.762,3.466,1.561];
    end
end

if flags.do_fig4_barumerli2020forum
    fig4_barumerli2020forum = [];

    if ~flags.do_redo
        fig4_barumerli2020forum = amt_cache('get', ...
            'fig4_barumerli2020forum',flags.cachemode);
    end
    
    if isempty(fig4_barumerli2020forum)
        % load 23 DTFs from baumgartner2014         
        amt_disp('Loading SOFA files');
        sbj_dtf = data_baumgartner2014('pool','global');        
        num_exp = 5;
        
        % generate stimulus
        % copyed from exp_baumgartner2014/do_fig10
        density = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 6, 8]; % ripples/oct
        depth =   10:10:40;        % ripple depth (peak-to-trough) in dB
        
        % 250-ms bursts, 20-ms raised-cosine fade in/out, flat from 0.6-16kHz
        fs = sbj_dtf(1).Obj.Data.SamplingRate;
        flow = 1e3;   % lower corner frequency of ripple modification in Hz
        fhigh = 16e3; % upper corner frequency of ripple modification in Hz
        Nf = 2^10;    % # Frequency bins

        f = 0:fs/2/Nf:fs/2;	% frequency bins
        id600 = find(f<=600,1,'last'); % index of 600 Hz (lower corner frequency of stimulus energy)
        idlow = find(f<=flow,1,'last'); % index of flow (ripples)
        idhigh = find(f>=fhigh,1,'first');  % index of fhigh (ripples)
        N600low = idlow - id600 +1;   % # bins without ripple modification
        Nlowhigh = idhigh - idlow +1; % # bins with ripple modification     % 
        O = log2(f(idlow:idhigh)/1e3);   % freq. trafo. to achieve equal ripple density in log. freq. scale

        % Raised-cosine "(i.e., cos^2)" ramp 1/8 octave wide
        fup = f(idlow)*2^(1/8);       % upper corner frequency of ramp upwards 
        idup = find(f<=fup,1,'last');
        Nup = idup-idlow+1;
        rampup = cos(-pi/2:pi/2/(Nup-1):0).^2;
        fdown = f(idhigh)*2^(-1/8);  % lower corner frequency of ramp downwards
        iddown = find(f>=fdown,1,'first');
        Ndown = idhigh-iddown+1;
        rampdown = cos(0:pi/2/(Ndown-1):pi/2).^2;
        ramp = [rampup ones(1,Nlowhigh-Nup-Ndown) rampdown];
        ramp = [-inf*ones(1,id600-1) zeros(1,N600low) ramp -inf*ones(1,Nf - idhigh)];

        % Ripples of Experiment I
        Sexp1 = zeros(Nf+1,length(density),2);  % 3rd dim: 1:0-phase 2:pi-phase
        Sexp1(idlow:idhigh,:,1) = (40/2* sin(2*pi*density'*O+ 0))';  % depth: 40dB, 0-phase
        Sexp1(idlow:idhigh,:,2) = (40/2* sin(2*pi*density'*O+pi))';  % depth: 40dB, pi-phase
        Sexp1 = repmat(ramp',[1,length(density),2]) .* Sexp1;
        Sexp1 = [Sexp1;Sexp1(Nf:-1:2,:,:)];
        Sexp1(isnan(Sexp1)) = -100;
        sexp1 = ifftreal(10.^(Sexp1/20),2*Nf);
        sexp1 = circshift(sexp1,Nf);  % IR corresponding to ripple modification
        % Ripples of Experiment II
        Sexp2 = zeros(Nf+1,length(depth),2);  % 3rd dim: 1:0-phase 2:pi-phase
        Sexp2(idlow:idhigh,:,1) = (depth(:)/2*sin(2*pi*1*O+ 0))';  % density: 1 ripple/oct, 0-phase
        Sexp2(idlow:idhigh,:,2) = (depth(:)/2*sin(2*pi*1*O+pi))';  % density: 1 ripple/oct, pi-phase
        Sexp2 = repmat(ramp',[1,length(depth),2]) .* Sexp2;
        Sexp2 = [Sexp2;Sexp2(Nf-1:-1:2,:,:)];
        Sexp2(isnan(Sexp2)) = -100;
        sexp2 = ifftreal(10.^(Sexp2/20),2*Nf);
        sexp2 = circshift(sexp2,Nf);  % IR corresponding to ripple modification
                        
        % preprocess templates for each user
        amt_disp('Processing subjects HRIR');
        for i = 1:length(sbj_dtf)
            % extract directions
            % filter targets' coordinates
            % convert from spherical to horizontal-polar coordinates
            horpolar_coords = SOFAconvertCoordinates(...
                                sbj_dtf(i).Obj.SourcePosition, ...
                                'spherical', 'horizontal-polar');   
            % polar in [60, 120]
            % lateral = 0
            idx = find(((horpolar_coords(:, 2) >= 300 ...
                            | horpolar_coords(:, 2) <= 60) ...
                            | (horpolar_coords(:, 2) >= 120 & ...
                                    horpolar_coords(:, 2) <= 240)) ...
                            & (horpolar_coords(:, 1) <= 30 & horpolar_coords(:, 1) >= -30));

            amt_disp(['Pre-processing subject #' num2str(i)],'progress');
            [sbj_template(i), sbj_target_flat(i)] = ...
                reijniers2014_preproc(sbj_dtf(i).Obj, ...
                    'targ_az', sbj_dtf(i).Obj.SourcePosition(idx, 1), ...
                    'targ_el', sbj_dtf(i).Obj.SourcePosition(idx, 2));
            
            amt_disp('Densities conditions');
            parfor j = 1:length(density)
                [~, sbj_target_exp1(i, j)] = ...
                    reijniers2014_preproc(sbj_dtf(i).Obj, ...
                    'source_ir', squeeze(sexp1(:, j, :)), ...
                    'targ_az', sbj_dtf(i).Obj.SourcePosition(idx, 1), ...
                    'targ_el', sbj_dtf(i).Obj.SourcePosition(idx, 2));
            end
            
            amt_disp('Depth conditions');
            parfor j = 1:length(depth)
                [~, sbj_target_exp2(i, j)] = ...
                    reijniers2014_preproc(sbj_dtf(i).Obj, ...
                    'source_ir', squeeze(sexp2(:, j, :)), ...
                    'targ_az', sbj_dtf(i).Obj.SourcePosition(idx, 1), ...
                    'targ_el', sbj_dtf(i).Obj.SourcePosition(idx, 2));
            end
        end
        
        % preallocation for results
        amt_disp('Allocating memory for results');
        estimations = struct('doa', struct([]));
        est_expflat = repmat(estimations, length(sbj_dtf)); 
        est_exp1 = repmat(estimations, ...
            length(sbj_dtf),length(density)); 
        est_exp2 = repmat(estimations, ...
            length(sbj_dtf),length(depth)); 

        % simulations
        for i = 1:length(sbj_dtf)
            amt_disp(['Processing subject #' num2str(i)],'progress');
            % flat spectrum estimations
            est_expflat(i, 1).doa = ... 
                reijniers2014(sbj_template(i), sbj_target_flat(i), 'num_exp', num_exp);
            
            % rippled estimations
            parfor j = 1:length(density)
                est_exp1(i, j).doa = ... 
                    reijniers2014(sbj_template(i), sbj_target_exp1(i, j), 'num_exp', num_exp);
            end
            
            parfor j =1:length(depth)
                est_exp2(i, j).doa = ... 
                reijniers2014(sbj_template(i), sbj_target_exp2(i, j), 'num_exp', num_exp);
            end
        end        

        % metrics
        % allocate memory for results
        % aggregate over different lateral angles
        pe_exp1 = zeros(length(sbj_dtf),length(density));
        pe_exp2 = zeros(length(sbj_dtf),length(depth));
        pe_flat = zeros(length(sbj_dtf), 1);

        for i = 1:length(sbj_dtf)
            % compute regression (see paper)   
            [f,r] = reijniers2014_metrics(est_expflat(i).doa,'sirpMacpherson2000');
            pe_flat(i) = reijniers2014_metrics(est_expflat(i).doa,f,r,'perMacpherson2003');

            for j = 1:size(est_exp1, 2)
                pe_exp1(i, j) = reijniers2014_metrics(est_exp1(i, j).doa, f, r, 'perMacpherson2003');
            end
            
            for j = 1:size(est_exp2, 2)
                pe_exp2(i, j) = reijniers2014_metrics(est_exp2(i, j).doa, f, r, 'perMacpherson2003');
            end
        end

        
        % save cache
        fig4_barumerli2020forum.pe_flat = pe_flat;
        fig4_barumerli2020forum.pe_exp1 = pe_exp1;
        fig4_barumerli2020forum.pe_exp2 = pe_exp2;
        amt_cache('set','fig4_barumerli2020forum', fig4_barumerli2020forum);
    end
    
    % simulations data
    pe_flat = fig4_barumerli2020forum.pe_flat;
    pe_exp1 = fig4_barumerli2020forum.pe_exp1;
    pe_exp2 = fig4_barumerli2020forum.pe_exp2;
    
    % Original data:
    data = data_macpherson2003;
    
    % Baumgartner2014's data
    % varargout{1} = {pe_exp1,pe_exp2,pe_flat,noDCN};
    data_baum_temp = exp_baumgartner2014('fig10', 'noplot');
    data_baum.pe_exp1 = data_baum_temp{1,1};
    data_baum.pe_exp2 = data_baum_temp{1,2};
    data_baum.pe_flat = data_baum_temp{1,3};
   
    % Phase condition handling
    % average across the phase condition
    % real data
    data.pe_exp1 = mean(data.pe_exp1,3);
    data.pe_exp2 = mean(data.pe_exp2,3);
    % baumgartner data 
    data_baum.pe_exp1 = mean(data_baum.pe_exp1,3);
    data_baum.pe_exp2 = mean(data_baum.pe_exp2,3);
    idphase = 1;

    % Increase
    % simulations
    pe_exp1 = pe_exp1 - pe_flat(:);
    pe_exp2 = pe_exp2 - pe_flat(:);
    % baumgartner data
    data_baum.pe_exp1 = data_baum.pe_exp1 - repmat(data_baum.pe_flat(:),1,size(data_baum.pe_exp1,2));
    data_baum.pe_exp2 = data_baum.pe_exp2 - repmat(data_baum.pe_flat(:),1,size(data_baum.pe_exp2,2));

    % Statistics
    % simulations
    quart_pe_flat = quantile(pe_flat,[.25 .50 .75]);
    quart_pe_exp1 = quantile(pe_exp1,[.25 .50 .75]);
    quart_pe_exp2 = quantile(pe_exp2,[.25 .50 .75]);
    
    % real data
    data.quart_pe_flat = quantile(data.pe_flat,[.25 .50 .75]);
    data.quart_pe_exp1 = quantile(data.pe_exp1,[.25 .50 .75]);
    data.quart_pe_exp2 = quantile(data.pe_exp2,[.25 .50 .75]);

    % baumgartner data
    data_baum.quart_pe_flat = quantile(data_baum.pe_flat,[.25 .50 .75]);
    data_baum.quart_pe_exp1 = quantile(data_baum.pe_exp1,[.25 .50 .75]);
    data_baum.quart_pe_exp2 = quantile(data_baum.pe_exp2,[.25 .50 .75]);

    % plot
    if flags.do_plot
        dx = 1.05;
        FontSize = kv.FontSize;
        MarkerSize = kv.MarkerSize;

        LineColor = [0 0.4470 0.7410];
        data.Marker = 'ko-';
        data.LineColor = [1 1 1]*0.3;
        data_baum.Marker = 'd-';
        data_baum.LineColor = [0.8500 0.3250 0.0980];
        
        % Exp1
        mFig = figure;
        mFig.Units = 'centimeters';
        mFig.Position = [5,5,13.5,12];
        subplot(2,8,1:8)
        mach = errorbar(data.density,data.quart_pe_exp1(2,:,idphase),...
        data.quart_pe_exp1(2,:,idphase) - data.quart_pe_exp1(1,:,idphase),...
        data.quart_pe_exp1(3,:,idphase) - data.quart_pe_exp1(2,:,idphase),...
        'o-','MarkerSize',MarkerSize, 'Color', data.LineColor, ...
        'MarkerFaceColor', data.LineColor);
        hold on
        reij = errorbar(data.density/dx,quart_pe_exp1(2,:,idphase),...
        quart_pe_exp1(2,:,idphase) - quart_pe_exp1(1,:,idphase),...
        quart_pe_exp1(3,:,idphase) - quart_pe_exp1(2,:,idphase),...
        's-','MarkerSize',MarkerSize, 'Color', LineColor,'MarkerFaceColor',LineColor);
        hold on
        baum = errorbar(data.density*dx,data_baum.quart_pe_exp1(2,:,idphase),...
        data_baum.quart_pe_exp1(2,:,idphase) - data_baum.quart_pe_exp1(1,:,idphase),...
        data_baum.quart_pe_exp1(3,:,idphase) - data_baum.quart_pe_exp1(2,:,idphase),...
        'd--','MarkerSize',MarkerSize, 'Color', data_baum.LineColor,'MarkerFaceColor',data_baum.LineColor);
        
        set(gca,'XScale','log','YMinorTick','on')
        set(gca,'XLim',[0.25/1.2 8*1.2],'XTick',data.density,'YLim',[-16 59],'FontSize',FontSize)
        xlabel('Ripple Density (ripples/octave)','FontSize',FontSize)
        ylabel({'Increase in';'Polar Error Rate (%)'},'FontSize',FontSize)
        
        % Exp2
        subplot(2,8,9:13)
        errorbar(data.depth,data.quart_pe_exp2(2,:,idphase),...
        data.quart_pe_exp2(2,:,idphase) - data.quart_pe_exp2(1,:,idphase),...
        data.quart_pe_exp2(3,:,idphase) - data.quart_pe_exp2(2,:,idphase),...
        'o-','MarkerSize',MarkerSize, 'Color', data.LineColor, ...
        'MarkerFaceColor', data.LineColor);
        hold on
        errorbar(data.depth-1,quart_pe_exp2(2,:,idphase),...
        quart_pe_exp2(2,:,idphase) - quart_pe_exp2(1,:,idphase),...
        quart_pe_exp2(3,:,idphase) - quart_pe_exp2(2,:,idphase),...
        's-','MarkerSize',MarkerSize, 'Color', LineColor,'MarkerFaceColor',LineColor);
        hold on
        errorbar(data.depth+1,data_baum.quart_pe_exp2(2,:,idphase),...
        data_baum.quart_pe_exp2(2,:,idphase) - data_baum.quart_pe_exp2(1,:,idphase),...
        data_baum.quart_pe_exp2(3,:,idphase) - data_baum.quart_pe_exp2(2,:,idphase),...
        'd--','MarkerSize',MarkerSize, 'Color', data_baum.LineColor,'MarkerFaceColor',data_baum.LineColor);

        set(gca,'XLim',[data.depth(1)-5 data.depth(end)+5],'XTick',data.depth,...
        'YLim',[-16 59],'YMinorTick','on','FontSize',FontSize)
        xlabel('Ripple Depth (dB)','FontSize',FontSize)
        ylabel({'Increase in';'Polar Error Rate (%)'},'FontSize',FontSize)
        ytick = get(gca,'YTick');
        ticklength = get(gca,'TickLength');

        % Baseline
        subplot(2,8,14:15)
        errorbar(-0.5,data.quart_pe_flat(2),...
        data.quart_pe_flat(2) - data.quart_pe_flat(1),...
        data.quart_pe_flat(3) - data.quart_pe_flat(2),...
        'o-','MarkerSize',MarkerSize, 'Color', data.LineColor, ...
        'MarkerFaceColor', data.LineColor);
        hold on
        errorbar(0,quart_pe_flat(2),...
        quart_pe_flat(2) - quart_pe_flat(1),...
        quart_pe_flat(3) - quart_pe_flat(2),...
        's-','MarkerSize',MarkerSize, 'Color', LineColor,'MarkerFaceColor',LineColor);
        hold on
        errorbar(0.5,data_baum.quart_pe_flat(2),...
        data_baum.quart_pe_flat(2) - data_baum.quart_pe_flat(1),...
        data_baum.quart_pe_flat(3) - data_baum.quart_pe_flat(2),...
        'd--','MarkerSize',MarkerSize, 'Color', data_baum.LineColor,'MarkerFaceColor',data_baum.LineColor);

        set(gca,'XLim',[-3 3],'XTick',0,'XTickLabel',{'Baseline'},...
        'YLim',[-15 59],'YTick',ytick,'TickLength',3*ticklength,...
        'FontSize',FontSize,'YAxisLocation','right')
        xlabel(' ','FontSize',FontSize)
        ylabel({'Polar Error Rate (%)'},'FontSize',FontSize)

        %legend
        leg = legend([mach, reij, baum], {'Actual', 'SA', 'SP'});
        leg.FontSize = FontSize - 1;
        leg.Units = 'centimeters';
        leg.Position = [9.281,10,3.466,1.561];
        
        % Overall correlation between actual and predicted median values
        m_pe_pred = [quart_pe_exp1(2,:,idphase) quart_pe_exp2(2,:,idphase)];
        m_pe_actual = [data.quart_pe_exp1(2,:,idphase) data.quart_pe_exp2(2,:,idphase)];
        r = corrcoef(m_pe_pred,m_pe_actual);
        r_sqr = r(2);

        amt_disp('Correlation between actual and predicted median values (15 conditions):')
        amt_disp(['w/  PSGE: r = ' num2str(r_sqr,'%0.2f')])
    end
    
end

function middlebroxplot(x,quantiles,MarkerSize,LineColor)
    lilen = 0.1; % length of horizontal lines

    % Symbols
    plot(x,quantiles(1),'x','MarkerSize',MarkerSize, 'MarkerEdgeColor', LineColor) % min
    hold on
    plot(x,quantiles(7),'x','MarkerSize',MarkerSize, 'MarkerEdgeColor', LineColor) % max

    % Horizontal lines
    line(x+0.5*[-lilen,lilen],repmat(quantiles(2),2),'Color',LineColor) % lower whisker
    line(x+[-lilen,lilen],repmat(quantiles(3),2),'Color',LineColor) % 25% Quartile
    line(x+[-lilen,lilen],repmat(quantiles(4),2),'Color',LineColor) % Median
    line(x+[-lilen,lilen],repmat(quantiles(5),2),'Color',LineColor) % 75% Quartile
    line(x+0.5*[-lilen,lilen],repmat(quantiles(6),2),'Color',LineColor) % upper whisker

    % Vertical lines
    line([x,x],quantiles(2:3),'Color',LineColor) % connector lower whisker
    line([x,x],quantiles(5:6),'Color',LineColor) % connector upper whisker
    line([x,x]-lilen,quantiles([3,5]),'Color',LineColor) % left box edge
    line([x,x]+lilen,quantiles([3,5]),'Color',LineColor) % left box edge