๐ญ Astropy#
Astropy is a widely-used Python library for astronomy. One of its many widely-used sub-packages is its astropy.units library, which provides objects and methods for working with physical quantities, units, and dimensions.
unxt uses Astropyโs units and dimensions objects as its backend, while providing a more function-oriented API and JAX support. Unsurprisingly, unxt has deep support for Astropy objects.
Dimensions#
>>> import unxt as u
>>> import astropy.units as apyu
>>> dim = apyu.get_physical_type("length") # Astropy
>>> dim
PhysicalType('length')
>>> u.dimension("length") # unxt
PhysicalType('length')
>>> u.dimension(dim) # unxt <-> Astropy
PhysicalType('length')
>>> u.dimension_of(dim) # unxt <-> Astropy
PhysicalType('length')
Units#
>>> import unxt as u
>>> import astropy.units as apyu
>>> meter = apyu.Unit("m") # Astropy
>>> meter
Unit("m")
>>> u.unit("m") # unxt
Unit("m")
>>> u.unit(meter) # unxt <-> Astropy
Unit("m")
>>> u.unit_of(meter) # unxt <-> Astropy
Unit("m")
Quantities#
unxt uses Astropyโs units and dimensions objects as its backend, but has its own Quantity class hierarchy.
Converting an Astropy Quantity to a unxt Quantity is straightforward โ use unxt.Quantity.from_:
>>> import unxt as u
>>> import astropy.units as apyu
>>> aq = apyu.Quantity(1, 'm') # Astropy Quantity
>>> aq
<Quantity 1. m>
>>> xq = u.Quantity.from_(aq) # unxt Quantity
>>> xq
Quantity(Array(1., dtype=float32), unit='m')
Alternatively, the multiple-dispatch library on which unxt is built enables 2-way conversion.
>>> from plum import convert
>>> convert(aq, u.Quantity)
Quantity(Array(1., dtype=float32), unit='m')
>>> convert(xq, apyu.Quantity)
<Quantity 1. m>
Unit Conversion with Astropy#
unxt provides full support for unit conversions using Astropyโs units. The low-level uconvert_value function works seamlessly with Astropy unit objects, enabling high-performance conversions suitable for JAX transformations.
uconvert_value with Astropy Units#
The uconvert_value function accepts Astropy unit objects and performs efficient numerical conversions:
>>> import unxt as u
>>> import astropy.units as apyu
>>> import numpy as np
>>> # Scalar conversion
>>> u.uconvert_value(apyu.Unit("km"), apyu.Unit("m"), 1000)
1.0
>>> # Array conversion
>>> u.uconvert_value(apyu.Unit("km"), apyu.Unit("m"), np.array([1000, 2000, 5000]))
array([1., 2., 5.])
>>> # No conversion when units are identical (hot-path optimization)
>>> u.uconvert_value(apyu.Unit("m"), apyu.Unit("m"), 1000)
1000
Complex Unit Conversions#
Support for composite units and unit equivalencies:
>>> # Velocity units
>>> u.uconvert_value(apyu.Unit("m/s"), apyu.Unit("km/s"), 1)
1000.0
>>> # With equivalencies (e.g., temperature)
>>> import astropy.units as apyu
>>> with apyu.add_enabled_equivalencies(apyu.temperature()):
... u.uconvert_value(apyu.Unit("deg_C"), apyu.Unit("K"), 273.15)
0.0
Performance Considerations#
uconvert_value with Astropy units is optimized for performance:
Hot-path: When units are identical, the value is returned unchanged
JAX compatible: Works with JIT compilation, vmap, and autodiff
Low overhead: Direct Astropy unit conversion without Quantity wrapping
>>> import jax
>>> import astropy.units as apyu
>>> @jax.jit
... def convert_to_km(values_in_m):
... return u.uconvert_value(apyu.Unit("km"), apyu.Unit("m"), values_in_m)
>>> convert_to_km(np.array([1000., 5000., 10000.]))
Array([ 1., 5., 10.], dtype=float32)