def run_sweep(ri, tone_banks, num_tone_samples, length_seconds=0, state=None, description='', verbose=False,
              wait_for_sync=0.1, **kwargs):
    """
    Return a SweepArray acquired using the given tone banks.

    Parameters
    ----------
    ri : RoachInterface
        An instance of a subclass.
    tone_banks : iterable of ndarray (float)
        An iterable of arrays (or a 2-D array) of frequencies to use for the sweep.
    num_tone_samples : int
        The number of samples in the playback buffer; must be a power of two.
    length_seconds : float
        The duration of each data stream; the default of 0 means the minimum unit of data that can be read out in the
        current configuration.
    state : dict
        The non-roach state to pass to the SweepArray.
    description : str
        A human-readable description of the measurement.
    verbose : bool
        If true, print progress messages.
    wait_for_sync : float
        Sleep for this time in seconds to let the ROACH sync finish.
    kwargs
        Keyword arguments passed to ri.get_measurement().

    Returns
    -------
    SweepArray
    """
    stream_arrays = core.MeasurementList()
    if verbose:
        print("Measuring bank")
    for n, tone_bank in enumerate(tone_banks):
        if verbose:
            print n,
            sys.stdout.flush()
        ri.set_tone_freqs(tone_bank, nsamp=num_tone_samples)
        ri.select_fft_bins(np.arange(tone_bank.size))
        # we wait a bit here to let the roach2 sync catch up.  figuring this out still.
        time.sleep(wait_for_sync)
        stream_arrays.append(ri.get_measurement(num_seconds=length_seconds, **kwargs))
    return basic.SweepArray(stream_arrays, state=state, description=description)