Open mhvk opened 8 years ago
That would make sense, and is in line with what I was considering we would need when I first tried to tackle cgs E&M units. That was way back and at the time I don't think we even had equivalencies fully working yet, though my memory is hazy. I definitely think this would be the right approach.
See also #745.
Another similar / related issue is #4086.
Reading #4086, I wondered whether the equivalency system itself might be good enough, i.e., whether one could device equivalencies which would make it possible to do something like
with u.set_enabled_equivalencies(u.electromagnetic('emu')):
...
(with exact names TBD). Given the description on the wikipedia page where, e.g., the cgs use system explicitly defines charge via the electrostatic force, this might indeed be handy.
However, it is not quite clear how to let this interact with constants
, where really within the context manager constants.e
should have a different unit. Possibly, the above set_em_system
would simply incorporate setting any required equivalencies.
Right, I was also thinking an equivalency would do the trick. As for constants we've already talked elsewhere about allowing multiple definitions for a constant, so might incorporate that somehow.
@MaxNoe - above the question had turned to whether a set of equivalencies might do the trick. My sense is that that is the case, but I'm not completely sure. It might be good to start with a list (or better, a set of tests!) that would do what you wanted, and then write the equivalencies to make it work...
p.s. As a probably worse alternative, one could make a new "constants" system in which mu0 and eps0 are whatever they should be in cgs. This is worse though in that the constants system has to be chosen per astropy session, i.e., one cannot easily work with different units systems inside different libraries.
I don't think equivalencies are the right API choice. It's not about converting units, it is the unit system itself that needs to be changed.
The worst thing in my opinion, is not being able to tell in which unit system equations or functions are written. With a context manager or decorator for functions, this will be clear:
with u.gaussian_cgs:
print(u.gauss.decompose())
print(u.gauss.decompose())
This should result in
1 cm(-1/2) g(1/2) s(-1)
1e-4 kg A(-1) s(-2)
As a probably worse alternative, one could make a new "constants" system in which mu0 and eps0 are whatever they should be in cgs.
The problem is not that they have different values, they simply do not exist. So one should not even define them when using cgs.
This is the way it is implemented by the way at the moment. However, the error message could be better:
In [1]: import astropy.constants as c
In [2]: c.e.name, c.e.gauss.value, c.e.gauss.unit
Out[2]: ('Electron charge', 4.80320467299766e-10, Unit("Fr"))
In [3]: c.eps0.name, c.eps0.gauss.value, c.eps0.gauss.unit
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-ecbc894f3cc9> in <module>
----> 1 c.eps0.name, c.eps0.gauss.value, c.eps0.gauss.unit
~/.local/anaconda3/lib/python3.7/site-packages/astropy/units/quantity.py in __getattr__(self, attr)
815 "'{0}' object has no '{1}' member".format(
816 self.__class__.__name__,
--> 817 attr))
818
819 def get_virtual_unit_attribute():
AttributeError: 'EMCODATA2014' object has no 'gauss' member
@MaxNoe - Without equivalencies, I'm not sure how one can avoid some of the units actually being defined differently in terms of other units, i.e., u.G
effectively changing. The easiest way to do that is using a method similar to that forhaving different constants (which also changes the units), but the problem then is that it becomes a full-session choice. This, of course, is risky: e.g., what happens if I call a library, and the library calculate a magnetic pressure using b**2/(2*c.mu0)
?
Indeed, this may be the problem with a u.gaussian_cgs
context as well. The advantage of it being a set of equivalencies is that they are used after all else fails, so the library would work fine.
Without equivalencies, I'm not sure how one can avoid some of the units actually being defined differently in terms of other units, i.e., u.G effectively changing.
That's kind of my point. I don't want to avoid that. Imho a clear separation of the different unit systems with transformation explictly at borders is preferable and possibly also the only correct way to do it.
This much reminds me of the encoding/decoding/string discussions in 2 vs. 3. 2 assumed interchangebility where there in reality was none, which lead to subtle errors as soon as non-ascii was encountered, 3 forces you to convert between bytes / unicode codepoints.
The different unit systems are not really interoperable, formulas in EM look very different, natural constants differ or don't exist in either system. So having the astropy units be SI by default and have a context manager or session settting to switch to CGS/Gauss or another unit system might be the clean solution.
I can see the preference within one piece of code, but, as I noted, if one goes for a system like that for setting constants, then it does imply the change is session-wide, i.e., one can not set a system just for a piece of code, and it will also affect any library calls, etc.
Anyway., I think we're reaching the point where a piece of code would help discussion...
So Fr
(statC/esu
) cannot be calculated as 1 Fr = 1 g1/2 cm3/2 s−1
and Gauss
cannot be calculated as 1 Gauss = cm-1/2 g1/2 s−1
?
By default, things effectively are treated as SI equivalents, and the cgs conversions depends on which system one is in. So, the units system needs to have a way to communicate what system one wants to be in, which is what this issue is about!
(This is a follow-up of #4355, combining comments by @eteq and myself; EDIT (2021): this also is meant to replace #1687, #5879 - calculate magnetic energy density, etc.; #4086 - coulomb-statcoulomb equivalency)
There are multiple versions of the E&M system in cgs [1] which are mutually incompatible. As a result, many cgs E&M unit conversions in astropy are not normally possible. It might be possible to devise a context manager within which conversion is allowed, i.e., one would do something like
and one could then happily convert charge per second into the relevant current, or calculate a force from just
charge1 * charge2 / distance**2
in the cgs ESU system.[1] https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units#Derivation_of_CGS_units_in_electromagnetism