A common convention in plasma physics is to use the electron-volt (eV) as a unit of temperature. Strictly speaking, the eV is not a unit of temperature but is rather a measure of the typical thermal energy per particle (using the relation E = k_B * T). The duality of eV as a unit of temperature and energy complicates the usage of units.
At present, several functions in parameters.py permit eV as a unit of temperature. The conversion from eV to K is done inside of the function using an equivalency as follows:
>>> from astropy import units as u
>>> (1*u.eV).to(u.K, equivalencies=u.temperature_energy())
<Quantity 11604.522060401008 K>
A problem with this approach is that this non-standard unit conversion is done silently and implicitly, and I am having doubts about this design decision.
Some considerations are:
Our options include:
kelvinify) to explicitly do the temperature conversion.>>> from astropy.units import keV
>>> from plasmapy.constants import k_B
>>> thermal_velocity(T=1.4*keV/k_B, particle='p')
The more I think about it, the more I am in favor of option 3. What does everyone else think?
In an ideal world 3 would be optimal, but the convention seems so prevalent that I think we have to consider alienating the users, which we - bear in mind - don't have yet. Taking this into account I'll have to go with option 1 for now, but I'm open to being convinced otherwise!
I guess what I'm trying to say is.... It seems all right to set out to improve the world of plasma science one formula translator at a time.
I was getting into this question while dev: I myself are not consistant ! :/
Offering a conversion function can be very usefull, for us and also as a tool of the library.
Either we force every temperature to be in Kelvin in the argument, or we look at every temperature arguments and if it is in eV, we change it to K, which would be redondant and slow.
Hence, 3 for me.
I have been working recently on trying to do calculations based off of published observations. Most of my energy has been spent trying to calculate thermal speeds from temperatures reported in eV (Almost every reconnection observation!).
I get all of the points and from design structure I agree that 3 would be the way to go, but from a user perspective it would be great to be able to enter eV as temperature.
Just food for thought ¯\_(ツ)_/¯
Is there a unit equivalency in astropy to allow this conversion? You could work on an API where the user has to explicitly provide the equivalency to say "treat eV as convertible to K"
Yep, I've used that equivalency a lot. It is: astropy.units.temperature_energy. What @Cadair said can be option 4. 😸
Looks like astropy.units.set_enabled_equivalencies() can do this already:
>>> from astropy import units as u
>>> u.set_enabled_equivalencies(u.temperature_energy())
>>> (5*u.eV).to(u.K) # sigh...
<Quantity 58022.61030200504 K>
So in essence, a short wrapper, say,
def some_easily_memorable_name():
u.set_enabled_equivalencies(u.temperature_energy())
And then we could have this located in plasmapy itself for ease of access? Does that make sense?
If you are going to be using just Kelvins I think you'll be pandering mainly to cold plasma people. In HEDP you have to use eV; it becomes absurd when you're talking about 2 MegaKelvins temperatures. I vote for allowing eV as a temperature input and just converting it into Kelvins.
I did some quick testing with timeit and it looks like the timing difference between a function with conversion and one without is negligible (have to subtract out cost of function call), or at least I can't measure it. I get time differences on the order of nanoseconds and it's volatile, meaning sometimes the function with conversion is faster than the function without. I assume this is because astropy is just doing a type check (Boolean operation) and a conversion (multiplication operation) under the hood, both of which are really quick.
it becomes absurd when you're talking about 2 MegaKelvins temperatures
I disagree with this on principal (sticking a u.MK is only one character more than u.K and infact the same as u.eV :wink:), but I appreciate the general point about conventions in different areas.
My opinion is that if you wish to do anything with units other than follow the SI units then you should have to be explicit about it.
Based on everything that people have said, my vote has changed to requiring that the equivalency between eV and K be made explicit, while also making it as easy as possible to set that equivalency. That seems like a fair compromise to me that could prevent some unanticipated behavior with unit conversions while also allowing people to use eV if that is their preference.
I've noticed that in solar physics it's pretty standard to use K and MK as temperature, though strangely not kK for some reason.
So I'm still not sure what the problem is with using eV for temperatures.... Sure it's an energy unit, but does this conflict with some sort of type checking? Is there some issue I'm unaware of with using T_e = T_e.to(units.K, equivalencies=units.temperature_energy()) within the function body?
As mentioned previously, I've not seen significant speed changes by adding this check/conversion. Here is the script I used to test timings; it is quite possible that I am doing something wrong.
eV_2_Kelvin.zip
I'm not 100% sure it plays well with the strict physical unit input settings we're toying with implementing here via astropy.units.quantity_input. I'll check. later.
The current thinking is that we'll go with a thin wrapper to the units.temperature_energy() so it can be enabled in scripts like this, running it like this at the beginning of a script (if that's at all possible with astropy):
plasmapy.allow_eV_as_T()
Implementing this wrapper should not take long. Testing it may be more difficult.
I suggested in https://github.com/astropy/astropy/issues/6999 that there be a unit such as eV_temp that would be eV as a unit of temperature rather than energy. Having a unit of eV_temp would eliminate my grumblings about using electron volts as a temperature in PlasmaPy's API since it would eliminate the ambiguity between whether an eV refers to temperature or energy. [We did decide on a policy of using SI units internally within PlasmaPy early on since it is the recognized international standard.]
If the astropy.units subpackage maintainers are amenable to the new units suggested in https://github.com/astropy/astropy/issues/6999, might anyone from PlasmaPy be interested in making an upstream contribution?
I changed the name of this issue to be 3% less controversial, since having an eV_temp unit in astropy.units would remove my objections to having a unit of energy be used as a unit of temperature. Given how strong our opinions are about eV as a unit of temperature, I'm thinking perhaps we should put this as one of our highest priorities.
My only request is that plasma physicists use notation like Te/kB = 1 keV so that the units actually make sense!
This would also help make the code more uniform as we currently have a hodgepodge of decorators and custom checks within functions for verifying units.
Seems like we could close this. We went with the equivalencies solution instead.
Most helpful comment
This would also help make the code more uniform as we currently have a hodgepodge of decorators and custom checks within functions for verifying units.