def test_init_spectral_quantity():
    sc = SpectralCoord(
        SpectralQuantity(10 * u.GHz, doppler_convention='optical'))
    assert sc.value == 10.
    assert sc.unit is u.GHz
    assert sc.doppler_convention == 'optical'
    assert sc.doppler_rest is None
    assert sc.observer is None
    assert sc.target is None
def test_apply_relativistic_doppler_shift():

    # Frequency
    sq1 = SpectralQuantity(1 * u.GHz)
    sq2 = _apply_relativistic_doppler_shift(sq1, 0.5 * c)
    assert_quantity_allclose(sq2, np.sqrt(1. / 3.) * u.GHz)

    # Wavelength
    sq3 = SpectralQuantity(500 * u.nm)
    sq4 = _apply_relativistic_doppler_shift(sq3, 0.5 * c)
    assert_quantity_allclose(sq4, np.sqrt(3) * 500 * u.nm)

    # Energy
    sq5 = SpectralQuantity(300 * u.eV)
    sq6 = _apply_relativistic_doppler_shift(sq5, 0.5 * c)
    assert_quantity_allclose(sq6, np.sqrt(1. / 3.) * 300 * u.eV)

    # Wavenumber
    sq7 = SpectralQuantity(0.01 / u.micron)
    sq8 = _apply_relativistic_doppler_shift(sq7, 0.5 * c)
    assert_quantity_allclose(sq8, np.sqrt(1. / 3.) * 0.01 / u.micron)

    # Velocity (doppler_convention='relativistic')
    sq9 = SpectralQuantity(200 * u.km / u.s,
                           doppler_convention='relativistic',
                           doppler_rest=1 * u.GHz)
    sq10 = _apply_relativistic_doppler_shift(sq9, 300 * u.km / u.s)
    assert_quantity_allclose(sq10, 499.999666 * u.km / u.s)
    assert sq10.doppler_convention == 'relativistic'

    # Velocity (doppler_convention='optical')
    sq11 = SpectralQuantity(200 * u.km / u.s,
                            doppler_convention='radio',
                            doppler_rest=1 * u.GHz)
    sq12 = _apply_relativistic_doppler_shift(sq11, 300 * u.km / u.s)
    assert_quantity_allclose(sq12, 499.650008 * u.km / u.s)
    assert sq12.doppler_convention == 'radio'

    # Velocity (doppler_convention='radio')
    sq13 = SpectralQuantity(200 * u.km / u.s,
                            doppler_convention='optical',
                            doppler_rest=1 * u.GHz)
    sq14 = _apply_relativistic_doppler_shift(sq13, 300 * u.km / u.s)
    assert_quantity_allclose(sq14, 500.350493 * u.km / u.s)
    assert sq14.doppler_convention == 'optical'

    # Velocity - check relativistic velocity addition
    sq13 = SpectralQuantity(0 * u.km / u.s,
                            doppler_convention='relativistic',
                            doppler_rest=1 * u.GHz)
    sq14 = _apply_relativistic_doppler_shift(sq13, 0.999 * c)
    assert_quantity_allclose(sq14, 0.999 * c)
    sq14 = _apply_relativistic_doppler_shift(sq14, 0.999 * c)
    assert_quantity_allclose(sq14, (0.999 * 2) / (1 + 0.999**2) * c)
    assert sq14.doppler_convention == 'relativistic'

    # Cases that should raise errors
    sq15 = SpectralQuantity(200 * u.km / u.s)
    with pytest.raises(ValueError, match='doppler_convention not set'):
        _apply_relativistic_doppler_shift(sq15, 300 * u.km / u.s)
    sq16 = SpectralQuantity(200 * u.km / u.s, doppler_rest=10 * u.GHz)
    with pytest.raises(ValueError, match='doppler_convention not set'):
        _apply_relativistic_doppler_shift(sq16, 300 * u.km / u.s)
    sq17 = SpectralQuantity(200 * u.km / u.s, doppler_convention='optical')
    with pytest.raises(ValueError, match='doppler_rest not set'):
        _apply_relativistic_doppler_shift(sq17, 300 * u.km / u.s)