def calibrate_on_noaa(device_index=0,
                      calibrator_freq=noaa_freq,
                      bandwidth=1.0 * u.MHz,
                      passes=20,
                      max_offset=1000,
                      default_offset=325):
    """
    Calibrate the RTL-SDR using a known NOAA weather station.

    Parameters
    ----------
    device_index : int
        The USB ID of the device.  Usually 0, sometimes 1.
    calibrator_freq : Quantity, MHz
        The frequency of the weather station.  The active one in Gainesville is
        preselected.
    bandwidth : Quantity, MHz
        The bandwidth of the observation to obtain.  Generally limited to <2.4
        MHz.  Will be used to set the sample rate of the SDR.
    passes : int
        Number of passes (single-integrations) to average prior to measuring
        the offset
    max_offset : int
        The maximum offset to search for, in parts-per-million.  This is set
        to avoid possibly detecting other (RFI) signals in-band
    default_offset : int
        The default offset to use when measuring the frequency offset.  A
        nonzero offset is needed to avoid having the signal channel landing on
        the central DC channel, which generally does not have a good
        measurement
    """

    sdr = RtlSdr(device_index=device_index)
    try:
        sdr.sample_rate = bandwidth.to(u.Hz).value
        sdr.gain = 15
        numsamples = 2048 * 4
        sdr.center_freq = calibrator_freq.to(u.Hz).value

        assert sdr.get_freq_correction() == 0

        if default_offset != 0:
            sdr.set_freq_correction(default_offset)

        foff = sdr.get_freq_correction()

        pses = []

        frq = np.fft.fftfreq(numsamples)
        idx = np.argsort(frq)

        for ii in range(passes):
            sdr.center_freq = calibrator_freq.to(u.Hz).value

            samples = sdr.read_samples(numsamples)

            ps = np.abs(np.fft.fft(samples))**2
            # this seems to be an unneeded hack
            # (but it might help avoid a spike at 0-offset?)
            ps[0] = np.mean(ps)
            pses.append(ps[idx])

            print(".", end='')

        mean_ps = np.mean(pses, axis=0)

        frequency = u.Quantity(sdr.fc * (1 - foff / 1e6) + sdr.rs * frq[idx],
                               u.Hz)
        print()
        print(f"sdr.fc={sdr.fc}, sdr.center_freq={sdr.center_freq}")

        cutout = ((frequency > calibrator_freq * (1 - max_offset)) &
                  (frequency < calibrator_freq * (1 + max_offset)))

        max_ind = np.argmax(mean_ps[cutout])
        meas_freq = frequency[cutout][max_ind]
        meas_offset = (meas_freq - calibrator_freq) / calibrator_freq

    finally:
        sdr.close()

    print(
        f"Measured frequency offset is {meas_offset.decompose().value*1e6} parts per million (ppm)"
    )
    return frequency, mean_ps, meas_freq, meas_offset.decompose()