astropy/astropy — pull request #1894 by mhvk (2013-12-11 18:09:45+00:00)
Title: Functional units: Mag, dB, and dex

Now that `Unit` and `Quantity` have calmed down a bit, something a bit bigger: introducing a framework for functional units and an application to logarithmic units, so that one do things like `dex(cm/s**2)`, `dB(mW)`, and `mag(AB)`.

I think the usage I have in mind is best illustrated through an example -- see the output from an ipython-notebook session using magnitudes on http://www.astro.utoronto.ca/~mhvk/functional_units_magnitudes.html

For here, just a very brief outline:
```
In [1]: import astropy.units as u, astropy.units.functional as lu
In [2]: iv = lu.Magnitude(100. * u.ct/u.s)
In [3]: iv, iv.quantity, iv.unit
Out[3]: (, , MagUnit('ct / s'))

In [4]: iv.unit.physical_unit, iv.unit.functional_unit
Out[4]: (Unit("ct / s"), Unit("mag"))
```

I hope initially to get feedback mostly on whether this covers what usage people can foresee.

Some notes:
- This is meant as a more general alternative to the `Magnitude` class of #1577. In practice, the idea is not dissimilar; the main difference is that rather than store a zero-point magnitude, the unit corresponding to mag=0 is stored (or, equivalently, what one divides by before taking the `log`).
- Like #1577, this explicitly is about *units*, not magnitude systems (see discussion in #1577, which convinced me that this is the right approach).
- There are a lot of test cases, but no documentation yet, as I want to be sure people agree with the approach.
- Similarly, I have not yet worried about reading in functional units from strings, or writing out to formats other than `generic` (i.e., no FITS, etc.)
- I decided not to subclass from `UnitBase`, as that required much larger changes to `units` (see my earlier trial, https://github.com/mhvk/astropy/tree/units-functional). However, an abstract base class with expectations of what any unit should provide might be helpful. Technical advice very welcome!
- The first four commits are from #1628, and only introduce `dex`, `mag`, and `dB` (without underlying physical unit).