Skip to content

Commit

Permalink
refactor: adhere to ISO 31-11 (#81)
Browse files Browse the repository at this point in the history
Signed-off-by: nstarman <[email protected]>
  • Loading branch information
nstarman authored Mar 30, 2024
1 parent 140380f commit 0305d56
Show file tree
Hide file tree
Showing 17 changed files with 193 additions and 185 deletions.
16 changes: 7 additions & 9 deletions src/coordinax/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ def components(cls) -> tuple[str, ...]:
>>> Cartesian2DVector.components
('x', 'y')
>>> SphericalVector.components
('r', 'phi', 'theta')
('r', 'theta', 'phi')
>>> RadialDifferential.components
('d_r',)
Expand Down Expand Up @@ -608,8 +608,8 @@ def to_units(
>>> cart = Cartesian2DVector(x=Quantity(1, "m"), y=Quantity(2, "km"))
>>> cart.to_units({"length": "km"})
Cartesian2DVector(
x=Quantity[PhysicalType('length')](value=f32[], unit=Unit("km")),
y=Quantity[PhysicalType('length')](value=f32[], unit=Unit("km"))
x=Quantity[...](value=f32[], unit=Unit("km")),
y=Quantity[...](value=f32[], unit=Unit("km"))
)
This also works for vectors with different units:
Expand All @@ -619,9 +619,8 @@ def to_units(
>>> sph.to_units({"length": "km", "angle": "deg"})
SphericalVector(
r=Distance(value=f32[], unit=Unit("km")),
phi=Quantity[PhysicalType('angle')](value=f32[], unit=Unit("deg")),
theta=Quantity[PhysicalType('angle')](value=f32[], unit=Unit("deg"))
)
theta=Quantity[...](value=f32[], unit=Unit("deg")),
phi=Quantity[...](value=f32[], unit=Unit("deg")) )
"""
# Ensure `units_` is PT -> Unit
Expand Down Expand Up @@ -667,9 +666,8 @@ def to_units(
>>> sph.to_units(ToUnitsOptions.consistent)
SphericalVector(
r=Distance(value=f32[], unit=Unit("m")),
phi=Quantity[PhysicalType('angle')](value=f32[], unit=Unit("rad")),
theta=Quantity[PhysicalType('angle')](value=f32[], unit=Unit("rad"))
)
theta=Quantity[...](value=f32[], unit=Unit("deg")),
phi=Quantity[...](value=f32[], unit=Unit("deg")) )
"""
units_ = {}
Expand Down
7 changes: 3 additions & 4 deletions src/coordinax/_base_vec.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,9 @@ def represent_as(self, target: type[VT], /, *args: Any, **kwargs: Any) -> VT:
>>> sph = vec.represent_as(SphericalVector)
>>> sph
SphericalVector(
r=Distance(value=f32[], unit=Unit("m")),
phi=Quantity[PhysicalType('angle')](value=f32[], unit=Unit("rad")),
theta=Quantity[PhysicalType('angle')](value=f32[], unit=Unit("rad"))
)
r=Distance(value=f32[], unit=Unit("m")),
theta=Quantity[...](value=f32[], unit=Unit("rad")),
phi=Quantity[...](value=f32[], unit=Unit("rad")) )
>>> sph.r
Distance(Array(3.7416575, dtype=float32), unit='m')
Expand Down
4 changes: 2 additions & 2 deletions src/coordinax/_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def check_r_non_negative(r: BatchableLength) -> BatchableLength:
)


def check_phi_range(phi: BatchableAngle) -> BatchableAngle:
def check_azimuth_range(phi: BatchableAngle) -> BatchableAngle:
"""Check that the polar angle is in the range [0, 2pi)."""
return eqx.error_if(
phi,
Expand All @@ -34,7 +34,7 @@ def check_phi_range(phi: BatchableAngle) -> BatchableAngle:
)


def check_theta_range(theta: BatchableAngle) -> BatchableAngle:
def check_polar_range(theta: BatchableAngle) -> BatchableAngle:
"""Check that the inclination angle is in the range [0, pi]."""
return eqx.error_if(
theta,
Expand Down
2 changes: 1 addition & 1 deletion src/coordinax/_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
_2pid = Quantity(360, "deg")


def converter_phi_to_range(phi: BatchableAngle) -> BatchableAngle:
def converter_azimuth_to_range(phi: BatchableAngle) -> BatchableAngle:
"""Wrap the polar angle to the range [0, 2pi).
It's safe to do this conversion since this is a phase cut, unlike `theta`,
Expand Down
19 changes: 13 additions & 6 deletions src/coordinax/_d2/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import coordinax._typing as ct
from .base import Abstract2DVector, Abstract2DVectorDifferential
from coordinax._base_vec import AbstractVector
from coordinax._checks import check_phi_range, check_r_non_negative
from coordinax._converters import converter_phi_to_range
from coordinax._checks import check_azimuth_range, check_r_non_negative
from coordinax._converters import converter_azimuth_to_range
from coordinax._utils import classproperty

# =============================================================================
Expand Down Expand Up @@ -130,9 +130,16 @@ def norm(self) -> ct.BatchableLength:

@final
class PolarVector(Abstract2DVector):
"""Polar vector representation.
r"""Polar vector representation.
Parameters
----------
r : BatchableDistance
Radial distance :math:`r \in [0,+\infty)`.
phi : BatchableAngle
Polar angle :math:`\phi \in [0,2\pi)`. We use the symbol `phi` to
adhere to the ISO standard 31-11.
We use the symbol `phi` instead of `theta` to adhere to the ISO standard.
"""

r: ct.BatchableDistance = eqx.field(
Expand All @@ -141,7 +148,7 @@ class PolarVector(Abstract2DVector):
r"""Radial distance :math:`r \in [0,+\infty)`."""

phi: ct.BatchableAngle = eqx.field(
converter=lambda x: converter_phi_to_range(
converter=lambda x: converter_azimuth_to_range(
Quantity["angle"].constructor(x, dtype=float) # pylint: disable=E1120
)
)
Expand All @@ -150,7 +157,7 @@ class PolarVector(Abstract2DVector):
def __check_init__(self) -> None:
"""Check the initialization."""
check_r_non_negative(self.r)
check_phi_range(self.phi)
check_azimuth_range(self.phi)

@classproperty
@classmethod
Expand Down
22 changes: 13 additions & 9 deletions src/coordinax/_d3/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import coordinax._typing as ct
from .base import Abstract3DVector, Abstract3DVectorDifferential
from coordinax._base_vec import AbstractVector
from coordinax._checks import check_phi_range, check_r_non_negative
from coordinax._converters import converter_phi_to_range
from coordinax._checks import check_azimuth_range, check_r_non_negative
from coordinax._converters import converter_azimuth_to_range
from coordinax._utils import classproperty

##############################################################################
Expand Down Expand Up @@ -82,8 +82,8 @@ def __add__(self, other: Any, /) -> "Cartesian3DVector":
>>> from unxt import Quantity
>>> from coordinax import Cartesian3DVector, SphericalVector
>>> q = Cartesian3DVector.constructor(Quantity([1, 2, 3], "kpc"))
>>> s = SphericalVector(r=Quantity(1, "kpc"), phi=Quantity(0, "deg"),
... theta=Quantity(90, "deg"))
>>> s = SphericalVector(r=Quantity(1, "kpc"), theta=Quantity(90, "deg"),
... phi=Quantity(0, "deg"))
>>> (q + s).x
Quantity['length'](Array(2., dtype=float32), unit='kpc')
Expand All @@ -103,8 +103,8 @@ def __sub__(self, other: Any, /) -> "Cartesian3DVector":
>>> from unxt import Quantity
>>> from coordinax import Cartesian3DVector, SphericalVector
>>> q = Cartesian3DVector.constructor(Quantity([1, 2, 3], "kpc"))
>>> s = SphericalVector(r=Quantity(1, "kpc"), phi=Quantity(0, "deg"),
... theta=Quantity(90, "deg"))
>>> s = SphericalVector(r=Quantity(1, "kpc"), theta=Quantity(90, "deg"),
... phi=Quantity(0, "deg"))
>>> (q - s).x
Quantity['length'](Array(0., dtype=float32), unit='kpc')
Expand Down Expand Up @@ -134,15 +134,19 @@ def norm(self) -> ct.BatchableLength:

@final
class CylindricalVector(Abstract3DVector):
"""Cylindrical vector representation."""
"""Cylindrical vector representation.
This adheres to ISO standard 31-11.
"""

rho: ct.BatchableLength = eqx.field(
converter=partial(Quantity["length"].constructor, dtype=float)
)
r"""Cylindrical radial distance :math:`\rho \in [0,+\infty)`."""

phi: ct.BatchableAngle = eqx.field(
converter=lambda x: converter_phi_to_range(
converter=lambda x: converter_azimuth_to_range(
Quantity["angle"].constructor(x, dtype=float) # pylint: disable=E1120
)
)
Expand All @@ -156,7 +160,7 @@ class CylindricalVector(Abstract3DVector):
def __check_init__(self) -> None:
"""Check the validity of the initialisation."""
check_r_non_negative(self.rho)
check_phi_range(self.phi)
check_azimuth_range(self.phi)

@classproperty
@classmethod
Expand Down
36 changes: 18 additions & 18 deletions src/coordinax/_d3/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def constructor(
"""
obj = obj.represent_as(apyc.PhysicsSphericalRepresentation)
return cls(r=obj.r, phi=obj.phi, theta=obj.theta)
return cls(r=obj.r, theta=obj.theta, phi=obj.phi)


@LonLatSphericalVector.constructor._f.register # noqa: SLF001
Expand Down Expand Up @@ -227,9 +227,9 @@ def constructor(
>>> dif = cx.LonCosLatSphericalDifferential.constructor(dsph)
>>> dif
LonCosLatSphericalDifferential(
d_distance=Quantity[...]( value=f32[], unit=Unit("km / s") ),
d_lon_coslat=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_lat=Quantity[...]( value=f32[], unit=Unit("mas / yr") )
d_lat=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_distance=Quantity[...]( value=f32[], unit=Unit("km / s") )
)
>>> dif.d_distance
Quantity['speed'](Array(1., dtype=float32), unit='km / s')
Expand Down Expand Up @@ -265,8 +265,8 @@ def vec_to_q(obj: Abstract3DVector, /) -> Shaped[Quantity["length"], "*batch 3"]
unit='kpc')
>>> vec = cx.CylindricalVector(rho=Quantity(1, unit="kpc"),
... phi=Quantity(2, unit="deg"),
... z=Quantity(3, unit="pc"))
... phi=Quantity(2, unit="deg"),
... z=Quantity(3, unit="pc"))
>>> convert(vec, Quantity)
Quantity['length'](Array([0.99939084, 0.0348995 , 0.003 ], dtype=float32),
unit='kpc')
Expand Down Expand Up @@ -472,8 +472,8 @@ def apysph_to_sph(obj: apyc.PhysicsSphericalRepresentation, /) -> SphericalVecto
>>> convert(sph, cx.SphericalVector)
SphericalVector(
r=Distance(value=f32[], unit=Unit("kpc")),
phi=Quantity[...](value=f32[], unit=Unit("deg")),
theta=Quantity[...](value=f32[], unit=Unit("deg"))
theta=Quantity[...](value=f32[], unit=Unit("deg")),
phi=Quantity[...](value=f32[], unit=Unit("deg"))
)
"""
Expand Down Expand Up @@ -534,9 +534,9 @@ def apysph_to_lonlatsph(obj: apyc.SphericalRepresentation, /) -> LonLatSpherical
... distance=1 * u.kpc)
>>> convert(sph, cx.LonLatSphericalVector)
LonLatSphericalVector(
distance=Distance(value=f32[], unit=Unit("kpc")),
lon=Quantity[...](value=f32[], unit=Unit("deg")),
lat=Quantity[...](value=f32[], unit=Unit("deg"))
lat=Quantity[...](value=f32[], unit=Unit("deg")),
distance=Distance(value=f32[], unit=Unit("kpc"))
)
"""
Expand Down Expand Up @@ -696,8 +696,8 @@ def diffsph_to_apysph(
>>> import coordinax as cx
>>> dif = cx.SphericalDifferential(d_r=Quantity(1, unit="km/s"),
... d_theta=Quantity(2, unit="mas/yr"),
... d_phi=Quantity(3, unit="mas/yr"))
... d_theta=Quantity(2, unit="mas/yr"),
... d_phi=Quantity(3, unit="mas/yr"))
>>> convert(dif, apyc.PhysicsSphericalDifferential)
<PhysicsSphericalDifferential (d_phi, d_theta, d_r) in (mas / yr, mas / yr, km / s)
(3., 2., 1.)>
Expand All @@ -709,8 +709,8 @@ def diffsph_to_apysph(
"""
return apyc.PhysicsSphericalDifferential(
d_r=convert(obj.d_r, apyu.Quantity),
d_phi=convert(obj.d_phi, apyu.Quantity),
d_theta=convert(obj.d_theta, apyu.Quantity),
d_phi=convert(obj.d_phi, apyu.Quantity),
)


Expand Down Expand Up @@ -740,8 +740,8 @@ def apysph_to_diffsph(
>>> convert(dif, cx.SphericalDifferential)
SphericalDifferential(
d_r=Quantity[...]( value=f32[], unit=Unit("km / s") ),
d_phi=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_theta=Quantity[...]( value=f32[], unit=Unit("mas / yr") )
d_theta=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_phi=Quantity[...]( value=f32[], unit=Unit("mas / yr") )
)
"""
Expand Down Expand Up @@ -812,9 +812,9 @@ def apysph_to_difflonlatsph(
... d_lon=3 * u.mas/u.yr)
>>> convert(dif, cx.LonLatSphericalDifferential)
LonLatSphericalDifferential(
d_distance=Quantity[...]( value=f32[], unit=Unit("km / s") ),
d_lon=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_lat=Quantity[...]( value=f32[], unit=Unit("mas / yr") )
d_lat=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_distance=Quantity[...]( value=f32[], unit=Unit("km / s") )
)
"""
Expand Down Expand Up @@ -888,9 +888,9 @@ def apysph_to_diffloncoslatsph(
... d_lon_coslat=3 * u.mas/u.yr)
>>> convert(dif, cx.LonCosLatSphericalDifferential)
LonCosLatSphericalDifferential(
d_distance=Quantity[...]( value=f32[], unit=Unit("km / s") ),
d_lon_coslat=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_lat=Quantity[...]( value=f32[], unit=Unit("mas / yr") )
d_lat=Quantity[...]( value=f32[], unit=Unit("mas / yr") ),
d_distance=Quantity[...]( value=f32[], unit=Unit("km / s") )
)
"""
Expand Down
Loading

0 comments on commit 0305d56

Please sign in to comment.