def simulate(scene):
    """Sweep the scene."""
    last_step_coarse = True
    f_cur, f_prev, f_prev2 = scene.get_focus_values([0, 0, 0])
    position = 1

    output = []

    while position < scene.step_count:
        f_prev2, f_prev, f_cur = f_prev, f_cur, scene.fvalues[position]

        if last_step_coarse:
            step_coarse = coarsefine.coarse_if_previously_coarse(
                f_prev2, f_prev, f_cur)
        else:
            step_coarse = coarsefine.coarse_if_previously_fine(
                f_prev2, f_prev, f_cur)

        if step_coarse:
            output.append((position, 0))
            position += 8
        else:
            output.append((position, 1))
            position += 1

        last_step_coarse = step_coarse

    return output
def search_sweep(scenes, always_coarse):
    print ("Search for a peak by sweeping from the first lens position, stop\n"
            "when a peak is found.")

    if always_coarse:
        print "Sweeping is done with coarse steps only."
    else:
        print "Sweeping is done using ml-based heuristics."

    data_rows = [("filename", "status", "steps")]

    for scene in scenes:
        last_step_coarse = True
        max_val = scene.fvalues[0]
        f_cur, f_prev, f_prev2 = scene.get_focus_values([0, 0, 0])
        current_pos = 1

        step_count = 1

        # Sweep in search of a maxima.
        while current_pos < scene.step_count - 1:
            # Size of the next step.
            if always_coarse:
                step_coarse = True
            else:
                f_prev2, f_prev, f_cur = \
                    f_prev, f_cur, scene.fvalues[current_pos]

                # Decide on size of the next step using the right decision tree
                if last_step_coarse:
                    step_coarse = coarsefine.coarse_if_previously_coarse(
                        f_prev2, f_prev, f_cur)
                else:
                    step_coarse = coarsefine.coarse_if_previously_fine(
                        f_prev2, f_prev, f_cur)

            if step_coarse:
                current_pos = min(scene.step_count - 1, current_pos + 8)
            else:
                current_pos = min(scene.step_count - 1, current_pos + 1)
            step_count += 1

            max_val = max(max_val, scene.fvalues[current_pos])
            if scene.fvalues[current_pos] < 0.7 * max_val:
                break

            last_step_coarse = step_coarse

        # Go back to peak using local search hillclimbing.
        while current_pos > 0:
            if scene.fvalues[current_pos] < scene.fvalues[current_pos - 1]:
                current_pos -= 1
                step_count += 1
            elif (current_pos > 1 and 
                  scene.fvalues[current_pos] < scene.fvalues[current_pos - 2]):
                # Tolerance of two fine steps.
                current_pos -= 2
                step_count += 2
            else:
                # Number of steps to move forward and back, 
                # due to two step tolerance
                step_count += 4
                break

        first_column = "%s (%d)" % (scene.filename, len(scene.maxima))
        if scene.distance_to_closest_peak(current_pos) < 1:
            if scene.distance_to_highest_peak(current_pos) <= 1:
                line = (first_column, "found highest", str(step_count))
            else:
                line = (first_column, "found a peak", str(step_count))
        else:
            line = (first_column, "failed", str(step_count))
        data_rows.append(line)

    print_aligned_data_rows(data_rows)