Repository: PlasmaPy/PlasmaPy

Issue:
Minor changes in CollisionFrequencies
@JaydenR2305 I noticed a couple minor changes I'd like to make for the new `CollisionFrequencies` class

1) Right now the `Coulomb_log` attribute must be an astropy quantity object (u.dimensionless_unscaled). However, it's natural to just enter this as a float. Can you add a line like this: 

```python
if not isinstance(Coulomb_log, u.Quantity):
      Coulomb_log *= u.dimensionless_unscaled

```


2) Right now an  unhandled error is raised if the n_b and v_a/T_a arrays are different sizes. I think there should be a validation check at the beginning of the function making sure they have the same shape. That requirement should also be added to the docstring.

If you open a new PR for that, it should be easy to merge

Discussion:
JaydenR2305: @pheuer This probably doesn't need a changelog entry
codecov[bot]: # [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1705?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) Report
> Merging [#1705](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1705?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) (3df0cbd) into [main](https://codecov.io/gh/PlasmaPy/PlasmaPy/commit/6bf914737c71992ca55ccfb9f1fa2157ca847197?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) (6bf9147) will **decrease** coverage by `0.01%`.
> The diff coverage is `75.00%`.

```diff
@@            Coverage Diff             @@
##             main    #1705      +/-   ##
==========================================
- Coverage   97.66%   97.65%   -0.02%     
==========================================
  Files          85       85              
  Lines        8183     8187       +4     
==========================================
+ Hits         7992     7995       +3     
- Misses        191      192       +1     
```


| [Impacted Files](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1705?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) | Coverage Δ | |
|---|---|---|
| [plasmapy/formulary/collisions.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1705/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy#diff-cGxhc21hcHkvZm9ybXVsYXJ5L2NvbGxpc2lvbnMucHk=) | `99.22% <75.00%> (-0.39%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)

pheuer: @JaydenR2305 I think it should probably still get a changelog just for recording purposes, but you can use the trivial tag e.g. 

"1705.trivial.rst" 

And just say "Minor improvements to plasmapy.formulary.collisions.CollisionFrequencies"

Patch:
diff --git a/changelog/1705.trivial.rst b/changelog/1705.trivial.rst
new file mode 100644
index 00000000..7014549f
--- /dev/null
+++ b/changelog/1705.trivial.rst
@@ -0,0 +1,1 @@
+Minor improvements to `~plasmapy.formulary.collisions.CollisionFrequencies`
diff --git a/docs/contributing/coding_guide.rst b/docs/contributing/coding_guide.rst
index 2fdd6fbe..94439915 100644
--- a/docs/contributing/coding_guide.rst
+++ b/docs/contributing/coding_guide.rst
@@ -62,8 +62,8 @@ Coding guidelines
      f(T_i = 1e6 * u.K, T_e = 2e6 * u.K)
 
   Similarly, when a function has parameters named ``T_e`` and ``T_i``,
-  these parameters should be made :term:`keyword-only` to avoid
-  ambiguity and reduce the chance of errors.
+  these parameters should be made |keyword-only| to avoid ambiguity and
+  reduce the chance of errors.
 
   .. code-block:: python
 
diff --git a/docs/contributing/doc_guide.rst b/docs/contributing/doc_guide.rst
index 858696f0..0736ff61 100644
--- a/docs/contributing/doc_guide.rst
+++ b/docs/contributing/doc_guide.rst
@@ -562,7 +562,7 @@ Here is an example docstring in the numpydoc_ format:
       b : `float`
           The right multiplicand.
 
-      switch_order : `bool`, optional, keyword-only
+      switch_order : `bool`, optional, |keyword-only|
           If `True`, return :math:`a - b`. If `False`, then return
           :math:`b - a`. Defaults to `True`.
 
diff --git a/docs/whatsnew/0.8.1.rst b/docs/whatsnew/0.8.1.rst
index 06501d3b..7f85c83e 100644
--- a/docs/whatsnew/0.8.1.rst
+++ b/docs/whatsnew/0.8.1.rst
@@ -52,7 +52,7 @@ Backwards Incompatible Changes
 
 - In `~plasmapy.diagnostics.thomson.spectral_density`, the arguments
   ``Te`` and ``Ti`` have been renamed ``T_e`` and ``T_i`` and are now
-  required :term:`keyword-only` arguments. (`#974
+  required |keyword-only| arguments. (`#974
   <https://github.com/plasmapy/plasmapy/pull/974>`__)
 - Moved the ``grid_resolution`` attribute from
   `~plasmapy.plasma.grids.AbstractGrid` to
@@ -81,7 +81,7 @@ Backwards Incompatible Changes
   and removed from the public API. (`#1440
   <https://github.com/plasmapy/plasmapy/pull/1440>`__)
 - The parameters ``Z`` and ``mass_numb`` to |Particle| are now
-  :term:`keyword-only`. (`#1456
+  |keyword-only|. (`#1456
   <https://github.com/plasmapy/plasmapy/pull/1456>`__)
 
 
diff --git a/plasmapy/diagnostics/thomson.py b/plasmapy/diagnostics/thomson.py
index 28903b56..d295e28e 100644
--- a/plasmapy/diagnostics/thomson.py
+++ b/plasmapy/diagnostics/thomson.py
@@ -294,11 +294,11 @@ def spectral_density(
         Total combined number density of all electron populations.
         (convertible to cm\ :sup:`-3`)
 
-    T_e : `~astropy.units.Quantity`, keyword-only, shape (Ne, )
+    T_e : `~astropy.units.Quantity`, |keyword-only|, shape (Ne, )
         Temperature of each electron component. Shape (Ne, ) must be equal to the
         number of electron populations Ne. (in K or convertible to eV)
 
-    T_i : `~astropy.units.Quantity`, keyword-only, shape (Ni, )
+    T_i : `~astropy.units.Quantity`, |keyword-only|, shape (Ni, )
         Temperature of each ion component. Shape (Ni, ) must be equal to the
         number of ion populations Ni. (in K or convertible to eV)
 
diff --git a/plasmapy/formulary/collisions.py b/plasmapy/formulary/collisions.py
index c460447f..946356e4 100644
--- a/plasmapy/formulary/collisions.py
+++ b/plasmapy/formulary/collisions.py
@@ -910,7 +910,7 @@ def collision_frequency(
     .. note::
         The `~plasmapy.formulary.collisions.collision_frequency` function has been
         replaced by the more general `~plasmapy.formulary.collisions.CollisionFrequencies` class.
-        To replicate the functionality of collision_frequency, create a
+        To replicate the functionality of `~plasmapy.formulary.collisions.collision_frequency`, create a
         `~plasmapy.formulary.collisions.CollisionFrequencies` class and access the ``Lorentz_collision_frequency`` attribute.
 
     Collision frequency of particles in a plasma.
@@ -2120,8 +2120,9 @@ def __init__(
         Raises
         ------
         `ValueError`
-            If both :math:`v_a` and :math:`T_a` are specified, or neither
-            :math:`v_a` nor :math:`T_a` are specified.
+            If both :math:`v_a` and :math:`T_a` are specified, neither
+            :math:`v_a` nor :math:`T_a` are specified, or specified arrays
+            don't have equal size.
 
         Notes
         -----
@@ -2203,6 +2204,13 @@ def __init__(
         elif T_a is not None:
             raise ValueError("Please specify either v_a or T_a, not both.")
 
+        if (
+            isinstance(v_a, np.ndarray)
+            and isinstance(n_b, np.ndarray)
+            and v_a.shape != n_b.shape
+        ):
+            raise ValueError("Please specify arrays of equal length.")
+
         self.test_particle = test_particle
         self.field_particle = field_particle
         self.v_a = v_a
@@ -2213,7 +2221,11 @@ def __init__(
         )
         self.n_b = n_b
         self.T_b = T_b
-        self.Coulomb_log = Coulomb_log
+        self.Coulomb_log = (
+            Coulomb_log
+            if isinstance(Coulomb_log, u.Quantity)
+            else Coulomb_log * u.dimensionless_unscaled
+        )
 
     @cached_property
     def _mass_ratio(self):
@@ -2321,7 +2333,7 @@ def phi(self):
         The parameter phi used in calculating collision frequencies
         calculated using the default error tolerances of `~scipy.integrate.quad`.
 
-        For more information refer to page 31 of the NRL Formulary.
+        For more information refer to page 31 of :cite:t:`nrlformulary:2019`.
         """
         vectorized_integral = np.vectorize(self._phi_explicit)
 
diff --git a/plasmapy/formulary/lengths.py b/plasmapy/formulary/lengths.py
index e8719dca..c356e382 100644
--- a/plasmapy/formulary/lengths.py
+++ b/plasmapy/formulary/lengths.py
@@ -127,14 +127,14 @@ def gyroradius(
         charge state information is provided, then the particles are assumed
         to be singly charged.
 
-    Vperp : `~astropy.units.Quantity`, optional, keyword-only
+    Vperp : `~astropy.units.Quantity`, optional, |keyword-only|
         The component of particle velocity that is perpendicular to the
         magnetic field in units convertible to meters per second.
 
-    T : `~astropy.units.Quantity`, optional, keyword-only
+    T : `~astropy.units.Quantity`, optional, |keyword-only|
         The particle temperature in units convertible to kelvin.
 
-    T_i : `~astropy.units.Quantity`, optional, keyword-only
+    T_i : `~astropy.units.Quantity`, optional, |keyword-only|
         The particle temperature in units convertible to kelvin.
         Note: Deprecated. Use ``T`` instead.
 
diff --git a/plasmapy/particles/atomic.py b/plasmapy/particles/atomic.py
index 769e5c45..ac50e78a 100644
--- a/plasmapy/particles/atomic.py
+++ b/plasmapy/particles/atomic.py
@@ -209,10 +209,10 @@ def particle_mass(
         particle; an integer representing an atomic number; or an
         instance of the Particle class.
 
-    Z: `int`, optional, keyword-only
+    Z: `int`, optional, |keyword-only|
         The ionization state of the ion.
 
-    mass_numb: `int`, optional, keyword-only
+    mass_numb: `int`, optional, |keyword-only|
         The mass number of an isotope.
 
     Returns
diff --git a/plasmapy/particles/ionization_state.py b/plasmapy/particles/ionization_state.py
index 7b53a4b3..0660dd27 100644
--- a/plasmapy/particles/ionization_state.py
+++ b/plasmapy/particles/ionization_state.py
@@ -193,14 +193,14 @@ class IonizationState:
         the number densities of each neutral/ion.  This argument cannot
         be specified when ``particle`` is an ion.
 
-    T_e: `~astropy.units.Quantity`, keyword-only, optional
+    T_e: `~astropy.units.Quantity`, |keyword-only|, optional
         The electron temperature or thermal energy per electron.
 
-    n_elem: `~astropy.units.Quantity`, keyword-only, optional
+    n_elem: `~astropy.units.Quantity`, |keyword-only|, optional
         The number density of the element, including neutrals and all
         ions.
 
-    tol: `float` or integer, keyword-only, optional
+    tol: `float` or integer, |keyword-only|, optional
         The absolute tolerance used by `~numpy.isclose` and similar
         functions when testing normalizations and making comparisons.
         Defaults to ``1e-15``.
@@ -828,16 +828,16 @@ def average_ion(
 
         Parameters
         ----------
-        include_neutrals : `bool`, optional, keyword-only
+        include_neutrals : `bool`, optional, |keyword-only|
             If `True`, include neutrals when calculating the mean values
             of the different particles.  If `False`, exclude neutrals.
             Defaults to `True`.
 
-        use_rms_charge : `bool`, optional, keyword-only
+        use_rms_charge : `bool`, optional, |keyword-only|
             If `True`, use the root mean square charge instead of the
             mean charge. Defaults to `False`.
 
-        use_rms_mass : `bool`, optional, keyword-only
+        use_rms_mass : `bool`, optional, |keyword-only|
             If `True`, use the root mean square mass instead of the mean
             mass. Defaults to `False`.
 
diff --git a/plasmapy/particles/ionization_state_collection.py b/plasmapy/particles/ionization_state_collection.py
index 3a50317f..ecf9c995 100644
--- a/plasmapy/particles/ionization_state_collection.py
+++ b/plasmapy/particles/ionization_state_collection.py
@@ -42,29 +42,29 @@ class IonizationStateCollection:
         with elements or isotopes as keys and `~astropy.units.Quantity`
         instances with units of number density.
 
-    abundances: `dict`, optional, keyword-only
+    abundances: `dict`, optional, |keyword-only|
         A `dict` with `~plasmapy.particles.particle_class.ParticleLike`
         objects used as the keys and the corresponding relative abundance as the
         values.  The values must be positive real numbers.
 
-    log_abundances: `dict`, optional, keyword-only
+    log_abundances: `dict`, optional, |keyword-only|
         A `dict` with `~plasmapy.particles.particle_class.ParticleLike`
         objects used as the keys and the corresponding base 10 logarithms of their
         relative abundances as the values.  The values must be real numbers.
 
-    n0: `~astropy.units.Quantity`, optional, keyword-only
+    n0: `~astropy.units.Quantity`, optional, |keyword-only|
         The number density normalization factor corresponding to the
         abundances.  The number density of each element is the product
         of its abundance and ``n0``.
 
-    T_e: `~astropy.units.Quantity`, optional, keyword-only
+    T_e: `~astropy.units.Quantity`, optional, |keyword-only|
         The electron temperature in units of temperature or thermal
         energy per particle.
 
-    kappa: `float`, optional, keyword-only
+    kappa: `float`, optional, |keyword-only|
         The value of kappa for a kappa distribution function.
 
-    tol: `float` or `integer`, optional, keyword-only
+    tol: `float` or `integer`, optional, |keyword-only|
         The absolute tolerance used by `~numpy.isclose` when testing
         normalizations and making comparisons.  Defaults to ``1e-15``.
 
@@ -874,16 +874,16 @@ def average_ion(
 
         Parameters
         ----------
-        include_neutrals : `bool`, optional, keyword-only
+        include_neutrals : `bool`, optional, |keyword-only|
             If `True`, include neutrals when calculating the mean values
             of the different particles.  If `False`, exclude neutrals.
             Defaults to `True`.
 
-        use_rms_charge : `bool`, optional, keyword-only
+        use_rms_charge : `bool`, optional, |keyword-only|
             If `True`, use the root mean square charge instead of the
             mean charge. Defaults to `False`.
 
-        use_rms_mass : `bool`, optional, keyword-only
+        use_rms_mass : `bool`, optional, |keyword-only|
             If `True`, use the root mean square mass instead of the mean
             mass. Defaults to `False`.
 
diff --git a/plasmapy/particles/nuclear.py b/plasmapy/particles/nuclear.py
index f87f2b31..8c87884e 100644
--- a/plasmapy/particles/nuclear.py
+++ b/plasmapy/particles/nuclear.py
@@ -123,12 +123,12 @@ def nuclear_reaction_energy(*args, **kwargs):
         A string representing the reaction, like
         ``"D + T --> alpha + n"`` or ``"Be-8 --> 2 * He-4"``.
 
-    reactants: `list`, `tuple`, or `str`, optional, keyword-only
+    reactants: `list`, `tuple`, or `str`, optional, |keyword-only|
         A `list` or `tuple` containing the reactants of a nuclear
         reaction (e.g., ``['D', 'T']``), or a string representing the
         sole reactant.
 
-    products: `list`, `tuple`, or `str`, optional, keyword-only
+    products: `list`, `tuple`, or `str`, optional, |keyword-only|
         A list or tuple containing the products of a nuclear reaction
         (e.g., ``['alpha', 'n']``), or a string representing the sole
         product.
diff --git a/plasmapy/particles/particle_class.py b/plasmapy/particles/particle_class.py
index 5e4630e7..de34ca87 100644
--- a/plasmapy/particles/particle_class.py
+++ b/plasmapy/particles/particle_class.py
@@ -233,10 +233,10 @@ class Particle(AbstractPhysicalParticle):
         integer representing the atomic number of an element; or a
         |Particle| instance.
 
-    mass_numb : `int`, optional, keyword-only
+    mass_numb : `int`, optional, |keyword-only|
         The mass number of an isotope or nuclide.
 
-    Z : `int`, optional, keyword-only
+    Z : `int`, optional, |keyword-only|
         The charge number of the particle.
 
     Raises
@@ -1512,16 +1512,16 @@ def is_category(
             Required categories in the form of one or more `str` objects
             or an iterable.
 
-        require : `str` or iterable providing `str` objects, optional, keyword-only
+        require : `str` or iterable providing `str` objects, optional, |keyword-only|
             One or more categories.  This method will return `False` if
             the |Particle| does not belong to all of these categories.
 
-        any_of : `str` or iterable providing `str` objects, optional, keyword-only
+        any_of : `str` or iterable providing `str` objects, optional, |keyword-only|
             One or more categories. This method will return `False` if
             the |Particle| does not belong to at least one of these
             categories.
 
-        exclude : `str` or iterable providing `str` objects, optional, keyword-only
+        exclude : `str` or iterable providing `str` objects, optional, |keyword-only|
             One or more categories.  This method will return `False` if
             the |Particle| belongs to any of these categories.
 
@@ -1824,10 +1824,10 @@ class DimensionlessParticle(AbstractParticle):
 
     Parameters
     ----------
-    mass : positive real number, keyword-only, optional
+    mass : positive real number, |keyword-only|, optional
         The mass of the dimensionless particle.  Defaults to `numpy.nan`.
 
-    charge : real number, keyword-only, optional
+    charge : real number, |keyword-only|, optional
         The electric charge of the dimensionless particle.  Defaults to
         `numpy.nan`.
 
diff --git a/plasmapy/particles/particle_collections.py b/plasmapy/particles/particle_collections.py
index b6836d86..7d49963b 100644
--- a/plasmapy/particles/particle_collections.py
+++ b/plasmapy/particles/particle_collections.py
@@ -360,11 +360,11 @@ def average_particle(
             particles contained in the |ParticleList| are assumed to be
             equally abundant.
 
-        use_rms_charge : `bool`, optional, keyword-only
+        use_rms_charge : `bool`, optional, |keyword-only|
             If `True`, use the root mean square charge instead of the mean
             charge. Defaults to `False`.
 
-        use_rms_mass : `bool`, optional, keyword-only
+        use_rms_mass : `bool`, optional, |keyword-only|
             If `True`, use the root mean square mass instead of the mean mass.
             Defaults to `False`.
 
diff --git a/plasmapy/utils/_units_helpers.py b/plasmapy/utils/_units_helpers.py
index fc5f1c73..84134cfd 100644
--- a/plasmapy/utils/_units_helpers.py
+++ b/plasmapy/utils/_units_helpers.py
@@ -29,14 +29,14 @@ def _get_physical_type_dict(
         A iterable that is expected to contain objects with physical
         types.
 
-    only_quantities : `bool`, keyword-only, optional
+    only_quantities : `bool`, |keyword-only|, optional
         If `True`, only `~astropy.units.Quantity` instances in
         ``iterable`` will be passed into the resulting `dict`. If
         `False`, then any unit, |PhysicalType|, or object that can be
         converted to a |Quantity| or that has a physical type will be
         included in the `dict`. Defaults to `False`.
 
-    numbers_become_quantities : `bool`, keyword-only, optional
+    numbers_become_quantities : `bool`, |keyword-only|, optional
         If `True`, `~numbers.Number` objects will be converted into
         dimensionless |Quantity| instances. If `False`,
         `~numbers.Number` objects will be skipped. Defaults to `False`.
diff --git a/plasmapy/utils/code_repr.py b/plasmapy/utils/code_repr.py
index b00327f2..b140b943 100644
--- a/plasmapy/utils/code_repr.py
+++ b/plasmapy/utils/code_repr.py
@@ -345,7 +345,7 @@ def method_call_string(
         other type of `object` if there is only one positional argument,
         to be used during instantiation of ``cls``.
 
-    kwargs_to_cls: `dict`, keyword-only optional
+    kwargs_to_cls: `dict`, |keyword-only| optional
         A `dict` containing the keyword arguments to be used during
         instantiation of ``cls``.
 
@@ -354,11 +354,11 @@ def method_call_string(
         used in the method call, or any other `object` if there is only
         one positional argument.
 
-    kwargs_to_method: `dict`, keyword-only, optional
+    kwargs_to_method: `dict`, |keyword-only|, optional
         A `dict` containing the keyword arguments to be used during
         the method call.
 
-    max_items : int, keyword-only, optional
+    max_items : int, |keyword-only|, optional
         The maximum number of items to include in a `~numpy.ndarray` or
         `~astropy.units.Quantity`; additional items will be truncated
         with an ellipsis.  Defaults to 12.


Test patch:
diff --git a/plasmapy/formulary/tests/test_collisions.py b/plasmapy/formulary/tests/test_collisions.py
index 7775f68a..c1fe4d20 100644
--- a/plasmapy/formulary/tests/test_collisions.py
+++ b/plasmapy/formulary/tests/test_collisions.py
@@ -1713,7 +1713,7 @@ class TestCollisionFrequencies:
         v_a=1 * u.m / u.s,
         T_b=1 * u.K,
         n_b=1 * u.m**-3,
-        Coulomb_log=1 * u.dimensionless_unscaled,
+        Coulomb_log=1,
     )
 
     MKS_unit_conversion_test_constructor_arguments = {
@@ -1762,6 +1762,7 @@ class TestCollisionFrequencies:
             ("energy_loss", u.Hz),
             ("x", u.dimensionless_unscaled),
             ("Lorentz_collision_frequency", u.Hz),
+            ("Coulomb_log", u.dimensionless_unscaled),
         ],
     )
     def test_units(self, attribute_to_test, expected_attribute_units):
@@ -2126,6 +2127,17 @@ def test_limit_values(
                     "Coulomb_log": 1 * u.dimensionless_unscaled,
                 },
             ),
+            # Arrays of unequal shape error
+            (
+                ValueError,
+                (Particle("e-"), Particle("e-")),
+                {
+                    "v_a": np.ndarray([1, 1]) * u.cm / u.s,
+                    "T_b": 1 * u.eV,
+                    "n_b": ones_array * u.cm**-3,
+                    "Coulomb_log": 1 * u.dimensionless_unscaled,
+                },
+            ),
         ],
     )
     def test_errors(