THE AUDITORY MODELING TOOLBOX

Applies to version: 0.9.8

View the help

Go to function

EXP_ZIEGELWANGER2013 - Figures from Ziegelwanger and Majdak (2013)

Program code:

function varargout=exp_ziegelwanger2013(varargin)
%EXP_ZIEGELWANGER2013   Figures from Ziegelwanger and Majdak (2013)
%   Usage: data = exp_ziegelwanger2013(flag)
%
%   EXP_ZIEGELWANGER2013(flags) reproduces figures of the paper from
%   Ziegelwanger and Majdak (2013).
%
%   Optional fields of output data structure:
%
%   The following flags can be specified:
%
%     'plot'    Plot the output of the experiment. This is the default.
%
%     'noplot'  Don't plot, print results in the console.
% 
%     'cached'	Reload previously calculated results. This is the default.
%
%     'redo'	  Recalculate results.
%
%     'fig1a'   Reproduce Fig. 1 from ziegelwanger2013:
%               Model parameters (sphere radius, sphere center) resulting
%               from fitting the off-axis model to HRTFs of human
%               listeners.
%
%     'fig1b'    Reproduce Fig. 1 from majdak2013:
%               
%               Left panel: 
%               Normalized HRIRs of NH89 (ARI database). Sound source was
%               placed 45 deg left in the horizontal plane.
%               Solid line: for the left ear
%               Dashed line: for the right ear
%               Vertical lines: Estimated TOAs
%               Arrows: Resulting ITDs from the corresponding TOAs
%               Circles, Red: Minimum-Phase Cross-Correlation Method
%               Triangle, Green: Time-Position of the HRIR-Maximum
%               Diamonds, Blue: Centroid of the HRIR
%               Squares, Magenta: Average Group Delay (1-5 kHz)
%               
%               Right panel: 
%               Estimated TOAs of NH89 (ARI database) in the horizontal
%               interaural plane.
%               Black: Minimum-Phase Cross-Correlation Method
%               Blue: Time-Position of the HRIR-Maximum
%               Green: Centroid of the HRIR
%               Red: Average Group Delay (1-5 kHz)
%
%     'fig2b'    Reproduce Fig. 2 from majdak2013:
%               
%               Right panel: 
%               Estimated TOAs, detected outliers and outlier adjusted set
%               of TOAs for NH89 (ARI database) in the horizontal plane.
%               Line: Estimated TOAs
%               Triangles (down), Blue: Detected outliers for the azimuthal
%               slope criterion
%               Triangles (up), Blue: Detected outliers for the sagittal
%               variance criterion
%               Dots, Red: Outlier-adjusted set
%
%     'fig3b'    Reproduce Fig. 3 from majdak2013:
%
%               Left panel:
%               Model parameters (sphere radius, ear position) resulting
%               from fitting the on-axis model to HRTFs of a rigid sphere.
%               Squares: for the left ear
%               Diamonds: for the right ear
%               Dashed lines: set values used in the numerical HRTF
%               calculation
%
%               Right panel:
%               Model parameters (sphere radius) resulting from fitting the
%               on-axis model to HRTFs of an off-axis placed rigid sphere.
%
%
%   Requirements: 
%   -------------
%
%   1) SOFA API from http://sourceforge.net/projects/sofacoustics for Matlab (in e.g. thirdparty/SOFA)
% 
%   2) Optimization Toolbox for Matlab
%
%   3) Data in hrtf/ziegelwanger2013
%
%   Examples:
%   ---------
%
%   To display Fig. 1a, use :
%
%     exp_ziegelwanger2013('fig1a');
%
%   To display Fig. 1b, use :
%
%     exp_ziegelwanger2013('fig1b');
%
%   To display Fig. 2b, use :
%
%     exp_ziegelwanger2013('fig2b');
%
%   To display Fig. 3b, use :
%
%     exp_ziegelwanger2013('fig3b');
%
%   See also: ziegelwanger2013, ziegelwanger2013_onaxis,
%   ziegelwanger2013_offaxis, data_ziegelwanger2013
%
%   References:
%     P. Majdak and H. Ziegelwanger. Continuous-direction model of the
%     broadband time-of-arrival in the head-related transfer functions. In
%     ICA 2013 Montreal, volume 19, page 050016, Montreal, Canada, 2013. ASA.
%     
%     H. Ziegelwanger and P. Majdak. Modeling the broadband time-of-arrival
%     of the head-related transfer functions for binaural audio. In
%     Proceedings of the 134th Convention of the Audio Engineering Society,
%     page 7, Rome, 2013.
%     
%
%   Url: http://amtoolbox.sourceforge.net/amt-0.9.8/doc/experiments/exp_ziegelwanger2013.php

% Copyright (C) 2009-2015 Piotr Majdak and Peter L. Søndergaard.
% This file is part of AMToolbox version 0.9.8
%
% 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: Harald Ziegelwanger, Acoustics Research Institute, Vienna,
% Austria

%% ------ Check input options --------------------------------------------

    definput.flags.type = {'missingflag',...
    'fig1a','fig1b','fig2b','fig3b'};
    definput.flags.plot = {'plot','noplot'};
    definput.import={'amt_cache'}; % get the flags of amt_cache
    
    % Parse input options
    [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;

%% Figure 1b
if flags.do_fig1b
    
    data=data_ziegelwanger2013('NH89',flags.cachemode);

    subplot(122)
    %---------------------------Threshold---------------------------
    [~,tmp]=ziegelwanger2013(data,1,0);
    MAX=tmp.toa;

    %---------------------------Centroid----------------------------
    [~,tmp]=ziegelwanger2013(data,2,0);
    CTD=tmp.toa;

    %---------------------------Groupdelay--------------------------
    [~,tmp]=ziegelwanger2013(data,3,0);
    AGD=tmp.toa;

    %---------------------------Minimal-Phase-----------------------
    [~,tmp]=ziegelwanger2013(data,4,0);
    MCM=tmp.toa;
    clear tmp

    plot_ziegelwanger2013(data,MCM(:,1),4,[0 0 0]/255,0,1,1,'-',1);
    hold on
    plot_ziegelwanger2013(data,MAX(:,1),4,[0 0 80]/255,0,1,1,'--',1);
    plot_ziegelwanger2013(data,CTD(:,1),4,[50 220 50]/255,0,1,1,'-',1);
    plot_ziegelwanger2013(data,AGD(:,1),4,[250 80 80]/255,0,1,1,'--',1);
    xlim([-10 370])
    ylim([0.65 2.05])
    grid off
    legend(' MCM',' MAX',' CTD',' AGD','Location','NorthWest');
    legend boxoff
    xlabel('Azimuth (deg) ')
    ylabel('TOA (ms) ')
%     set(gca,'FontSize',ticklabelsize,'LineWidth',bw,'LineWidth',bw);%,'YTick',[-0.8 -0.4 0 0.4 0.8]
    title('');
    
    subplot(121)
    time=(0:data.API.N-1)/data.Data.SamplingRate*1000;
    MAX=round(MAX);
    CTD=round(CTD);
    AGD=round(AGD);
    MCM=round(MCM);
    idx=ARI_FindPosition(data,85,0);

    fprintf(['MAX: ITD is ' num2str(time(diff(MAX(idx,:),1,2))) ' ms\n'])
    fprintf(['CTD: ITD is ' num2str(time(diff(CTD(idx,:),1,2))) ' ms\n'])
    fprintf(['AGD: ITD is ' num2str(time(diff(AGD(idx,:),1,2))) ' ms\n'])
    fprintf(['MCM: ITD is ' num2str(time(diff(MCM(idx,:),1,2))) ' ms\n'])

    plot(time,squeeze(data.Data.IR(idx,1,:))/max(abs(data.Data.IR(idx,1,:))),'k-');
    hold on
    plot(time,squeeze(data.Data.IR(idx,2,:))/max(abs(data.Data.IR(idx,2,:))),'k--')
    h=stem([time(MCM(idx,1)) time(MCM(idx,1))],[-2 data.Data.IR(idx,1,MCM(idx,1))/max(abs(data.Data.IR(idx,1,:)))],'r-','BaseValue',-1);
    stem([time(CTD(idx,1)) time(CTD(idx,1))],[-2 data.Data.IR(idx,1,CTD(idx,1))/max(abs(data.Data.IR(idx,1,:)))],'g-','BaseValue',-1)
    stem([time(MAX(idx,1)) time(MAX(idx,1))],[-2 data.Data.IR(idx,1,MAX(idx,1))/max(abs(data.Data.IR(idx,1,:)))],'b-','BaseValue',-1)
    stem([time(AGD(idx,1)) time(AGD(idx,1))],[-2 data.Data.IR(idx,1,AGD(idx,1))/max(abs(data.Data.IR(idx,1,:)))],'m-','BaseValue',-1)
    stem([time(MCM(idx,2)) time(MCM(idx,2))],[-2 data.Data.IR(idx,2,MCM(idx,2))/max(abs(data.Data.IR(idx,2,:)))],'r-','BaseValue',-1)
    stem([time(CTD(idx,2)) time(CTD(idx,2))],[-2 data.Data.IR(idx,2,CTD(idx,2))/max(abs(data.Data.IR(idx,2,:)))],'g-','BaseValue',-1)
    stem([time(AGD(idx,2)) time(AGD(idx,2))],[-2 data.Data.IR(idx,2,AGD(idx,2))/max(abs(data.Data.IR(idx,2,:)))],'m-','BaseValue',-1)
    stem([time(MAX(idx,2)) time(MAX(idx,2))],[-2 data.Data.IR(idx,2,MAX(idx,2))/max(abs(data.Data.IR(idx,2,:)))],'b-','BaseValue',-1)
    plot(time(MAX(idx,1)),data.Data.IR(idx,1,MAX(idx,1))/max(abs(data.Data.IR(idx,1,:))),'b^','MarkerFaceColor','b')
    plot(time(MCM(idx,1)),data.Data.IR(idx,1,MCM(idx,1))/max(abs(data.Data.IR(idx,1,:))),'ro','MarkerFaceColor','r')
    plot(time(CTD(idx,1)),data.Data.IR(idx,1,CTD(idx,1))/max(abs(data.Data.IR(idx,1,:))),'gd','MarkerFaceColor','g')
    plot(time(AGD(idx,1)),data.Data.IR(idx,1,AGD(idx,1))/max(abs(data.Data.IR(idx,1,:))),'ms','MarkerFaceColor','m')
    plot(time(MAX(idx,2)),data.Data.IR(idx,2,MAX(idx,2))/max(abs(data.Data.IR(idx,2,:))),'b^','MarkerFaceColor','b')
    plot(time(MCM(idx,2)),data.Data.IR(idx,2,MCM(idx,2))/max(abs(data.Data.IR(idx,2,:))),'ro','MarkerFaceColor','r')
    plot(time(CTD(idx,2)),data.Data.IR(idx,2,CTD(idx,2))/max(abs(data.Data.IR(idx,2,:))),'gd','MarkerFaceColor','g')
    plot(time(AGD(idx,2)),data.Data.IR(idx,2,AGD(idx,2))/max(abs(data.Data.IR(idx,2,:))),'ms','MarkerFaceColor','m')
    xlim([0.4 2.1])
    ylim([-1.1 1.1])
    xlabel('Time (ms) ')
    ylabel('Amplitude ')
%     set(gca,'FontSize',ticklabelsize,'LineWidth',bw,'LineWidth',bw,'XTick',[2.5 3 3.5 4]);
    set(get(h,'Baseline'),'Visible','off')
end

%% Figure 2b
if flags.do_fig2b
        
    data=data_ziegelwanger2013('NH89',flags.cachemode);
    ch=1;

    p0_onaxis=[[0.0875; pi/2; 0; 0.0001] [0.0875; -pi/2; 0; 0.0001]];
    p0_onaxis=transpose(p0_onaxis);
    p_onaxis=zeros(size(p0_onaxis));
    p0_offaxis=zeros(2,7);
    p_offaxis=p0_offaxis;

    indicator=zeros(data.API.M,data.API.R);
    indicator_hor=indicator;
    indicator_sag=indicator;
    pos=zeros(data.API.M,8);
    pos(:,1:2)=data.SourcePosition(:,1:2);
    [pos(:,6),pos(:,7)]=sph2hor(data.SourcePosition(:,1),data.SourcePosition(:,2));
    pos(:,8)=cumsum(ones(data.API.M,1));
    [~,tmp]=ziegelwanger2013(data,4,0);
    toaEst=tmp.toa;

    % Outlier detection: smooth TOA in horizontal planes
    epsilon=5;
    slope=zeros(data.API.M,1);
    for ele=min(pos(:,2)):epsilon:max(pos(:,2)) %calculate slope for each elevation along azimuth
        idx=find(pos(:,2)>ele-epsilon/2 & pos(:,2)<=ele+epsilon/2);
        if numel(idx)>1
            idx(length(idx)+1)=idx(1);
            slope(idx(1:end-1),1)=diff(toaEst(idx,ch))./abs(diff(pos(idx,1)));
        end
    end
    sloperms=sqrt(sum(slope.^2)/length(slope));
    if sloperms<30/(length(find(pos(:,2)==0))/2)
        sloperms=30/(length(find(pos(:,2)==0))/2);
    end
    for ele=min(pos(:,2)):epsilon:max(pos(:,2))
        idx=find(pos(:,2)>ele-epsilon/2 & pos(:,2)<=ele+epsilon/2);
        for ii=1:length(idx)-1
            if abs(slope(idx(ii)))>sloperms
                for jj=0:1
                    if ii+jj==0 || ii+jj==length(idx)
                        indicator_hor(idx(end),ch)=1;
                    else
                        indicator_hor(idx(mod(ii+jj,length(idx))),ch)=1;
                    end
                end
            end
        end
        clear idx
    end

    % Outlier detection: constant TOA in sagittal planes
    epsilon=2;
    for ii=1:20
        sag_dev=zeros(data.API.M,1);
        for lat=-90:epsilon:90
            idx=find(pos(:,6)>lat-epsilon/2 & pos(:,6)<=lat+epsilon/2); 
            idx2=find(pos(:,6)>lat-epsilon/2 & pos(:,6)<=lat+epsilon/2 & indicator_hor(:,ch)==0 & indicator(:,ch)==0);
            if length(idx2)>2
                sag_dev(idx,1)=toaEst(idx,ch)-mean(toaEst(idx2,ch));
            end
        end
        sag_var=sqrt(sum(sag_dev.^2)/length(sag_dev));
        if sag_var<2
            sag_var=2;
        end
        indicator(:,ch)=zeros(size(indicator,1),1);
        indicator_sag(:,ch)=zeros(size(indicator_sag,1),1);
        indicator_sag(abs(sag_dev)>sag_var,ch)=ones(length(find(abs(sag_dev)>sag_var)),1);
        indicator(abs(sag_dev)>sag_var | indicator_hor(:,ch)==1,ch)=ones(length(find(abs(sag_dev)>sag_var | indicator_hor(:,ch)==1)),1);
    end

    clear sag_dev; clear sag_var;

    plot_ziegelwanger2013(data,toaEst,4,'k',0,1,1,{'-'},1);
    hold on
    h=plot_ziegelwanger2013(data,indicator_sag.*toaEst,3,'w',0,1,1,{'^'},4);
    set(h,'MarkerFaceColor','w','MarkerEdgeColor','w');
    h=plot_ziegelwanger2013(data,indicator_hor.*toaEst,3,'w',0,1,1,{'v'},4);
    set(h,'MarkerFaceColor','w','MarkerEdgeColor','w');
    h=plot_ziegelwanger2013(data,indicator_sag.*toaEst,3,'b',0,1,1,{'^'},4);
    set(h,'LineWidth',2);
    h=plot_ziegelwanger2013(data,indicator_hor.*toaEst,3,'b',0,1,1,{'v'},4);
    set(h,'LineWidth',2);
    h=plot_ziegelwanger2013(data,(-indicator+1).*toaEst,3,'r',0,1,1,{'o'},4);
    set(h,'MarkerFaceColor','r','MarkerEdgeColor','r');
    ylabel('TOA (ms)')
    xlabel('Azimuth (deg)')
    grid off
    xlim([-10 370])
    ylim([0.65 1.65])
    title('')
    set(gca,'YTick',[0.7 1 1.3 1.6])
end

%% Figure 3b
if flags.do_fig3b

    figure
    sym='sdo'; %plot symbols
    clr=[0,0,255; 255,0,0; 255,255,67]/255; %plot colors
    meclr=[0,0,255; 255,0,0; 255,255,67]/255; %marker edge colors
    
    data=data_ziegelwanger2013('SPHERE_ROT',flags.cachemode);
    
    % radii
    subplot(311)
    var=[squeeze(data.results.p_onaxis(1,1,:))*100 squeeze(data.results.p_onaxis(1,2,:))*100 data.radius(:)/10];
    for ch=1:size(data.results.p_onaxis,2)
        plot(var(:,ch),sym(ch),'MarkerEdgeColor',meclr(ch,:),'MarkerFaceColor',clr(ch,:));
        hold on
    end
    plot(var(:,3),'k--')
    clear var;
    ylabel('r in cm')

    %phi
    subplot(312)
    var=[squeeze(data.results.p_onaxis(2,1,:))/pi*180 squeeze(data.results.p_onaxis(2,2,:))/pi*180 -data.phi+ones(length(data.phi),1)*90 -data.phi-ones(length(data.phi),1)*90];
    for ch=1:size(data.results.p_onaxis,2)
        plot(var(:,ch),sym(ch),'MarkerEdgeColor',meclr(ch,:),'MarkerFaceColor',clr(ch,:));
        hold on
    end
    for ch=1:size(data.results.p_onaxis,2)
        plot(1:9,var(1:9,2+ch),'k--')
        plot(10:14,var(10:14,2+ch),'k--')
        plot(15:23,var(15:23,2+ch),'k--')
        plot(24:28,var(24:28,2+ch),'k--')
        plot(29:37,var(29:37,2+ch),'k--')
        plot(38:42,var(38:42,2+ch),'k--')
    end
    clear var;
    set(gca,'YTick',[-90 90])
    ylabel('\phi_e in deg')

    %theta
    subplot(313)
    var=[squeeze(data.results.p_onaxis(3,1,:))/pi*180 squeeze(data.results.p_onaxis(3,2,:))/pi*180 data.theta -data.theta];
    for ch=1:size(data.results.p_onaxis,2)
        plot(var(:,ch),sym(ch),'MarkerEdgeColor',meclr(ch,:),'MarkerFaceColor',clr(ch,:));
        hold on
    end
    for ch=1:size(data.results.p_onaxis,2)
        plot(1:9,var(1:9,2+ch),'k--')
        plot(10:14,var(10:14,2+ch),'k--')
        plot(15:23,var(15:23,2+ch),'k--')
        plot(24:28,var(24:28,2+ch),'k--')
        plot(29:37,var(29:37,2+ch),'k--')
        plot(38:42,var(38:42,2+ch),'k--')
    end
    clear var;
    ylabel('\theta_e in deg')
    xlabel('Condition')
    
    figure
    sym='sdo'; %plot symbols
    clr=[0,0,255; 255,0,0; 255,255,67]/255; %plot colors
    meclr=[0,0,255; 255,0,0; 255,255,67]/255; %marker edge colors
    
    data=data_ziegelwanger2013('SPHERE_DIS',flags.cachemode);
    
    p1=data.results.p_onaxis(:,:,[1:3 length(data.xM)/3+1:length(data.xM)/3+3 length(data.xM)/3*2+1:length(data.xM)/3*2+3]);
    r1=data.radius([1:3 length(data.xM)/3+1:length(data.xM)/3+3 length(data.xM)/3*2+1:length(data.xM)/3*2+3]);
    yM1=data.yM([1:3 length(data.xM)/3+1:length(data.xM)/3+3 length(data.xM)/3*2+1:length(data.xM)/3*2+3]);

    %radii
    subplot(211)
%         ymax2=round(max(max(squeeze(p1(1,:,:)*100))))+1;
    var=[squeeze(p1(1,1,:))*100 squeeze(p1(1,2,:))*100 r1/10];
    for ch=1:size(p1,2)
        plot(var(:,ch),sym(ch),'MarkerEdgeColor',meclr(ch,:),'MarkerFaceColor',clr(ch,:));
        hold on
    end
    plot(r1/10,'k--')
    clear var;
    ylabel('r in cm')

    %yM
    subplot(212)
    plot(-yM1*100,'k--')
    clear var;
    xlabel('Condition')
    ylabel('y_M in cm ')
end

%% Figure 1a
if flags.do_fig1a
    
    hrtf={'ARI','CIPIC','LISTEN'};
    sym='ods'; %plot symbols

    %-------------------------------Load Data----------------------------------
    for kk=1:length(hrtf)
        data=data_ziegelwanger2013(hrtf{kk},flags.cachemode);
        if kk==3
            data.results=data.results([1:27 29:end]);
        end
        temp1=zeros(size(data.results(1).meta.p_onaxis,1),size(data.results(1).meta.p_onaxis,2),length(data.results));
        temp3=zeros(size(data.results(1).meta.p_offaxis,1),size(data.results(1).meta.p_offaxis,2),length(data.results));
        for ii=1:length(data.results)
            temp1(:,:,ii)=data.results(ii).meta.p_onaxis;
            temp3(:,1:size(data.results(ii).meta.p_offaxis,2),ii)=data.results(ii).meta.p_offaxis;
        end
        p_onaxis{kk}=temp1;
        p_offaxis{kk}=temp3;
    end
    
    %radii
    temp=1;
    for kk=1:length(hrtf)
        var(temp:temp+size(p_onaxis{kk},3)-1,:)= ...
            [squeeze(mean(p_offaxis{kk}(1,:,:)*100,2)) kk* ...
             ones(size(p_onaxis{kk},3),1) transpose(1: ...
                                                    size(p_onaxis{kk},3))];
        varl(temp:temp+size(p_onaxis{kk},3)-1,:)= ...
            [squeeze(p_offaxis{kk}(1,1,:)*100) kk* ...
             ones(size(p_onaxis{kk},3),1) transpose(1: ...
                                                    size(p_onaxis{kk},3))];
        varr(temp:temp+size(p_onaxis{kk},3)-1,:)= ...
            [squeeze(p_offaxis{kk}(1,2,:)*100) kk* ...
             ones(size(p_onaxis{kk},3),1) transpose(1: ...
                                                    size(p_onaxis{kk},3))];
        temp=size(var,1)+1;
    end
    [~,idx]=sort(var(:,1));
    var=var(idx,:);
    varl=varl(idx,:);
    varr=varr(idx,:);
    var(:,3)=transpose(1:size(var,1));
    varl(:,3)=transpose(1:size(var,1));
    varr(:,3)=transpose(1:size(var,1));
    subplot(411)
    for kk=1:length(hrtf)
        h{kk}=plot(var(var(:,2)==kk,3),var(var(:,2)==kk,1),sym(kk),'MarkerEdgeColor','b','MarkerFaceColor','b');
        hold on
    end
    ylabel('Average r (cm)')
    xlim([-1.5 temp+1.5])
    ylim([7.5 10.57])
%     legend([h{1},h{2},h{3}],'ARI','CIPIC','LISTEN','Location','NorthWest');
    legend boxoff

    subplot(412)
    for kk=1:length(hrtf)
        plot(var(var(:,2)==kk,3),abs(varl(varl(:,2)==kk,1)-varr(varr(:,2)==kk,1)),sym(kk),'MarkerEdgeColor','b','MarkerFaceColor','b');
        hold on
    end
    ylabel('Binaural difference of r (cm)')
    xlim([-1.5 temp+1.5])
    ylim([-0.5 3.5])
    clear var varl varr;
    
    % yM
    temp=1;
    for kk=1:length(hrtf)
        var(temp:temp+size(p_onaxis{kk},3)-1,:)=[squeeze(mean(p_offaxis{kk}(3,:,:)*100,2)) kk*ones(size(p_onaxis{kk},3),1) transpose(1:size(p_onaxis{kk},3))];
        varl(temp:temp+size(p_onaxis{kk},3)-1,:)=[squeeze(p_offaxis{kk}(3,1,:)*100) kk*ones(size(p_onaxis{kk},3),1) transpose(1:size(p_onaxis{kk},3))];
        varr(temp:temp+size(p_onaxis{kk},3)-1,:)=[squeeze(p_offaxis{kk}(3,2,:)*100) kk*ones(size(p_onaxis{kk},3),1) transpose(1:size(p_onaxis{kk},3))];
        temp=size(var,1)+1;
    end
    var=var(idx,:);
    varl=varl(idx,:);
    varr=varr(idx,:);
    var(:,3)=transpose(1:size(var,1));
    varl(:,3)=transpose(1:size(var,1));
    varr(:,3)=transpose(1:size(var,1));
    subplot(413)
    for kk=1:length(hrtf)
        plot(var(var(:,2)==kk,3),var(var(:,2)==kk,1),sym(kk),'MarkerEdgeColor','b','MarkerFaceColor','b');
        hold on
    end
    ylabel('y_M in cm')
    xlim([-1.5 temp+1.5])
    ylim([-3 4])

    subplot(414)
    for kk=1:length(hrtf)
        plot(var(var(:,2)==kk,3),abs(varl(varl(:,2)==kk,1)-varr(varr(:,2)==kk,1)),sym(kk),'MarkerEdgeColor','b','MarkerFaceColor','b');
        hold on
    end
    ylabel('Binaural difference of r (cm)')
    xlim([-1.5 temp+1.5])
    ylim([-0.5 3.5])
    clear var varl varr;

    xlabel('Subjects')

end



end

function idx=ARI_FindPosition(data,azimuth,elevation)
    psi=sin(elevation/180*pi).*sin(data.SourcePosition(:,2)/180*pi) + ...
        cos(elevation/180*pi).*cos(data.SourcePosition(:,2)/180*pi).*...
        cos(azimuth/180*pi-data.SourcePosition(:,1)/180*pi);
    [~,idx]=min(acos(psi));
end