diff --git a/src/coordinax/_interop/coordinax_interop_astropy/constructors.py b/src/coordinax/_interop/coordinax_interop_astropy/constructors.py index 2df7a7dd..9eab6a24 100644 --- a/src/coordinax/_interop/coordinax_interop_astropy/constructors.py +++ b/src/coordinax/_interop/coordinax_interop_astropy/constructors.py @@ -11,11 +11,12 @@ import coordinax as cx +# ============================================================================ +# From an Astropy object -@dispatch(precedence=-1) -def vector( - cls: type[cx.vecs.AbstractPos3D], obj: apyc.CartesianRepresentation, / -) -> cx.CartesianPos3D: + +@dispatch +def vector(obj: apyc.CartesianRepresentation, /) -> cx.CartesianPos3D: """Construct from a :class:`astropy.coordinates.CartesianRepresentation`. This re-dispatches to :meth:`coordinax.vecs.CartesianPos3D.from_`. @@ -26,18 +27,16 @@ def vector( >>> from astropy.coordinates import CartesianRepresentation >>> cart = CartesianRepresentation(1, 2, 3, unit="m") - >>> vec = cx.vecs.AbstractPos3D.from_(cart) + >>> vec = cx.vector(cart) >>> vec.x Quantity['length'](Array(1., dtype=float32), unit='m') """ - return cx.CartesianPos3D.from_(obj) + return vector(cx.vecs.CartesianPos3D, obj) -@dispatch(precedence=-1) -def vector( - cls: type[cx.vecs.AbstractPos3D], obj: apyc.CylindricalRepresentation, / -) -> cx.vecs.CylindricalPos: +@dispatch +def vector(obj: apyc.CylindricalRepresentation, /) -> cx.vecs.CylindricalPos: """Construct from a :class:`astropy.coordinates.CylindricalRepresentation`. This re-dispatches to :meth:`coordinax.vecs.CylindricalPos.from_`. @@ -50,91 +49,19 @@ def vector( >>> cyl = CylindricalRepresentation(rho=1 * u.km, phi=2 * u.deg, ... z=30 * u.m) - >>> vec = cx.vecs.AbstractPos3D.from_(cyl) + >>> vec = cx.vector(cyl) >>> vec.rho Quantity['length'](Array(1., dtype=float32), unit='km') """ - return cx.vecs.CylindricalPos.from_(obj) - - -@dispatch(precedence=-1) -def vector( - cls: type[cx.vecs.AbstractPos3D], obj: apyc.PhysicsSphericalRepresentation, / -) -> cx.SphericalPos: - """Construct from a :class:`astropy.coordinates.PhysicsSphericalRepresentation`. - - This re-dispatches to :meth:`coordinax.vecs.SphericalPos.from_`. - - Examples - -------- - >>> import astropy.units as u - >>> import coordinax as cx - >>> from astropy.coordinates import PhysicsSphericalRepresentation - - >>> sph = PhysicsSphericalRepresentation(r=1 * u.km, theta=2 * u.deg, - ... phi=3 * u.deg) - >>> vec = cx.vecs.AbstractPos3D.from_(sph) - >>> vec.r - Distance(Array(1., dtype=float32), unit='km') - - """ - return cx.SphericalPos.from_(obj) - - -@dispatch(precedence=-1) -def vector( - cls: type[cx.vecs.AbstractPos3D], obj: apyc.SphericalRepresentation, / -) -> cx.vecs.LonLatSphericalPos: - """Construct from a :class:`astropy.coordinates.SphericalRepresentation`. - - This re-dispatches to :meth:`coordinax.vecs.LonLatSphericalPos.from_`. - - Examples - -------- - >>> import astropy.units as u - >>> import coordinax as cx - >>> from astropy.coordinates import SphericalRepresentation - - >>> sph = SphericalRepresentation(lon=3 * u.deg, lat=2 * u.deg, - ... distance=1 * u.km) - >>> vec = cx.vecs.AbstractPos3D.from_(sph) - >>> vec.distance - Distance(Array(1., dtype=float32), unit='km') - - """ - return cx.vecs.LonLatSphericalPos.from_(obj) - - -# ------------------------------------------------------------------- + return vector(cx.vecs.CylindricalPos, obj) @dispatch -def vector( - cls: type[cx.CartesianPos3D], obj: apyc.BaseRepresentation, / -) -> cx.CartesianPos3D: - """Construct from a :class:`astropy.coordinates.BaseRepresentation`. - - Examples - -------- - >>> import coordinax as cx - >>> from astropy.coordinates import CartesianRepresentation - - >>> cart = CartesianRepresentation(1, 2, 3, unit="km") - >>> vec = cx.CartesianPos3D.from_(cart) - >>> vec.x - Quantity['length'](Array(1., dtype=float32), unit='km') - - """ - obj = obj.represent_as(apyc.CartesianRepresentation) - return cls(x=obj.x, y=obj.y, z=obj.z) - +def vector(obj: apyc.CylindricalRepresentation, /) -> cx.vecs.CylindricalPos: + """Construct from a :class:`astropy.coordinates.CylindricalRepresentation`. -@dispatch -def vector( - cls: type[cx.vecs.CylindricalPos], obj: apyc.BaseRepresentation, / -) -> cx.vecs.CylindricalPos: - """Construct from a :class:`astropy.coordinates.BaseRepresentation`. + This re-dispatches to :meth:`coordinax.vecs.CylindricalPos.from_`. Examples -------- @@ -144,20 +71,19 @@ def vector( >>> cyl = CylindricalRepresentation(rho=1 * u.km, phi=2 * u.deg, ... z=30 * u.m) - >>> vec = cx.vecs.CylindricalPos.from_(cyl) + >>> vec = cx.vector(cyl) >>> vec.rho Quantity['length'](Array(1., dtype=float32), unit='km') """ - obj = obj.represent_as(apyc.CylindricalRepresentation) - return cls(rho=obj.rho, phi=obj.phi, z=obj.z) + return vector(cx.vecs.CylindricalPos, obj) @dispatch -def vector( - cls: type[cx.SphericalPos], obj: apyc.BaseRepresentation, / -) -> cx.SphericalPos: - """Construct from a :class:`astropy.coordinates.BaseRepresentation`. +def vector(obj: apyc.PhysicsSphericalRepresentation, /) -> cx.SphericalPos: + """Construct from a :class:`astropy.coordinates.PhysicsSphericalRepresentation`. + + This re-dispatches to :meth:`coordinax.vecs.SphericalPos.from_`. Examples -------- @@ -167,20 +93,19 @@ def vector( >>> sph = PhysicsSphericalRepresentation(r=1 * u.km, theta=2 * u.deg, ... phi=3 * u.deg) - >>> vec = cx.SphericalPos.from_(sph) + >>> vec = cx.vector(sph) >>> vec.r Distance(Array(1., dtype=float32), unit='km') """ - obj = obj.represent_as(apyc.PhysicsSphericalRepresentation) - return cls(r=obj.r, theta=obj.theta, phi=obj.phi) + return vector(cx.SphericalPos, obj) @dispatch -def vector( - cls: type[cx.vecs.LonLatSphericalPos], obj: apyc.BaseRepresentation, / -) -> cx.vecs.LonLatSphericalPos: - """Construct from a :class:`astropy.coordinates.BaseRepresentation`. +def vector(obj: apyc.SphericalRepresentation, /) -> cx.vecs.LonLatSphericalPos: + """Construct from a :class:`astropy.coordinates.SphericalRepresentation`. + + This re-dispatches to :meth:`coordinax.vecs.LonLatSphericalPos.from_`. Examples -------- @@ -190,22 +115,37 @@ def vector( >>> sph = SphericalRepresentation(lon=3 * u.deg, lat=2 * u.deg, ... distance=1 * u.km) - >>> vec = cx.vecs.LonLatSphericalPos.from_(sph) + >>> vec = cx.vector(sph) >>> vec.distance Distance(Array(1., dtype=float32), unit='km') """ - obj = obj.represent_as(apyc.SphericalRepresentation) - return cls(distance=obj.distance, lon=obj.lon, lat=obj.lat) + return vector(cx.vecs.LonLatSphericalPos, obj) -##################################################################### +@dispatch +def vector(obj: apyc.UnitSphericalRepresentation) -> cx.vecs.TwoSpherePos: + """Construct from a :class:`astropy.coordinates.UnitSphericalRepresentation`. + + This re-dispatches to :meth:`coordinax.vecs.TwoSpherePos.from_`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import UnitSphericalRepresentation + + >>> sph = UnitSphericalRepresentation(lon=3 * u.deg, lat=2 * u.deg) + >>> vec = cx.vector(sph) + >>> vec.theta + Angle(Array(2., dtype=float32), unit='deg') + + """ + return vector(cx.vecs.TwoSpherePos, obj) @dispatch -def vector( - cls: type[cx.vecs.AbstractVel3D], obj: apyc.CartesianDifferential, / -) -> cx.CartesianVel3D: +def vector(obj: apyc.CartesianDifferential, /) -> cx.CartesianVel3D: """Construct from a :class:`astropy.coordinates.CartesianDifferential`. This re-dispatches to :meth:`coordinax.vecs.CartesianVel3D.from_`. @@ -217,18 +157,16 @@ def vector( >>> from astropy.coordinates import CartesianDifferential >>> dcart = CartesianDifferential(1, 2, 3, unit="km/s") - >>> dif = cx.vecs.AbstractVel3D.from_(dcart) + >>> dif = cx.vector(dcart) >>> dif.d_x Quantity['speed'](Array(1., dtype=float32), unit='km / s') """ - return cx.CartesianVel3D.from_(obj) + return vector(cx.CartesianVel3D, obj) @dispatch -def vector( - cls: type[cx.vecs.AbstractVel3D], obj: apyc.CylindricalDifferential, / -) -> cx.vecs.CylindricalVel: +def vector(obj: apyc.CylindricalDifferential, /) -> cx.vecs.CylindricalVel: """Construct from a :class:`astropy.coordinates.CylindricalDifferential`. This re-dispatches to :meth:`coordinax.vecs.CylindricalVel.from_`. @@ -241,18 +179,16 @@ def vector( >>> dcyl = apyc.CylindricalDifferential(d_rho=1 * u.km / u.s, d_phi=2 * u.mas/u.yr, ... d_z=2 * u.km / u.s) - >>> dif = cx.vecs.AbstractVel3D.from_(dcyl) + >>> dif = cx.vector(dcyl) >>> dif.d_rho Quantity['speed'](Array(1., dtype=float32), unit='km / s') """ - return cx.vecs.CylindricalVel.from_(obj) + return vector(cx.vecs.CylindricalVel, obj) @dispatch -def vector( - cls: type[cx.vecs.AbstractVel3D], obj: apyc.PhysicsSphericalDifferential, / -) -> cx.SphericalVel: +def vector(obj: apyc.PhysicsSphericalDifferential, /) -> cx.SphericalVel: """Construct from a :class:`astropy.coordinates.PhysicsSphericalDifferential`. This re-dispatches to :meth:`coordinax.vecs.SphericalVel.from_`. @@ -265,18 +201,16 @@ def vector( >>> dsph = PhysicsSphericalDifferential(d_r=1 * u.km / u.s, d_theta=2 * u.mas/u.yr, ... d_phi=3 * u.mas/u.yr) - >>> dif = cx.vecs.AbstractVel3D.from_(dsph) + >>> dif = cx.vector(dsph) >>> dif.d_r Quantity['speed'](Array(1., dtype=float32), unit='km / s') """ - return cx.SphericalVel.from_(obj) + return vector(cx.SphericalVel, obj) @dispatch -def vector( - cls: type[cx.vecs.AbstractVel3D], obj: apyc.SphericalDifferential, / -) -> cx.vecs.LonLatSphericalVel: +def vector(obj: apyc.SphericalDifferential, /) -> cx.vecs.LonLatSphericalVel: """Construct from a :class:`astropy.coordinates.SphericalDifferential`. This re-dispatches to :meth:`coordinax.vecs.LonLatSphericalVel.from_`. @@ -290,18 +224,16 @@ def vector( >>> dsph = SphericalDifferential(d_distance=1 * u.km / u.s, ... d_lon=2 * u.mas/u.yr, ... d_lat=3 * u.mas/u.yr) - >>> dif = cx.vecs.AbstractVel3D.from_(dsph) + >>> dif = cx.vector(dsph) >>> dif.d_distance Quantity['speed'](Array(1., dtype=float32), unit='km / s') """ - return cx.vecs.LonLatSphericalVel.from_(obj) + return vector(cx.vecs.LonLatSphericalVel, obj) @dispatch -def vector( - cls: type[cx.vecs.AbstractVel3D], obj: apyc.SphericalCosLatDifferential, / -) -> cx.vecs.LonCosLatSphericalVel: +def vector(obj: apyc.SphericalCosLatDifferential, /) -> cx.vecs.LonCosLatSphericalVel: """Construct from a :class:`astropy.coordinates.SphericalCosLatDifferential`. This re-dispatches to :meth:`coordinax.vecs.LonCosLatSphericalVel.from_`. @@ -315,7 +247,7 @@ def vector( >>> dsph = SphericalCosLatDifferential(d_distance=1 * u.km / u.s, ... d_lon_coslat=2 * u.mas/u.yr, ... d_lat=3 * u.mas/u.yr) - >>> dif = cx.vecs.AbstractVel3D.from_(dsph) + >>> dif = cx.vector(dsph) >>> dif LonCosLatSphericalVel( d_lon_coslat=Quantity[...]( value=f32[], unit=Unit("mas / yr") ), @@ -326,10 +258,144 @@ def vector( Quantity['speed'](Array(1., dtype=float32), unit='km / s') """ - return cx.vecs.LonCosLatSphericalVel.from_(obj) + return vector(cx.vecs.LonCosLatSphericalVel, obj) + + +@dispatch +def vector(obj: apyc.UnitSphericalDifferential) -> cx.vecs.TwoSphereVel: + """Construct from a :class:`astropy.coordinates.UnitSphericalDifferential`. + + This re-dispatches to :meth:`coordinax.vecs.TwoSphereVel.from_`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import UnitSphericalDifferential + + >>> dsph = UnitSphericalDifferential(d_lon=3 * u.deg/u.s, d_lat=2 * u.deg/u.s) + >>> vel = cx.vector(dsph) + >>> vel.d_phi + Quantity[...](Array(3., dtype=float32), unit='deg / s') + + """ + return vector(cx.vecs.TwoSphereVel, obj) + + +# ============================================================================ +# From an Astropy coordinate, to a specific vector type + + +@dispatch +def vector( + cls: type[cx.CartesianPos3D], obj: apyc.BaseRepresentation, / +) -> cx.CartesianPos3D: + """Construct from a :class:`astropy.coordinates.BaseRepresentation`. + + Examples + -------- + >>> import coordinax as cx + >>> from astropy.coordinates import CartesianRepresentation + + >>> cart = CartesianRepresentation(1, 2, 3, unit="km") + >>> vec = cx.CartesianPos3D.from_(cart) + >>> vec.x + Quantity['length'](Array(1., dtype=float32), unit='km') + + """ + obj = obj.represent_as(apyc.CartesianRepresentation) + return cls(x=obj.x, y=obj.y, z=obj.z) -# ------------------------------------------------------------------- +@dispatch +def vector( + cls: type[cx.vecs.CylindricalPos], obj: apyc.BaseRepresentation, / +) -> cx.vecs.CylindricalPos: + """Construct from a :class:`astropy.coordinates.BaseRepresentation`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import CylindricalRepresentation + + >>> cyl = CylindricalRepresentation(rho=1 * u.km, phi=2 * u.deg, + ... z=30 * u.m) + >>> vec = cx.vecs.CylindricalPos.from_(cyl) + >>> vec.rho + Quantity['length'](Array(1., dtype=float32), unit='km') + + """ + obj = obj.represent_as(apyc.CylindricalRepresentation) + return cls(rho=obj.rho, phi=obj.phi, z=obj.z) + + +@dispatch +def vector( + cls: type[cx.SphericalPos], obj: apyc.BaseRepresentation, / +) -> cx.SphericalPos: + """Construct from a :class:`astropy.coordinates.BaseRepresentation`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import PhysicsSphericalRepresentation + + >>> sph = PhysicsSphericalRepresentation(r=1 * u.km, theta=2 * u.deg, + ... phi=3 * u.deg) + >>> vec = cx.SphericalPos.from_(sph) + >>> vec.r + Distance(Array(1., dtype=float32), unit='km') + + """ + obj = obj.represent_as(apyc.PhysicsSphericalRepresentation) + return cls(r=obj.r, theta=obj.theta, phi=obj.phi) + + +@dispatch +def vector( + cls: type[cx.vecs.LonLatSphericalPos], obj: apyc.BaseRepresentation, / +) -> cx.vecs.LonLatSphericalPos: + """Construct from a :class:`astropy.coordinates.BaseRepresentation`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import SphericalRepresentation + + >>> sph = SphericalRepresentation(lon=3 * u.deg, lat=2 * u.deg, + ... distance=1 * u.km) + >>> vec = cx.vecs.LonLatSphericalPos.from_(sph) + >>> vec.distance + Distance(Array(1., dtype=float32), unit='km') + + """ + obj = obj.represent_as(apyc.SphericalRepresentation) + return cls(distance=obj.distance, lon=obj.lon, lat=obj.lat) + + +@dispatch +def vector( + cls: type[cx.vecs.TwoSpherePos], obj: apyc.BaseRepresentation, / +) -> cx.vecs.TwoSpherePos: + """Construct from a :class:`astropy.coordinates.BaseRepresentation`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import UnitSphericalRepresentation + + >>> sph = UnitSphericalRepresentation(lon=3 * u.deg, lat=2 * u.deg) + >>> vec = cx.vecs.TwoSpherePos.from_(sph) + >>> vec.theta + Angle(Array(2., dtype=float32), unit='deg') + + """ + obj = obj.represent_as(apyc.UnitSphericalRepresentation) + return cls(phi=obj.lon, theta=obj.lat) @dispatch @@ -451,6 +517,27 @@ def vector( ) +@dispatch +def vector( + cls: type[cx.vecs.TwoSphereVel], obj: apyc.UnitSphericalDifferential, / +) -> cx.vecs.TwoSphereVel: + """Construct from a :class:`astropy.coordinates.BaseDifferential`. + + Examples + -------- + >>> import astropy.units as u + >>> import coordinax as cx + >>> from astropy.coordinates import UnitSphericalDifferential + + >>> sph = UnitSphericalDifferential(d_lon=3 * u.deg/u.s, d_lat=2 * u.deg/u.s) + >>> vel = cx.vecs.TwoSphereVel.from_(sph) + >>> vel.d_phi + Quantity[...](Array(3., dtype=float32), unit='deg / s') + + """ + return cls(d_phi=obj.d_lon, d_theta=obj.d_lat) + + #####################################################################