def _find_just_detectable_tone_amplitude_aux(detector_info, noise_samples, s):
    
    low = 100
    high = 10000
    
    # Loop invariant: just detectable amplitude is in (low, high].
    
    while low != high - 1:
        
        # print('tone amplitude is in ({}, {}]...'.format(low, high))
        
        mid = _round((low + high) / 2)
        
        samples = np.array(noise_samples)
        s.tone_amplitudes = mid
        _add_tones(samples, s)
        
        clips = old_detector.detect(samples, detector_info)
        
        if len(clips) == 0:
            low = mid
        else:
            high = mid
            
    return high
def _run_passband_test(detector_info):
    
    s = Bunch(
        sample_rate=_SAMPLE_RATE,
        duration=10,
        background_noise_amplitude=100,
        tone_start_times=[5],
        tone_durations=.2,
        tone_amplitudes=1.414 * detector_info.just_detectable_tone_amplitude,
        tone_onset_duration=.01
    )
    
    f0, f1 = detector_info.passband_bracket
    f_inc = 100
    
#     f0 = 2700
#     f1 = 2800
#     f_inc = 10
    
    for f in range(f0, f1, f_inc):
        
        samples = _create_background_noise(s)
        s.tone_frequencies = f
        _add_tones(samples, s)
        
        clips = old_detector.detect(samples, detector_info)
        
        middle = ' not' if len(clips) == 0 else ''
        print('{} Hz tone{} detected'.format(f, middle))
def _find_just_detectable_impulse_amplitude_aux(detector_info, samples, s):
    
    impulse_index = _round(s.impulse_time * s.sample_rate)

    low = 100
    high = 30000
    
    # Loop invariant: just detectable amplitude is in (low, high].
    
    while low != high - 1:
        
        # print('impulse amplitude is in ({}, {}]...'.format(low, high))
        
        mid = _round((low + high) / 2)
        
        samples[impulse_index] = mid
        
        clips = old_detector.detect(samples, detector_info)
        
        if len(clips) == 0:
            low = mid
        else:
            high = mid
            
    return high
def _run_filter_length_test(detector_info):
    
    tone_frequency = detector_info.f1 - 500
    
    n = 10
    jd = detector_info.just_detectable_tone_amplitude
    inc = _round(.1 * jd)
    tone_amplitudes = list(jd + (1 + np.arange(n)) * inc)
    
#     tone_amplitudes = list(1200 + np.arange(10) * 200)
    
    min_length, max_length = detector_info.filter_length_bracket
    filter_lengths = range(min_length, max_length + 1)
    
    results = np.zeros(
        (len(filter_lengths), len(tone_amplitudes), 2), dtype='int')
    
    for j, tone_amplitude in enumerate(tone_amplitudes):
        
        print('processing test tone with amplitude {}, frequency {}'.format(
            tone_amplitude, tone_frequency))
        
        # print('creating constant tone test signal...')
        s = Bunch(
            sample_rate=_SAMPLE_RATE,
            duration=10,
            background_noise_amplitude=100,
            tone_start_times=[5],
            tone_durations=.2,
            tone_amplitudes=tone_amplitude,
            tone_frequencies=tone_frequency,
            tone_onset_duration=.01
        )
        
        samples = _create_background_noise(s)
        _add_tones(samples, s)

    
        # print('running old detector...')
        old_clips = old_detector.detect(samples, detector_info)
    
        # print('running new detector...')
        for i, filter_length in enumerate(filter_lengths):
            s = detector_info
            s.filter_length = filter_length
            new_clips = new_detector.detect(samples, s)
            # print('old:', old_clips)
            # print('new:', new_clips)
            results[i, j, 0] = new_clips[0][0] - old_clips[0][0]
            results[i, j, 1] = new_clips[0][1] - old_clips[0][1]
            
    
    for i, filter_length in enumerate(filter_lengths):
        strings = [
            _format_result(results[i, j]) for j in range(len(tone_amplitudes))]
        print('{}    {}'.format(filter_length, '    '.join(strings)))
def _run_clip_duration_extrema_tests(detector_info):
    
    print(
        'running test that should yield a single clip whose length is '
        'the larger of the minimum clip duration and the integration '
        'time (only approximately in the latter case) plus the padding...')
    
    s = Bunch(
        sample_rate=_SAMPLE_RATE,
        duration=10,
        background_noise_amplitude=100,
        impulse_times=[5],
        impulse_amplitudes=10000
    )
    
    samples = _create_background_noise(s)
    _add_impulses(samples, s)
    
    clips = old_detector.detect(samples, detector_info)
    
    print('clips: {}'.format(clips))
    
    print()
     
    print(
        'running test that should yield a single clip whose length is '
        'the maximum clip duration plus the padding...')
     
    s = Bunch(
        sample_rate=_SAMPLE_RATE,
        duration=20,
        background_noise_amplitude=100,
        noise_burst_times=[5],
        noise_burst_durations=10,
        noise_burst_amplitudes=10000
    )
     
    samples = _create_background_noise(s)
    _add_noise_bursts(samples, s)
     
    clips = old_detector.detect(samples, detector_info)
     
    print('clips: {}'.format(clips))
def _find_clip_suppressor_count_threshold(detector_info):
    
    num_impulses = 50
    separation = .5
    
    s = Bunch(
        sample_rate=_SAMPLE_RATE,
        duration=10 + (num_impulses - 1) * separation,
        background_noise_amplitude=100,
        impulse_times=5 + np.arange(num_impulses) * separation,
        impulse_amplitudes=10000
    )

    np.random.seed(0)
    samples = _create_background_noise(s)
    _add_impulses(samples, s)
    
    clips = old_detector.detect(samples, detector_info)
    
    return len(clips) + 1
def _find_clip_suppressor_period(detector_info, threshold):
    
    for period in range(threshold, 3 * threshold):
        
        num_impulses = threshold
        separation = (period - .5) / (threshold - 1)
    
        s = Bunch(
            sample_rate=_SAMPLE_RATE,
            duration=10 + (num_impulses - 1) * separation,
            background_noise_amplitude=100,
            impulse_times=5 + np.arange(num_impulses) * separation,
            impulse_amplitudes=10000
        )
    
        np.random.seed(0)
        samples = _create_background_noise(s)
        _add_impulses(samples, s)
        
        clips = old_detector.detect(samples, detector_info)
        
        if len(clips) == threshold:
            return period - 1
def _get_clip_length_for_integration_time_impulses(detector_info, separation):
    
    separation /= _SAMPLE_RATE
    num_impulses = 20
    
    amplitude = detector_info.just_detectable_impulse_amplitude
    first_amplitude = 1.1 * amplitude
    other_amplitude = .8 * amplitude
    amplitudes = [first_amplitude] + ([other_amplitude] * (num_impulses - 1))
    
    s = Bunch(
        sample_rate=_SAMPLE_RATE,
        duration=10 + (num_impulses - 1) * separation,
        background_noise_amplitude=100,
        impulse_times=5 + np.arange(num_impulses) * separation,
        impulse_amplitudes=amplitudes
    )

    np.random.seed(0)
    samples = _create_background_noise(s)
    _add_impulses(samples, s)
    
    return old_detector.detect(samples, detector_info)
def _run_short_noise_burst_test(detector_info):
    
    # For this test the signal is a short noise burst.
    
    print('running the detector on a short noise burst...')
    
    for amplitude in range(100, 400, 10):
        
        s = Bunch(
            sample_rate=_SAMPLE_RATE,
            duration=10,
            background_noise_amplitude=100,
            noise_burst_times=[5],
            noise_burst_durations=.01,
            noise_burst_amplitudes=amplitude
        )
    
        samples = _create_background_noise(s)
        _add_noise_bursts(samples, s)
        
        clips = old_detector.detect(samples, detector_info)
    
        print(amplitude, clips)            
def _run_delay_test(detector_info):
    
    # For this test the signal is two equal-amplitude impulses separated by
    # `_DELAY_TEST_IMPULSE_SEPARATION` seconds. Neither impulse is powerful
    # enough to trip the detector alone but their combination will trip the
    # detector if they are separated by less than the delay.
    
    print('running delay test...')
    
    s = Bunch(
        sample_rate=_SAMPLE_RATE,
        duration=10,
        background_noise_amplitude=100,
        impulse_times=[5, 5 + _DELAY_TEST_IMPULSE_SEPARATION],
        impulse_amplitudes=
            detector_info.just_detectable_impulse_amplitude - 200
    )
    
    samples = _create_background_noise(s)
    _add_impulses(samples, s)
    
    clips = old_detector.detect(samples, detector_info)
    
    print('clips: {}'.format(clips))