def calculate_fdl_vs_dur(dur_low, dur_high, n_dur): """ Calculates ideal observer FDL vs duration Arguments: dur_low (float): lowest duration to test in seconds dur_high (float): highest duration to test in seconds n_dur (int): number of durations to test... frequencies between dur_low and dur_high will be distributed logarithmically Returns: tuple of ndarrays, the first containing all-information thresholds, the second containing rate-place thresholds, and the third containing the durations at which they were estimated """ # Initialize simulator object sim = anf.AuditoryNerveHeinz2001() # Define stimulus parameters tone_level = 40 tone_freq = 970 tone_ramp_dur = 0.004 tone_durs = 10**np.linspace(np.log10(dur_low), np.log10(dur_high), n_dur) # Encode stimulus parameters params = { 'level': tone_level, 'freq': tone_freq, 'dur_ramp': tone_ramp_dur } params = si.wiggle_parameters(params, 'dur', tone_durs) # Encode model parameters params = si.append_parameters(params, [ 'cf_low', 'cf_high', 'n_cf', 'fs', 'n_fiber_per_chan', 'delta_theta', 'API' ], [100, 10000, 60, int(500e3), 200, [0.001], np.zeros(1)]) # Encode increment and synthesize params = si.increment_parameters(params, {'freq': 0.001}) synth = PureToneHeinz2001() stimuli = synth.synthesize_sequence(params) params = si.stitch_parameters(params, '_input', stimuli) # Run model output = sim.run(params, parallel=True, runfunc=dc.decode_ideal_observer(sim.simulate)) t_AI = [ x[0] for x in output ] # extract AI thresholds, which are always the first element of each tuple in results t_RP = [ x[1] for x in output ] # extract RP thresholds, which are always the second element of each tuple in results # Return return np.array(t_AI), np.array(t_RP), tone_durs
def test_ideal_observer_real_simulation_with_level_roving(): """ Test that ideal observer analysis on simple pure tone FDLs shows increasing FDLs with increasing frequency in the context of a mild level rove on the pure tone """ # Initialize simulator object sim = anf.AuditoryNerveHeinz2001() # Define stimulus parameters fs = int(200e3) def tone_level(): return np.random.uniform(25, 35, 1) tone_dur = 0.1 tone_ramp_dur = 0.01 tone_freqs = [1000, 2000, 4000, 8000] # Encode stimulus parameters params = { 'level': tone_level, 'dur': tone_dur, 'dur_ramp': tone_ramp_dur, 'fs': fs } params = si.wiggle_parameters(params, 'freq', tone_freqs) # Encode model parameters params = si.stitch_parameters(params, 'cf_low', [1000, 2000, 4000, 8000]) params = si.stitch_parameters(params, 'cf_high', [1000, 2000, 4000, 8000]) params = si.append_parameters( params, ['fs', 'n_cf', 'n_fiber_per_chan', 'delta_theta', 'API'], [int(200e3), 1, 5, [0.001, 0.001], np.array([[0, 0], [0, 1 / 6**2]])]) # Encode repeats and increments params = si.repeat_parameters(params, 10) params = si.increment_parameters(params, {'freq': 0.001, 'level': 0.001}) # Synthesize stimuli and encode in params synth = sy.PureTone() stimuli = synth.synthesize_sequence(params) params = si.stitch_parameters(params, '_input', stimuli) # Run model output = sim.run(params, parallel=True, runfunc=decode_ideal_observer(sim.simulate)) # Extract AI thresholds output = [ out[0] for out in output ] # AI thresholds are always the first element of each tuple in output # Check to make sure that thresholds grow with frequency assert np.all(np.diff(output) > 0)
def test_ideal_observer_FDL_vs_frequency(): """ Test that ideal observer analysis on simple pure tone FDLs shows increasing FDLs with increasing frequency """ # Initialize simulator object sim = anf.AuditoryNerveHeinz2001() # Define stimulus parameters fs = int(200e3) tone_level = 30 tone_dur = 0.1 tone_ramp_dur = 0.01 tone_freqs = [1000, 2000, 4000, 8000] # Encode stimulus information params = { 'level': tone_level, 'dur': tone_dur, 'dur_ramp': tone_ramp_dur, 'fs': fs } params = si.wiggle_parameters(params, 'freq', tone_freqs) # Encode model information params = si.stitch_parameters(params, 'cf_low', [1000, 2000, 4000, 8000]) params = si.stitch_parameters(params, 'cf_high', [1000, 2000, 4000, 8000]) params = si.append_parameters( params, ['n_cf', 'fs', 'n_fiber_per_chan', 'delta_theta', 'API'], [1, int(200e3), 5, [0.001], np.zeros((1))]) # Flatten and increment frequency params = si.flatten_parameters(params) params = si.increment_parameters(params, {'freq': 0.001}) synth = sy.PureTone() stimuli = synth.synthesize_sequence(params) params = si.stitch_parameters(params, '_input', stimuli) # Run model output = sim.run(params, parallel=True, runfunc=decode_ideal_observer(sim.simulate)) # Extract AI thresholds output = [ out[0] for out in output ] # AI thresholds are always the first element of each tuple in output # Check to make sure that thresholds grow with frequency assert np.all(np.diff(output) > 0)
def test_increment_parameters_input_dict_with_repeated_increment_value_callable_value(): """ Test that increment_parameters correctly handles parameter names appended with (#)_ when the associated parameter value is callable """ results = si.increment_parameters(parameters={'a': lambda: 1, 'b': 2}, increments={'(1)_a': 0.01, '(2)_a': 0.02}) assert results[0]['a'] == 1 and results[1]['a'] == 1.01 and results[2]['a'] == 1.02
def test_increment_parameters_array(): """ Test that increment_parameters accepts an array as input """ results = si.increment_parameters(parameters=np.array([{'a': 0.01}]), increments={'a': 0.01}) assert results[0][0]['a'] == 0.01 and results[0][1]['a'] == 0.02
def test_increment_parameters_input_nested_list(): """ Test that increment_parameters accepts a nested list as input """ results = si.increment_parameters(parameters=[{'a': 1, 'b': 2}, [[{'a': 1, 'b': 2}, {'a': 1, 'b': 2}], [{'a': 2, 'b': 40}]]], increments={'a': 0.01}) assert results[1][0][0][0]['a'] == 1 and results[1][0][0][1]['a'] == 1.01
def test_increment_parameters_input_dict(): """ Test that increment_parameters accepts a dict as input """ results = si.increment_parameters(parameters={'a': 1, 'b': 2}, increments={'a': 0.01}) assert results[0]['a'] == 1 and results[1]['a'] == 1.01