coordinax.charts

Contents

coordinax.charts#

The coordinax.charts module provides chart objects and chart-level coordinate maps for representing points on manifolds.

Overview#

A chart defines how point coordinates are represented:

  • Component names (for example x, y, z or r, theta, phi)

  • Coordinate dimensions (for example length, angle)

  • Transition and realization behavior through the functional API

Use chart instances (for example cart3d, sph3d) when transforming concrete coordinate data.

For a step-by-step walkthrough, see Working With Charts.

Quick Start#

import coordinax.charts as cxc
import unxt as u

# Use predefined chart instances.
cart = cxc.cart3d
sph = cxc.sph3d

# Same-manifold chart transition.
p = {"x": u.Q(1, "km"), "y": u.Q(2, "km"), "z": u.Q(3, "km")}
p_sph = cxc.pt_map(p, cart, sph)

# General realization map (defaults to transition map for same manifold charts).
p_sph2 = cxc.pt_map(p, cart, sph)

# Pick canonical Cartesian chart without transforming coordinates.
cart_of_sph = cxc.cartesian_chart(sph)

Functional API#

  • cartesian_chart: return a chart’s canonical Cartesian chart

  • guess_chart: infer a chart from keys or array/quantity trailing shape

  • cdict: normalize inputs to component dictionaries

  • pt_map: transform points between charts on the same or different manifolds

  • jac_pt_map: compute the Jacobian of a point map between charts on the same or different manifolds

Available Objects#

Chart Families#

The module exports both concrete chart classes and predefined instances.

0D Charts#

  • Cart0D / cart0d: Zero-dimensional Cartesian (scalar)

1D Charts#

  • Cart1D / cart1d: 1D Cartesian

  • Radial1D / radial1d: Radial distance

  • Time1D / time1d: 1D time chart

2D Charts#

  • Cart2D / cart2d: 2D Cartesian

  • Polar2D / polar2d: Polar coordinates

  • SphericalTwoSphere / sph2: 2-sphere (theta, phi)

  • LonLatSphericalTwoSphere / lonlat_sph2: 2-sphere (lon, lat)

  • LonCosLatSphericalTwoSphere / loncoslat_sph2: 2-sphere (lon_coslat, lat)

  • MathSphericalTwoSphere / math_sph2: mathematical 2-sphere convention

Intrinsic two-sphere charts do not have a global Cartesian 2D chart; requesting cartesian_chart(...) on this family raises NoGlobalCartesianChartError.

3D Charts#

  • Cart3D / cart3d: 3D Cartesian

  • Cylindrical3D / cyl3d: Cylindrical coordinates

  • Spherical3D / sph3d: Spherical coordinates (physics convention)

  • LonLatSpherical3D / lonlat_sph3d: Longitude/latitude spherical

  • LonCosLatSpherical3D / loncoslat_sph3d: Lon/cos(lat) spherical

  • MathSpherical3D / math_sph3d: Mathematical spherical convention

  • ProlateSpheroidal3D: Prolate spheroidal chart with required Delta parameter

ProlateSpheroidal3D does not export a predefined instance because chart instances depend on the focal parameter Delta.

4D Charts#

  • MinkowskiCT / minkowskict: 4D Minkowski spacetime chart with the conventional 3+1 split. Components are (ct, x, y, z), all with dimension "length". This is a single (non-product) flat chart whose metric is \(\eta = \operatorname{diag}(-1, 1, 1, 1)\). The chart is self-Cartesian: cartesian_chart(minkowskict) is minkowskict.

6D Charts#

  • PoincarePolar6D / poincarepolar6d: 6D Poincare polar chart family

N-D Charts#

  • CartND / cartnd: N-dimensional Cartesian

Product Charts#

  • CartesianProductChart: namespace-prefixed product chart with dot-delimited component keys (for example q.x, q.y, p.x, …)

Product-chart transitions are factorwise: each factor chart transforms independently and then components are merged.

Notes#

  • Use chart instances (for example cart3d, sph3d) as conversion arguments.

  • Intrinsic two-sphere charts do not define a global Cartesian 2D chart.

coordinax.charts Module.

Let’s start by constructing some charts and see how they work.

>>> import coordinax.charts as cxc

We can create a 3D Cartesian chart like this:

>>> cart_chart = cxc.Cart3D()
>>> cart_chart == cxc.cart3d  # predefined instance
True

Charts have components and coordinate dimensions:

>>> cart_chart.components
('x', 'y', 'z')
>>> cart_chart.coord_dimensions
('length', 'length', 'length')

There are many different charts available, such as spherical coordinates:

>>> sph_chart = cxc.Spherical3D()
>>> sph_chart == cxc.sph3d  # predefined instance
True
>>> sph_chart.components
('r', 'theta', 'phi')
>>> sph_chart.coord_dimensions
('length', 'angle', 'angle')

Another example is a 4D Minkowski spacetime chart:

>>> st_chart = cxc.MinkowskiCT()
>>> st_chart.components
('ct', 'x', 'y', 'z')
>>> st_chart.coord_dimensions
('length', 'length', 'length', 'length')
>>> st_chart.cartesian is st_chart
True

We can also build arbitrary Cartesian products of charts (without flattening) using CartesianProductChart:

>>> prod_chart = cxc.CartesianProductChart((cxc.time1d, cxc.sph3d), ("t", "q"))
>>> prod_chart
CartesianProductChart(
    factors=(Time1D(M=Rn(1)), Spherical3D(M=Rn(3))),
    factor_names=('t', 'q')
)
>>> prod_chart.components
('t.t', 'q.r', 'q.theta', 'q.phi')

With charts we can transform point coordinates between different coordinate systems.

>>> import unxt as u
>>> q = {"x": u.Q(1, "km"), "y": u.Q(2, "km"), "z": u.Q(3, "km")}
>>> q_sph = cxc.pt_map(q, cxc.cart3d, cxc.sph3d)
>>> q_sph
{'r': Q(3.74165739, 'km'), 'theta': Q(0.64052231, 'rad'),
 'phi': Q(1.10714872, 'rad')}

We can also compute the Jacobian of the point map:

>>> jac = cxc.jac_pt_map(q, cxc.cart3d, cxc.sph3d)
class coordinax.charts.AbstractChart#

Bases: Generic[MT, Ks, Ds]

Abstract base class for charts (coordinate representations).

M: MT#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

abstract property components: Ks#

The names of the components.

abstract property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

abstract property cartesian: AbstractChart[MT, Ks, Ds]#

Return the corresponding Cartesian chart.

check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

class coordinax.charts.AbstractFixedComponentsChart#

Bases: AbstractChart[MT, Ks, Ds]

Abstract base class for charts with fixed components and dimensions.

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

abstract property cartesian: AbstractChart[MT, Ks, Ds]#

Return the corresponding Cartesian chart.

check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property ndim: int#

Number of coordinate components (chart dimension).

M: MT#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

class coordinax.charts.AbstractDimensionalFlag#

Bases: object

Marker base class for dimension flags.

A dimension flag is a lightweight mixin used for typing and dispatch. Flags do not store data; instead, they classify a chart. These flags must be combined with concrete subclasses of {class}`AbstractChart`.

exception coordinax.charts.NoGlobalCartesianChartError#

Bases: Exception

Raised when a chart has no global Cartesian representation.

Some charts represent coordinates on curved manifolds (e.g., 2-sphere) that cannot be globally mapped to a flat Cartesian space without singularities or discontinuities.

Examples

2-sphere charts (intrinsic coordinates on a spherical surface) have no global Cartesian 2D representation. To work with these charts:

  • Use an EmbeddedChart to embed in 3D Euclidean space

  • Use local projections when available

  • Work directly in the intrinsic coordinates

add_note()#

Exception.add_note(note) – add a note to the exception

args#
with_traceback()#

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

coordinax.charts.cartesian_chart(chart: AbstractChart, /)#

Return the canonical Cartesian chart for a 0D chart.

>>> import coordinax.charts as cxc
>>> cxc.cartesian_chart(cxc.cart0d) is cxc.cart0d
True
Parameters:

chart (AbstractChart)

Return type:

AbstractChart

coordinax.charts.guess_chart(*_: Any)#

Infer a chart from keys or from array/quantity trailing shape.

This is a lightweight heuristic API.

Examples

>>> import jax.numpy as jnp
>>> import unxt as u
>>> import coordinax.charts as cxc
>>> cxc.guess_chart(frozenset(("x", "y", "z")))
Cart3D(M=Rn(3))
>>> cxc.guess_chart({"x": 1.0, "y": 2.0, "z": 3.0})
Cart3D(M=Rn(3))
>>> q = u.Q([1.0, 2.0, 3.0], "m")
>>> cxc.guess_chart(q)
Cart3D(M=Rn(3))
>>> x = jnp.array([1.0, 2.0, 3.0])
>>> cxc.guess_chart(x)
Cart3D(M=Rn(3))
coordinax.charts.guess_chart(obj: frozenset[str], /) AbstractChart
Parameters:

_ (Any)

Return type:

AbstractChart

Infer a chart from the keys of a component dictionary.

Note that many charts may share the same component names (e.g., Spherical3D and MathSpherical3D both use ‘r’, ‘theta’, ‘phi’). These are completely indistinguishable from component names alone, so this function will return the first matching chart it finds. Since the function is cached, the result will be consistent across calls.

>>> import coordinax.charts as cxc
>>> d = {"x": 1.0, "y": 2.0, "z": 3.0}
>>> chart = cxc.guess_chart(d)
>>> chart
Cart3D(M=Rn(3))
coordinax.charts.guess_chart(obj: dict[str, Any], /) AbstractChart
Parameters:

_ (Any)

Return type:

AbstractChart

Infer a chart from the keys of a component dictionary.

Note that many charts may share the same component names (e.g., Spherical3D and MathSpherical3D both use ‘r’, ‘theta’, ‘phi’). These are completely indistinguishable from component names alone, so this function will return the first matching chart it finds. Since the function is cached, the result will be consistent across calls.

>>> import coordinax.charts as cxc
>>> d = {"x": 1.0, "y": 2.0, "z": 3.0}
>>> chart = cxc.guess_chart(d)
>>> chart
Cart3D(M=Rn(3))
coordinax.charts.guess_chart(_: jaxtyping.Shaped[Array, '*batch 1'] | jaxtyping.Shaped[AbstractQuantity, '*batch 1'], /) AbstractChart
Parameters:

_ (Any)

Return type:

AbstractChart

Infer a 1D Cartesian chart from last dimension of a value / quantity.

>>> import unxt as u
>>> import coordinax.charts as cx
>>> q = u.Q([1.0], "m")
>>> cxc.guess_chart(q)
Cart1D(M=Rn(1))
coordinax.charts.guess_chart(_: jaxtyping.Shaped[Array, '*batch 2'] | jaxtyping.Shaped[AbstractQuantity, '*batch 2'], /) AbstractChart
Parameters:

_ (Any)

Return type:

AbstractChart

Infer a 2D Cartesian chart from last dimension of a value / quantity.

>>> import unxt as u
>>> import coordinax.charts as cx
>>> q = u.Q([1.0, 2.0], "m")
>>> cxc.guess_chart(q)
Cart2D(M=Rn(2))
coordinax.charts.guess_chart(_: jaxtyping.Shaped[Array, '*batch 3'] | jaxtyping.Shaped[AbstractQuantity, '*batch 3'], /) AbstractChart
Parameters:

_ (Any)

Return type:

AbstractChart

Infer a 3D Cartesian chart from last dimension of a value / quantity.

>>> import unxt as u
>>> import coordinax.charts as cx
>>> q = u.Q([1.0, 2.0, 3.0], "m")
>>> cxc.guess_chart(q)
Cart3D(M=Rn(3))
coordinax.charts.guess_chart(_: jaxtyping.Shaped[Array, '*batch N'] | jaxtyping.Shaped[AbstractQuantity, '*batch N'], /) AbstractChart
Parameters:

_ (Any)

Return type:

AbstractChart

Infer a N-dimensional Cartesian chart from last dimension of a value / quantity.

>>> import unxt as u
>>> import coordinax.charts as cx
>>> q = u.Q([1.0, 2.0, 3.0, 4.0], "m")
>>> cxc.guess_chart(q)
CartND(M=Rn(True))
coordinax.charts.guess_chart(obj: RadialRepresentation) Radial1D
Parameters:

_ (Any)

Return type:

AbstractChart

Guess astropy.coordinates.RadialRepresentation -> Radial1D.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.RadialRepresentation(distance=1 * apyu.kpc)
>>> cxc.guess_chart(vec)
Radial1D(M=Rn(1))
coordinax.charts.guess_chart(obj: UnitSphericalRepresentation) LonLatSphericalTwoSphere
Parameters:

_ (Any)

Return type:

AbstractChart

Guess astropy.UnitSphericalRepresentation -> LonLatSphericalTwoSphere.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.UnitSphericalRepresentation(lon=90 * apyu.deg, lat=45 * apyu.deg)
>>> cxc.guess_chart(vec)
LonLatSphericalTwoSphere(M=Sn(2))
coordinax.charts.guess_chart(obj: CartesianRepresentation) Cart3D
Parameters:

_ (Any)

Return type:

AbstractChart

Guess astropy.coordinates.CartesianRepresentation -> Cart3D.

>>> import astropy.coordinates as apyc
>>> import coordinax.charts as cxc
>>> cxc.guess_chart(apyc.CartesianRepresentation(1, 2, 3))
Cart3D(M=Rn(3))
coordinax.charts.guess_chart(obj: CylindricalRepresentation) Cylindrical3D
Parameters:

_ (Any)

Return type:

AbstractChart

Guess astropy.coordinates.CylindricalRepresentation -> Cylindrical3D.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.CylindricalRepresentation(1 * apyu.km, 2 * apyu.deg, 3 * apyu.km)
>>> cxc.guess_chart(vec)
Cylindrical3D(M=Rn(3))
coordinax.charts.guess_chart(obj: PhysicsSphericalRepresentation) Spherical3D
Parameters:

_ (Any)

Return type:

AbstractChart

Guess astropy.coordinates.PhysicsSphericalRepresentation -> Spherical3D.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.PhysicsSphericalRepresentation(
...     r=1 * apyu.kpc, theta=45 * apyu.deg, phi=90 * apyu.deg)
>>> cxc.guess_chart(vec)
Spherical3D(M=Rn(3))
coordinax.charts.guess_chart(obj: SphericalRepresentation) LonLatSpherical3D
Parameters:

_ (Any)

Return type:

AbstractChart

Guess astropy.coordinates.SphericalRepresentation -> LonLatSpherical3D.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.SphericalRepresentation(
...     lon=90 * apyu.deg, lat=45 * apyu.deg, distance=1 * apyu.kpc)
>>> cxc.guess_chart(vec)
LonLatSpherical3D(M=Rn(3))
Parameters:

_ (Any)

Return type:

AbstractChart

coordinax.charts.cdict(_: Any, /)#

Normalize an input object into a component dictionary.

Keys are component names and values are corresponding scalars/arrays or quantities.

Parameters:
  • obj

    An object to extract a component dictionary from. Dispatch rules include:

    • collections.abc.Mapping: returned as-is

    • unxt.Quantity: treated as Cartesian coordinates with components in the last dimension, matched to the appropriate Cartesian chart

    • Point: extracted from obj.data

  • _ (Any)

Returns:

A mapping from component names to values.

Return type:

dict[str, Any]

Examples

>>> import jax.numpy as jnp
>>> import coordinax.main as cx
>>> import unxt as u

Extract from a Mapping:

>>> d = {"x": u.Q(1.0, "m"), "y": u.Q(2.0, "m"), "z": u.Q(3.0, "m")}
>>> cx.cdict(d)
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
>>> d = {"x": 1.0, "y": 2.0, "z": 3.0}
>>> cx.cdict(d)
{'x': 1.0, 'y': 2.0, 'z': 3.0}

Extract from a unxt.Quantity treated as Cartesian:

>>> q = u.Q([1, 2, 3], "m")
>>> cx.cdict(q)
{'x': Q(1, 'm'), 'y': Q(2, 'm'), 'z': Q(3, 'm')}

Specify the chart for a unxt.Quantity. For homogeneous unit Quantities, this must be Cartesian:

>>> cx.cdict(q, cx.cart3d)
{'x': Q(1, 'm'), 'y': Q(2, 'm'), 'z': Q(3, 'm')}

Extract from an Array-like object with a registered chart:

>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cx.cdict(arr, cx.cart3d)
{'x': Array(1., dtype=float64), 'y': Array(2., dtype=float64),
 'z': Array(3., dtype=float64)}
coordinax.charts.cdict(obj: dict[str, Any], /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Return a dictionary as-is.

>>> import coordinax.main as cx
>>> d = {"x": 1.0, "y": 2.0}
>>> cx.cdict(d)
{'x': 1.0, 'y': 2.0}
coordinax.charts.cdict(obj: dict[str, Any], chart: AbstractChart, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Return a dictionary as-is.

>>> import coordinax.charts as cxc
>>> d = {"x": 1.0, "y": 2.0}
>>> cxc.cdict(d, cxc.cart2d)
{'x': 1.0, 'y': 2.0}
coordinax.charts.cdict(obj: AbstractQuantity, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a Quantity.

Treats the Quantity as a Cartesian vector with components in the last dimension. The appropriate Cartesian chart is determined from the last dimension of the quantity.

>>> import coordinax.main as cx
>>> import unxt as u
>>> q = u.Q([1.0, 2.0, 3.0], "m")
>>> cx.cdict(q)
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: AbstractQuantity, keys: tuple[str, ...], /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a Quantity using specified keys.

Treats the Quantity as a vector with components in the last dimension, splitting along that axis according to the provided keys.

This function requires that: 1. The last dimension of the quantity matches the number of chart components 2. The chart has homogeneous coordinate dimensions (all components have the

same physical dimension, like Cartesian charts)

Raises:

ValueError – If the last dimension of the quantity doesn’t match the chart’s component count, or if dimensions don’t match.

Parameters:

_ (Any)

Return type:

dict[str, Any]

Examples

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> q = u.Q([1.0, 2.0, 3.0], "m")
>>> cxc.cdict(q, ('x', 'y', 'z'))
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: QMatrix, keys: tuple[str, ...], /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a 1D QMatrix.

This overload supports heterogeneous per-component units by constructing one quantity per chart component from the corresponding numeric slice and unit in the QMatrix.

Raises:

ValueError – If obj is not 1D, or if the last dimension does not match the number of provided keys.

Parameters:

_ (Any)

Return type:

dict[str, Any]

Examples

>>> import jax.numpy as jnp
>>> import unxt as u
>>> from coordinax.internal import QMatrix
>>> q = QMatrix(jnp.array([1.0, 2.0, 3.0]),
...                    unit=("m", "km/s", "rad"))
>>> cxc.cdict(q, ('x', 'y', 'z'))
{'x': Q(1., 'm'), 'y': Q(2., 'km / s'), 'z': Q(3., 'rad')}
coordinax.charts.cdict(obj: AbstractQuantity, chart: AbstractChart, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a Quantity.

Treats the Quantity as a vector with components in the last dimension, splitting along that axis according to the chart’s component names.

This function requires that: 1. The last dimension of the quantity matches the number of chart components 2. The chart has homogeneous coordinate dimensions (all components have the

same physical dimension, like Cartesian charts)

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> q = u.Q([1.0, 2.0, 3.0], "m")
>>> cxc.cdict(q, cxc.cart3d)
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: QMatrix, chart: AbstractChart, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a 1D QMatrix.

This overload supports heterogeneous per-component units by constructing one quantity per chart component from the corresponding numeric slice and unit in the QMatrix.

>>> import jax.numpy as jnp
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> from coordinax.internal import QMatrix
>>> q = QMatrix(
...     jnp.array([1.0, 2.0, 3.0]),
...     unit=(u.unit("m"), u.unit("km/s"), u.unit("rad")),
... )
>>> cxc.cdict(q, cxc.cart3d)
{'x': Q(1., 'm'), 'y': Q(2., 'km / s'), 'z': Q(3., 'rad')}
coordinax.charts.cdict(obj: ArrayLike, keys: tuple[str, ...], /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from an array.

Raises:

ValueError – If the last dimension of the quantity doesn’t match a known Cartesian chart (0D, 1D, 2D, or 3D).

Parameters:

_ (Any)

Return type:

dict[str, Any]

Examples

>>> import coordinax.main as cx
>>> import jax.numpy as jnp
>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cx.cdict(arr, ('x', 'y', 'z'))
{'x': Array(1., dtype=float64), 'y': Array(2., dtype=float64),
 'z': Array(3., dtype=float64)}
coordinax.charts.cdict(obj: ArrayLike, chart: AbstractChart, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from an array.

>>> import coordinax.main as cx
>>> import jax.numpy as jnp
>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cx.cdict(arr, cx.cart3d)
{'x': Array(1., dtype=float64), 'y': Array(2., dtype=float64),
 'z': Array(3., dtype=float64)}
coordinax.charts.cdict(obj: ArrayLike, unit: Unit | UnitBase | CompositeUnit | str | UnitsMatrix | None, keys: tuple[str, ...], /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from an array.

>>> import coordinax.main as cx
>>> import jax.numpy as jnp
>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cx.cdict(arr, "m", ('x', 'y', 'z'))
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: ArrayLike, unit: Unit | UnitBase | CompositeUnit | str | UnitsMatrix | None, chart: AbstractChart, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from an array.

>>> import coordinax.main as cx
>>> import jax.numpy as jnp
>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cx.cdict(arr, "m", cx.cart3d)
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: ArrayLike, unit: Unit | UnitBase | CompositeUnit | str | UnitsMatrix, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from an array.

Treats the array as a Cartesian vector with components in the last dimension. The appropriate Cartesian chart is determined from the last dimension of the quantity.

>>> import coordinax.charts as cxc
>>> import jax.numpy as jnp
>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cxc.cdict(arr, "m")
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: ArrayLike, usys: AbstractUnitSystem, chart: AbstractChart, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from an array.

Raises:

ValueError – If the last dimension of the quantity doesn’t match a known Cartesian chart (0D, 1D, 2D, or 3D).

Parameters:

_ (Any)

Return type:

dict[str, Any]

Examples

>>> import coordinax.main as cx
>>> import unxt as u
>>> import jax.numpy as jnp
>>> arr = jnp.array([1.0, 2.0, 3.0])
>>> cx.cdict(arr, u.unitsystems.si, cx.cart3d)
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.cdict(obj: coordinax.vectors._src.point.Point, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a Point.

>>> import coordinax.main as cx
>>> import unxt as u
>>> vec = cx.Point.from_(u.Q([1, 2, 3], "m"))
>>> d = cx.cdict(vec)
>>> list(d.keys())
['x', 'y', 'z']
coordinax.charts.cdict(obj: coordinax.vectors._src.tangent.Tangent, /) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Extract component dictionary from a Tangent.

>>> import coordinax.main as cx
>>> import coordinax.representations as cxr
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> d = {"x": u.Q(1.0, "m/s"), "y": u.Q(2.0, "m/s"), "z": u.Q(3.0, "m/s")}
>>> vec = cx.Tangent.from_(d, cxc.cart3d, cxr.coord_vel)
>>> d = cx.cdict(vec)
>>> list(d.keys())
['x', 'y', 'z']
coordinax.charts.cdict(r: CartesianRepresentation) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Convert an astropy CartesianRepresentation to a CDict.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.CartesianRepresentation(1 * apyu.km, 2 * apyu.km, 3 * apyu.km)
>>> cxc.cdict(vec)
{'x': Q(1., 'km'), 'y': Q(2., 'km'), 'z': Q(3., 'km')}
coordinax.charts.cdict(r: CylindricalRepresentation) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Convert an astropy CylindricalRepresentation to a CDict.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.CylindricalRepresentation(1 * apyu.m, 45 * apyu.deg, 3 * apyu.m)
>>> cxc.cdict(vec)
{'rho': Q(1., 'm'), 'phi': Q(45., 'deg'), 'z': Q(3., 'm')}
coordinax.charts.cdict(r: PhysicsSphericalRepresentation) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Convert an astropy PhysicsSphericalRepresentation to a CDict.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.PhysicsSphericalRepresentation(
...     phi=45 * apyu.deg, theta=30 * apyu.deg, r=1 * apyu.m)
>>> cxc.cdict(vec)
{'r': Q(1., 'm'), 'theta': Q(30., 'deg'), 'phi': Q(45., 'deg')}
coordinax.charts.cdict(r: SphericalRepresentation) dict[str, Any]
Parameters:

_ (Any)

Return type:

dict[str, Any]

Convert an astropy SphericalRepresentation to a CDict.

>>> import astropy.coordinates as apyc
>>> import astropy.units as apyu
>>> import coordinax.charts as cxc
>>> vec = apyc.SphericalRepresentation(
...     lon=90 * apyu.deg, lat=45 * apyu.deg, distance=1 * apyu.kpc)
>>> cxc.cdict(vec)
{'lon': Q(90., 'deg'), 'lat': Q(45., 'deg'), 'distance': Q(1., 'kpc')}
Parameters:

_ (Any)

Return type:

dict[str, Any]

coordinax.charts.jac_pt_map(*args: Any, **kwargs: Any)#

Compute the Jacobian of the chart transition map at a base point.

Examples

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> J = cxc.jac_pt_map(
...     {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")},
...     cxc.cart3d, cxc.sph3d,
... )
>>> J.value.shape
(3, 3)
coordinax.charts.jac_pt_map(at: NoneType, /, *fixed_args: Any, **fixed_kw: Any) Any
Parameters:
Return type:

Any

Higher-order function for fixed-arg Jacobian point map.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> map = cxc.jac_pt_map(None, cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> at = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> map(at)
QMatrix(
    [[ 1.,  0.,  0.],
     [-0., -0., -1.],
     [ 0.,  1.,  0.]],
    '((, , ), (rad / m, rad / m, rad / m), (rad / m, rad / m, rad / m))'
)
>>> import jax
>>> J = jax.vmap(map)(jax.tree.map(lambda x: x[None], at))
>>> J.shape
(1, 3, 3)
coordinax.charts.jac_pt_map(from_chart: AbstractChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None) Callable[[object], Any]
Parameters:
Return type:

Any

Higher-order function for fixed-arg Jacobian point map.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> map = cxc.jac_pt_map(cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> at = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> map(at)
QMatrix(
    [[ 1.,  0.,  0.],
     [-0., -0., -1.],
     [ 0.,  1.,  0.]],
    '((, , ), (rad / m, rad / m, rad / m), (rad / m, rad / m, rad / m))'
)
>>> import jax
>>> J = jax.vmap(map)(jax.tree.map(lambda x: x[None], at))
>>> J.shape
(1, 3, 3)
coordinax.charts.jac_pt_map(at: Array, from_chart: AbstractChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem) Array
Parameters:
Return type:

Any

Compute the Jacobian at a plain-array base point.

Treats at as a flat numeric array whose elements are the from_chart coordinates expressed. Returns the JAX array Jacobian $J^j{}_i = partial tau^j / partial q^i$, without unit annotation.

>>> import jax.numpy as jnp
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> jac_fn = cxc.jac_pt_map(None, cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> at = jnp.array([1, 0, 0])
>>> jac_fn(at)
Array([[ 1.,  0.,  0.],
       [-0., -0., -1.],
       [ 0.,  1.,  0.]], dtype=float64)
>>> import jax
>>> J = jax.vmap(jac_fn)(at[None])
>>> J.shape
(1, 3, 3)
coordinax.charts.jac_pt_map(at: dict[str, Any], from_chart: AbstractChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) Array | QMatrix
Parameters:
Return type:

Any

Compute the Jacobian at a coordinate-dictionary base point.

The primary dict-input dispatch. Branches on whether the values of at carry physical units:

Array-valued branch (no units in any value)

Stacks the dict values into a plain array via jnp.stack, then forwards to jac_pt_map(at_arr, from_chart, to_chart, usys=usys) which requires usys. For chart pairs without an analytical Array dispatch this means usys must be provided.

Quantity-valued branch (at least one value carries a unit)

Packs at into a 1-D QMatrix via pack_to_qmatrix(at, keys=from_chart.components), promotes any integer or boolean leaves to the default floating-point dtype (other dtypes, including complex, are left unchanged and will raise a TypeError from jax.jacfwd if passed), then computes J_qq = jax.jacfwd(pt_map_fn)(at_in). Because jacfwd applied to a QMatrix-in / QMatrix-out function yields a nested QMatrix, _repack_q_from_jac is called to extract the correct 2-D unit structure.

Returns:

Plain array when at is array-valued; QMatrix of shape (n_out, n_in) with per-element units otherwise.

Return type:

Any

Raises:
  • ValueError – If at keys do not match from_chart.components (via check_data).

  • plum.NotFoundLookupError – If the array-valued branch cannot resolve a dispatch (e.g. generic chart pair with usys=None).

Parameters:

Examples

>>> import coordinax.charts as cxc
>>> import unxt as u

Quantity-valued dict (no usys needed):

>>> at = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> J = cxc.jac_pt_map(at, cxc.cart3d, cxc.sph3d)
>>> J.value.shape
(3, 3)

Plain-array dict (usys required):

>>> import jax.numpy as jnp
>>> at_arr = {"x": jnp.array(1.0), "y": jnp.array(0.0), "z": jnp.array(0.0)}
>>> J2 = cxc.jac_pt_map(at_arr, cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> J2.shape
(3, 3)
coordinax.charts.jac_pt_map(at: Array, from_chart: Cart2D, to_chart: Polar2D, /, *, usys: AbstractUnitSystem | None = None) Array
Parameters:
Return type:

Any

Compute the Jacobian of the transition function between two charts.

$$ J = frac{partial(r,theta)}{partial(x,y)}

= ( x/r & y/r -y/r^2 & x/r^2 ) = ( costheta & sintheta -sintheta/r & costheta/r )

$$

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> x = jnp.array([1.0, 1.0])
>>> cxc.jac_pt_map(cxc.cart2d, cxc.polar2d, usys=u.unitsystems.si)(x)
Array([[ 0.70710678,  0.70710678],
       [-0.5       ,  0.5       ]], dtype=float64)
coordinax.charts.jac_pt_map(at: AbstractQuantity, from_chart: Cart2D, to_chart: Polar2D, /, *, usys: AbstractUnitSystem | None = None) QMatrix
Parameters:
Return type:

Any

Compute the Jacobian of the transition function between two charts.

$$ J = frac{partial(r,theta)}{partial(x,y)}

= ( x/r & y/r -y/r^2 & x/r^2 ) = ( costheta & sintheta -sintheta/r & costheta/r )

$$

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> x = u.Q(jnp.array([1.0, 1.0]), "m")
>>> cxc.jac_pt_map(cxc.cart2d, cxc.polar2d, usys=u.unitsystems.si)(x)
QMatrix([[ 0.70710678,  0.70710678],
                [-0.5       ,  0.5       ]], '((, ), (rad / m, rad / m))')
Parameters:
Return type:

Any

coordinax.charts.pt_map(*args: Any, **kwargs: Any)#

Transform position coordinates from one chart to another.

This function implements the most general point-coordinate map between two compatible chart representations of the same geometric point. It is a point-wise map that preserves the physical location while changing the coordinate description.

For charts in the same atlas on the same manifold, this reduces to the ordinary chart transition map handled by pt_map. It is the intrinsic coordinate-change operation: the underlying point on the manifold is unchanged, and only its coordinate representation is changed.

However, this function is not restricted to two charts on the same manifold. It may also represent a realization-style map between charts attached to different manifolds when one is a realization of the other, such as an intrinsic chart on an embedded manifold and a chart on its ambient manifold. In that case, this function may change both the chart and the manifold in which the point is being represented.

Mathematical Definition:

Let $(U, varphi_{mathrm{from}})$ and $(V, varphi_{mathrm{to}})$ be charts on the same manifold $M$, with overlapping domains. The transition map is

$$

varphi_{mathrm{to}} circ varphi_{mathrm{from}}^{-1} : varphi_{mathrm{from}}(U cap V) to varphi_{mathrm{to}}(U cap V).

$$

If a point $p in U cap V$ has coordinates $q = varphi_{mathrm{from}}(p)$, then this function returns $p’ = varphi_{mathrm{to}}(p)$ for the same manifold point.

More generally, if $varphi_{mathrm{from}} : U subset M to mathbb{R}^n$ and $psi_{mathrm{to}} : W subset N to mathbb{R}^m$ are chart maps on manifolds $M$ and $N$, and there is a point map $F : M supset U to W subset N$, then pt_map represents the coordinate expression

$$ psi_{mathrm{to}} circ F circ varphi_{mathrm{from}}^{-1}. $$

  • 3D Spherical → Cartesian:

    $$

    x &= r sintheta cosphi \ y &= r sintheta sinphi \ z &= r costheta

    $$

Raises:

NotImplementedError – If no transformation rule is registered for the specific pair of charts (to_chart, from_chart).

Parameters:
Return type:

dict[str, Any]

Notes

  • This is a position-only transformation.

  • This function may map between charts on the same manifold or across manifolds, provided a compatible point map is defined between them.

  • Transformations preserve physical dimensions. For example, converting from polar to Cartesian preserves that r has length dimension and produces x and y with length dimension.

  • Some transformations may introduce singularities (e.g., polar coordinates at the origin, spherical coordinates at poles).

  • Transformations are composable: transforming $A to B to C$ yields the same result as a direct $A to C$ transformation (up to numerical precision).

  • Identity transformations (same from_chart and to_chart) return the input unchanged.

See also

pt_map

transform position coordinates between charts on the

same

Examples

>>> import quaxed.numpy as jnp
>>> import coordinax.charts as cxc
>>> import unxt as u

Transform from 2D polar to Cartesian:

>>> p_polar = {"r": u.Q(2.0, "m"), "theta": u.Angle(jnp.pi / 4, "rad")}
>>> cxc.pt_map(p_polar, cxc.polar2d, cxc.cart2d)
{'x': Q(1.41421356, 'm'), 'y': Q(1.41421356, 'm')}

Transform from 3D spherical to Cartesian:

>>> p_sph = {"theta": u.Angle(jnp.pi / 2, "rad"), "phi": u.Angle(0.0, "rad"),
...          "r": u.Q(5.0, "km")}
>>> cxc.pt_map(p_sph, cxc.sph3d, cxc.cart3d)
{'x': Q(5., 'km'), 'y': Q(0., 'km'), 'z': Q(3.061617e-16, 'km')}

Transform from Cartesian to cylindrical:

>>> p_xyz = {"x": u.Q(3.0, "m"), "y": u.Q(4.0, "m"), "z": u.Q(5.0, "m")}
>>> cxc.pt_map(p_xyz, cxc.cart3d, cxc.cyl3d)
{'rho': Q(5., 'm'), 'phi': Q(0.92729522, 'rad'), 'z': Q(5., 'm')}
coordinax.charts.pt_map(q: NoneType, /, *fixed_args: Any, **fixed_kw: Any) Callable[..., Any]
Parameters:
Return type:

dict[str, Any]

Return a partial function for point transformation.

>>> import coordinax.charts as cxc
>>> import unxt as u

Coordinates without units are the default.

>>> q = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> map = cxc.pt_map(None, cxc.cart3d, cxc.sph3d)
>>> map(q)
{'r': Q(1., 'm'), 'theta': Q(1.57079633, 'rad'), 'phi': Q(0., 'rad')}

Coordinates without units are also accepted, interpreted having units of the unxt.AbstractUnitSystem, which must be passed.

>>> q = {"x": 1.0, "y": 0.0, "z": 0.0}
>>> map = cxc.pt_map(None, cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> map(q)
{'r': Array(1., dtype=float64, ...),
 'theta': Array(1.57079633, dtype=float64),
 'phi': Array(0., dtype=float64, ...)}

unxt.Quantity inputs are also accepted, and are interpreted as being in Cartesian coordinates.

>>> p = u.Q([1.0, 0.0, 0.0], "m")
>>> map = cxc.pt_map(None, cxc.cart3d, cxc.sph3d)
>>> map(p)
QMatrix([1.        , 1.57079633, 0.        ], '(m, rad, rad)')

Array-Like inputs are interpreted as Cartesian coordinates with units from the required unxt.AbstractUnitSystem.

>>> q = [1.0, 0.0, 0.0]
>>> map = cxc.pt_map(None, cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> map(q)
Array([1.        , 1.57079633, 0.        ], dtype=float64)
coordinax.charts.pt_map(from_chart: AbstractChart, to_chart: AbstractChart, /, **fixed_kw: Any) Callable[..., Any]
Parameters:
Return type:

dict[str, Any]

Return a partial function for point transformation.

>>> import coordinax.charts as cxc
>>> import unxt as u

Coordinates without units are the default.

>>> p = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> map = cxc.pt_map(cxc.cart3d, cxc.sph3d)
>>> map(p)
{'r': Q(1., 'm'), 'theta': Q(1.57079633, 'rad'), 'phi': Q(0., 'rad')}

Coordinates without units are also accepted, interpreted having units of the unxt.AbstractUnitSystem, which must be passed.

>>> p = {"x": 1.0, "y": 0.0, "z": 0.0}
>>> map = cxc.pt_map(cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> map(p)
{'r': Array(1., dtype=float64, ...),
 'theta': Array(1.57079633, dtype=float64),
 'phi': Array(0., dtype=float64, ...)}

unxt.Quantity inputs are also accepted, and are interpreted as being in Cartesian coordinates.

>>> p = u.Q([1.0, 0.0, 0.0], "m")
>>> map = cxc.pt_map(cxc.cart3d, cxc.sph3d)
>>> map(p)
QMatrix([1.        , 1.57079633, 0.        ], '(m, rad, rad)')

Array-Like inputs are interpreted as Cartesian coordinates with units from the required unxt.AbstractUnitSystem.

>>> p = [1.0, 0.0, 0.0]
>>> map = cxc.pt_map(cxc.cart3d, cxc.sph3d, usys=u.unitsystems.si)
>>> map(p)
Array([1.        , 1.57079633, 0.        ], dtype=float64)
coordinax.charts.pt_map(x: Any, from_chart: AbstractChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) Any
Parameters:
Return type:

dict[str, Any]

Point transformation from chart to chart, using their manifolds.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {}
>>> cxc.pt_map(p, cxc.cart0d, cxc.cart0d)
{}
>>> p = {"r": u.Q(5.0, "m")}
>>> cxc.pt_map(p, cxc.radial1d, cxc.cart1d)
{'x': Q(5., 'm')}
>>> p = {"r": u.Q(5.0, "m"), "theta": u.Q(90, "deg")}
>>> cxc.pt_map(p, cxc.polar2d, cxc.cart2d)
{'x': Q(3.061617e-16, 'm'), 'y': Q(5., 'm')}
>>> p = {"r": u.Q(5.0, "m"), "theta": u.Q(90, "deg"), "phi": u.Q(0, "deg")}
>>> cxc.pt_map(p, cxc.sph3d, cxc.cart3d)
{'x': Q(5., 'm'), 'y': Q(0., 'm'), 'z': Q(3.061617e-16, 'm')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: AbstractManifold, from_chart: AbstractChart, to_M: AbstractManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

AbstractChart -> Cartesian -> AbstractChart.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"r": u.Q(5.0, "m"), "theta": u.Q(90, "deg")}
>>> map = cxc.pt_map.invoke(dict[str, u.Q], cxm.Rn, cxc.AbstractChart,
...                         cxm.Rn, cxc.AbstractChart)
>>> map(p, cxm.R2, cxc.polar2d, cxm.R2, cxc.cart2d)
{'x': Q(3.061617e-16, 'm'), 'y': Q(5., 'm')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: AbstractChart, to_M: EuclideanManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Identity conversion for matching charts.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> import quaxed.numpy as jnp
>>> q = {}
>>> q2 = cxc.pt_map(q, cxm.R0, cxc.cart0d, cxm.R0, cxc.cart0d)
>>> q is q2
True
>>> q = {"r": u.Q(3.0, "m")}
>>> q2 = cxc.pt_map(q, cxm.R1, cxc.radial1d, cxm.R1, cxc.radial1d)
>>> q is q2
True
>>> q = {"x": u.Q(1.0, "m"), "y": u.Q(2.0, "m")}
>>> q2 = cxc.pt_map(q, cxm.R2, cxc.cart2d, cxm.R2, cxc.cart2d)
>>> q is q2
True
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Radial1D, to_M: EuclideanManifold, to_chart: Cart1D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Radial1D -> Cart1D.

The r coordinate is converted to the x coordinate of the 1D system.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> q = {"r": u.Q(5.0, "m")}
>>> cxc.pt_map(q, cxm.R1, cxc.radial1d, cxm.R1, cxc.cart1d)
{'x': Q(5., 'm')}
>>> q = {"r": 5.0}  # No units
>>> cxc.pt_map(q, cxm.R1, cxc.radial1d, cxm.R1, cxc.cart1d)
{'x': 5.0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cart1D, to_M: EuclideanManifold, to_chart: Radial1D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cart1D -> Radial1D.

The x coordinate is converted to the r coordinate of the 1D system.

Assumptions:

  • Cart1D and Radial1D are

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"x": u.Q(5.0, "m")}
>>> cxc.pt_map(p, cxm.R1, cxc.cart1d, cxm.R1, cxc.radial1d)
{'r': Q(5., 'm')}
>>> p = {"x": 5.0}  # No units
>>> cxc.pt_map(p, cxm.R1, cxc.cart1d, cxm.R1, cxc.radial1d)
{'r': 5.0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Polar2D, to_M: EuclideanManifold, to_chart: Cart2D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Polar2D -> Cart2D.

The r and theta coordinates are converted to the x and y coordinates of the 2D Cartesian system.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"r": u.Q(5.0, "m"), "theta": u.Q(90, "deg")}
>>> cxc.pt_map(p, cxm.R2, cxc.polar2d, cxm.R2, cxc.cart2d)
{'x': Q(3.061617e-16, 'm'), 'y': Q(5., 'm')}
>>> p = {"r": 5, "theta": 90}  # No units
>>> usys = u.unitsystem("km", "deg")
>>> cxc.pt_map(p, cxm.R2, cxc.polar2d, cxm.R2, cxc.cart2d, usys=usys)
{'x': Array(3.061617e-16, dtype=float64, ...),
 'y': Array(5., dtype=float64, ...)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cart2D, to_M: EuclideanManifold, to_chart: Polar2D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cart2D -> Polar2D.

The x and y coordinates are converted to the r and theta coordinates of the 2D polar system.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"x": u.Q(3, "m"), "y": u.Q(4, "m")}
>>> cxc.pt_map(p, cxm.R2, cxc.cart2d, cxm.R2, cxc.polar2d)
{'r': Q(5., 'm'), 'theta': Q(0.92729522, 'rad')}
>>> p = {"x": 3, "y": 4}  # No units
>>> cxc.pt_map(p, cxm.R2, cxc.cart2d, cxm.R2, cxc.polar2d)
{'r': Array(5., dtype=float64, ...),
 'theta': Array(0.92729522, dtype=float64, ...)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cylindrical3D, to_M: EuclideanManifold, to_chart: Cart3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cylindrical3D -> Cart3D.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"rho": u.Q(1.0, "m"), "phi": u.Q(90, "deg"), "z": u.Q(2.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, cxc.cart3d)
{'x': Q(6.123234e-17, 'm'), 'y': Q(1., 'm'), 'z': Q(2., 'm')}
>>> p = {"rho": 1.0, "phi": 90, "z": 2.0}  # No units
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, cxc.cart3d, usys=usys)
{'x': Array(6.123234e-17, dtype=float64, ...), 'y': Array(1., dtype=float64, ...),
 'z': 2.0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Spherical3D, to_M: EuclideanManifold, to_chart: Cart3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Spherical3D -> Cart3D.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> import quaxed.numpy as jnp

A point on the +z axis (theta=0):

>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(0, "deg"), "phi": u.Q(0, "deg")}
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.cart3d)
{'x': Q(0., 'm'), 'y': Q(0., 'm'), 'z': Q(1., 'm')}

A point on the equator (theta=90 deg, phi=0):

>>> p = {"r": 2.0, "theta": 90, "phi": 0}
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.cart3d, usys=usys)
{'x': Array(2., dtype=float64, ...),
 'y': Array(0., dtype=float64, ...),
 'z': Array(1.2246468e-16, dtype=float64, ...)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: LonLatSpherical3D, to_M: EuclideanManifold, to_chart: Cart3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

LonLatSpherical3D -> Cart3D.

>>> import coordinax.charts as cxc
>>> import unxt as u

A point at the north pole (lat=90 deg):

>>> p = {"lon": u.Q(0, "deg"), "lat": u.Q(90, "deg"), "distance": u.Q(1.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.lonlat_sph3d, cxm.R3, cxc.cart3d)
{'x': Q(6.123234e-17, 'm'), 'y': Q(0., 'm'), 'z': Q(1., 'm')}

A point on the equator at lon=0:

>>> p = {"lon": 0, "lat": 0, "distance": 2}
>>> cxc.pt_map(p, cxm.R3, cxc.lonlat_sph3d, cxm.R3, cxc.cart3d)
{'x': Array(2., dtype=float64, ...),
 'y': Array(0., dtype=float64, ...),
 'z': Array(0., dtype=float64, ...)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: LonCosLatSpherical3D, to_M: EuclideanManifold, to_chart: Cart3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

LonCosLatSpherical3D -> Cart3D.

Components are (lon_coslat, lat, r), where lon_coslat := lon * cos(lat). Longitude is undefined at the poles (cos(lat) == 0); we set lon = 0 by convention there to avoid NaNs.

>>> import coordinax.charts as cxc
>>> import unxt as u

A point on the equator (lat=0, so lon_coslat = lon):

>>> p = {"lon_coslat": u.Q(0, "deg"), "lat": u.Q(0, "deg"),
...      "distance": u.Q(1.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.loncoslat_sph3d, cxm.R3, cxc.cart3d)
{'x': Q(1., 'm'), 'y': Q(0., 'm'), 'z': Q(0., 'm')}

At the north pole (lat=90), lon_coslat is effectively 0 regardless of lon:

>>> p = {"lon_coslat": u.Q(0, "deg"), "lat": u.Q(90, "deg"),
...      "distance": u.Q(2.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.loncoslat_sph3d, cxm.R3, cxc.cart3d)
{'x': Q(1.2246468e-16, 'm'), 'y': Q(0., 'm'), 'z': Q(2., 'm')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: MathSpherical3D, to_M: EuclideanManifold, to_chart: Cart3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

MathSpherical3D -> Cart3D.

  • theta: azimuth in the x-y plane (longitude-like)

  • phi : polar angle from +z, with phi in [0, pi]

>>> import coordinax.charts as cxc
>>> import unxt as u

A point on the +z axis (phi=0):

>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(0, "deg"), "phi": u.Q(0, "deg")}
>>> cxc.pt_map(p, cxm.R3, cxc.math_sph3d, cxm.R3, cxc.cart3d)
{'x': Q(0., 'm'), 'y': Q(0., 'm'), 'z': Q(1., 'm')}

A point on the +x axis (theta=0, phi=90):

>>> p = {"r": u.Q(2.0, "m"), "theta": u.Q(0, "deg"), "phi": u.Q(90, "deg")}
>>> cxc.pt_map(p, cxm.R3, cxc.math_sph3d, cxm.R3, cxc.cart3d)
{'x': Q(2., 'm'), 'y': Q(0., 'm'), 'z': Q(1.2246468e-16, 'm')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: ProlateSpheroidal3D, to_M: EuclideanManifold, to_chart: Cart3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

ProlateSpheroidal3D -> Cart3D.

We calculate through cylindrical coordinates first:

$rho = sqrt{(mu-Delta^2)left(1-frac{|\nu|}{Delta^2}right)}$ $z = sqrt{mu,frac{|\nu|}{Delta^2}};mathrm{sign}(nu)$ $phi = phi.$

Then convert to Cartesian:

$x=rhocosphi$, $y=rhosinphi$, $z=z$.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> import quaxed.numpy as jnp
>>> prolatesph3d = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2.0, "m"))
>>> p = {"mu": u.Q(5.0, "m2"), "nu": u.Q(1.0, "m2"), "phi": u.Q(0, "rad")}
>>> cxc.pt_map(p, cxm.R3, prolatesph3d, cxm.R3, cxc.cart3d)
{'x': Q(0.8660254, 'm'), 'y': Q(0., 'm'), 'z': Q(1.11803399, 'm')}
>>> p = {"mu": 5.0, "nu": 1.0, "phi": 0}  # No units
>>> usys = u.unitsystem("m", "rad")
>>> cxc.pt_map(p, cxm.R3, prolatesph3d, cxm.R3, cxc.cart3d, usys=usys)
{'x': Array(0.8660254, dtype=float64),
 'y': Array(0., dtype=float64),
 'z': Array(1.11803399, dtype=float64)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cart3D, to_M: EuclideanManifold, to_chart: Cylindrical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cart3D -> Cylindrical3D.

>>> import coordinax.main as cx
>>> import unxt as u
>>> p = {"x": u.Q(3.0, "m"), "y": u.Q(4.0, "m"), "z": u.Q(5.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cart3d, cxm.R3, cxc.cyl3d)
{'rho': Q(5., 'm'), 'phi': Q(0.92729522, 'rad'), 'z': Q(5., 'm')}
>>> p = {"x": 3.0, "y": 4.0, "z": 5.0}  # No units
>>> cxc.pt_map(p, cxm.R3, cxc.cart3d, cxm.R3, cxc.cyl3d)
{'rho': Array(5., dtype=float64, ...),
 'phi': Array(0.92729522, dtype=float64, ...),
 'z': 5.0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cart3D | Cylindrical3D, to_M: EuclideanManifold, to_chart: AbstractSpherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cart3D -> Spherical3D -> AbstractSpherical3D.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"x": u.Q(0.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(1.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cart3d, cxm.R3, cxc.loncoslat_sph3d)
{'lon_coslat': Q(0., 'rad'), 'lat': Q(90., 'deg'), 'distance': Q(1., 'm')}
>>> p = {"rho": 0, "phi": 180, "z": 1}
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, cxc.loncoslat_sph3d, usys=usys)
{'lon_coslat': Array(1.10218212e-14, dtype=float64),
 'lat': Array(1.57079633, dtype=float64),
 'distance': Array(1., dtype=float64, weak_type=True)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cart3D, to_M: EuclideanManifold, to_chart: Spherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cart3D -> Spherical3D.

>>> import coordinax.charts as cxc
>>> import unxt as u

A point on the +z axis:

>>> p = {"x": u.Q(0.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(1.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cart3d, cxm.R3, cxc.sph3d)
{'r': Q(1., 'm'), 'theta': Q(0., 'rad'), 'phi': Q(0., 'rad')}

A point on the +x axis:

>>> p = {"x": 2.0, "y": 0.0, "z": 0.0}  # No units
>>> cxc.pt_map(p, cxm.R3, cxc.cart3d, cxm.R3, cxc.sph3d)
{'r': Array(2., dtype=float64, ...),
 'theta': Array(1.57079633, dtype=float64),
 'phi': Array(0., dtype=float64, ...)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cylindrical3D, to_M: EuclideanManifold, to_chart: Spherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cylindrical3D -> Spherical3D.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

A point on the z-axis (rho=0):

>>> p = {"rho": u.Q(0.0, "m"), "phi": u.Q(0, "rad"), "z": u.Q(1.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, cxc.sph3d)
{'r': Q(1., 'm'), 'theta': Q(0., 'rad'), 'phi': Q(0, 'rad')}

A point in the xy-plane (z=0):

>>> p = {"rho": 3.0, "phi": 0, "z": 0.0}  # No units
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, cxc.sph3d)
{'r': Array(3., dtype=float64, ...), 'theta': Array(1.57079633, dtype=float64),
 'phi': 0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Spherical3D, to_M: EuclideanManifold, to_chart: Cylindrical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Spherical3D -> Cylindrical3D.

>>> import coordinax.charts as cxc
>>> import coordinax.manifolds as cxm
>>> import unxt as u

A point on the +z axis (theta=0):

>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(0, "rad"), "phi": u.Q(0, "rad")}
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.cyl3d)
{'rho': Q(0., 'm'), 'phi': Q(0, 'rad'), 'z': Q(1., 'm')}

A point on the equator (theta=90 deg):

>>> p = {"r": 2.0, "theta": 90, "phi": 0}  # No units
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.cyl3d, usys=usys)
{'rho': Array(2., dtype=float64, ...), 'phi': 0,
 'z': Array(1.2246468e-16, dtype=float64, ...)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Spherical3D, to_M: EuclideanManifold, to_chart: LonLatSpherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Spherical3D -> LonLatSpherical3D.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

Spherical theta=0 corresponds to lat=90 (north pole):

>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(0, "rad"), "phi": u.Q(0, "rad")}
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.lonlat_sph3d)
{'lon': Q(0, 'rad'), 'lat': Q(90., 'deg'), 'distance': Q(1., 'm')}

Spherical theta=90 deg corresponds to lat=0 (equator):

>>> p = {"r": 1.0, "theta": 0, "phi": 0}  # No units
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.lonlat_sph3d)
{'lon': 0, 'lat': 1.5707963267948966, 'distance': 1.0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Spherical3D, to_M: EuclideanManifold, to_chart: LonCosLatSpherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Spherical3D -> LonCosLatSpherical3D.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

On the equator (theta=90 deg), lon_coslat equals lon:

>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(90, "deg"), "phi": u.Q(45, "deg")}
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.loncoslat_sph3d)
{'lon_coslat': Q(45., 'deg'), 'lat': Q(0., 'deg'), 'distance': Q(1., 'm')}

At the north pole (theta=0), lon_coslat = 0 regardless of phi:

>>> p = {"r": 1.0, "theta": 0, "phi": 45}  # No units
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.loncoslat_sph3d, usys=usys)
{'lon_coslat': Array(2.7554553e-15, dtype=float64, ...),
 'lat': 1.5707963267948966, 'distance': 1.0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Spherical3D, to_M: EuclideanManifold, to_chart: MathSpherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Spherical3D -> MathSpherical3D.

Swaps theta and phi: Physics (theta=polar, phi=azimuth) to Math (theta=azimuth, phi=polar).

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(30, "deg"), "phi": u.Q(60, "deg")}
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.math_sph3d)
{'r': Q(1., 'm'), 'theta': Q(60, 'deg'), 'phi': Q(30, 'deg')}
>>> p = {"r": 1.0, "theta": 30, "phi": 60}  # No units
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.sph3d, cxm.R3, cxc.math_sph3d, usys=usys)
{'r': 1.0, 'theta': 60, 'phi': 30}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: MathSpherical3D, to_M: EuclideanManifold, to_chart: Spherical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

MathSpherical3D -> Spherical3D.

Swaps theta and phi: Math (theta=azimuth, phi=polar) to Physics (theta=polar, phi=azimuth).

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(60, "deg"), "phi": u.Q(30, "deg")}
>>> cxc.pt_map(p, cxm.R3, cxc.math_sph3d, cxm.R3, cxc.sph3d)
{'r': Q(1., 'm'), 'theta': Q(30, 'deg'), 'phi': Q(60, 'deg')}
>>> p = {"r": 1.0, "theta": 60, "phi": 30}  # No units
>>> usys = u.unitsystem("m", "deg")
>>> cxc.pt_map(p, cxm.R3, cxc.math_sph3d, cxm.R3, cxc.sph3d, usys=usys)
{'r': 1.0, 'theta': 30, 'phi': 60}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: ProlateSpheroidal3D, to_M: EuclideanManifold, to_chart: Cylindrical3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

ProlateSpheroidal3D -> Cylindrical3D.

Uses the focal length $Delta$ stored on from_chart.

Validity constraints (enforced by the representation) are:

  • $Delta > 0$,

  • $mu ge Delta^2$,

  • $|nu| le Delta^2$.

The conversion proceeds via

$rho = sqrt{(mu-Delta^2)left(1-frac{|\nu|}{Delta^2}right)}$, $z = sqrt{mu,frac{|\nu|}{Delta^2}},mathrm{sign}(nu)$, $phi = phi$.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> prolatesph3d = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2.0, "m"))
>>> p = {"mu": u.Q(5.0, "m2"), "nu": u.Q(1.0, "m2"), "phi": u.Q(0, "rad")}
>>> cxc.pt_map(p, cxm.R3, prolatesph3d, cxm.R3, cxc.cyl3d)
{'rho': Q(0.8660254, 'm'), 'phi': Q(0, 'rad'), 'z': Q(1.11803399, 'm')}
>>> p = {"mu": 5.0, "nu": 1.0, "phi": 0}  # No units
>>> usys = u.unitsystem("m", "rad")
>>> cxc.pt_map(p, cxm.R3, prolatesph3d, cxm.R3, cxc.cyl3d, usys=usys)
{'rho': Array(0.8660254, dtype=float64), 'phi': 0,
 'z': Array(1.11803399, dtype=float64)}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: Cylindrical3D, to_M: EuclideanManifold, to_chart: ProlateSpheroidal3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Cylindrical3D -> ProlateSpheroidal3D.

Uses the focal length $Delta$ stored on to_chart.

Let $R^2 = rho^2$ and $z^2 = z^2$ and define

$S = R^2 + z^2 + Delta^2$, $D_f = R^2 + z^2 - Delta^2$, $D = sqrt{D_f^2 + 4 R^2 Delta^2}$.

Then

$mu = Delta^2 + tfrac12(D + D_f)$ (with numerically-stable branches), $|nu| = dfrac{2Delta^2}{S + D},z^2$, and $nu = |\nu|,mathrm{sign}(z)$, with a stability fix when $Delta^2 - |nu|$ is small.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> prolatesph3d = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2.0, "m"))

A point on the z-axis (rho=0):

>>> p = {"rho": u.Q(0.0, "m"), "phi": u.Q(0, "rad"), "z": u.Q(3.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, prolatesph3d)
{'mu': Q(9., 'm2'), 'nu': Q(4., 'm2'), 'phi': Q(0, 'rad')}

A point in the xy-plane (z=0):

>>> p = {"rho": u.Q(2.0, "m"), "phi": u.Q(0, "rad"), "z": u.Q(0.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, prolatesph3d)
{'mu': Q(8., 'm2'), 'nu': Q(0., 'm2'), 'phi': Q(0, 'rad')}

Without units:

>>> p = {"rho": 2.0, "phi": 0, "z": 3.0}  # No units
>>> usys = u.unitsystem("m", "rad")
>>> cxc.pt_map(p, cxm.R3, cxc.cyl3d, cxm.R3, prolatesph3d, usys=usys)
{'mu': Array(14.52079729, dtype=float64),
 'nu': Array(2.47920271, dtype=float64), 'phi': 0}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: ProlateSpheroidal3D, to_M: EuclideanManifold, to_chart: ProlateSpheroidal3D, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

{class}`coordinax.charts.ProlateSpheroidal3D` -> itself.

If the focal length is unchanged (to_chart.Delta == from_chart.Delta), this is the identity map.

If the focal length changes, we convert via cylindrical coordinates:

Prolate(Delta_in) -> Cylindrical -> Prolate(Delta_out).

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

Same focal length (identity transformation):

>>> prolate = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2.0, "m"))
>>> p = {"mu": u.Q(5.0, "m2"), "nu": u.Q(1.0, "m2"), "phi": u.Q(0, "rad")}
>>> cxc.pt_map(p, cxm.R3, prolate, cxm.R3, prolate)
{'mu': Q(5., 'm2'),
 'nu': Q(1., 'm2'),
 'phi': Q(0., 'rad')}

Different focal lengths (converts via cylindrical):

>>> prolate_in = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2.0, "m"))
>>> prolate_out = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(3.0, "m"))
>>> p = {"mu": u.Q(5.0, "m2"), "nu": u.Q(1.0, "m2"), "phi": u.Q(0, "rad")}
>>> cxc.pt_map(p, cxm.R3, prolate_in, cxm.R3, prolate_out)
{'mu': Q(9.85889894, 'm2'),
 'nu': Q(1.14110106, 'm2'),
 'phi': Q(0., 'rad')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: CartND, to_M: EuclideanManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

CartND -> AbstractChart.

Converts from N-dimensional Cartesian (with a single ‘q’ array) to any other chart type by first extracting the appropriate fixed-dimensional Cartesian representation.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

Convert 3D CartND to Spherical:

>>> p = {"q": u.Q([1.0, 0.0, 0.0], "m")}
>>> cxc.pt_map(p, cxm.RN, cxc.cartnd, cxm.R3, cxc.sph3d)
{'r': Q(1., 'm'), 'theta': Q(1.57079633, 'rad'), 'phi': Q(0., 'rad')}

Convert 2D CartND to Polar:

>>> p = {"q": u.Q([3.0, 4.0], "m")}
>>> cxc.pt_map(p, cxm.RN, cxc.cartnd, cxm.R2, cxc.polar2d)
{'r': Q(5., 'm'), 'theta': Q(0.92729522, 'rad')}

Convert 1D CartND to Radial:

>>> p = {"q": u.Q([5.0], "m")}
>>> cxc.pt_map(p, cxm.RN, cxc.cartnd, cxm.R1, cxc.radial1d)
{'r': Q(5., 'm')}

Convert CartND to Cart3D:

>>> p = {"q": u.Q([1.0, 2.0, 3.0], "m")}
>>> cxc.pt_map(p, cxm.RN, cxc.cartnd, cxm.R3, cxc.cart3d)
{'x': Q(1., 'm'), 'y': Q(2., 'm'), 'z': Q(3., 'm')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: EuclideanManifold, from_chart: AbstractChart, to_M: EuclideanManifold, to_chart: CartND, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

AbstractChart -> CartND.

Converts from any chart type to N-dimensional Cartesian (with a single ‘q’ array) by first transforming to the appropriate fixed-dimensional Cartesian representation.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

Convert Cart3D to CartND:

>>> p = {"x": u.Q(1.0, "m"), "y": u.Q(2.0, "m"), "z": u.Q(3.0, "m")}
>>> cxc.pt_map(p, cxm.R3, cxc.cart3d, cxm.R3, cxc.cartnd)
{'q': Q([1., 2., 3.], 'm')}

Convert Cart2D to CartND:

>>> p = {"x": u.Q(3.0, "m"), "y": u.Q(4.0, "m")}
>>> cxc.pt_map(p, cxm.R2, cxc.cart2d, cxm.R2, cxc.cartnd)
{'q': Q([3., 4.], 'm')}

Convert Radial to CartND:

>>> p = {"r": u.Q(3.0, "m")}
>>> cxc.pt_map(p, cxc.radial1d, cxc.cartnd)
{'q': Q([3.], 'm')}

Convert Cylindrical to CartND (z-axis point):

>>> p = {"rho": u.Q(0.0, "m"), "phi": u.Q(0, "rad"), "z": u.Q(5.0, "m")}
>>> cxc.pt_map(p, cxc.cyl3d, cxc.cartnd)
{'q': Q([0., 0., 5.], 'm')}
coordinax.charts.pt_map(q: AbstractQuantity, from_M: EuclideanManifold, from_chart: AbstractChart, to_M: EuclideanManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) AbstractQuantity
Parameters:
Return type:

dict[str, Any]

Identity point transform for Quantity inputs on uniform-unit charts.

For charts where all components share the same unit (Cartesian charts, 0D/1D charts), a Quantity can be passed directly and is returned unchanged when the source and target charts are the same type.

This dispatch only handles identity transformations (same chart type). For transformations between different chart types with Quantity input, the Quantity must first be converted to a coordinate dictionary.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u

1D Cartesian (identity):

>>> q = u.Q([5.0], "m")
>>> cxc.pt_map(q, cxm.R1, cxc.cart1d, cxm.R1, cxc.cart1d, usys=None) is q
True

2D Cartesian (identity):

>>> q = u.Q([3.0, 4.0], "m")
>>> cxc.pt_map(q, cxm.R2, cxc.cart2d, cxm.R2, cxc.cart2d, usys=None) is q
True

3D Cartesian (identity):

>>> q = u.Q([1.0, 2.0, 3.0], "km")
>>> cxc.pt_map(q, cxm.R3, cxc.cart3d, cxm.R3, cxc.cart3d, usys=None) is q
True

N-D Cartesian (identity):

>>> q = u.Q([1.0, 2.0, 3.0, 4.0], "m")
>>> cxc.pt_map(q, cxm.RN, cxc.cartnd, cxm.RN, cxc.cartnd, usys=None) is q
True
coordinax.charts.pt_map(p: AbstractQuantity, from_M: EuclideanManifold, from_chart: AbstractChart, to_M: EuclideanManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) QMatrix
Parameters:
Return type:

dict[str, Any]

Transform a QMatrix between charts.

Converts the components of a QMatrix from one chart to another, preserving the matrix structure with potentially different units per component.

>>> import coordinax.charts as cxc
>>> import unxt as u

2D Cartesian to Polar:

>>> q = u.Q([3.0, 4.0], "m")
>>> result = cxc.pt_map(q, cxc.cart2d, cxc.polar2d)
>>> result.shape
(2,)
>>> result.unit
UnitsMatrix("(m, rad)")

3D Cartesian to Spherical:

>>> q = u.Q([1.0, 0.0, 0.0], "kpc")
>>> result = cxc.pt_map(q, cxc.cart3d, cxc.sph3d)
>>> result.shape
(3,)

Batched transformation:

>>> q_batch = u.Q([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], "m")
>>> result = cxc.pt_map(q_batch, cxc.cart3d, cxc.sph3d)
>>> result.shape
(2, 3)
coordinax.charts.pt_map(p: Array | list, from_M: EuclideanManifold, from_chart: AbstractChart, to_M: EuclideanManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None) Array
Parameters:
Return type:

dict[str, Any]

Point transform for array input.

Transforms a point represented as a raw array (without units) from one chart to another. The unit system usys provides the units for interpreting the array components.

Return type:

dict[str, Any]

Returns:

  • Array – Array of shape (..., ndim) containing the transformed coordinates in to_chart.

  • >>> import coordinax.charts as cxc

  • >>> import unxt as u

  • >>> import jax.numpy as jnp

  • **Cartesian to Spherical (3D) (****)

  • >>> usys = u.unitsystem(“m”, “rad”)

  • >>> p = jnp.array([1.0, 0.0, 0.0]) # Point on x-axis

  • >>> cxc.pt_map(p, cxc.cart3d, cxc.sph3d, usys=usys)

  • Array([1. , 1.57079633, 0. ], dtype=float64)

  • The result is [r, theta, phi] = [1, pi/2, 0] (on equator, x-axis).

  • **Spherical to Cartesian (3D) (****)

  • >>> p = jnp.array([2.0, jnp.pi/4, 0.0]) # r=2, theta=45°, phi=0

  • >>> cxc.pt_map(p, cxc.sph3d, cxc.cart3d, usys=usys)

  • Array([1.41421356, 0. , 1.41421356], dtype=float64)

  • **Cartesian to Cylindrical (****)

  • >>> p = jnp.array([3.0, 4.0, 5.0])

  • >>> cxc.pt_map(p, cxc.cart3d, cxc.cyl3d, usys=usys)

  • Array([5. , 0.92729522, 5. ], dtype=float64)

  • The result is [rho, phi, z] = [5, arctan(4/3), 5].

  • **Batched transformation (****)

  • >>> p_batch = jnp.array([[1.0, 0.0, 0.0],

  • … [0.0, 1.0, 0.0],

  • … [0.0, 0.0, 1.0]])

  • >>> cxc.pt_map(p_batch, cxc.cart3d, cxc.sph3d, usys=usys)

  • Array([[1. , 1.57079633, 0. ], – [1. , 1.57079633, 1.57079633], [1. , 0. , 0. ]], dtype=float64)

  • **2D Cartesian to Polar (****)

  • >>> usys_2d = u.unitsystem(“m”, “rad”)

  • >>> p = jnp.array([3.0, 4.0])

  • >>> cxc.pt_map(p, cxc.cart2d, cxc.polar2d, usys=usys_2d)

  • Array([5. , 0.92729522], dtype=float64)

  • .. py (function:: pt_map(p: dict[str, typing.Any], from_M: coordinax._src.product.manifold.CartesianProductManifold, from_chart: coordinax._src.product.chart.AbstractCartesianProductChart, to_M: coordinax._src.product.manifold.CartesianProductManifold, to_chart: coordinax._src.product.chart.AbstractCartesianProductChart, /, *, usys: unxt._src.unitsystems.base.AbstractUnitSystem | None = None) -> dict[str, typing.Any]) – :noindex:

  • ABC CartesianProductChart -> CartesianProductChart (factorwise).

  • Transforms between product charts by applying coordinax.charts.pt_map to

  • each factor independently. Requires compatible factor structure (same number

  • of factors, pairwise compatible).

  • Mathematical definition

  • $$ varphi left(prod_i S_i,;prod_i R_i,;pright) – = bigl(varphi(S_i,,R_i,,p_i)bigr)_i $$

  • where $varphi$ denotes {func}`~coordinax.charts.pt_map` and

  • $p_i$ are the factor dictionaries split from $p$.

Parameters:

Examples

>>> import coordinax.charts as cxc
>>> import unxt as u

Transform a Cartesian product chart between spatial representations:

>>> prod_crt = cxc.CartesianProductChart((cxc.time1d, cxc.cart3d), ("t", "q"))
>>> prod_sph = cxc.CartesianProductChart((cxc.time1d, cxc.sph3d), ("t", "q"))
>>> p = {"t.t": u.Q(1.0, "s"), "q.x": u.Q(1.0, "m"), "q.y": u.Q(0.0, "m"),
...      "q.z": u.Q(0.0, "m")}
>>> result = cxc.pt_map(p, prod_crt, prod_sph)
>>> result["t.t"]
Q(1., 's')
>>> result["q.r"]
Q(1., 'm')
coordinax.charts.pt_map(p: dict[str, Any], from_M: AbstractManifold, from_chart: AbstractChart, to_M: CartesianProductManifold, to_chart: AbstractCartesianProductChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

AbstractChart -> Cartesian -> AbstractCartesianProductChart.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> chart = cxc.CartesianProductChart((cxc.sph2, cxc.cart1d), ("S2", "R1"))
>>> map = cxc.pt_map.invoke(dict[str, u.Q], cxc.Cart3D, cxc.CartesianProductChart)
>>> try: map({}, cxc.cart3d, chart)
... except NotImplementedError as e: print(e)
No general transform between Cart3D and CartesianProductChart.
Define explicit rules for non-product to product conversions.
coordinax.charts.pt_map(p: dict[str, Any], from_M: CartesianProductManifold, from_chart: AbstractCartesianProductChart, to_M: AbstractManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

AbstractCartesianProductChart -> Cartesian -> AbstractChart.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> chart = cxc.CartesianProductChart((cxc.sph2, cxc.cart1d), ("S2", "R1"))
>>> map = cxc.pt_map.invoke(dict[str, u.Q], cxc.CartesianProductChart, cxc.Cart3D)
>>> try: map({}, chart, cxc.cart3d)
... except NotImplementedError as e: print(e)
No general transform between CartesianProductChart and Cart3D.
Define explicit rules for product to non-product conversions.
coordinax.charts.pt_map(p: dict[str, Any], from_chart: EmbeddedChart, to_chart: EmbeddedChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Convert between embedded manifolds with a shared ambient space.

This function transforms intrinsic coordinates from one embedded manifold to another by: 1. Embedding the point into the ambient space of the source manifold 2. Transforming in the ambient space (if the ambient charts differ) 3. Projecting back to the intrinsic coordinates of the target manifold

>>> import coordinax.charts as cxc
>>> import coordinax.manifolds as cxm
>>> import unxt as u
>>> import quaxed.numpy as jnp

Example 1: Two spheres with different radii

Both spheres use the same intrinsic SphericalTwoSphere chart but have different radii:

>>> sphere1 = cxm.EmbeddedChart(cxm.TwoSphereIn3D(radius=u.Q(1.0, "km")))
>>> sphere2 = cxm.EmbeddedChart(cxm.TwoSphereIn3D(radius=u.Q(2.0, "km")))

A point on sphere1 (theta=pi/4, phi=0):

>>> p = {"theta": u.Q(45, "deg"), "phi": u.Q(0, "deg")}
>>> p2 = cxc.pt_map(p, sphere1, sphere2)
>>> {k: v.uconvert("deg") for k, v in p2.items()}
{'theta': Q(45, 'deg'), 'phi': Q(0, 'deg')}

The angular coordinates are preserved (both spheres share the same angular parameterization via projection through the shared ambient space).

coordinax.charts.pt_map(p: dict[str, Any], from_chart: AbstractChart, to_chart: EmbeddedChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Project an ambient position into an embedded chart.

This transforms coordinates from an ambient chart (e.g., Cartesian or Spherical) into the intrinsic coordinates of an embedded manifold.

>>> import coordinax.charts as cxc
>>> import coordinax.manifolds as cxm
>>> import unxt as u
>>> import quaxed.numpy as jnp

From Cartesian ambient to SphericalTwoSphere intrinsic:

>>> sphere = cxm.EmbeddedChart(cxm.TwoSphereIn3D(radius=u.Q(1.0, "m")))

A point on the unit sphere in Cartesian coords (on equator, x-axis):

>>> p_cart = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> cxc.pt_map(p_cart, cxc.cart3d, sphere)
{'theta': Q(1.57079633, 'rad'), 'phi': Q(0., 'rad')}

From Spherical ambient to SphericalTwoSphere intrinsic:

The ambient spherical coords (r, theta, phi) project to intrinsic (theta, phi), discarding the radial component:

>>> p_sph = {"r": 5, "theta": 1, "phi": 0.5}  # No units
>>> usys = u.unitsystem("m", "rad")
>>> cxc.pt_map(p_sph, cxc.sph3d, sphere, usys=usys)
{'theta': 1, 'phi': 0.5}
coordinax.charts.pt_map(p: dict[str, Any], from_chart: EmbeddedChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Embed intrinsic coordinates into an ambient representation.

This transforms intrinsic coordinates of an embedded manifold into coordinates of an ambient chart, which may differ from the embedding’s native ambient chart.

>>> import coordinax.charts as cxc
>>> import coordinax.manifolds as cxm
>>> import unxt as u
>>> import quaxed.numpy as jnp

From SphericalTwoSphere intrinsic to Cartesian ambient:

>>> sphere = cxm.EmbeddedChart(cxm.TwoSphereIn3D(radius=u.Q(1.0, "m")))

A point on the unit sphere (on equator, x-axis):

>>> p_sph = {"theta": u.Q(1.0, "rad"), "phi": u.Q(0.0, "rad")}
>>> cxc.pt_map(p_sph, sphere, cxc.cart3d)
{'x': Q(0.84147098, 'm'), 'y': Q(0., 'm'), 'z': Q(0.54030231, 'm')}

From SphericalTwoSphere intrinsic to Spherical ambient:

>>> p_sph = {"theta": u.Q(1.0, "rad"), "phi": u.Q(0.5, "rad")}
>>> cxc.pt_map(p_sph, sphere, cxc.sph3d)
{'r': Q(1., 'm'), 'theta': Q(1., 'rad'), 'phi': Q(0.5, 'rad')}
coordinax.charts.pt_map(p: dict[str, Any], M: EmbeddedManifold, from_chart: AbstractChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Convert between embedded manifolds with a shared ambient space.

>>> import unxt as u
>>> import coordinax.charts as cxc
>>> import coordinax.manifolds as cxm
>>> M = cxm.embedded_twosphere(radius=u.Q(1, "kpc"))
>>> M
EmbeddedManifold(intrinsic=HyperSphericalManifold(...),
                 ambient=Rn(3),
                 embed_map=TwoSphereIn3D(radius=Q(1, 'kpc')))
>>> x_cart = {"x": u.Q(1, "m"), "y": u.Q(2, "m"), "z": u.Q(3, "m")}
>>> x_sph2 = cxc.pt_map(x_cart, M, cxc.cart3d, cxc.loncoslat_sph2)
>>> x_sph2
{'lon_coslat': Q(0.66164791, 'rad'), 'lat': Q(53.3007748, 'deg')}
>>> cxc.pt_map(x_sph2, M, cxc.loncoslat_sph2, cxc.cart3d)
{'x': Q(0.26726124, 'kpc'), 'y': Q(0.53452248, 'kpc'),
 'z': Q(0.80178373, 'kpc')}
coordinax.charts.pt_map(p: Any, from_chart: Abstract3D, to_chart: AbstractSphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) Any
Parameters:
Return type:

dict[str, Any]

Project a point from the ambient chart to the two-sphere intrinsic chart.

This realization map is a special case for projecting from 3D charts to the two-sphere intrinsic chart, which is a common use case. The projection does not depend on the radius of the embedding, so this projection works in general.

>>> import unxt as u
>>> import coordinax.charts as cxc
>>> q = {"x": u.Q(1.0, "km"), "y": u.Q(0.0, "km"), "z": u.Q(0.0, "km")}
>>> cxc.pt_map(q, cxc.cart3d, cxc.sph2)
{'theta': Q(1.57079633, 'rad'), 'phi': Q(0., 'rad')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: AbstractChart, to_M: HyperSphericalManifold, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

Identity conversion for matching charts.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> q = {"theta": u.Q(30, "deg"), "phi": u.Q(60, "deg")}
>>> cxc.pt_map(q, cxc.sph2, cxc.sph2) is q
True
>>> q = {"lon": u.Q(45, "deg"), "lat": u.Q(10, "deg")}
>>> cxc.pt_map(q, cxc.lonlat_sph2, cxc.lonlat_sph2) is q
True
>>> q = {"lon_coslat": u.Q(30, "deg"), "lat": u.Q(20, "deg")}
>>> cxc.pt_map(q, cxc.loncoslat_sph2, cxc.loncoslat_sph2) is q
True
>>> q = {"theta": u.Q(60, "deg"), "phi": u.Q(30, "deg")}
>>> cxc.pt_map(q, cxc.math_sph2, cxc.math_sph2) is q
True
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: SphericalTwoSphere, to_M: HyperSphericalManifold, to_chart: LonLatSphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

SphericalTwoSphere -> LonLatSphericalTwoSphere.

lat = pi/2 - theta, lon = phi.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"theta": u.Q(0, "rad"), "phi": u.Q(0, "rad")}  # North pole
>>> cxc.pt_map(p, cxm.S2, cxc.sph2, cxm.S2, cxc.lonlat_sph2)
{'lon': Q(0, 'rad'), 'lat': Q(90., 'deg')}
>>> p = {"theta": u.Q(90, "deg"), "phi": u.Q(45, "deg")}  # Equator
>>> cxc.pt_map(p, cxm.S2, cxc.sph2, cxm.S2, cxc.lonlat_sph2)
{'lon': Q(45, 'deg'), 'lat': Q(0, 'deg')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: LonLatSphericalTwoSphere, to_M: HyperSphericalManifold, to_chart: SphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

LonLatSphericalTwoSphere -> SphericalTwoSphere.

theta = pi/2 - lat, phi = lon.

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"lon": u.Q(45, "deg"), "lat": u.Q(0, "deg")}
>>> cxc.pt_map(p, cxm.S2, cxc.lonlat_sph2, cxm.S2, cxc.sph2)
{'theta': Q(90, 'deg'), 'phi': Q(45, 'deg')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: SphericalTwoSphere, to_M: HyperSphericalManifold, to_chart: LonCosLatSphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

SphericalTwoSphere -> LonCosLatSphericalTwoSphere.

lat = pi/2 - theta, lon_coslat = phi * cos(lat).

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> import quaxed.numpy as jnp
>>> p = {"theta": u.Q(90, "deg"), "phi": u.Q(45, "deg")}  # equator
>>> cxc.pt_map(p, cxm.S2, cxc.sph2, cxm.S2, cxc.loncoslat_sph2)
{'lon_coslat': Q(45., 'deg'), 'lat': Q(0., 'deg')}
>>> p = {"theta": u.Q(0, "deg"), "phi": u.Q(45, "deg")}  # north pole
>>> result = cxc.pt_map(p, cxm.S2, cxc.sph2, cxm.S2, cxc.loncoslat_sph2)
>>> bool(jnp.allclose(u.ustrip("deg", result["lat"]), 90.0))
True
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: LonCosLatSphericalTwoSphere, to_M: HyperSphericalManifold, to_chart: SphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

LonCosLatSphericalTwoSphere -> SphericalTwoSphere.

theta = pi/2 - lat, phi = lon_coslat / cos(lat).

>>> import coordinax.charts as cxc
>>> import coordinax.manifolds as cxm
>>> import unxt as u
>>> p = {"lon_coslat": u.Q(45, "deg"), "lat": u.Q(0, "deg")}
>>> cxc.pt_map(p, cxm.S2, cxc.loncoslat_sph2, cxm.S2, cxc.sph2)
{'theta': Q(90., 'deg'), 'phi': Q(45., 'deg')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: SphericalTwoSphere, to_M: HyperSphericalManifold, to_chart: MathSphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

SphericalTwoSphere -> MathSphericalTwoSphere.

Swaps theta and phi (physics -> math convention).

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"theta": u.Q(30, "deg"), "phi": u.Q(60, "deg")}
>>> cxc.pt_map(p, cxm.S2, cxc.sph2, cxm.S2, cxc.math_sph2)
{'theta': Q(60, 'deg'), 'phi': Q(30, 'deg')}
coordinax.charts.pt_map(p: dict[str, Any], from_M: HyperSphericalManifold, from_chart: MathSphericalTwoSphere, to_M: HyperSphericalManifold, to_chart: SphericalTwoSphere, /, *, usys: AbstractUnitSystem | None = None) dict[str, Any]
Parameters:
Return type:

dict[str, Any]

MathSphericalTwoSphere -> SphericalTwoSphere.

Swaps theta and phi (math -> physics convention).

>>> import coordinax.manifolds as cxm
>>> import coordinax.charts as cxc
>>> import unxt as u
>>> p = {"theta": u.Q(60, "deg"), "phi": u.Q(30, "deg")}
>>> cxc.pt_map(p, cxm.S2, cxc.math_sph2, cxm.S2, cxc.sph2)
{'theta': Q(30, 'deg'), 'phi': Q(60, 'deg')}
coordinax.charts.pt_map(x: Any, from_chart: AbstractChart, from_rep: Representation, to_chart: AbstractChart, to_rep: Representation, /, usys: AbstractUnitSystem | None = None) Any
Parameters:
Return type:

dict[str, Any]

Convert point data between charts.

Convert a point from Cartesian coordinates to spherical coordinates:

>>> import coordinax.representations as cxr
>>> import coordinax.charts as cxc

Define a point in Cartesian coordinates:

>>> p = {"x": 1.0, "y": 2.0, "z": 3.0}

Convert it to spherical coordinates:

>>> q = cxc.pt_map(p, cxc.cart3d, cxr.point, cxc.sph3d, cxr.point)
>>> q
{'r': Array(3.74165739, dtype=float64, ...),
 'theta': Array(0.64052231, dtype=float64),
 'phi': Array(1.10714872, dtype=float64, ...)}

The output q represents the same geometric point but expressed in the target chart.

The representation remains unchanged; only the chart changes:

>>> cxc.pt_map(q, cxc.sph3d, cxr.point, cxc.cart3d, cxr.point)
{'x': Array(1., dtype=float64), 'y': Array(2., dtype=float64),
 'z': Array(3., dtype=float64)}

Let’s work through more examples.

Cartesian to Spherical (with units):

>>> import unxt as u
>>> p = {"x": u.Q(1.0, "m"), "y": u.Q(0.0, "m"), "z": u.Q(0.0, "m")}
>>> cxc.pt_map(p, cxc.cart3d, cxr.point, cxc.sph3d, cxr.point)
{'r': Q(1., 'm'), 'theta': Q(1.57079633, 'rad'), 'phi': Q(0., 'rad')}

Cylindrical to Cartesian (without units):

>>> p = {"rho": 3.0, "phi": 0, "z": 4.0}
>>> cxc.pt_map(p, cxc.cyl3d, cxr.point, cxc.cart3d, cxr.point)
{'x': Array(3., dtype=float64, ...), 'y': Array(0., dtype=float64, ...),
 'z': 4.0}

Polar to Cartesian (2D):

>>> p = {"r": u.Q(5.0, "m"), "theta": u.Q(90, "deg")}
>>> cxc.pt_map(p, cxc.polar2d, cxr.point, cxc.cart2d, cxr.point)
{'x': Q(3.061617e-16, 'm'), 'y': Q(5., 'm')}

Between Spherical variants (Spherical to LonLatSpherical):

>>> p = {"r": u.Q(1.0, "m"), "theta": u.Q(45, "deg"), "phi": u.Q(0, "deg")}
>>> cxc.pt_map(p, cxc.sph3d, cxr.point, cxc.lonlat_sph3d, cxr.point)
{'lon': Q(0, 'deg'), 'lat': Q(45., 'deg'), 'distance': Q(1., 'm')}

Identity conversion (same chart):

>>> p = {"x": u.Q(2.0, "m"), "y": u.Q(3.0, "m")}
>>> cxc.pt_map(p, cxc.cart2d, cxr.point, cxc.cart2d, cxr.point) is p
True
coordinax.charts.pt_map(x: Any, from_chart: AbstractChart, from_rep: Representation, to_chart: AbstractChart, /, usys: AbstractUnitSystem | None = None) Any
Parameters:
Return type:

dict[str, Any]

Convert point data between charts.

Convert a point from Cartesian coordinates to spherical coordinates:

>>> import coordinax.representations as cxr
>>> import coordinax.charts as cxc

Define a point in Cartesian coordinates:

>>> p = {"x": 1.0, "y": 2.0, "z": 3.0}

Convert it to spherical coordinates:

>>> q = cxc.pt_map(p, cxc.cart3d, cxr.point, cxc.sph3d)
>>> q
{'r': Array(3.74165739, dtype=float64, ...),
 'theta': Array(0.64052231, dtype=float64),
 'phi': Array(1.10714872, dtype=float64, ...)}

The output q represents the same geometric point but expressed in the target chart.

The representation remains unchanged; only the chart changes:

>>> cxc.pt_map(q, cxc.sph3d, cxr.point, cxc.cart3d)
{'x': Array(1., dtype=float64), 'y': Array(2., dtype=float64),
 'z': Array(3., dtype=float64)}
coordinax.charts.pt_map(x: Any, from_chart: AbstractChart, from_geom: PointGeometry, from_rep: Representation, to_chart: AbstractChart, to_geom: PointGeometry, to_rep: Representation, /, usys: AbstractUnitSystem | None = None) Any
Parameters:
Return type:

dict[str, Any]

Convert point data between charts.

Convert a point from Cartesian coordinates to spherical coordinates:

>>> import coordinax.representations as cxr
>>> import coordinax.charts as cxc

Define a point in Cartesian coordinates:

>>> p = {"x": 1.0, "y": 2.0, "z": 3.0}

Convert it to spherical coordinates:

>>> cxc.pt_map(p, cxc.cart3d, cxr.point_geom, cxr.point,
...                             cxc.sph3d, cxr.point_geom, cxr.point)
{'r': Array(3.74165739, dtype=float64, ...),
 'theta': Array(0.64052231, dtype=float64),
 'phi': Array(1.10714872, dtype=float64, ...)}
coordinax.charts.pt_map(from_vec: coordinax.vectors._src.point.Point, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) coordinax.vectors._src.point.Point
Parameters:
Return type:

dict[str, Any]

Convert a point from one chart to another.

>>> import unxt as u
>>> import coordinax.main as cx
>>> import coordinax.charts as cxc
>>> vec = cx.Point.from_([1, 1, 1], "m")
>>> print(vec)
<Point: chart=Cart3D (x, y, z) [m]
    [1 1 1]>
>>> sph_vec = cxc.pt_map(vec, cx.sph3d)
>>> print(sph_vec)
<Point: chart=Spherical3D (r[m], theta[rad], phi[rad])
    [1.732 0.955 0.785]>
coordinax.charts.pt_map(from_vec: coordinax.vectors._src.point.Point, from_chart: AbstractChart, to_chart: AbstractChart, /, *, usys: AbstractUnitSystem | None = None) coordinax.vectors._src.point.Point
Parameters:
Return type:

dict[str, Any]

Convert a vector from one chart to another.

>>> import unxt as u
>>> import coordinax.main as cx
>>> import coordinax.charts as cxc
>>> vec = cx.Point.from_([1, 1, 1], "m")
>>> sph_vec = cxc.pt_map(vec, cxc.cart3d, cx.sph3d)
>>> print(sph_vec)
<Point: chart=Spherical3D (r[m], theta[rad], phi[rad])
    [1.732 0.955 0.785]>
Parameters:
Return type:

dict[str, Any]

class coordinax.charts.Abstract0D#

Bases: AbstractDimensionalFlag

Marker flag for 0D representations.

A 0D representation has no coordinate component.

class coordinax.charts.Cart0D(*, M: MT = Rn(0))#

Bases: AbstractFixedComponentsChart[MT, tuple[()], tuple[()]], Abstract0D

Zero-dimensional Cartesian chart.

This chart has no coordinate components and no coordinate dimensions. It is the canonical Cartesian chart for 0D representations.

>>> import coordinax.charts as cxc
>>> cxc.cart0d.components
()
>>> cxc.cart0d.coord_dimensions
()
>>> isinstance(cxc.cartesian_chart(cxc.cart0d), cxc.Cart0D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(0)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Self#

Return the canonical Cartesian chart for a 0D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Cart0D().cartesian, cxc.Cart0D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Abstract1D#

Bases: AbstractDimensionalFlag

Marker flag for 1D representations.

A 1D representation has exactly one coordinate component. Examples include Cartesian $(x)$ or radial $(r)$ coordinates.

class coordinax.charts.Cart1D(*, M: MT = Rn(1))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘x’]], tuple[Literal[‘length’]]], Abstract1D

One-dimensional Cartesian chart $(x)$.

Components are ordered as ("x",) with dimension ("length",).

This chart is the canonical 1D Cartesian chart and is returned by {func}`coordinax.charts.cartesian_chart` for 1D charts.

Examples

>>> import coordinax.charts as cxc
>>> cxc.cart1d.components
('x',)
>>> cxc.cart1d.coord_dimensions
('length',)
>>> isinstance(cxc.cartesian_chart(cxc.cart1d), cxc.Cart1D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(1)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Self#

Return the canonical Cartesian chart for a 1D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Cart1D().cartesian, cxc.Cart1D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Radial1D(*, M: MT = Rn(1))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘r’]], tuple[Literal[‘length’]]], Abstract1D

One-dimensional radial chart $(r)$.

Components are ordered as ("r",) with dimension ("length",).

This chart is semantically equivalent to {class}`coordinax.charts.Cart1D` but uses r instead of x. Its canonical Cartesian projection is {obj}`coordinax.charts.cart1d`.

Examples

>>> import coordinax.charts as cxc
>>> cxc.radial1d.components
('r',)
>>> cxc.radial1d.coord_dimensions
('length',)
>>> isinstance(cxc.cartesian_chart(cxc.radial1d), cxc.Cart1D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(1)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Cart1D[MT]#

Return the canonical Cartesian chart for a 1D radial chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Radial1D().cartesian, cxc.Cart1D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Time1D(*, M: MT = Rn(1))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘t’]], tuple[Literal[‘time’]]], Abstract1D

One-dimensional time chart (t).

Components are ordered as ("t",) with dimension ("time",).

This chart is the canonical 1D time chart and is often used as the first factor in spacetime product charts.

Examples

>>> import coordinax.charts as cxc
>>> cxc.time1d.components
('t',)
>>> cxc.time1d.coord_dimensions
('time',)
>>> isinstance(cxc.cartesian_chart(cxc.time1d), cxc.Time1D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(1)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Time1D#

Return the canonical Cartesian chart for a 1D time chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Time1D().cartesian, cxc.Time1D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Abstract2D#

Bases: AbstractDimensionalFlag

Marker flag for 2D representations.

A 2D representation has exactly two coordinate components. This does not imply that the underlying manifold is flat; for example, the two-sphere uses two angular coordinates but represents a curved surface.

class coordinax.charts.Cart2D(*, M: MT = Rn(2))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘x’], Literal[‘y’]], tuple[Literal[‘length’], Literal[‘length’]]], Abstract2D

Two-dimensional Cartesian chart $(x, y)$.

Components are ordered as ("x", "y") with dimensions ("length", "length").

This chart is the canonical 2D Cartesian chart and is returned by {func}`coordinax.charts.cartesian_chart` for 2D charts.

Examples

>>> import coordinax.charts as cxc
>>> cxc.cart2d.components
('x', 'y')
>>> cxc.cart2d.coord_dimensions
('length', 'length')
>>> isinstance(cxc.cartesian_chart(cxc.cart2d), cxc.Cart2D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Self#

Return the canonical Cartesian chart for a 2D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Cart2D().cartesian, cxc.Cart2D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Polar2D(*, M: MT = Rn(2))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘r’], Literal[‘theta’]], tuple[Literal[‘length’], Literal[‘angle’]]], Abstract2D

Two-dimensional polar chart $(r, theta)$.

Components are ordered as ("r", "theta") with dimensions ("length", "angle").

This chart has direct transitions with {class}`coordinax.charts.Cart2D` and its canonical Cartesian projection is {obj}`coordinax.charts.cart2d`.

Examples

>>> import coordinax.charts as cxc
>>> cxc.polar2d.components
('r', 'theta')
>>> cxc.polar2d.coord_dimensions
('length', 'angle')
>>> isinstance(cxc.cartesian_chart(cxc.polar2d), cxc.Cart2D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Cart2D[MT]#

Return the canonical Cartesian chart for a 2D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Cart2D().cartesian, cxc.Cart2D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Abstract3D#

Bases: AbstractDimensionalFlag

Marker flag for 3D representations.

A 3D representation has exactly three coordinate components. These may parameterize Euclidean space (Cartesian), curvilinear coordinates (cylindrical, spherical), or other three-dimensional manifolds.

class coordinax.charts.Cart3D(*, M: MT = Rn(3))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘x’], Literal[‘y’], Literal[‘z’]], tuple[Literal[‘length’], Literal[‘length’], Literal[‘length’]]], Abstract3D

Three-dimensional Cartesian chart $(x, y, z)$.

Components are ordered as ("x", "y", "z") with dimensions ("length", "length", "length").

This chart is the canonical 3D Cartesian chart and is returned by {func}`coordinax.charts.cartesian_chart` for 3D charts.

Examples

>>> import coordinax.charts as cxc
>>> cxc.cart3d.components
('x', 'y', 'z')
>>> cxc.cart3d.coord_dimensions
('length', 'length', 'length')
>>> isinstance(cxc.cartesian_chart(cxc.cart3d), cxc.Cart3D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Self#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.cart3d.cartesian, cxc.Cart3D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Cylindrical3D(*, M: MT = Rn(3))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘rho’], Literal[‘phi’], Literal[‘z’]], tuple[Literal[‘length’], Literal[‘angle’], Literal[‘length’]]], Abstract3D

Three-dimensional cylindrical chart $(rho, phi, z)$.

Components are ordered as ("rho", "phi", "z") with dimensions ("length", "angle", "length").

This chart has direct transitions with {class}`coordinax.charts.Cart3D` and its canonical Cartesian projection is {obj}`coordinax.charts.cart3d`.

Examples

>>> import coordinax.charts as cxc
>>> cxc.cyl3d.components
('rho', 'phi', 'z')
>>> cxc.cyl3d.coord_dimensions
('length', 'angle', 'length')
>>> isinstance(cxc.cartesian_chart(cxc.cyl3d), cxc.Cart3D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D cylindrical chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Cylindrical3D().cartesian, cxc.Cart3D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.AbstractSpherical3D#

Bases: AbstractFixedComponentsChart[MT, Ks, Ds], Abstract3D

Abstract spherical vector representation.

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Spherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonLatSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.MathSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonCosLatSpherical3D().cartesian, cxc.Cart3D)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.Spherical3D(*, M: MT = Rn(3))#

Bases: AbstractSpherical3D[MT, tuple[Literal[‘r’], Literal[‘theta’], Literal[‘phi’]], tuple[Literal[‘length’], Literal[‘angle’], Literal[‘angle’]]]

Three-dimensional spherical coordinates $(r, theta, phi)$.

The Cartesian embedding is

$x = rsinthetacosphi,$ $y = rsinthetasinphi,$ $z = rcostheta.$

Here $r ge 0$, $theta in [0,pi]$ is the polar (colatitude) angle, and $phi$ is the azimuth.

This convention matches the physics / mathematics definition of spherical coordinates.

Examples

>>> import coordinax.charts as cxc
>>> cxc.sph3d.components
('r', 'theta', 'phi')
>>> cxc.sph3d.coord_dimensions
('length', 'angle', 'angle')
>>> isinstance(cxc.cartesian_chart(cxc.sph3d), cxc.Cart3D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Spherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonLatSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.MathSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonCosLatSpherical3D().cartesian, cxc.Cart3D)
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.LonLatSpherical3D(*, M: MT = Rn(3))#

Bases: AbstractSpherical3D[MT, tuple[Literal[‘lon’], Literal[‘lat’], Literal[‘distance’]], tuple[Literal[‘angle’], Literal[‘angle’], Literal[‘length’]]]

Longitude-latitude spherical coordinates.

Components are $(mathrm{lon}, mathrm{lat}, r)$ where:

  • lon is the azimuthal angle in the equatorial plane,

  • lat is the latitude in $[-pi/2, pi/2]$,

  • r is the radial distance.

Relation to standard spherical coordinates:

$mathrm{lat} = pi/2 - theta$, $mathrm{lon} = \phi$.

Examples

>>> import coordinax.charts as cxc
>>> cxc.lonlat_sph3d.components
('lon', 'lat', 'distance')
>>> cxc.lonlat_sph3d.coord_dimensions
('angle', 'angle', 'length')
>>> isinstance(cxc.cartesian_chart(cxc.lonlat_sph3d), cxc.Cart3D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Spherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonLatSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.MathSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonCosLatSpherical3D().cartesian, cxc.Cart3D)
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.LonCosLatSpherical3D(*, M: MT = Rn(3))#

Bases: AbstractSpherical3D[MT, tuple[Literal[‘lon_coslat’], Literal[‘lat’], Literal[‘distance’]], tuple[Literal[‘angle’], Literal[‘angle’], Literal[‘length’]]]

Longitude-cos(latitude) spherical coordinates.

Components are $(mathrm{lon}cosmathrm{lat}, mathrm{lat}, r)$. This form is sometimes used to improve numerical behavior near the poles, since $cos(mathrm{lat}) to 0$ as $|mathrm{lat}| to pi/2$.

Examples

>>> import coordinax.charts as cxc
>>> cxc.loncoslat_sph3d.components
('lon_coslat', 'lat', 'distance')
>>> cxc.loncoslat_sph3d.coord_dimensions
('angle', 'angle', 'length')
>>> isinstance(cxc.cartesian_chart(cxc.loncoslat_sph3d), cxc.Cart3D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Spherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonLatSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.MathSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonCosLatSpherical3D().cartesian, cxc.Cart3D)
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.MathSpherical3D(*, M: MT = Rn(3))#

Bases: AbstractSpherical3D[MT, tuple[Literal[‘r’], Literal[‘theta’], Literal[‘phi’]], tuple[Literal[‘length’], Literal[‘angle’], Literal[‘angle’]]]

Mathematical-convention spherical coordinates $(r, theta, phi)$.

In this convention:

  • $phi$ is the polar angle measured from the positive $z$ axis,

  • $theta$ is the azimuthal angle in the $xy$-plane.

This differs from the physics convention used by {class}`coordinax.charts.Spherical3D`, where $theta$ and $phi$ are swapped.

Examples

>>> import coordinax.charts as cxc
>>> cxc.math_sph3d.components
('r', 'theta', 'phi')
>>> cxc.math_sph3d.coord_dimensions
('length', 'angle', 'angle')
>>> isinstance(cxc.cartesian_chart(cxc.math_sph3d), cxc.Cart3D)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.Spherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonLatSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.MathSpherical3D().cartesian, cxc.Cart3D)
True
>>> isinstance(cxc.LonCosLatSpherical3D().cartesian, cxc.Cart3D)
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.ProlateSpheroidal3D(*, Delta: ]], M: MT = Rn(3))#

Bases: Abstract3D, AbstractFixedComponentsChart[MT, tuple[Literal[‘mu’], Literal[‘nu’], Literal[‘phi’]], tuple[Literal[‘area’], Literal[‘area’], Literal[‘angle’]]]

Prolate spheroidal coordinates $(mu, nu, phi)$ with focal length $Delta$.

These coordinates are adapted to systems with two foci separated by distance $2Delta$.

Validity constraints enforced by this representation:

  • $Delta > 0$,

  • $mu ge Delta^2$,

  • $|nu| le Delta^2$.

The parameter $Delta$ is stored as metadata on the representation.

Examples

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> chart = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2, "kpc"))
>>> chart.components
('mu', 'nu', 'phi')
>>> chart.coord_dimensions
('area', 'area', 'angle')
>>> isinstance(cxc.cartesian_chart(chart), cxc.Cart3D)
True
>>> d = {"mu": u.Q(4, "kpc2"), "nu": u.Q(0.1, "kpc2"), "phi": u.Q(1, "rad")}
>>> chart.check_data(d)  # doesn't raise
{'mu': Q(4, 'kpc2'), 'nu': Q(0.1, 'kpc2'), 'phi': Q(1, 'rad')}
Parameters:
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

Delta: value > 0]]#

Focal length of the coordinate system.

M: MT = Rn(3)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: Cart3D[MT]#

Return the canonical Cartesian chart for a 3D chart.

>>> import coordinax.charts as cxc
>>> import unxt as u
>>> chart = cxc.ProlateSpheroidal3D(Delta=u.StaticQuantity(2, "kpc"))
>>> isinstance(chart.cartesian, cxc.Cart3D)
True
class coordinax.charts.Abstract4D#

Bases: AbstractDimensionalFlag

Marker flag for 4-D representations.

A 4-D representation has exactly four coordinate components. The primary example is the Minkowski spacetime chart (ct, x, y, z).

class coordinax.charts.Abstract6D#

Bases: AbstractDimensionalFlag

Marker flag for 6-D representations.

An 6-D representation has an arbitrary number of coordinate components. Examples include Cartesian representations in arbitrary dimensions.

class coordinax.charts.PoincarePolar6D(*, M: AbstractManifold = NoManifold())#

Bases: AbstractFixedComponentsChart[Any, tuple[Literal[‘rho’], Literal[‘pp_phi’], Literal[‘z’], Literal[‘dt_rho’], Literal[‘dt_pp_phi’], Literal[‘dt_z’]], tuple[Literal[‘length’], Literal[‘length / time**0.5’], Literal[‘length’], Literal[‘speed’], Literal[‘length / time**1.5’], Literal[‘speed’]]], Abstract6D

Six-dimensional Poincare-polar chart.

Components are ordered as $(rho,;mathrm{pp_phi},;z,;dotrho,;dot{mathrm{pp_phi}},;dot z)$ with dimensions $(mathrm{length},;mathrm{length}/mathrm{time}^{1/2},;mathrm{length},;mathrm{speed},;mathrm{length}/mathrm{time}^{3/2},;mathrm{speed})$.

Examples

>>> import coordinax.charts as cxc
>>> cxc.poincarepolar6d.components
('rho', 'pp_phi', 'z', 'dt_rho', 'dt_pp_phi', 'dt_z')
>>> cxc.poincarepolar6d.coord_dimensions
('length', 'length / time**0.5', 'length', 'speed', 'length / time**1.5', 'speed')
>>> isinstance(cxc.poincarepolar6d, cxc.PoincarePolar6D)
True
Parameters:

M (AbstractManifold)

M: AbstractManifold = NoManifold()#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: NoReturn#

PoincarePolar6D has no global Cartesian 6D representation.

check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.AbstractND#

Bases: AbstractDimensionalFlag

Marker flag for N-D representations.

An N-D representation has an arbitrary number of coordinate components. Examples include Cartesian representations in arbitrary dimensions.

M: AbstractManifold = NoManifold()#
class coordinax.charts.CartND(*, M: MT = Rn(True))#

Bases: AbstractFixedComponentsChart[MT, tuple[Literal[‘q’]], tuple[Literal[‘length’]]], AbstractND

N-dimensional Cartesian chart.

Components are ordered as ("q",) with dimension ("length",), where q stores the N Cartesian components as a single length-valued array.

This chart is the canonical Cartesian chart for arbitrary dimension.

Examples

>>> import coordinax.charts as cxc
>>> cxc.cartnd.components
('q',)
>>> cxc.cartnd.coord_dimensions
('length',)
>>> isinstance(cxc.cartesian_chart(cxc.cartnd), cxc.CartND)
True
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = Rn(True)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: Self#

Return the canonical Cartesian chart for an N-D chart.

>>> import coordinax.charts as cxc
>>> isinstance(cxc.CartND().cartesian, cxc.CartND)
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.AbstractSphericalHyperSphere#

Bases: AbstractFixedComponentsChart[MT, Ks, Ds]

Abstract base class for intrinsic charts on the unit hypersphere.

All hypersphere charts represent coordinates on the surface of a unit hypersphere. There is no global Cartesian representation for these charts; they live on a curved manifold.

Concrete subclasses define specific coordinate systems:

  • Physics convention: polar (colatitude) and azimuthal angles

  • Longitude-latitude: geographic-style coordinates

  • Mathematics convention: azimuthal and polar angles (swapped)

Notes

  • The intrinsic geometry is non-Euclidean (curved).

  • To embed in 3D Euclidean space, use an EmbeddedChart.

  • cartesian_chart(...) raises NoGlobalCartesianChartError for all 2-sphere charts.

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

M: MT#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

class coordinax.charts.AbstractSphericalOneSphere#

Bases: AbstractSphericalHyperSphere[MT, Ks, Ds], Abstract1D

Abstract base class for intrinsic charts on the unit circle.

All circle charts represent coordinates on the surface of a unit circle. There is no global Cartesian 1D representation for these charts; they live on a curved 1D manifold.

Notes

  • The intrinsic geometry is non-Euclidean (curved).

  • To embed in higher Euclidean spaces, use an EmbeddedManifold.

  • cartesian_chart(...) raises NoGlobalCartesianChartError for all circle charts.

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

M: MT#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

class coordinax.charts.CircularOneSphere(*, M: MT = HyperSphericalManifold(ndim=1))#

Bases: AbstractSphericalOneSphere[MT, tuple[Literal[‘phi’]], tuple[Literal[‘angle’]]]

Standard circular coordinates on the unit circle.

Parameters:
  • phi – Angular coordinate with angular units.

  • M (MT)

Notes

  • CircularOneSphere is a curved 1D manifold; there is no global Cartesian 1D chart. cartesian_chart(CircularOneSphere) raises.

Examples

>>> import coordinax.charts as cxc
>>> cxc.sph1.components
('phi',)
>>> cxc.sph1.coord_dimensions
('angle',)
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = HyperSphericalManifold(ndim=1)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.AbstractSphericalTwoSphere(*, M: MT = HyperSphericalManifold(ndim=2))#

Bases: AbstractSphericalHyperSphere[MT, Ks, Ds], Abstract2D

Abstract base class for intrinsic charts on the unit two-sphere.

All 2-sphere charts represent coordinates on the surface of a unit sphere. There is no global Cartesian 2D representation for these charts; they live on a curved 2D manifold.

Concrete subclasses define specific coordinate systems:

  • Physics convention: polar (colatitude) and azimuthal angles

  • Longitude-latitude: geographic-style coordinates

  • Mathematics convention: azimuthal and polar angles (swapped)

Notes

  • The intrinsic geometry is non-Euclidean (curved).

  • To embed in 3D Euclidean space, use an EmbeddedManifold.

  • cartesian_chart(...) raises NoGlobalCartesianChartError for all 2-sphere charts.

Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = HyperSphericalManifold(ndim=2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.SphericalTwoSphere(*, M: MT = HyperSphericalManifold(ndim=2))#

Bases: AbstractSphericalTwoSphere[MT, tuple[Literal[‘theta’], Literal[‘phi’]], tuple[Literal[‘angle’], Literal[‘angle’]]]

Intrinsic chart on the unit two-sphere with components (theta, phi).

Uses the physics convention: $theta in [0,pi]$ is the polar (colatitude) angle measured from the positive $z$-axis, and $phi in (-pi,pi]$ is the azimuthal angle.

Parameters:
  • theta – Polar (colatitude) angle with angular units.

  • phi – Azimuthal angle with angular units.

  • M (MT)

Notes

  • SphericalTwoSphere is a curved 2D manifold; there is no global Cartesian 2D chart. cartesian_chart(SphericalTwoSphere) raises.

  • The intrinsic metric is diag(1, sin^2 theta).

  • The longitude is undefined at the poles theta=0,pi.

Examples

>>> import coordinax.charts as cxc
>>> cxc.sph2.components
('theta', 'phi')
>>> cxc.sph2.coord_dimensions
('angle', 'angle')
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = HyperSphericalManifold(ndim=2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.LonLatSphericalTwoSphere(*, M: MT = HyperSphericalManifold(ndim=2))#

Bases: AbstractSphericalTwoSphere[MT, tuple[Literal[‘lon’], Literal[‘lat’]], tuple[Literal[‘angle’], Literal[‘angle’]]]

Longitude-latitude chart on the two-sphere.

Components are $(mathrm{lon},;mathrm{lat})$ where:

  • lon is the azimuthal angle (longitude),

  • lat $in [-pi/2,;pi/2]$ is the latitude.

Relation to {class}`SphericalTwoSphere`:

$mathrm{lat} = pi/2 - theta$, $mathrm{lon} = phi$.

Examples

>>> import coordinax.charts as cxc
>>> cxc.lonlat_sph2.components
('lon', 'lat')
>>> cxc.lonlat_sph2.coord_dimensions
('angle', 'angle')
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = HyperSphericalManifold(ndim=2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.LonCosLatSphericalTwoSphere(*, M: MT = HyperSphericalManifold(ndim=2))#

Bases: AbstractSphericalTwoSphere[MT, tuple[Literal[‘lon_coslat’], Literal[‘lat’]], tuple[Literal[‘angle’], Literal[‘angle’]]]

Longitude-cos(latitude) chart on the two-sphere.

Components are $(mathrm{lon}cosmathrm{lat},;mathrm{lat})$.

This form can improve numerical behavior near the poles because $cos(mathrm{lat}) to 0$ as $|mathrm{lat}| to pi/2$.

Examples

>>> import coordinax.charts as cxc
>>> cxc.loncoslat_sph2.components
('lon_coslat', 'lat')
>>> cxc.loncoslat_sph2.coord_dimensions
('angle', 'angle')
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

M: MT = HyperSphericalManifold(ndim=2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

class coordinax.charts.MathSphericalTwoSphere(*, M: MT = HyperSphericalManifold(ndim=2))#

Bases: AbstractSphericalTwoSphere[MT, tuple[Literal[‘theta’], Literal[‘phi’]], tuple[Literal[‘angle’], Literal[‘angle’]]]

Math-convention chart on the two-sphere.

Components are $(theta, phi)$ where, contrary to the physics convention used in {class}`SphericalTwoSphere`:

  • $theta$ is the azimuthal angle,

  • $phi in [0, pi]$ is the polar angle.

The conversion from {class}`SphericalTwoSphere` simply swaps the two angles.

Examples

>>> import coordinax.charts as cxc
>>> cxc.math_sph2.components
('theta', 'phi')
>>> cxc.math_sph2.coord_dimensions
('angle', 'angle')
Parameters:

M (TypeVar(MT, bound= AbstractManifold))

property cartesian: NoReturn#

Raise NoGlobalCartesianChartError for any 2-sphere chart.

2-sphere charts have no global Cartesian 2D representation.

Examples

>>> import coordinax.charts as cxc
>>> try:
...     cxc.sph2.cartesian
... except Exception as exc:
...     print(type(exc).__name__)
...     print("no global Cartesian representation" in str(exc))
NoGlobalCartesianChartError
True
property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).

M: MT = HyperSphericalManifold(ndim=2)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

check_data(data: CDictT, /, *, values: bool = False, **kw: Any)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

  • kw (Any)

Return type:

TypeVar(CDictT, bound= dict[str, Any])

class coordinax.charts.AbstractCartesianProductChart#

Bases: AbstractChart[CartesianProductManifold, Ks, Ds]

Abstract base class for Cartesian product charts.

A Cartesian product chart is defined by a finite ordered tuple of factor charts. The product chart’s components are the concatenation of factor components, and transformations follow factorwise laws.

Mathematical definition:

M = ∏ᵢ Mᵢ (product manifold) TₚM ≅ ⊕ᵢ T_{pᵢ}Mᵢ (tangent bundle splits)

Component key convention (normative):
  • General product charts use dot-delimited string keys: "factor_name.c" where factor_name identifies the factor and c is the factor’s component key.

  • Specialized products (i.e. AbstractFlatCartesianProductChart subclasses) may expose flat string keys as a documented exception when component names are guaranteed collision-free.

Normative requirements: - factors is an ordered tuple of charts - factor_names is always a tuple of unique strings with length matching factors - ndim must equal sum(f.ndim for f in factors) - components must follow the key convention above

factors: tuple[AbstractChart[Any, Any, Any], ...]#

Ordered tuple of factor charts.

factor_names: tuple[str, ...]#

Factor names for namespaced keys. Must be unique and aligned with factors.

property ndims: tuple[int, ...]#

sum of factor dimensions.

Type:

Total dimension

split_components(p: dict[str, Any], /)#

Partition a CDict by factor components.

For namespaced products: select keys "name_i.c" and strip prefix to yield factor dict keyed by c.

Parameters:

p (dict[str, Any]) – Point dictionary with keys matching this chart’s components.

Returns:

Tuple of dictionaries, one per factor, with factor-native keys.

Return type:

tuple[dict[str, Any], ...]

merge_components(parts: tuple[Mapping[str, V], ...], /)#

Merge factor CDicts into a single CDict.

For namespaced products: re-attach dot-delimited prefix "name_i.c" for each factor key.

Parameters:

parts (tuple[Mapping[str, TypeVar(V)], ...]) – Tuple of dictionaries, one per factor, with factor-native keys.

Returns:

Merged dictionary in this chart’s component order.

Return type:

dict[str, TypeVar(V)]

property M: CartesianProductManifold#

Return the product manifold of the factor charts’ manifolds.

Examples

>>> import coordinax.charts as cxc
>>> chart = cxc.CartesianProductChart((cxc.cart3d, cxc.cart3d), ("q", "p"))
>>> chart.M
CartesianProductManifold(factors=(Rn(3), Rn(3)), factor_names=('q', 'p'))
property components: Ks#

dot-delimited strings "factor_name.component".

Components are dot-delimited string keys to avoid collisions:

(f”{name_0}.{c}” for c in factors[0].components, …)

Type:

Component keys

property coord_dimensions: Ds#

Concatenation of factor coordinate dimensions.

property ndim: int#

sum of factor dimensions.

Type:

Total dimension

abstract property cartesian: AbstractChart[MT, Ks, Ds]#

Return the corresponding Cartesian chart.

check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

class coordinax.charts.AbstractFlatCartesianProductChart#

Bases: AbstractCartesianProductChart[Ks, Ds]

Abstract base class for flat-key Cartesian product charts.

A flat-key Cartesian product chart is a specialization of {class}`AbstractCartesianProductChart` where the component keys are guaranteed to be collision-free across factors, allowing the use of flat string keys instead of dot-delimited string keys.

Subclasses must provide factor_names and ensure that factor components do not collide.

Normative requirements: - factor_names must be provided (abstract property) - components is the direct concatenation of factor components

(must be collision-free)

abstract property factor_names: tuple[str, ...]#

Factor names for flat-key Cartesian product charts.

Subclasses must provide factor names even though components are flat.

split_components(p: dict[str, Any], /)#

Partition a CDict by factor components.

For flat-key products: partition by factor.components directly.

Parameters:

p (dict[str, Any]) – Point dictionary with keys matching this chart’s components.

Returns:

Tuple of dictionaries, one per factor, with factor-native keys.

Return type:

tuple[dict[str, Any], ...]

merge_components(parts: tuple[Mapping[str, V], ...])#

Merge factor CDicts into a single CDict.

For flat-key products: merge as-is (keys already match components).

Parameters:

parts (tuple[Mapping[str, TypeVar(V)], ...]) – Tuple of dictionaries, one per factor, with factor-native keys.

Returns:

Merged dictionary in this chart’s component order.

Return type:

dict[str, TypeVar(V)]

property components: Ks#

flat strings (collision-free concatenation of factors).

Components are the direct concatenation of factor component strings (must be collision-free).

Type:

Component keys

property M: CartesianProductManifold#

Return the product manifold of the factor charts’ manifolds.

Examples

>>> import coordinax.charts as cxc
>>> chart = cxc.CartesianProductChart((cxc.cart3d, cxc.cart3d), ("q", "p"))
>>> chart.M
CartesianProductManifold(factors=(Rn(3), Rn(3)), factor_names=('q', 'p'))
abstract property cartesian: AbstractChart[MT, Ks, Ds]#

Return the corresponding Cartesian chart.

check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property coord_dimensions: Ds#

Concatenation of factor coordinate dimensions.

property ndim: int#

sum of factor dimensions.

Type:

Total dimension

property ndims: tuple[int, ...]#

sum of factor dimensions.

Type:

Total dimension

factors: tuple[AbstractChart[Any, Any, Any], ...]#

Ordered tuple of factor charts.

final class coordinax.charts.CartesianProductChart(factors: tuple[AbstractChart[Any, Any, Any], ...], factor_names: tuple[str, ...])#

Bases: AbstractCartesianProductChart[Ks, Ds]

Concrete Cartesian product chart with dot-delimited component keys.

Constructs a product chart from a tuple of factor charts and factor names. Components are dot-delimited string keys "factor_name.component_name" to avoid collisions (e.g., phase space with repeated Cart3D factors).

Parameters:

Examples

>>> import coordinax.charts as cxc
>>> chart = cxc.CartesianProductChart((cxc.cart3d, cxc.cart3d), ("q", "p"))
>>> chart.components
('q.x', 'q.y', 'q.z', 'p.x', 'p.y', 'p.z')
>>> chart.ndim
6
>>> chart["p"]
Cart3D(M=Rn(3))
>>> chart.M
CartesianProductManifold(factors=(Rn(3), Rn(3)), factor_names=('q', 'p'))
factors: tuple[AbstractChart[Any, Any, Any], ...]#

Ordered tuple of factor charts.

factor_names: tuple[str, ...]#

Factor names for namespaced keys. Must be unique and aligned with factors.

property M: CartesianProductManifold#

Return the product manifold of the factor charts’ manifolds.

Examples

>>> import coordinax.charts as cxc
>>> chart = cxc.CartesianProductChart((cxc.cart3d, cxc.cart3d), ("q", "p"))
>>> chart.M
CartesianProductManifold(factors=(Rn(3), Rn(3)), factor_names=('q', 'p'))
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

dot-delimited strings "factor_name.component".

Components are dot-delimited string keys to avoid collisions:

(f”{name_0}.{c}” for c in factors[0].components, …)

Type:

Component keys

property coord_dimensions: Ds#

Concatenation of factor coordinate dimensions.

merge_components(parts: tuple[Mapping[str, V], ...], /)#

Merge factor CDicts into a single CDict.

For namespaced products: re-attach dot-delimited prefix "name_i.c" for each factor key.

Parameters:

parts (tuple[Mapping[str, TypeVar(V)], ...]) – Tuple of dictionaries, one per factor, with factor-native keys.

Returns:

Merged dictionary in this chart’s component order.

Return type:

dict[str, TypeVar(V)]

property ndim: int#

sum of factor dimensions.

Type:

Total dimension

property ndims: tuple[int, ...]#

sum of factor dimensions.

Type:

Total dimension

split_components(p: dict[str, Any], /)#

Partition a CDict by factor components.

For namespaced products: select keys "name_i.c" and strip prefix to yield factor dict keyed by c.

Parameters:

p (dict[str, Any]) – Point dictionary with keys matching this chart’s components.

Returns:

Tuple of dictionaries, one per factor, with factor-native keys.

Return type:

tuple[dict[str, Any], ...]

property cartesian: CartesianProductChart#

Get Cartesian version of a namespaced product chart (factorwise).

Returns a CartesianProductChart with each factor replaced by its cartesian_chart version, preserving factor_names.

Examples

>>> import coordinax.charts as cxc
>>> product = cxc.CartesianProductChart((cxc.sph3d, cxc.sph3d), ("q", "p"))
>>> cart_product = cxc.cartesian_chart(product)
>>> cart_product
CartesianProductChart(
    factors=(Cart3D(M=Rn(3)), Cart3D(M=Rn(3))), factor_names=('q', 'p')
)
final class coordinax.charts.GalileanCT(spatial_chart: ~coordinax._src.base.charts.AbstractFixedComponentsChart[~typing.Any, ~typing.Any, ~typing.Any] = Cart3D(M=Rn(3)), *, c: ~jaxtyping.Float[StaticQuantity[PhysicalType({'speed', 'velocity'})], ''] = StaticQuantity(f64[](numpy), 'km / s'))#

Bases: AbstractFlatCartesianProductChart[Ks, Ds]

4D spacetime rep with components (ct, x, y, z) and Minkowski metric.

This is a Cartesian product chart: GalileanCT(spatial_chart) ≡ time1d x spatial_chart

The time component is always the canonical 1D time chart time1d with component “t”. The time coordinate is automatically converted to ct using the speed of light.

Mathematical definition: $$

x^0 = ct,quad x^i = text{spatial components} \ g = mathrm{diag}(-1, 1, 1, 1) quad text{(signature } - + + +)

$$

Parameters:
  • spatial_chart (AbstractFixedComponentsChart[Any, Any, Any]) – Spatial position rep supplying component names and dimensions.

  • c (Float[StaticQuantity[PhysicalType({'speed', 'velocity'})], '']) – Speed of light used to form ct from t (defaults to Quantity(299_792.458, "km/s")).

Returns:

Representation with components ("ct", *spatial_chart.components) and dimensions ("length", *spatial_chart.coord_dimensions).

Return type:

Rep

Notes

  • The first factor is always time1d; the time chart is not user-selectable.

Examples

>>> import unxt as u
>>> import coordinax.charts as cxc
>>> cxc.GalileanCT()
GalileanCT()
>>> cxc.GalileanCT(cxc.sph3d)
GalileanCT(spatial_chart=Spherical3D(M=Rn(3)))
spatial_chart: AbstractFixedComponentsChart[Any, Any, Any] = Cart3D(M=Rn(3))#

coordinax.charts.cart3d.

Type:

Spatial part of the representation. Defaults

c: Float[StaticQuantity[PhysicalType({'speed', 'velocity'})], ''] = StaticQuantity(f64[](numpy), 'km / s')#

Speed of light, by default Quantity(299_792.458, "km/s").

property M: AbstractManifold#

The manifold this chart belongs to, derived from the spatial chart.

property time_chart: AbstractChart[Any, Any, Any]#

Time factor chart (always time1d).

property factors: tuple[AbstractChart[Any, Any, Any], ...]#

Return (time1d, spatial_chart) as required by product chart spec.

property factor_names: tuple[str, ...]#

Factor names are (‘time’, ‘space’).

split_components(p: dict[str, Any])#

Split CDict by factors, keeping ‘ct’ for time factor.

GalileanCT uses ‘ct’ for the time component. The split returns factor dicts with their native keys (‘ct’ for time, spatial keys for space).

Parameters:

p (dict[str, Any])

Return type:

tuple[dict[str, Any], dict[str, Any]]

merge_components(parts: tuple[dict[str, Any], dict[str, Any]], /)#

Merge factor CDicts back into GalileanCT components.

Expects time factor dict with ‘ct’ key, spatial factor dict with spatial keys.

Parameters:

parts (tuple[dict[str, Any], dict[str, Any]])

Return type:

dict[str, Any]

check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

flat strings (collision-free concatenation of factors).

Components are the direct concatenation of factor component strings (must be collision-free).

Type:

Component keys

property ndim: int#

sum of factor dimensions.

Type:

Total dimension

property ndims: tuple[int, ...]#

sum of factor dimensions.

Type:

Total dimension

property coord_dimensions: Ds#

Concatenation of factor coordinate dimensions.

property cartesian: GalileanCT[Any, Any]#

Get a Cartesian-chart version of the given spacetime chart.

Examples

>>> import coordinax.charts as cxc
>>> rep = cxc.GalileanCT(cxc.sph3d)
>>> rep
GalileanCT(spatial_chart=Spherical3D(M=Rn(3)))
>>> rep.cartesian  # default is Cart3D
GalileanCT(spatial_chart=Cart3D(M=Rn(3)))
final class coordinax.charts.MinkowskiCT(*, M: MinkowskiManifold = MinkowskiManifold(ndim=4))#

Bases: Abstract4D, AbstractFixedComponentsChart[MinkowskiManifold, tuple[Literal[‘ct’], Literal[‘x’], Literal[‘y’], Literal[‘z’]], tuple[Literal[‘length’], Literal[‘length’], Literal[‘length’], Literal[‘length’]]]

4D Minkowski spacetime chart $(ct, x, y, z)$.

A single flat chart with the conventional 3+1 split: one time-like coordinate $ct$ (speed-of-light times coordinate time, carrying units of length) and three spatial coordinates $x$, $y$, $z$.

All four components carry dimension "length", so the metric $eta = operatorname{diag}(-1, 1, 1, 1)$ is dimensionless.

Parameters:

M (MinkowskiManifold) – The manifold this chart belongs to. Defaults to a fresh MinkowskiManifold instance.

Examples

>>> import coordinax.charts as cxc
>>> cxc.MinkowskiCT()
MinkowskiCT(M=MinkowskiManifold(ndim=4))
>>> cxc.minkowskict.components
('ct', 'x', 'y', 'z')
>>> cxc.minkowskict.coord_dimensions
('length', 'length', 'length', 'length')
>>> cxc.minkowskict.ndim
4
M: MinkowskiManifold = MinkowskiManifold(ndim=4)#

The manifold that this chart belongs to.

Default is no_manifold for charts that do not belong to any manifold.

property cartesian: MinkowskiCT#

Return self — MinkowskiCT is already the Cartesian chart.

Examples

>>> import coordinax.charts as cxc
>>> cxc.minkowskict.cartesian is cxc.minkowskict
True
check_data(data: CDictT, /, *, keys: bool = True, values: bool = False)#

Check that the data is compatible with the chart.

Parameters:
  • data (TypeVar(CDictT, bound= dict[str, Any])) – The data to check.

  • keys (bool) – Whether to check that the keys of data match chart.components. If False, this check is skipped. Default is True.

  • values (bool) – Whether to check that the dimensions of the values in data match chart.coord_dimensions. If False, this check is skipped. Default is False.

Return type:

TypeVar(CDictT, bound= dict[str, Any])

property components: Ks#

The names of the components.

property coord_dimensions: Ds#

The dimensions of the components.

property ndim: int#

Number of coordinate components (chart dimension).