THE AUDITORY MODELING TOOLBOX

Applies to version: 1.3.0

View the help

Go to function

DEMO_VERHULST2018 - Demo of the auditory brainstem model described by Verhulst et al (2018)

Program code:

%DEMO_VERHULST2018 Demo of the auditory brainstem model described by Verhulst et al (2018)
%  
%   This script computes the responses to one click of single polarity.
%
%   The following figures are obtained:
%
%   - Characteristic frequencies of equidistant points along the cochlea.
%
%   - Ear-canal pressure signals that can be used to simulate 
%     otoacoustic emissions (see also demo_verhulst2012.m).
%
%   - Simulated basilar membrane velocity (v) or inner-hair-cell
%     voltage (vihc).
%
%   - Simulated unit responses to HSR, MSR, LSR neurons, auditory
%     nerve responses, and cochlear nucleus (CN) and inferior colliculus (IC) neurons.
%
%   - Population responses waave I, III, V, and envelope following responses.
%
%
%   The current demo is based on the scripts ExampleSimulation.m and 
%   ExampleAnalysis_function.m from https://github.com/HearingTechnology/Verhulstetal2018Model
%
%   License:
%   --------
%
%   This model is licensed under the UGent Academic License. Further usage details are provided 
%   in the UGent Academic License which can be found in the AMT directory "licences" and at 
%   <https://raw.githubusercontent.com/HearingTechnology/Verhulstetal2018Model/master/license.txt>.%
%
%   Figure 1: Characteristic frequencies of equidistant points along the cochlea.
%
%   Figure 2: Ear-canal pressure signals that can be used to simulate otoacoustic emissions.
%
%   Figure 3: Simulated basilar membrane velocity (v) or inner-hair-cell voltage (vihc).
%
%   Figure 4: Simulated unit responses to HSR, MSR, LSR neurons, auditory nerve responses, and cochlear nucleus (CN) and inferior colliculus (IC) neurons.
%
%   Figure 5: Population responses waave I, III, V, and envelope following responses.
%
%   See also: verhulst2018, verhulst2012
%
%   Url: http://amtoolbox.org/amt-1.3.0/doc/demos/demo_verhulst2018.php

%   #License: ugent
%   #StatusDoc: Good
%   #StatusCode: Good
%   #Verification: Unknown
%   #Requirements: MATLAB M-Signal PYTHON C
%   #Author: Alejandro Osses (2020): primary implementation based on https://github.com/HearingTechnology/Verhulstetal2018Model
%   #Author: Piotr Majdak (2021): adaptations for the AMT 1.0

% 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. 

%%% Generic model configuration:
fc_flag='all'; % 1000 cochlear sections
% fc_flag = 'half'; % for 500 cochlear sections
% fc_flag = 'abr';  % for 401 cochlear sections
numH = 13; % Nr. of high-spontaneous   rate neurons to be simulated (default=13)
numM =  3; % Nr. of middle-spontaneous rate (default=3)
numL =  3; % Nr. of low-spontaneous    rate (default=3)

freq2show = 1000;

%%% Stimulus generation:
fs = 100e3; % 100 kHz, sampling frequency
dt = 1/fs;
L  = [40 70 100]; % dB SPL, three stimulus levels, you can add/remove levels here
p0 = 2e-5; % Pa, reference pressure

dur = 50e-3; % 50 ms, stimulus duration
dur_click = 100e-6; % 100 us, click duration
dur_click_samples = round(dur_click*fs); % click duration in samples

t = 0:dt:dur-dt;
N_samples = length(t);
N_levels  = length(L);

insig=zeros(N_samples,N_levels); % Memory allocation. Each column is one test signal

for j=1:N_levels
    L_in_dB_peSPL = p0*10^(L(j)/20)*sqrt(2)*2; % conversion from dB to dB peSPL
    insig(10:10+dur_click_samples,j)=L_in_dB_peSPL; % one (positive) polarity click
end
%%% End Stimulus generation

%% set synaptopathy and store the results
% decide which responses you want to store: 
    % e= emission 
    % v= velocity 
    % i=ihc 
    % h=hsr 
    % m=msr 
    % l=lsr 
    % b=summed AN responses for each CF as well as CN and IC responses 
    % w=population response waves I, III, V

%% start the simulation
output = verhulst2018(insig,fs,fc_flag, ...
           'v','oae','anfH','anfM','anfL',... % model flags, specify the required output 
           'numH',numH,'numM',numM,'numL',numL); % number of AN fibres

cf = output(1).cf; % characteristic frequencies of the simulated cochlear sections
N_CFs = length(cf);

%%%% Figure 1"    CF=output.cf;
% cf is sorted in a base-to-apex (from high-to-low frequencies):
figure(1)
plot(cf), hold on
xlabel('Cochlear Channel Number [-]')
ylabel('Characteristic Frequency [Hz]')
%%%

fs_bm = output.fs_bm; %the sampling frequency of BM, OAE and IHC are higher to avoid numerical errors (see Altoe et al., 2014 JASA)
fs_an = output.fs_an; %the sampling frequency of AN, CN, IC and waves are 5 times lower
N_samples_an = size(output(1).an_summed,1);
t_an  = [0:N_samples_an-1]/fs_an; % time after the AN. By default is a decimated  version of t_bm
f = 0:fs_bm/N_samples:fs_bm-1/N_samples; % Frequency if FFT to v_BM is assessed

% Pick a channel number to plot results from. The CF corresponding to the
% channel number depends on whether you chose 'all', 'half' or 'abr':
idx_bin = find(freq2show < cf, 1,'last'); % looks for bin that is at 'freq_to_show'

% Reorganisation of the data for easier processing:
oae=zeros(N_samples,N_levels);
v=zeros(N_samples,N_levels);
ihc=zeros(N_samples,N_levels);
vrms=zeros(1,N_CFs);
ihcrms=zeros(1,N_CFs);
for j=1:N_levels
   oae(:,j)    = output(j).oae(:);
   v(:,j)      = output(j).v(:,idx_bin);
   ihc(:,j)    = output(j).ihc(:,idx_bin);
   vrms(j,:)   = rms(output(j).v);
   ihcrms(j,:) = rms(output(j).ihc);
end

%% Ear-canal pressure and Otoacoustic emissions (OAE):
% This figure is the ear-canal pressure.
% For OAE simulations:
%    - To get the reflection-source OAE, do the following simulation (see 
%      also demo_verhulst2012.m):
%          OAE_{reflections on}-OAE_{reflections off}
%    - To get the distortion-source OAE, do a normalisation using a low level
%      (linear) simulation that the reflections off

%%%% Figure 2
figure(2),
subplot(2,1,1)
plot(1000*t,oae), hold on
xlabel('Time [ms]'),ylabel('Ear Canal Pressure [Pa]'),
xlim([0 20]),
% ylim([-0.02 0.02]),
legend(num2str(L')),legend('boxoff')

subplot(2,1,2), % figure
plot(f/1000,20*log10(abs(fft(oae/p0)))); hold on
xlabel('Frequency [kHz]'),
ylabel('EC Magnitude [dB re p0]'),
xlim([0 12]),
legend(num2str(L')),
legend('boxoff')

%% v_bm and V_IHC 
figure(3),
subplot(2,2,1),
plot(1000*t,v), hold on
xlabel('Time [ms]');
ylabel('v_{bm} [m/s]');
xlim([0 30]);
title(['CF of ',num2str(round(cf(idx_bin))),' Hz']);
legend(num2str(L'));
legend('boxoff');

subplot(2,2,2),
plot(cf/1000,20*log10(vrms)), hold on
xlabel('CF [kHz]');
ylabel('rms of v_{bm} [dB re 1 m/s]');
xlim([0 14]),
% ylim([max(max(20*log10(vrms)))-100 max(max(20*log10(vrms)))+10])
title(['Excitation Pattern'])
legend(num2str(L'));
legend('boxoff');

subplot(2,2,3),
plot(1000*t,ihc), hold on
xlabel('Time [ms]');
ylabel('V_{ihc} [V]');
xlim([0 30]);
title(['CF of ',num2str(round(cf(idx_bin))),' Hz']);
legend(num2str(L'));
legend('boxoff');

subplot(2,2,4),
plot(cf/1000,ihcrms), hold on
xlabel('CF [kHz]');
ylabel('rms of V_{ihc} [V]');
xlim([0 14]);
%ylim([max(max(20*log10(ihcrms)))-100 max(max(20*log10(ihcrms)))+10])
title('Excitation Pattern');
legend(num2str(L'));
legend('boxoff');

% Reorganisation of the data for easier processing
for j = 1:N_levels
    HSR(:,j)=output(j).anfH(:,idx_bin);
    MSR(:,j)=output(j).anfM(:,idx_bin);
    LSR(:,j)=output(j).anfL(:,idx_bin);
    AN(:,j)=output(j).an_summed(:,idx_bin);
    CN(:,j)=output(j).cn(:,idx_bin);
    IC(:,j)=output(j).ic(:,idx_bin);
    W1(:,j)=output(j).w1(:);
    W3(:,j)=output(j).w3(:);
    W5(:,j)=output(j).w5(:);
    EFR(:,j)=output(j).w1+output(j).w3+output(j).w5;
end

%single unit responses
figure(4),
subplot(3,2,1),
plot(1000*t_an,HSR), hold on
title(['CF of ',num2str(round(cf(idx_bin))),' Hz'])
xlim([0 20]);
xlabel('Time [ms]');
ylabel('HSR fiber [spikes/s]')
legend(num2str(L'));
legend('boxoff')

subplot(3,2,3),
plot(1000*t_an,MSR), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('MSR fiber [spikes/s]')

subplot(3,2,5),
plot(1000*t_an,LSR), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('LSR fiber [spikes/s]');

subplot(3,2,2),
plot(1000*t_an,AN), hold on
title(['CF of ',num2str(round(cf(idx_bin))),' Hz'])
xlim([0 20]);
xlabel('Time [ms]');
ylabel('sum AN [spikes/s]');

% Spikes summed across all fibers @ 1 CF
subplot(3,2,4),
plot(1000*t_an,CN), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('CN [spikes/s]')

subplot(3,2,6),
plot(1000*t_an,IC), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('IC [spikes/s]')

% Population responses
figure(5)
subplot(4,1,1),
plot(1000*t_an,1e6*W1), hold on
title('Population Responses summed across simulated CFs');
xlim([0 20]);
xlabel('Time [ms]');
ylabel('W-1 [\muV]');
legend(num2str(L'));
legend('boxoff')

subplot(4,1,2),
plot(1000*t_an,1e6*W3), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('W-3 [\muV]')

subplot(4,1,3),
plot(1000*t_an,1e6*W5), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('W-5 [\muV]');

subplot(4,1,4),
plot(1000*t_an,1e6*EFR), hold on
xlim([0 20]);
xlabel('Time [ms]');
ylabel('EFR [\muV]');
%%%%%%%%%%%%%%%%%

amt_disp(['Showing results for frequency of ' num2str(freq2show) ' Hz']);