THE AUDITORY MODELING TOOLBOX

Applies to version: 1.6.0

View the help

Go to function

DATA_MAJDAK2013
Listener-specific localization responses

Program code:

function data = data_majdak2013(varargin)
%DATA_MAJDAK2013 Listener-specific localization responses
%   Usage: data = data_majdak2013();
%          data = data_majdak2013('control');
%          data = data_majdak2013('target');
%          data_majdak2013('fig6')
%          pretest = data_majdak2013('B');
%          pretest = data_majdak2013('LP');
%          pretest = data_majdak2013('W');          
% 
%   Input parameters:
%     B          : Return the data from the pretest for the broadband condition
%     LP         : Return the data from the pretest for the low-passed condition
%     W          : Return the data from the pretest for the warped condition
%     fig6       : Plot the Figure 6
%     all        : Default. Return all data of all subjects
%     control    : Return all data of the control group (trained on the low-passed condition)
%     target     : Return all data series of the target group (trained on the warped condition)
%
%     
%   Output parameters:
%     pretest  : Structure with the data from the pretest only. It contains the following fields:
%
%                - id*: Subject ID.
%
%                - mtx*: Item list with trials and angles. Each row contains information 
%                  about a single trial. The columnn describe the target 
%                  and response angles in the format of the item list used 
%                  in LOCALIZATIONERROR.
%
%                      
%     data       : Structure with the data from the pretest, training, and posttest. 
%                  It contains the following fields:
%
%                  - subject_str*: Listener ID (string).
%
%                  - pos*: Item list with trials and angles. Each row contains information 
%                    about a single trial. The columnn describe the target 
%                    and response angles in the format of the item list used 
%                    in LOCALIZATIONERROR.
%
%                  - session*: Session index (as an integer number).
%
%                  - session_str*: Session name (as a string).
%
%                  - trial*: Trial index within each session.
%
%                  - is_control*: Flag describing the control group (1) or target group (0).
%
%
%   pretest = DATA_MAJDAK2013(..) returns listener-specific responses
%   from Majdak et al.  (2013) obtained from a localization pretest.
%
%   data = DATA_MAJDAK2013(..) returns listener-specific responses
%   from Majdak et al.  (2013) obtained from a localization pretest, training, 
%   and posttest. 
%
%   To display Figure 6 from Majdak et al. (2013) use :
%
%     data_majdak2013('fig6');
%
%   References:
%     P. Majdak, T. Walder, and B. Laback. Effect of long-term training on
%     sound localization performance with spectrally warped and band-limited
%     head-related transfer functions. The Journal of the Acoustical Society
%     of America, 134:2148--2159, 2013.
%     
%
%   Url: http://amtoolbox.org/amt-1.6.0/doc/data/data_majdak2013.php


%   #Requirements: M-Curve
%   #Author: Robert Baumgartner (2015): implementation of control and target data.
%   #Author: David Poirier-Q. (2022): implementation of learning data (fig6)
%   #Author: Clara Hollomey (2023): integration in the AMT
%   #Author: Piotr Majdak (2024): integration of plotting figure 6 and fixing issue #215.

% This file is licensed unter the GNU General Public License (GPL) either 
% version 3 of the license, or any later version as published by the Free Software 
% Foundation. Details of the GPLv3 can be found in the AMT directory "licences" and 
% at <https://www.gnu.org/licenses/gpl-3.0.html>. 
% You can redistribute this file and/or modify it under the terms of the GPLv3. 
% This file is distributed without any warranty; without even the implied warranty 
% of merchantability or fitness for a particular purpose. 


%% Check input options

% Define input flags
definput.import={'amt_cache'};
definput.flags.condition = {'all','BB','LP','W','control', 'target', 'fig6'};

% Parse input options
[flags, ~] = ltfatarghelper({},definput,varargin);


%% Load data
if flags.do_all
    data = amt_load('majdak2013', 'data_fig6.mat');
    data = data.data;
end

if flags.do_control || flags.do_target
    data = amt_load('majdak2013', 'data_fig6.mat');
    data = data.data;
      % select data
    selVect = data.is_control == contains(flags.condition, 'control');    
      % apply filter across struct fields
    fieldNames = fieldnames(data);
    for iField = 1:length(fieldNames)
        data.(fieldNames{iField}) = data.(fieldNames{iField})(selVect, :);
    end

end

if flags.do_BB || flags.do_W || flags.do_LP 
    x = amt_load('majdak2013', 'data.mat');
    C = find(ismember(x.condition,flags.condition));
    for ll = 1:length(x.subject)

      data(ll).mtx = x.subject(ll).expData{C}(:,1:8);
      data(ll).id = x.subject(ll).id;

    end
end

%% Plot Figure 6
if flags.do_fig6
  data = amt_load('majdak2013', 'data_fig6.mat');
  data = data.data;

    % init locals
  nonTrainingSessionNames = {'learn', 'post_learn', 'pre_test_dummy', 'post_test_dummy', 'pre_test_warped', 'post_test_warped'};
  traininSessionNames = {'training_1', 'training_2', 'training_3', 'training_4', 'training_5', 'training_6', 'training_7', 'training_8', 'training_9', 'training_10', 'training_11', 'training_12', 'training_13', 'training_14', 'training_15', 'training_16', 'training_17', 'training_18', 'training_19', 'training_20', 'training_21'};
  configs = struct('sessionNames', {{}}, 'stat', [], 'isControl', 0);

    % loop over subject groups
  for iControl = 0:1
      % loop over pre/post test sessions
      for iSession = 1:length(nonTrainingSessionNames)
          configs(end+1) = struct('sessionNames', {{nonTrainingSessionNames{iSession}}}, 'stat', [], 'isControl', iControl);
      end
      % add training sessions (grouped)
      configs(end+1) = struct('sessionNames', {traininSessionNames}, 'stat', [], 'isControl', iControl);
  end
  configs(1) = [];  % remove first (dummy)

  % compute stats
  errbaridx = 2;
  cialpha = 0.05; % 95% confidence interval
  N = 4200;
  errorTypeStr = {'querrMiddlebrooks', 'rmsPmedianlocal', 'precL'};
  amt_disp(''); 
    % loop over error types
  for ii = 1:numel(errorTypeStr)
    err = errorTypeStr{ii};
      % loop over config (sessions)
    for iConfig = 1:length(configs)
        config = configs(iConfig);
        meanallid = [];
        % loop over subsession (for training)
        for iSession = 1:length(config.sessionNames)
              % log
            amt_disp(sprintf('Process Test:    %d/%d; Session: %d/%d', iConfig, length(configs), iSession, length(config.sessionNames)), 'volatile');
              % init filter
            selVect = data.is_control == config.isControl;
            selVect = selVect & ismember(data.session_str, config.sessionNames{iSession});
              % discard first 50 trials for learning session 
            if( ismember(config.sessionNames, 'learn') ); selVect = selVect & data.trial > 50; end
              % stats
            meanallid(iSession, :) = bootstrp(sum(selVect), @(m) localizationerror(m,err), data.pos(selVect, :));
        end
          % compute stats
        [muprepost,sigprepost,muciprepost,sigciprepost] = normfit(meanallid.', cialpha);
        configs(iConfig).stat(:,1) = muprepost;
        configs(iConfig).stat(:,2) = sigprepost;
        configs(iConfig).stat(:,3) = diff(muciprepost)/2;
        configs(iConfig).stat(:,4) = diff(sigciprepost)/2;
    end
	amt_disp();

    % model training performances
    
      % control group
    x=(200:200:N)';
    yhat=configs(14).stat(:,1);
    [yfitC, r, ~, COVB]=nlinfit(x,yhat,@exponential,[10 -0.0005 min(yhat)]);
      % warped group
    x=(200:200:N)';
    yhatW=configs(7).stat(:,1);
    [yfitW, rW, ~, COVBW]=nlinfit(x,yhatW,@exponential,[16 -0.0005 min(yhatW)]);

      % plot data
    figure; hold on;
    set(gcf,'Position',[10   226   616   484],'PaperType','A4');
    prepos=-200;
    postpos=N+400;
      % prepare variables
    statPP = reshape([configs(8:13).stat], 4, 6).';
    statPPW = reshape([configs(1:6).stat], 4, 6).';
    stat = configs(14).stat;
    statW = configs(7).stat;
      % model: control
    newx=(100:50:N+100)';
      % model: warped
    [ypred, delta]=nlpredci(@exponential,newx,real(yfitW),real(rW),'covar',real(COVBW));
    hp=patch([newx; flipud(newx)], [ypred+delta; flipud(ypred-delta)],[1 1 1]*0.7);
    set(hp, 'Edgecolor', [1 1 1]*0.7);
    plot(newx,ypred,'k','LineWidth',1);
    [ypred, delta]=nlpredci(@exponential,newx,real(yfitC),real(r),'covar',real(COVB));
    hp=patch([newx; flipud(newx)], [ypred+delta; flipud(ypred-delta)],[1 1 1]*0.8);
    set(hp, 'Edgecolor', [1 1 1]*0.8);
    plot(newx,ypred,'k','LineWidth',1);
      % control: pre- & post
    h=errorbar([prepos; N+100], [statPP(1,1); NaN], [statPP(2,errbaridx); NaN], 'g^'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','g'); leg_BBcontrol=h;
    h=errorbar([postpos; N+100], [statPP(2,1); NaN], [statPP(2,errbaridx); NaN], 'g^'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','g');
    h=errorbar([prepos; N+100], [statPP(3,1); NaN], [statPP(3,errbaridx); NaN], 'ro'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','r'); leg_BLcontrol=h;
    h=errorbar([postpos; N+100], [statPP(4,1); NaN], [statPP(4,errbaridx); NaN], 'ro'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','r');
    h=errorbar([prepos; N+100], [statPP(5,1); NaN], [statPP(5,errbaridx); NaN], 'bs'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','b'); leg_WPcontrol=h;
    h=errorbar([postpos; N+100], [statPP(6,1); NaN], [statPP(6,errbaridx); NaN], 'bs'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','b');
      % warped: pre- & post
    h=errorbar([prepos+50; N+150], [statPPW(1,1); NaN], [statPPW(2,errbaridx); NaN], 'g^'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','w'); leg_BBtarget=h;
    h=errorbar([postpos+50; N+150], [statPPW(2,1); NaN], [statPPW(2,errbaridx); NaN], 'g^'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','w');
    h=errorbar([prepos+50; N+100], [statPPW(3,1); NaN], [statPPW(3,errbaridx); NaN], 'ro'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','w'); leg_BLtarget=h;
    h=errorbar([postpos+50; N+100], [statPPW(4,1); NaN], [statPPW(4,errbaridx); NaN], 'ro'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','w');
    h=errorbar([prepos+50; N+100], [statPPW(5,1); NaN], [statPPW(5,errbaridx); NaN], 'bs'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','w'); leg_WPtarget=h;
    h=errorbar([postpos+100; N+100], [statPPW(6,1); NaN], [statPPW(6,errbaridx); NaN], 'bs'); local_tick(h);
    set(h,'LineWidth', 1,  'LineStyle','none','MarkerFaceColor','w');
      % training: control group
    h1=errorbar([(200:200:N)'; N+100],[stat(:,1); NaN],[stat(:,errbaridx); NaN],'ro');
    set(h1,'LineWidth', 1, 'LineStyle','none','MarkerFaceColor','r','LineStyle','-');
      % training: warped group
    h1=errorbar([(200:200:N)'; N+100],[statW(:,1); NaN],[statW(:,errbaridx); NaN],'bs');
    set(h1,'LineWidth', 1, 'LineStyle','none','MarkerFaceColor','w','LineStyle','-');
      % plot formatting
    xlabel('Training day number','FontName','Arial');
    [~,meta]=localizationerror(zeros(1, 9), err);
    ylabel(meta.ylabel,'FontName','Arial');
    box on;
    set(gca,'XLim',[prepos-300 postpos+300],'FontName','Arial');
    set(gca,'XTick',[200:2*200:N ]);
    celli=1:N/200';
    c=num2cell(celli(1:2:end))';
    set(gca,'XTickLabel',c);
    set(gca, 'TickLength', [0.02 0.05]);
    set(gca,'LineWidth',1);
    switch err
        case 'querrMiddlebrooks'
            set(gca,'YLim', [2 34.9]);
        case 'rmsPmedianlocal'
            set(gca,'YLim', [26 49]);
        case 'precL'
            set(gca,'YLim', [10.2 20.2]);
            set(gca, 'YTick', 10:2:20);
            h=legend([leg_BBcontrol leg_BLcontrol leg_WPcontrol leg_BBtarget leg_BLtarget leg_WPtarget], ...
                'Control Broadband', 'Control Band-Limited', 'Control Warped', ...
                'Target Broadband', 'Target Band-Limited', 'Target Warped');
            set(h,'Fontsize',10,'LineWidth',1);
    end
  end
end

%% local functions
function y=exponential(a,x)
y=real(a(1).*exp(a(2)*x)+a(3));

function local_tick(h)
% Adjust the width of errorbars
% Based on errorbar_tick from Arnaud Laurent (2009) and Jerome Briot (Dut) 
%   http://www.developpez.net/forums/f148/environnements-developpement/matlab/
%   http://www.mathworks.com/matlabcentral/newsreader/author/94805
%   http://www.developpez.net/forums/u125006/dut/
%
% Adapted for data_majdak2013 by Piotr Majdak (2024)

w = diff(get(gca,'XLim'))/80;
x = get(h(1),'xdata');
x(4:9:end) = x(1:9:end)-w/2;
x(7:9:end) = x(1:9:end)-w/2;
x(5:9:end) = x(1:9:end)+w/2;
x(8:9:end) = x(1:9:end)+w/2;
set(h(1),'xdata',x(:));