Binaural hearing graph

Matlab code from Vannson et al., 2017 (paper here)

This code has been simplified for displaying purposes.

The primary objective of this study was to correlate speech-in-noise abilities with pure-tone audiometry in individuals with unilateral hearing loss, with the goal of developing a predictive model.

    
    % Binaural graph
    % NV, Toulouse , July 2014
    
 
    clear all
    close all
    clc

    % Cmd 

    binaural = 1;   % 1 = Plot binaural graph 
    matrix   = 1;   % 1 = Plot matrix graph 
    keep     = 1;   % 1 = Save figure 
    tostudy  = 2;  % group to compute    

    % Param 

    groups   = {'Binauralite' ,...
                'Binauralite-perdue' ,...
                'Binauralite-rehabilite', ...
                'Binauralite-rehabilite-NA',...
                'perdue-NA',...
                'TEMOINS'};
                   

   
    source          = 'F:\NV_PhD\Data_sujets\Results';
    boris           = 'F:\NV_PhD\Data_Boris';
    mfile           = 'F:\NV_PhD\Tools\Matlab';
    img             = 'F:\NV_PhD\PhD_img';        


    police          = 12;
    font            = 'bold';
    graph_ext       = '-dpng';
    reso            = '-r900';
    col             = [ 0.9 0 0 ; 0 0.7 0 ; 0 0 0.9 ;1 165/255 0;0.5 0.5 0.5; .8 .8 .8];

    % NV Norms (new both : n = 27) 
    normes     = [-5.3154 -13.45 -13.45];
    std_normes = [0.6697  3.71 3.71];
    cutoff     = std_normes;

    
    % -------------------------------------------------------------------------
    
    % add mfile folder (matlab file)
    addpath(genpath(mfile))

    % Load data

    cd(source)
    folder  = [ pwd  filesep 'Groupe_' char(cellstr(groups(tostudy)))];
    name    = char(cellstr(groupes(tostudy)));
    sprintf('Group data loaded is :  %s', name)
    cd(folder)

    % Choose to load only audio and matrix data 
    
    data       = load(['data_'  char(cellstr(groupes(tostudy))) '.mat']);   
    audio      = data.data.audiometrie;  audiometry
    matrix     = data.data.matrix; Speech-in-noise data(Matrix) 

    % Sort ears 
    % check ears and rearrange them to put the better ear within the first column
    
    NHL_OD = audio(:,1);
    NHL_OG = audio(:,2);

    oreilles = [NHL_OD NHL_OG];
    for k = 1 : length(oreilles)

            if oreilles(k,1) >= 25 
                oreilles(k,[1,2]) = oreilles(k,[2,1]);
            end

            if oreilles(k,1) > oreilles (k,2)
                oreilles(k,[1,2]) = oreilles(k,[2,1]);
            end
    end

    
    % Check for real uhl patients based upon oreilles (:,1)= < 20 dB
    
    deafness = [num2cell(oreilles) num2cell(matrix) num2cell(audio)];
    uhl = {[]}; 
    bhl = uhl;
    for i = 1: size(deafness,1)
        if  cell2mat(deafness(i,1)) <= 20
            uhl{i,1} = deafness(i,:);
        else
            bhl{i,1} = deafness(i,:);
        end
    end
    emptyCells = cellfun(@isempty,uhl);
    uhl(emptyCells) = [];
    emptyCells = cellfun(@isempty,BHL);
    bhl(emptyCells) = [];

    % Save uhl and bhl groups 
    save uhl uhl 
    save bhl bhl 



    
    % Binaural graph 
    % -------------------------------------------------------------------------
    
    if binaural == 1

        % Matrix limits 
        normes = normes(1,2);
        cutoff = cutoff(1,2);


        % Matrix data : % dio - dicho - inv conditions

        x = [oreilles(:,1) matrix(:,3)];
        y = [oreilles(:,2) matrix(:,2)];

        figure
        set(gcf,'name',[titlegraphe,' ',name,' ',date],'numbertitle','off')
        set(gcf,'Toolbar','none','Menu','none');  
        hold on
        box on

         % gca 
        set(gca,'ydir','reverse')   
        axis([-15 15 0 120])
        set(gca,'position',[0.13,0.32,.8,0.58]);

         % line 
        line ([ normes  normes],[ 0 120],'linestyle','-','color','r')
        line ([ normes+cutoff normes+cutoff],[ 0 120]'linestyle','--','color','r')
        line ([ normes-cutoff  normes-cutoff ],[ 0 120],'linestyle','--','color','r')
        line ([ 0 0 ],[ 0 120],'linestyle','--','color','k')
        line ([min(xlim) max(xlim)],[20  20],'linestyle','--','color','k')


        % plot pts 
        hbo = plot(uhl(:,5),uhl(:,1),'ob','markersize',6,'LineWidth',2,'markeredgecolor',col(3,:));
        hmo = plot(uhl(:,4),uhl(:,2),'or','markersize',6,'LineWidth',2,'markeredgecolor',col(1,:));

        % Multiple correlation analysis 
        [rmat,~,pmat]   = spear(matrix(:,2),matrix(:,3));
        [rbad,~,pbad]   = spear(uhl(:,2),uhl(:,4))
        [rgood,~,pgood] = spear(uhl(:,1),uhl(:,5))

        % Fitting on only the bad ears 
        [cbad,gbad] = fit(uhl(:,4),uhl(:,2),'poly1','robust','Off');
        pp = plot(cbad,'k');
        set(pp,'linewidth',1.5);
        legend off
        
        % info 
        text(6.5,40,sprintf('rho = %2.2f, p < %2.3f',rbad,pbad),'fontsize',police)
        text(6.5,47,sprintf('r^2    = %2.2f',rbad*rbad),'fontsize',police)
        text(6.5,33,sprintf('n     = %2.0f',size(uhl,1)),'fontsize',police)
                
        % labels & legend 
        ylabel('PTA threshold [dB HL]','fontsize',police)
        xlabel('SRT [dB SNR]','fontsize',police)
        legend off
        legend([hbo,hmo],{'Better ear';'Poorer ear'},'fontsize',police)

        text('string','2*\sigma','HorizontalAlignment','center','position',[-7.8 90],'fontsize',police-4)
        text('string','A','HorizontalAlignment','center','position',[-17 -5],'fontsize',police,'fontweight','bold')
                
        annotation('doublearrow',  [.29 .35], [.44 .44],...
            'Head1Length',police-6,'Head1Width',police-6,...
            'Head2Length',police-6,'Head2Width',police-6);
        
       
        % boxplot beneath 
        hl = axes('position',[0.13,0.05,0.8,0.3]); 
        set(gca,'ydir','reverse')
        axis([-15 15 0 120])
        axis off
        line ([ normes+cutoff normes+cutoff],[ 0 120],'linestyle','--','color','r')

      
        %  add boxplot on the bottom
        htop = axes('position',[0.13,0.08,0.8,0.2]);
        p = boxplot(htop,in(:,5),'color','b','position',-10,'width',3,'orientation','horizontal');
        set(p,'linewidth',1.5)
        hold on
        p = boxplot(htop,out(:,5),'position',-5,'color','b','width',3,'orientation','horizontal');
        set(p,'linewidth',1.5)
        % add nhl to the boxplot graph 
        ndata = mean(nhl(:,2:3),2);
        p = boxplot(htop,ndata,'position',2,'color','k','width',3,'orientation','horizontal');
        set(p,'linewidth',1.5); 
        set(gca,'XTickLabel',{' '},'YTickLabel',{' '})
        axis([-14.66 15  -14 14])
        axis off


        text('string','NHL (n = 11)','HorizontalAlignment','center','position',[-9.5 7],'fontsize',police) 
        text('string','Good performers (n = 21)','HorizontalAlignment','center','position',[-12 -5],'fontsize',police)  
        text('string','Bad performers (n = 14)','HorizontalAlignment','center','position',[-1 -.5],'fontsize',police)  
        text('string','B','HorizontalAlignment','center','position',[-17 7],'fontsize',police,'fontweight','bold')    

        % Create textboxs & arrows

        annotation(gcf,'textbox',...
        [0.15 0.05 0.01 0.020],...
        'String',{'Efficient'},...
        'HorizontalAlignment','center',...
        'fontsize',police,...
        'LineStyle','none');

        annotation(gcf,'textbox',...
        [0.55 0.05 0.01 0.020],...
        'String',{'Deficient'},...
        'HorizontalAlignment','center',...
        'fontsize',police,...
        'LineStyle','none');

        annotation(gcf,'arrow',[0.4 0.5],...
        [0.05 0.05],'HeadWidth',6,'LineWidth',0.6);
        annotation(gcf,'arrow',[0.3 0.2],...
        [0.05 0.05],'HeadWidth',6,'LineWidth',0.6);


        % savefig 
        if keep == 1
            cd(pwd)
            print(graph_ext,reso,'PTAvsSRT')
        end

    
Binaural Graph Image

        

    
    % Matrix good vs bad performers
    % -------------------------------------------------------------------------
    
    
    Based upon the previous binaural graph, sort patients into good and bad performers 
    for further analysis and plot their Matrix results! The sorting will depend on the 
    better ear SRT (matrix) score.
    

    
     
    Filter out uhl data to find uhl in and uhl out patients 
    out = uhl*0;
    in  = uhl;  % to discard out data 
    for j = 1 : size(uhl) 
        if uhl(j,1) <= 20 & uhl(j,5)> (normes+cutoff) 
            out(j,:) =  uhl(j,:);    
        end  
    end
    
    idxo                = out(:,1) == 0;
    out(idxo,:)         = [];
    in(out(:,end),:)    = [];

    % Save in and out groups 
    save in in 
    save out out 


    if matrix == 1

        % From Boris : load nhl data
        addpath(genpath(boris))
        nhl  = load('Boris_NHL_matrix.txt');
        nhl  = nhl(:,1:3);  % dio - dicho - inv

        % gather dicho _inv
        dicho = [nhl(:,2) nhl(:,3)];
        dicho = mean(dicho,2);

        % plot param 
        leg         = {'Dichotic','Diotic','Reversed dichotic '};
        xlabeltxt   = 'Subjects';
        ylabeltxt   = 'SRT [dB SNR] ';
        deaf_ear    = 'impaired ear';
        titlegraph  = 'Matrix test';
        mk          = 8; % marker size 
    
        % figure 
        figure
        set(gcf,'Toolbar','none','Menu','none');  
        set(gca,'LooseInset',get(gca,'TightInset'))
        hold on
        box on

        % plot nhl data (dio - dicho - inv)
        hnhl = plot(1,dicho,'ok','markersize',mk);
        plot(5,nhl(:,1),'ok','markersize',mk)
        plot(9,dicho,'ok','markersize',mk)
        
        % boxplots 
        % plot all point first
        hin = plot(2,in(:,4),'ob','markersize',mk);
        plot(6,in(:,3),'ob','markersize',mk)
        plot(10,in(:,5),'ob','markersize',mk)
        
        hout = plot(3,out(:,4),'or','markersize',mk);
        plot(7,out(:,3),'or','markersize',mk)
        plot(11,out(:,5),'or','markersize',mk)
        
        % dicho
        boxplot(dicho,'position',1,'color','k','width',.5) % dicho
        set(gca,'XTickLabel',{' '})
        boxplot(in(:,4),'position',2,'color','k','width',.5)
        set(gca,'XTickLabel',{' '})
        h = boxplot(out(:,4),'position',3,'color','k','width',.5);
        set(h(7,:),'Visible','off') ;
        set(gca,'XTickLabel',{' '})
        
        % dio 
        boxplot(nhl(:,1),'position',5,'color','k','width',.5) % dio
        set(gca,'XTickLabel',{' '})
        h = boxplot(in(:,3),'position',6,'color','k','width',.5);
        set(h(7,:),'Visible','off') ;
        set(gca,'XTickLabel',{' '})
        h = boxplot(out(:,3),'position',7,'color','k','width',.5);
        set(h(7,:),'Visible','off') ;
        set(gca,'XTickLabel',{' '})
        
        % Inv
        nl = boxplot(dicho,'position',9,'color','k','width',.5); % inv
        set(gca,'XTickLabel',{' '})
        il = boxplot(in(:,5),'position',10,'color','k','width',.5);
        set(gca,'XTickLabel',{' '})
        ol = boxplot(out(:,5),'position',11,'color','k','width',.5);
        set(ol(7,:),'Visible','off') ;
        set(gca,'XTickLabel',{' '})
       
        ylabel('SRT [dB SNR]','fontsize',police)
        axis([0 12 -20 20])
    
        % bootstrap stats 
        st_inv_out     = bootci(10000,@mean, out(:,5));
        st_inv_in      = bootci(10000,@mean, in(:,5));
        st_inv_nhl     = bootci(10000,@mean, nhl(:,3));
        
        st_dicho_out   = bootci(10000,@mean, out(:,4));
        st_dicho_in    = bootci(10000,@mean, in(:,4));
        st_dicho_nhl   = bootci(10000,@mean, nhl(:,2));
        
        st_dio_nhl     = bootci(10000,@mean, nhl(:,1));
        st_dio_out     = bootci(10000,@mean, out(:,3));
        st_dio_in      = bootci(10000,@mean, in(:,3));    


        % Display stats results 
        % text
        
        % dicho
        text('string','*','HorizontalAlignment','center','position',[1.5 6],'fontsize',police+2) 
        text('string','*','HorizontalAlignment','center','position',[2.5 11],'fontsize',police+2) 
        text('string','*','HorizontalAlignment','center','position',[2 14],'fontsize',police+2) 
        
        % dio
        text('string','*','HorizontalAlignment','center','position',[5.5 6],'fontsize',police+2) 
        text('string','*','HorizontalAlignment','center','position',[6.5 10],'fontsize',police+2) 
        text('string','*','HorizontalAlignment','center','position',[6 14],'fontsize',police+2) 
        
        % inv
        text('string','N.S','HorizontalAlignment','center','position',[9.5 -3],'fontsize',police-1) % inv
        text('string','*','HorizontalAlignment','center','position',[10.5 4],'fontsize',police+2) % inv
        text('string','*','HorizontalAlignment','center','position',[10 11],'fontsize',police+2) % inv
        
        
        % line
        line([1 2],[5 5],'linestyle','-','color','k','linewidth',1.1)
        line([2 3],[10 10],'linestyle','-','color','k','linewidth',1.1)
        line([1 3 ],[13 13],'linestyle','-','color','k','linewidth',1.1)
        
        line([5 6],[5 5],'linestyle','-','color','k','linewidth',1.1)
        line([6 7],[9 9],'linestyle','-','color','k','linewidth',1.1)
        line([5 7 ],[13 13],'linestyle','-','color','k','linewidth',1.1)
        
        line([9 10],[-4.5 -4.5],'linestyle','-','color','k','linewidth',1.1)
        line([10 11],[3 3],'linestyle','-','color','k','linewidth',1.1)
        line([9 11],[10 10],'linestyle','-','color','k','linewidth',1.1)
        
        
        set(gca,'position', [0.1675,0.1285,0.76,0.40])
        
        % legend
        legend([hnhl(3,1);hin(4,1);hout(5,1)],...
        {'NHL (n = 11)','Good performers (n = 21)','Bad performers (n = 14)'},'fontsize',police-1)
        legend boxoff
        set(legend,'position',[0.43 0.41 0.2 0.3],'orientation','horizontal')

        % add details to the figure 
        set(gca,'Xtick',[2,6,10])
        text('string','S_P_EN_B_E','HorizontalAlignment','center','position',[2 -24.5],'fontsize',police-1)% dicho           
        text('string','S_F_R_O_N_TN_F_R_O_N_T','HorizontalAlignment','center','position',[6 -24.5],'fontsize',police-1)%dio
        text('string','N_P_ES_B_E','HorizontalAlignment','center','position',[10 -24.5],'fontsize',police-1) % inv
        
        % add conditions 
        text('string',leg(1)','HorizontalAlignment','center','position',[2 -22],'fontsize',police-1)% dicho           
        text('string',leg(2),'HorizontalAlignment','center','position',[6 -22],'fontsize',police-1)%dio
        text('string',leg(3),'HorizontalAlignment','center','position',[10 -22],'fontsize',police-1) % inv
        

        % imgs 
        addpath(genpath(img))
        folder  = dir(fullfile(img,'ENG_*.png'));
        dicho   = imread(folder(1).name,'BackgroundColor',[1 1 1]);
        dio     = imread(folder(2).name,'BackgroundColor',[1 1 1]);
        inv     = imread(folder(3).name,'BackgroundColor',[1 1 1]);

        hold on
        haxinv   = axes('Position', [.165, .62, .24, .24]);
        imshow(dicho)
        haxdicho = axes('Position', [.425, .62, .24, .24]);
        imshow(dio)
        
        % legend for schemes 
        hold on
        scatter(100,280,'ok','filled')
        ht = text(150,280,deaf_ear,'fontweight','normal','fontsize', police-1,'color','k');
        haxdio   = axes('Position', [.685, .62, .24, .24]); 
        imshow(inv)
        
        
        % add textbox & arrows 

        % Create textbox
        annotation(gcf,'textbox',...
        [0.045 0.17 0.01 0.020],...
        'String',{'Efficient'},...
        'HorizontalAlignment','center',...
        'fontsize',police,...
        'LineStyle','none');
    
        % Create textbox
        annotation(gcf,'textbox',...
        [0.045 0.47 0.01 0.020],...
        'String',{'Deficient'},...
        'HorizontalAlignment','center',...
        'fontsize',police,...
        'LineStyle','none');

        % Create arrow
        annotation(gcf,'arrow',[0.05 0.05],...
        [0.30 0.230],'HeadWidth',8,'LineWidth',0.8);
        
        % Create arrow
        annotation(gcf,'arrow',[0.05 0.05],...
        [0.35 0.42],'HeadWidth',8,'LineWidth',0.8);
        
        %savefig 
        if keep == 1
            cd(art_folder)
            print(graph_ext,reso,['Matrix_NHL_' date])
        end
    
Binaural Graph Image

The code continues to deepen our understanding of how good and bad performers differ.