def goto(reference_beats,
         estimated_beats,
         goto_threshold=0.35,
         goto_mu=0.2,
         goto_sigma=0.2):
    validate(reference_beats, estimated_beats)
    if estimated_beats.size == 0 or reference_beats.size == 0:
        return 0.
    beat_error = np.ones(reference_beats.shape[0])
    paired = np.zeros(reference_beats.shape[0])
    goto_criteria = 0
    for n in range(1, reference_beats.shape[0]-1):
        previous_interval = 0.5*(reference_beats[n] - reference_beats[n-1])
        window_min = reference_beats[n] - previous_interval
        next_interval = 0.5*(reference_beats[n+1] - reference_beats[n])
        window_max = reference_beats[n] + next_interval
        beats_in_window = np.logical_and((estimated_beats >= window_min),
                                         (estimated_beats < window_max))
        if beats_in_window.sum() == 0 or beats_in_window.sum() > 1:
            paired[n] = 0
            beat_error[n] = 1
        else:
            paired[n] = 1
            offset = estimated_beats[beats_in_window] - reference_beats[n]
            if offset < 0:
                beat_error[n] = offset/previous_interval
            else:
                beat_error[n] = offset/next_interval
    incorrect_beats = np.flatnonzero(np.abs(beat_error) > goto_threshold)
    if incorrect_beats.shape[0] < 3:
        track = beat_error[incorrect_beats[0] + 1:incorrect_beats[-1] - 1]
        goto_criteria = 1
    else:
        track_len = np.max(np.diff(incorrect_beats))
        track_start = np.flatnonzero(np.diff(incorrect_beats) == track_len)[0]
        if track_len - 1 > .25*(reference_beats.shape[0] - 2):
            goto_criteria = 1
            start_beat = incorrect_beats[track_start]
            end_beat = incorrect_beats[track_start + 1]
            track = beat_error[start_beat:end_beat + 1]
    if goto_criteria:
        if np.mean(np.abs(track)) < goto_mu \
           and np.std(track, ddof=1) < goto_sigma:
            goto_criteria = 3
    return 1.0*(goto_criteria == 3)