Repository: PlasmaPy/PlasmaPy

Issue:
Create physics exceptions and warnings
Several of the exceptions and warnings that come up in PlasmaPy result from when we try to violate the laws of physics.  Most of the time these violations cause a `UserWarning` or raise a `ValueError`, but these are pretty generic and don't give much insight into the cause of the problem.  To help with exception handling, I propose that we create new exceptions and warnings, such as `PhysicsError` and `PhysicsWarning`.  We could additionally be more specific and also have `RelativityError` and/or `RelativityWarning`.  One possibility would be to put these in a new file called `plasmapy/utils/exceptions.py`.

This would be a good first contribution for someone who is somewhat familiar with Python.  Here's documentation on [user-defined exceptions](https://docs.python.org/3/tutorial/errors.html#user-defined-exceptions.  Thank you!


Discussion:

Patch:
diff --git a/plasmapy/physics/parameters.py b/plasmapy/physics/parameters.py
index c08fb40c..88b2a900 100644
--- a/plasmapy/physics/parameters.py
+++ b/plasmapy/physics/parameters.py
@@ -14,6 +14,7 @@
 # bit more than @quantity_input as it can allow
 
 from ..utils import _check_quantity, check_relativistic, check_quantity
+from ..utils.exceptions import PhysicsError
 
 
 r"""Values should be returned as an Astropy Quantity in SI units.
@@ -105,14 +106,22 @@ def Alfven_speed(B, density, ion="p"):
     UnitConversionError
         If the magnetic field or density is not in appropriate units.
 
-    UserWarning
-        If the Alfven velocity exceeds 10% of the speed of light, or
-        if units are not provided and SI units are assumed.
+    RelativityError
+        If the Alfven velocity is greater than or equal to the speed of light
 
     ValueError
         If the density is negative, or the ion mass or charge state
         cannot be found.
 
+    UserWarning
+        if units are not provided and SI units are assumed.
+
+    Warns
+    -----
+    RelativityWarning
+        If the Alfven velocity exceeds 10% of the speed of light
+
+
     Notes
     -----
     The Alfven velocity :math:`V_A` is the typical propagation speed
@@ -228,6 +237,9 @@ def ion_sound_speed(*ignore, T_e=0*units.K, T_i=0*units.K,
     ValueError
         If the ion mass, adiabatic index, or temperature are invalid.
 
+    PhysicsError
+        If an adiabatic index is less than one.
+
     UnitConversionError
         If the temperature is in incorrect units.
 
@@ -293,11 +305,11 @@ def ion_sound_speed(*ignore, T_e=0*units.K, T_i=0*units.K,
                         "a float or int in ion_sound_speed")
 
     if not 1 <= gamma_e <= np.inf:
-        raise ValueError("The adiabatic index for electrons must be between "
-                         "one and infinity")
+        raise PhysicsError("The adiabatic index for electrons must be between "
+                           "one and infinity")
     if not 1 <= gamma_i <= np.inf:
-        raise ValueError("The adiabatic index for ions must be between "
-                         "one and infinity")
+        raise PhysicsError("The adiabatic index for ions must be between "
+                           "one and infinity")
 
     T_i = T_i.to(units.K, equivalencies=units.temperature_energy())
     T_e = T_e.to(units.K, equivalencies=units.temperature_energy())
@@ -332,7 +344,7 @@ def thermal_speed(T, particle="e", method="most_probable"):
 
     method : string, optional
         Method to be used for calculating the thermal speed. Options are
-        'most_probable' (default), 'rms', and 'mean_magnitude'. 
+        'most_probable' (default), 'rms', and 'mean_magnitude'.
 
     Returns
     -------
@@ -1145,7 +1157,8 @@ def lower_hybrid_frequency(B, n_i, ion='p'):
     The lower hybrid frequency is given through the relation
 
     .. math::
-        \frac{1}{\omega_{lh}^2} = \frac{1}{\omega_{ci}^2 + \omega_{pi}^2} + \frac{1}{\omega_{ci}\omega_{ce}}
+        \frac{1}{\omega_{lh}^2} = \frac{1}{\omega_{ci}^2 + \omega_{pi}^2} +
+        \frac{1}{\omega_{ci}\omega_{ce}}
 
     where :math:`\omega_{ci}` is the ion gyrofrequency,
     :math:`\omega_{ce}` is the electron gyrofrequency, and
diff --git a/plasmapy/physics/quantum.py b/plasmapy/physics/quantum.py
index 64248c27..8a14f9c3 100644
--- a/plasmapy/physics/quantum.py
+++ b/plasmapy/physics/quantum.py
@@ -7,6 +7,7 @@
 from ..constants import c, h, hbar, m_e, eps0, e, k_B
 from ..atomic import ion_mass
 from ..utils import _check_quantity, _check_relativistic, check_quantity
+from ..utils.exceptions import RelativityError
 from .relativity import Lorentz_factor
 
 
@@ -37,7 +38,7 @@ def deBroglie_wavelength(V, particle):
     UnitConversionError
         If the velocity is not in appropriate units.
 
-    ValueError
+    RelativityError
         If the magnitude of V is faster than the speed of light.
 
     UserWarning
@@ -72,8 +73,9 @@ def deBroglie_wavelength(V, particle):
     V = np.abs(V)
 
     if np.any(V >= c):
-        raise ValueError("Velocity input in deBroglie_wavelength cannot be "
-                         "greater than or equal to the speed of light.")
+        raise RelativityError("Velocity input in deBroglie_wavelength cannot "
+                              "be greater than or equal to the speed of "
+                              "light.")
 
     if not isinstance(particle, units.Quantity):
         try:
@@ -145,7 +147,7 @@ def thermal_deBroglie_wavelength(T_e):
 
     See also
     --------
-    
+
 
     Example
     -------
@@ -158,6 +160,7 @@ def thermal_deBroglie_wavelength(T_e):
     lambda_dbTh = h / np.sqrt(2 * np.pi * m_e * k_B * T_e)
     return lambda_dbTh.to(units.m)
 
+
 @check_quantity({
     'n_e': {'units': units.m**-3, 'can_be_negative': False}
 })
@@ -214,6 +217,7 @@ def Fermi_energy(n_e):
     energy_F = coeff * (3 * n_e / np.pi) ** (2/3)
     return energy_F.to(units.Joule)
 
+
 @check_quantity({
     'n_e': {'units': units.m**-3, 'can_be_negative': False}
 })
@@ -246,14 +250,14 @@ def Thomas_Fermi_length(n_e):
 
     Notes
     -----
-    The Thomas-Fermi screening length is the exponential scale length for 
+    The Thomas-Fermi screening length is the exponential scale length for
     charge screening and is given by
 
     .. math::
     \lambda_TF = \sqrt{\frac{2 \epsilon_0 E_F}{3 n_e e^2}}
 
     for an electron degenerate gas.
-    
+
     This quantity is often used in place of the Debye length for analysis
     of cold, dense plasmas (e.g. warm dense matter, condensed matter).
 
@@ -276,4 +280,4 @@ def Thomas_Fermi_length(n_e):
     """
     energy_F = Fermi_energy(n_e)
     lambda_TF = np.sqrt(2 * eps0 * energy_F / (3 * n_e * e ** 2))
-    return lambda_TF.to(units.m)
\ No newline at end of file
+    return lambda_TF.to(units.m)
diff --git a/plasmapy/physics/relativity.py b/plasmapy/physics/relativity.py
index f63100a8..efcfe0d0 100644
--- a/plasmapy/physics/relativity.py
+++ b/plasmapy/physics/relativity.py
@@ -4,6 +4,7 @@
 from ..constants import c
 from ..atomic import (ion_mass, charge_state)
 from ..utils import _check_quantity
+from ..utils.exceptions import RelativityError
 
 
 def Lorentz_factor(V):
@@ -59,8 +60,8 @@ def Lorentz_factor(V):
     _check_quantity(V, 'V', 'Lorentz_factor', units.m/units.s)
 
     if not np.all(np.abs(V) <= c):
-        raise ValueError("The Lorentz factor cannot be calculated for speeds "
-                         "faster than the speed of light.")
+        raise RelativityError("The Lorentz factor cannot be calculated for "
+                              "speeds faster than the speed of light. ")
 
     if V.size > 1:
 
diff --git a/plasmapy/utils/checks.py b/plasmapy/utils/checks.py
index d0c847d4..fa762090 100644
--- a/plasmapy/utils/checks.py
+++ b/plasmapy/utils/checks.py
@@ -4,6 +4,8 @@
 import numpy as np
 from astropy import units as u
 from ..constants import c
+import warnings
+from plasmapy.utils.exceptions import RelativityWarning, RelativityError
 
 
 def check_quantity(validations):
@@ -103,7 +105,7 @@ def wrapper(*args, **kwargs):
 
 
 def check_relativistic(func=None, betafrac=0.1):
-    r"""Raises an error when the output of the decorated
+    r"""Warns or raises an error when the output of the decorated
     function is greater than `betafrac` times the speed of light
 
     Parameters
@@ -131,9 +133,14 @@ def check_relativistic(func=None, betafrac=0.1):
     ValueError
         If V contains any NaNs
 
-    UserWarning
-        If V is greater than betafrac times the speed of light
+    RelativityError
+        If V is greater than or equal to the speed of light
 
+    Warns
+    -----
+    RelativityWarning
+        If V is greater than or equal to betafrac times the speed of light,
+        but less than the speed of light
 
     Examples
     --------
@@ -285,7 +292,7 @@ def _check_quantity(arg, argname, funcname, units, can_be_negative=True,
 
 
 def _check_relativistic(V, funcname, betafrac=0.1):
-    r"""Raise UserWarnings if a velocity is relativistic or superrelativistic
+    r"""Warn or raise error if a velocity is relativistic or superrelativistic
 
     Parameters
     ----------
@@ -296,8 +303,7 @@ def _check_relativistic(V, funcname, betafrac=0.1):
         The name of the original function to be printed in the error messages.
 
     betafrac : float
-        The minimum fraction of the speed of light that will raise a
-        UserWarning
+        The minimum fraction of the speed of light that will generate a warning
 
     Raises
     ------
@@ -310,8 +316,14 @@ def _check_relativistic(V, funcname, betafrac=0.1):
     ValueError
         If V contains any NaNs
 
-    UserWarning
-        If V is greater than betafrac times the speed of light
+    RelativityError
+        If V is greater than or equal to the speed of light
+
+    Warns
+    -----
+    RelativityWarning
+        If V is greater than or equal to the specified fraction of the speed of
+        light
 
     Examples
     --------
@@ -332,14 +344,16 @@ def _check_relativistic(V, funcname, betafrac=0.1):
     if np.any(np.isnan(V.value)):
         raise ValueError("V includes NaNs in " + funcname)
 
-    beta = np.max(np.abs((V/c).value))
+    beta = np.max(np.abs((V.si/c).value))
 
     if beta == np.inf:
-        raise UserWarning(funcname + " is yielding an infinite velocity.")
+        raise RelativityError(funcname + " is yielding an infinite velocity.")
     elif beta >= 1:
-        raise UserWarning(funcname + " is yielding a velocity that is " +
-                          str(round(beta, 3)) + " times the speed of light.")
+        raise RelativityError(funcname + " is yielding a velocity that is " +
+                              str(round(beta, 3)) + " times the speed of " +
+                              "light.")
     elif beta >= betafrac:
-        raise UserWarning(funcname + " is yielding a velocity that is " +
-                          str(round(beta*100, 3)) + "% of the speed of " +
-                          "light. Relativistic effects may be important.")
+        warnings.warn(funcname + " is yielding a velocity that is " +
+                      str(round(beta*100, 3)) + "% of the speed of " +
+                      "light. Relativistic effects may be important.",
+                      RelativityWarning)
diff --git a/plasmapy/utils/exceptions.py b/plasmapy/utils/exceptions.py
new file mode 100644
index 00000000..fb4cf204
--- /dev/null
+++ b/plasmapy/utils/exceptions.py
@@ -0,0 +1,53 @@
+"""
+plasmapy.utils.exceptions
+===============
+
+Custom Error and Warning names to improve readability
+"""
+
+
+# ----------
+# Exceptions:
+# ----------
+
+class PlasmaPyError(Exception):
+    """Base class of PlasmaPy custom errors.
+
+    All custom exceptions raised by PlasmaPy should inherit from this class
+    and be defined in this module.
+
+    Custom exceptions can inherit from other exception types too. Thus, if code
+    already knows how to handle a ValueError, it won't need any specific
+    modification.
+    """
+
+
+class PhysicsError(PlasmaPyError, ValueError):
+    """Error for use of a physics value outside PlasmaPy theoretical bounds"""
+
+
+class RelativityError(PhysicsError):
+    """Error for use of a speed greater than or equal to the speed of light"""
+
+
+# ----------
+# Warnings:
+# ----------
+
+class PlasmaPyWarning(Warning):
+    """Base class of PlasmaPy custom warnings.
+
+    All PlasmaPy custom warnings should inherit from this class and be defined
+    in this module.
+
+    Warnings should be issued using warnings.warn, which will not break
+    execution if unhandled.
+    """
+
+
+class PhysicsWarning(PlasmaPyWarning):
+    """Warning for using a mildly worrisome physics value"""
+
+
+class RelativityWarning(PhysicsWarning):
+    """Warning for use of a speed quantity approaching the speed of light"""


Test patch:
diff --git a/plasmapy/physics/tests/test_parameters.py b/plasmapy/physics/tests/test_parameters.py
index 8f658d34..67f50d7e 100644
--- a/plasmapy/physics/tests/test_parameters.py
+++ b/plasmapy/physics/tests/test_parameters.py
@@ -3,10 +3,11 @@
 import numpy as np
 import pytest
 from astropy import units as u
+from warnings import simplefilter
 
-
+from ...utils.exceptions import RelativityWarning, RelativityError
+from ...utils.exceptions import PhysicsError
 from ...constants import c, m_p, m_e, e, mu0
-
 from ..parameters import (Alfven_speed,
                           gyrofrequency,
                           gyroradius,
@@ -21,6 +22,7 @@
                           upper_hybrid_frequency,
                           lower_hybrid_frequency)
 
+
 B = 1.0*u.T
 Z = 1
 ion = 'p'
@@ -106,10 +108,10 @@ def test_Alfven_speed():
     with pytest.raises(ValueError):
         Alfven_speed(B, n_i, ion='spacecats')
 
-    with pytest.raises(UserWarning):  # relativistic
+    with pytest.warns(RelativityWarning):  # relativistic
         Alfven_speed(5e1*u.T, 5e19*u.m**-3, ion='p')
 
-    with pytest.raises(UserWarning):  # super-relativistic
+    with pytest.raises(RelativityError):  # super-relativistic
         Alfven_speed(5e8*u.T, 5e19*u.m**-3, ion='p')
 
     with pytest.raises(ValueError):
@@ -121,10 +123,10 @@ def test_Alfven_speed():
     with pytest.raises(ValueError):
         Alfven_speed(1*u.T, np.nan*u.m**-3, ion='p')
 
-    with pytest.raises(UserWarning):
+    with pytest.raises(RelativityError):
         assert Alfven_speed(np.inf*u.T, 1*u.m**-3, ion='p') == np.inf*u.m/u.s
 
-    with pytest.raises(UserWarning):
+    with pytest.raises(RelativityError):
         assert Alfven_speed(-np.inf*u.T, 1*u.m**-3, ion='p') == np.inf*u.m/u.s
 
     with pytest.raises(UserWarning):
@@ -151,8 +153,8 @@ def test_ion_sound_speed():
 
     assert ion_sound_speed(T_e=T_e, gamma_e=1) == ion_sound_speed(T_e=T_e)
 
-    with pytest.raises(UserWarning):
-        assert ion_sound_speed(T_i=T_i, gamma_i=np.inf) == np.inf*u.m/u.s
+    with pytest.raises(RelativityError):
+        ion_sound_speed(T_i=T_i, gamma_i=np.inf)
 
     with pytest.raises(ValueError):
         ion_sound_speed(T_i=np.array([5, 6, 5])*u.K, T_e=np.array([3, 4])*u.K)
@@ -163,10 +165,10 @@ def test_ion_sound_speed():
     with pytest.raises(TypeError):
         ion_sound_speed('p')
 
-    with pytest.raises(ValueError):
+    with pytest.raises(PhysicsError):
         ion_sound_speed(T_i=T_i, gamma_i=0.9999)
 
-    with pytest.raises(ValueError):
+    with pytest.raises(PhysicsError):
         ion_sound_speed(T_i=T_i, gamma_e=0.9999)
 
     with pytest.raises(TypeError):
@@ -181,10 +183,10 @@ def test_ion_sound_speed():
     with pytest.raises(ValueError):
         ion_sound_speed(T_i=-np.abs(T_i))
 
-    with pytest.raises(UserWarning):
-        ion_sound_speed(T_i=5e12*u.K)
+    with pytest.warns(RelativityWarning):
+        ion_sound_speed(T_i=5e11*u.K)
 
-    with pytest.raises(UserWarning):
+    with pytest.raises(RelativityError):
         ion_sound_speed(T_i=5e19*u.K)
 
     with pytest.raises(u.UnitConversionError):
@@ -226,10 +228,10 @@ def test_thermal_speed():
     with pytest.raises(ValueError):
         thermal_speed(-T_e)
 
-    with pytest.raises(UserWarning):
+    with pytest.warns(RelativityWarning):
         thermal_speed(1e9*u.K)
 
-    with pytest.raises(UserWarning):
+    with pytest.raises(RelativityError):
         thermal_speed(5e19*u.K)
 
     with pytest.raises(UserWarning):
@@ -254,10 +256,10 @@ def test_thermal_speed():
     with pytest.raises(ValueError):
         thermal_speed(-T_e, particle='p')
 
-    with pytest.raises(UserWarning):
+    with pytest.warns(RelativityWarning):
         thermal_speed(1e11*u.K, particle='p')
 
-    with pytest.raises(UserWarning):
+    with pytest.raises(RelativityError):
         thermal_speed(1e14*u.K, particle='p')
 
     with pytest.raises(ValueError):
diff --git a/plasmapy/physics/tests/test_quantum.py b/plasmapy/physics/tests/test_quantum.py
index 22ba9741..060a8b6c 100644
--- a/plasmapy/physics/tests/test_quantum.py
+++ b/plasmapy/physics/tests/test_quantum.py
@@ -2,11 +2,13 @@
 import pytest
 import astropy.units as u
 from ...constants import c, h
-from ..quantum import (deBroglie_wavelength, 
-                       thermal_deBroglie_wavelength, 
-                       Fermi_energy, 
+from ...utils.exceptions import RelativityError
+from ..quantum import (deBroglie_wavelength,
+                       thermal_deBroglie_wavelength,
+                       Fermi_energy,
                        Thomas_Fermi_length)
 
+
 def test_deBroglie_wavelength():
 
     dbwavelength1 = deBroglie_wavelength(2e7*u.cm/u.s, 'e')
@@ -39,7 +41,7 @@ def test_deBroglie_wavelength():
     assert deBroglie_wavelength(1*u.m/u.s, 5*u.kg) == \
         deBroglie_wavelength(100*u.cm/u.s, 5000*u.g)
 
-    with pytest.raises(ValueError):
+    with pytest.raises(RelativityError):
         deBroglie_wavelength(c*1.000000001, 'e')
 
     with pytest.raises(UserWarning):
@@ -51,12 +53,15 @@ def test_deBroglie_wavelength():
     with pytest.raises(ValueError):
         deBroglie_wavelength(8*u.m/u.s, 'sddsf')
 
+
 # defining some plasma parameters for tests
 T_e = 1 * u.eV
 n_e = 1e23 * u.cm**-3
 # should probably change this to use unittest module
 # add tests for numpy arrays as inputs
 # add tests for different astropy units (random fuzzing method?)
+
+
 def test_thermal_deBroglie_wavelength():
     r"""Test the thermal_deBroglie_wavelength function in quantum.py."""
     lambda_dbTh = thermal_deBroglie_wavelength(T_e)
@@ -77,6 +82,7 @@ def test_thermal_deBroglie_wavelength():
     with pytest.raises(ValueError):
         thermal_deBroglie_wavelength(T_e=-1*u.eV)
 
+
 def test_Fermi_energy():
     r"""Test the Fermi_energy function in quantum.py."""
     energy_F = Fermi_energy(n_e)
@@ -97,6 +103,7 @@ def test_Fermi_energy():
     with pytest.raises(ValueError):
         Fermi_energy(n_e=-1*u.m**-3)
 
+
 def test_Thomas_Fermi_length():
     r"""Test the Thomas_Fermi_length function in quantum.py."""
     lambda_TF = Thomas_Fermi_length(n_e)
@@ -116,4 +123,3 @@ def test_Thomas_Fermi_length():
         Thomas_Fermi_length("Bad Input")
     with pytest.raises(ValueError):
         Thomas_Fermi_length(n_e=-1*u.m**-3)
-    
\ No newline at end of file
diff --git a/plasmapy/physics/tests/test_relativity.py b/plasmapy/physics/tests/test_relativity.py
index 30080f09..d4df1c74 100644
--- a/plasmapy/physics/tests/test_relativity.py
+++ b/plasmapy/physics/tests/test_relativity.py
@@ -5,6 +5,7 @@
 from astropy import units as u
 from ...constants import c
 from ..relativity import Lorentz_factor
+from ...utils.exceptions import RelativityError
 
 
 def test_Lorentz_factor():
@@ -25,7 +26,7 @@ def test_Lorentz_factor():
     assert (Lorentz_factor(3*u.m/u.s)*u.dimensionless_unscaled).unit == \
         u.dimensionless_unscaled
 
-    with pytest.raises(ValueError):
+    with pytest.raises(RelativityError):
         Lorentz_factor(1.0000000001*c)
 
     with pytest.raises((ValueError, UserWarning)):
diff --git a/plasmapy/physics/tests/test_transport.py b/plasmapy/physics/tests/test_transport.py
index a1553e55..f69e6094 100644
--- a/plasmapy/physics/tests/test_transport.py
+++ b/plasmapy/physics/tests/test_transport.py
@@ -5,6 +5,7 @@
 import pytest
 from astropy import units as u
 
+from ...utils.exceptions import RelativityWarning, RelativityError
 from ...constants import c, m_p, m_e, e, mu0
 
 from ..transport import (Coulomb_logarithm)
@@ -38,8 +39,11 @@ def test_Coulomb_logarithm():
     assert np.isclose(Coulomb_logarithm(1e5*u.K, 5*u.m**-3, ('e', 'e'),
                                         V=1e4*u.m/u.s), 21.379082011)
 
-    with pytest.raises(UserWarning):
-        Coulomb_logarithm(1e5*u.K, 1*u.m**-3, ('e', 'p'), 299792458*u.m/u.s)
+    with pytest.warns(RelativityWarning):
+        Coulomb_logarithm(1e5*u.K, 1*u.m**-3, ('e', 'p'), 0.9*c)
+
+    with pytest.raises(RelativityError):
+        Coulomb_logarithm(1e5*u.K, 1*u.m**-3, ('e', 'p'), 1.0*c)
 
     with pytest.raises(u.UnitConversionError):
         Coulomb_logarithm(1e5*u.g, 1*u.m**-3, ('e', 'p'), 29979245*u.m/u.s)
diff --git a/plasmapy/utils/tests/test_checks.py b/plasmapy/utils/tests/test_checks.py
index d8c54062..c88e3f2a 100644
--- a/plasmapy/utils/tests/test_checks.py
+++ b/plasmapy/utils/tests/test_checks.py
@@ -4,6 +4,7 @@
 from astropy import units as u
 import pytest
 
+from ...utils.exceptions import RelativityWarning, RelativityError
 from ...constants import c
 from ..checks import (
     _check_quantity, _check_relativistic, check_relativistic,
@@ -224,21 +225,25 @@ def func(x, y, z=10*u.eV):
 ]
 
 # (speed, betafrac, error)
-relativisitc_error_examples = [
-    (0.11*c, 0.1, UserWarning),
-    (1.0*c, 0.1, UserWarning),
-    (1.1*c, 0.1, UserWarning),
-    (np.inf*u.cm/u.s, 0.1, UserWarning),
-    (-0.11*c, 0.1, UserWarning),
-    (-1.0*c, 0.1, UserWarning),
-    (-1.1*c, 0.1, UserWarning),
-    (-np.inf*u.cm/u.s, 0.1, UserWarning),
-    (2997924581*u.cm/u.s, 0.1, UserWarning),
-    (0.02*c, 0.01, UserWarning),
+relativistic_error_examples = [
     (u.m/u.s, 0.1, TypeError),
     (51513.35, 0.1, TypeError),
     (5*u.m, 0.1, u.UnitConversionError),
-    (np.nan*u.m/u.s, 0.1, ValueError)
+    (np.nan*u.m/u.s, 0.1, ValueError),
+    (1.0*c, 0.1, RelativityError),
+    (1.1*c, 0.1, RelativityError),
+    (np.inf*u.cm/u.s, 0.1, RelativityError),
+    (-1.0*c, 0.1, RelativityError),
+    (-1.1*c, 0.1, RelativityError),
+    (-np.inf*u.cm/u.s, 0.1, RelativityError),
+]
+
+# (speed, betafrac, warning)
+relativistic_warning_examples = [
+    (0.11*c, 0.1),
+    (-0.11*c, 0.1),
+    (2997924581*u.cm/u.s, 0.1),
+    (0.02*c, 0.01),
 ]
 
 
@@ -248,12 +253,19 @@ def test__check_relativisitc_valid(speed, betafrac):
     _check_relativistic(speed, 'f', betafrac=betafrac)
 
 
-@pytest.mark.parametrize("speed, betafrac, error", relativisitc_error_examples)
+@pytest.mark.parametrize("speed, betafrac, error", relativistic_error_examples)
 def test__check_relativistic_errors(speed, betafrac, error):
     with pytest.raises(error):
         _check_relativistic(speed, 'f', betafrac=betafrac)
 
 
+@pytest.mark.parametrize("speed, betafrac",
+                         relativistic_warning_examples)
+def test__check_relativistic_warnings(speed, betafrac):
+    with pytest.warns(RelativityWarning):
+        _check_relativistic(speed, 'f', betafrac=betafrac)
+
+
 # Tests for check_relativistic decorator
 @pytest.mark.parametrize("speed, betafrac", non_relativistic_speed_examples)
 def test_check_relativistic_decorator(speed, betafrac):
@@ -289,7 +301,7 @@ def speed_func():
     speed_func()
 
 
-@pytest.mark.parametrize("speed, betafrac, error", relativisitc_error_examples)
+@pytest.mark.parametrize("speed, betafrac, error", relativistic_error_examples)
 def test_check_relativistic_decorator_errors(speed, betafrac, error):
 
     @check_relativistic(betafrac=betafrac)