Source code for brian2hears.filtering.drnl

import numpy as np

from .filterbank import FunctionFilterbank, CombinedFilterbank
from .filterbanklibrary import *

__all__ = ['DRNL']

def set_parameters(cf,type,param):
    
    parameters=dict()
    parameters['stape_scale']=0.00014 
    parameters['order_linear']=3
    parameters['order_nonlinear']=3

    if type=='guinea pig':
        parameters['cf_lin_p0']=0.339
        parameters['cf_lin_m']=0.339
        parameters['bw_lin_p0']=1.3
        parameters['bw_lin_m']=0.53
        parameters['cf_nl_p0']=0
        parameters['cf_nl_m']=1.
        parameters['bw_nl_p0']=0.8
        parameters['bw_nl_m']=0.58
        parameters['a_p0']=1.87
        parameters['a_m']=0.45
        parameters['b_p0']=-5.65
        parameters['b_m']=0.875
        parameters['c_p0']=-1.
        parameters['c_m']=0
        parameters['g_p0']=5.68
        parameters['g_m']=-0.97
        parameters['lp_lin_cutoff_p0']=0.339
        parameters['lp_lin_cutoff_m']=0.339
        parameters['lp_nl_cutoff_p0']=0
        parameters['lp_nl_cutoff_m']=1.
        
    elif type=='human':
        parameters['cf_lin_p0']=-0.067
        parameters['cf_lin_m']=1.016
        parameters['bw_lin_p0']=0.037
        parameters['bw_lin_m']=0.785
        parameters['cf_nl_p0']=-0.052
        parameters['cf_nl_m']=1.016
        parameters['bw_nl_p0']=-0.031
        parameters['bw_nl_m']=0.774
        parameters['a_p0']=1.402
        parameters['a_m']=0.819
        parameters['b_p0']=1.619
        parameters['b_m']=-0.818  
        parameters['c_p0']=-0.602
        parameters['c_m']=0
        parameters['g_p0']=4.2
        parameters['g_m']=0.48
        parameters['lp_lin_cutoff_p0']=-0.067
        parameters['lp_lin_cutoff_m']=1.016
        parameters['lp_nl_cutoff_p0']=-0.052
        parameters['lp_nl_cutoff_m']=1.016
        
    if param: 
        if not isinstance(param, dict): 
            raise TypeError('given parameters must be a dict')
        for key in param.keys():
            if not key in parameters:
                raise Exception(key + ' is invalid key entry for given parameters')
            parameters[key] = param[key]
    return parameters
    
[docs]class DRNL(CombinedFilterbank): r''' Implementation of the dual resonance nonlinear (DRNL) filter as described in Lopez-Paveda, E. and Meddis, R., "A human nonlinear cochlear filterbank", JASA 2001. The entire pathway consists of the sum of a linear and a nonlinear pathway. The linear path consists of a bank of bandpass filters (second order gammatone), a low pass function, and a gain/attenuation factor, g, in a cascade. The nonlinear path is a cascade consisting of a bank of gammatone filters, a compression function, a second bank of gammatone filters, and a low pass function, in that order. Initialised with arguments: ``source`` Source of the cochlear model. ``cf`` List or array of center frequencies. ``type`` defines the parameters set corresponding to a certain fit. It can be either: ``type='human'`` The parameters come from Lopez-Paveda, E. and Meddis, R.., "A human nonlinear cochlear filterbank", JASA 2001. ``type ='guinea pig'`` The parameters come from Summer et al., "A nonlinear filter-bank model of the guinea-pig cochlear nerve: Rate responses", JASA 2003. ``param`` Dictionary used to overwrite the default parameters given in the original papers. The possible parameters to change and their default values for humans (see Lopez-Paveda, E. and Meddis, R.,"A human nonlinear cochlear filterbank", JASA 2001. for notation) are:: param['stape_scale']=0.00014 param['order_linear']=3 param['order_nonlinear']=3 from there on the parameters are given in the form :math:`x=10^{\mathrm{p0}+m\log_{10}(\mathrm{cf})}` where ``cf`` is the center frequency:: param['cf_lin_p0']=-0.067 param['cf_lin_m']=1.016 param['bw_lin_p0']=0.037 param['bw_lin_m']=0.785 param['cf_nl_p0']=-0.052 param['cf_nl_m']=1.016 param['bw_nl_p0']=-0.031 param['bw_nl_m']=0.774 param['a_p0']=1.402 param['a_m']=0.819 param['b_p0']=1.619 param['b_m']=-0.818 param['c_p0']=-0.602 param['c_m']=0 param['g_p0']=4.2 param['g_m']=0.48 param['lp_lin_cutoff_p0']=-0.067 param['lp_lin_cutoff_m']=1.016 param['lp_nl_cutoff_p0']=-0.052 param['lp_nl_cutoff_m']=1.016 ''' def __init__(self, source, cf, type='human', param={}): CombinedFilterbank.__init__(self, source) source = self.get_modified_source() cf = np.asarray(np.atleast_1d(cf)) nbr_cf=len(cf) parameters=set_parameters(cf,type,param) #conversion to stape velocity (which are the units needed for the further centres) source=source*parameters['stape_scale'] #### Linear Pathway #### #bandpass filter (second order gammatone filter) cf_linear=10**(parameters['cf_lin_p0']+parameters['cf_lin_m']*np.log10(cf)) bandwidth_linear=10**(parameters['bw_lin_p0']+parameters['bw_lin_m']*np.log10(cf)) gammatone=ApproximateGammatone(source, cf_linear, bandwidth_linear, order=parameters['order_linear']) #linear gain g=10**(parameters['g_p0']+parameters['g_m']*np.log10(cf)) func_gain=lambda x:g*x gain= FunctionFilterbank(gammatone,func_gain) #low pass filter(cascade of 4 second order lowpass butterworth filters) cutoff_frequencies_linear=10**(parameters['lp_lin_cutoff_p0']+parameters['lp_lin_cutoff_m']*np.log10(cf)) order_lowpass_linear=2 lp_l=LowPass(gain,cutoff_frequencies_linear) lowpass_linear=Cascade(gain,lp_l,4) #### Nonlinear Pathway #### #bandpass filter (third order gammatone filters) cf_nonlinear=10**(parameters['cf_nl_p0']+parameters['cf_nl_m']*np.log10(cf)) bandwidth_nonlinear=10**(parameters['bw_nl_p0']+parameters['bw_nl_m']*np.log10(cf)) bandpass_nonlinear1=ApproximateGammatone(source, cf_nonlinear, bandwidth_nonlinear, order=parameters['order_nonlinear']) #compression (linear at low level, compress at high level) a=10**(parameters['a_p0']+parameters['a_m']*np.log10(cf)) #linear gain b=10**(parameters['b_p0']+parameters['b_m']*np.log10(cf)) v=10**(parameters['c_p0']+parameters['c_m']*np.log10(cf))#compression exponent func_compression=lambda x:np.sign(x)*np.minimum(a*abs(x),b*abs(x)**v) compression=FunctionFilterbank(bandpass_nonlinear1, func_compression) #bandpass filter (third order gammatone filters) bandpass_nonlinear2=ApproximateGammatone(compression, cf_nonlinear, bandwidth_nonlinear, order=parameters['order_nonlinear']) #low pass filter cutoff_frequencies_nonlinear=10**(parameters['lp_nl_cutoff_p0']+parameters['lp_nl_cutoff_m']*np.log10(cf)) order_lowpass_nonlinear=2 lp_nl=LowPass(bandpass_nonlinear2,cutoff_frequencies_nonlinear) lowpass_nonlinear=Cascade(bandpass_nonlinear2,lp_nl,3) #adding the two pathways drnl_filter=lowpass_linear+lowpass_nonlinear self.set_output(drnl_filter)