Repository: PlasmaPy/PlasmaPy

Issue:
Computation of gyroradius from Plasmapy, in case of missing temperature should return NaNs instead of ValueError
<!--

Thanks for opening an issue! To help us react appropriately to your report,
please first look through https://github.com/PlasmaPy/PlasmaPy/issues and check
whether no other issue already describes your problem.

For more general "how do I do X?" type questions, please speak to us in real
time on https://app.element.io/#/room/#plasmapy:openastronomy.org or ask on
GitHub Discussions: https://github.com/plasmapy/plasmapy/discussions . We'll be
more than happy to help! :)

-->

## Feature request

<!--

Please include details of the feature you would like to see, why you would
like to see it/the use case

-->
At present if I do the following, a ```ValueError``` is raised:
```python
>>> from plasmapy.formulary.parameters import gyroradius
>>> gyroradius(5 * u.nT, particle='p+', T_i=numpy.nan * u.K)
ValueError: Must give Vperp or T_i, but not both, as arguments to gyroradius
```
which is the wrong kind of error being raised. Error arises because temperature (```T_i```) data is NaN and not because the user is providing both ```T_i``` and ```Vperp```., as the text accompanying the error claims.

Another problem with this is that if we are trying to calculate gyroradius from a spacecraft data and at at any specific time, if both the magnetic field and (```B```) and ```T_i``` or ```Vperp``` data are missing, it raises the ```ValueError``` and stops the code from executing.

If instead of doing that, the code has the option to just set such values of gyroradius to ```numpy.nan``` (as is already happening when ```B``` is ```numpy.nan```), it increases its functionality and doesn't force the user to feed clean data.

I have also attached a screenshot of the error!
![gyroradius_error](https://user-images.githubusercontent.com/25327981/108413585-0d055b80-71e0-11eb-9902-9c679e974805.png)



Discussion:
I ran into this issue today, again! And spent 10 minutes wondering why it is giving `ValueError`. Then I realized it is an on open issue and hasn't been solved yet!
Hi, I just wanted to look into this and was trying to wrap my head around those if-else clauses in the source code. If I understood you correctly, and please correct me if I'm wrong, you suggest that the function simply returns a `np.nan` if `T_i=np.nan` or (and) `Vperp=np.nan`.

In addition, you are suggesting that if the magnetic field is `np.nan` a `np.nan` should be returned. That is already the case as long as either `Vperp` or `T_i` is a finite value but should also be the case if all input parameters were `np.nan`.

Am I understanding that correctly?
Yes, that is kind of what I am saying, apart from the fact that the code raises wrong kind of error. As I mentioned in my first comment based on the example I gave, "Error arises because temperature `(T_i)` data is `NaN `and not because the user is providing both `T_i `and `Vperp`., as the text accompanying the error claims."

And yeah I also suggested that the behaviour code has for `B=np.nan` should be replicated for `T_i=np.nan`, thus if someone inputs one or more values, as long as inputs are syntactically correct, the code should give `np.nan` as an output and not raise an error!
thanks for clarifying, will try to look into that this evening (or tomorrow, as I have a full schedule today).

Resolving patch:
diff --git a/plasmapy/formulary/parameters.py b/plasmapy/formulary/parameters.py
--- a/plasmapy/formulary/parameters.py
+++ b/plasmapy/formulary/parameters.py
@@ -1198,7 +1198,7 @@ def gyroradius(
 
     # check 1: ensure either Vperp or T_i invalid, keeping in mind that
     # the underlying values of the astropy quantity may be numpy arrays
-    if np.any(np.logical_not(np.logical_xor(isfinite_Vperp, isfinite_Ti))):
+    if np.any(np.logical_and(isfinite_Vperp, isfinite_Ti)):
         raise ValueError(
             "Must give Vperp or T_i, but not both, as arguments to gyroradius"
         )


Test patch:
diff --git a/plasmapy/formulary/tests/test_parameters.py b/plasmapy/formulary/tests/test_parameters.py
--- a/plasmapy/formulary/tests/test_parameters.py
+++ b/plasmapy/formulary/tests/test_parameters.py
@@ -802,6 +802,11 @@ def test_gyroradius():
 
     assert gyroradius(B, "e-", Vperp=25 * u.m / u.s).unit.is_equivalent(u.m)
 
+    # test for possiblity to allow nan for input values
+    assert np.isnan(gyroradius(np.nan * u.T, particle="e-", T_i=1 * u.K))
+    assert np.isnan(gyroradius(1 * u.T, particle="e-", T_i=np.nan * u.K))
+    assert np.isnan(gyroradius(1 * u.T, particle="e-", Vperp=np.nan * u.m / u.s))
+
     Vperp = 1e6 * u.m / u.s
     Bmag = 1 * u.T
     omega_ce = gyrofrequency(Bmag, "e-")