Provides a set of utility functions dealing with computational geometry. class mangadap.util.geometry.SemiMajorAxisCoo(xc=None, yc=None, rot=None, pa=None, ell=None)[source]

Bases: object

Calculate the semi-major axis coordinates given a set of input parameters following $${\mathbf x} = {\mathbf A}^{-1}\ {\mathbf b}$$, where

\begin{align}\begin{aligned}\begin{split}{\mathbf A} = \left[ \begin{array}{rrrrrr} 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ \cos\psi & \sin\psi & -1 & 0 & 0 & 0 \\ -\sin\psi & \cos\psi & 0 & -1 & 0 & 0 \\ 0 & 0 & \sin\phi_0 & \cos\phi_0 & -1 & 0 \\ 0 & 0 & -\cos\phi_0 & \sin\phi_0 & 0 & \varepsilon-1 \end{array} \right]\end{split}\\\begin{split}{\mathbf b} = \left[ \begin{array}{r} x_f \\ y_f \\ -x_0 \\ -y_0 \\ 0 \\ 0 \end{array} \right]\end{split}\end{aligned}\end{align}

such that

$\begin{split}{\mathbf x} = \left[ \begin{array}{r} x_f \\ y_f \\ x_s \\ y_s \\ x_a \\ y_a \end{array} \right]\end{split}$
and:
• $$\psi$$ is the Cartesian rotation of the focal-plane relative to the sky-plane (+x toward East; +y toward North),

• $$\phi_0$$ is the on-sky position angle of the major axis of the ellipse, defined as the angle from North through East

• $$\varepsilon=1-b/a$$ is the ellipticity based on the the semi-minor to semi-major axis ratio ($$b/a$$).

• $$(x_f,y_f)$$ is the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

• $$(x_s,y_s)$$ is the on-sky position of $$(x_f,y_f)$$ relative to the center of the ellipse, and

• $$(x_a,y_a)$$ is the Cartesian position of $$(x_f,y_f)$$ in units of the semi-major axis.

This form is used such that $${\mathbf A}$$ need only be defined once per class instance.

The class also allows for inverse calculations, i.e., calculating the focal-plane positions provide the semi-major axis coordinates. In this case,

\begin{align}\begin{aligned}\begin{split}{\mathbf C} = \left[ \begin{array}{rrrr} \cos\psi & \sin\psi & -1 & 0 \\ -\sin\psi & \cos\psi & 0 & -1 \\ 0 & 0 & \sin\phi_0 & \cos\phi_0 \\ 0 & 0 & -\cos\phi_0 & \sin\phi_0 \end{array} \right]\end{split}\\\begin{split}{\mathbf d} = \left[ \begin{array}{r} -x_0 \\ -y_0 \\ x_a \\ y_a (1-\varepsilon) \end{array} \right]\end{split}\end{aligned}\end{align}

such that

$\begin{split}{\mathbf f} = \left[ \begin{array}{r} x_f \\ y_f \\ x_s \\ y_s \end{array} \right]\end{split}$

and $${\mathbf f} = {\mathbf C}^{-1}\ {\mathbf d}$$.

Parameters:
• xc (float) – Same as $$x_0$$, defined above

• yc (float) – Same as $$y_0$$, defined above

• rot (float) – Same as $$\psi$$, defined above

• pa (float) – Same as $$\phi_0$$, defined above

• ell (float) – Same as $$\varepsilon$$, defined above

xc,yc

a reference on-sky position relative to the center of the ellipse (galaxy center); same as $$(x_0,y_0)$$ defined above

Type:

float,float

rot

Cartesian rotation of the focal-plane relative to the sky-plane (+x toward East; +y toward North); same as $$\psi$$ defined above

Type:

float

pa

On-sky position angle of the major axis of the ellipse, defined as the angle from North through East and is the same as $$\phi_0$$ defined above

Type:

float

ell

Ellipticity define as $$\varepsilon=1-b/a$$, based on the semi-minor to semi-major axis ratio ($$b/a$$) of the ellipse.

Type:

float

A

The coordinate transformation matrix

Type:

numpy.ndarray

Alu

The lu array returned by scipy.linalg.lu_factor, which is used to calculate the LU decomposition of $${\mathbf A}$$

Type:

numpy.ndarray

Apiv

The piv array returned by scipy.linalg.lu_factor, which is used to calculate the LU decomposition of $${\mathbf A}$$

Type:

numpy.ndarray

B

The vector $${\mathbf b}$$, as defined above, used to calculate $${\mathbf x} = {\mathbf A}^{-1}\ {\mathbf b}$$

Type:

numpy.ndarray

C

The coordinate transformation matrix use for the inverse operations

Type:

numpy.ndarray

Clu

The lu array returned by scipy.linalg.lu_factor, which is used to calculate the LU decomposition of $${\mathbf C}$$

Type:

numpy.ndarray

Cpiv

The piv array returned by scipy.linalg.lu_factor, which is used to calculate the LU decomposition of $${\mathbf C}$$

Type:

numpy.ndarray

D

The vector $${\mathbf d}$$, as defined above, used to calculate $${\mathbf f} = {\mathbf C}^{-1}\ {\mathbf d}$$

Type:

numpy.ndarray

_calculate_cartesian(r, theta)[source]

Invert the calculation of the semi-major-axis polar coordinates to calculate the semi-major-axis Cartesian coordinates $$(x_a,y_a)$$ using

$\begin{split}x_a &= \pm R / \sqrt{1 + \tan^2\theta}\\ y_a &= -x_a\ \tan\theta\end{split}$

where $$x_a$$ is negative when $$\pi/2 \leq \theta < 3\pi/2$$.

Parameters:
• r (array-like) – The semi-major-axis polar coordinates $$(R,\theta)$$.

• theta (array-like) – The semi-major-axis polar coordinates $$(R,\theta)$$.

Returns:

The semi-major-axis Cartesian coordinates: $$x_a, y_a$$.

Return type:

numpy.ndarray

_calculate_polar(x, y)[source]

Calculate the polar coordinates (radius and azimuth) provided the Cartesian semi-major-axis coordinates $$(x_a,y_a)$$ using

$\begin{split}R &= \sqrt{x_a^2 + y_a^2} \\ \theta &= \tan^{-1}\left(\frac{-y_a}{x_a}\right)\end{split}$
Parameters:
• x (array-like) – The semi-major-axis Cartesian coordinates $$(x_a,y_a)$$.

• y (array-like) – The semi-major-axis Cartesian coordinates $$(x_a,y_a)$$.

Returns:

The semi-major-axis polar coordinates: $$R, \theta$$.

Return type:

numpy.ndarray

_defined()[source]

Determine if the object is defined such that its methods can be used to convert between coordinate systems.

_setA()[source]

Set the transformation matrix and calculate its LU decomposition for forward operations.

_setB(x, y)[source]

Set the on-sky coordinate vector for forward operations.

Parameters:
• x (float) – Single values for use in calculating the semi-major-axis coordinates.

• y (float) – Single values for use in calculating the semi-major-axis coordinates.

_setC()[source]

Set the transformation matrix and calculate its LU decomposition for inverse operations.

_setD(x, y)[source]

Set the semi-major-axis coordinate vector for inverse operations.

Parameters:
• x (float) – Single values for use in calculating the on-sky focal plane coordinates.

• y (float) – Single values for use in calculating the on-sky focal plane coordinates.

cartesian(x, y)[source]

Calculate $${\mathbf x}$$ using solve() for the provided $$(x_f,y_f)$$ and return the semi-major-axis Cartesian and coordinates, $$(x_a,y_a)$$.

Parameters:
• x (array-like) – The coordinate $$(x_f,y_f)$$, which is the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

• y (array-like) – The coordinate $$(x_f,y_f)$$, which is the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

Returns:

Two arrays with the semi-major-axis Cartesian coordinates, $$x_a, y_a$$.

Return type:

numpy.ndarray

cartesian_invert(x, y)[source]

Calculate $${\mathbf f}$$ using solve() for the provided $$(x_a,y_a)$$ and return focal-plane cartesian coordinates $$(x_f,y_f)$$.

Parameters:
• x (array-like) – The semi-major-axis Cartesian coordinates $$(x_a,y_a)$$.

• y (array-like) – The semi-major-axis Cartesian coordinates $$(x_a,y_a)$$.

Returns:

The focal-plane Cartesian coordinates $$(x_f,y_f)$$.

Return type:

numpy.ndarray

coo(x, y)[source]

Calculate $${\mathbf x}$$ using solve() for the provided $$(x_f,y_f)$$ and return the semi-major-axis Cartesian and polar coordinates, $$(x_a,y_a)$$ and $$(R,\theta)$$. This combines the functionality of cartesian() and polar(), and so is more efficient than using these both separately.

Parameters:
• x (array-like) – The coordinates $$(x_f,y_f)$$, which are the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

• y (array-like) – The coordinates $$(x_f,y_f)$$, which are the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

Returns:

Four arrays with the semi-major-axis Cartesian and polar coordinates: $$x_a, y_a, R, \theta$$.

Return type:

numpy.ndarray

polar(x, y)[source]

Calculate $${\mathbf x}$$ using solve() for the provided $$(x_f,y_f)$$ and return the semi-major-axis polar coordinates, $$(R,\theta)$$, where

$\begin{split}R &= \sqrt{x_a^2 + y_a^2} \\ \theta &= \tan^{-1}\left(\frac{-y_a}{x_a}\right)\end{split}$
Parameters:
• x (array-like) – The coordinate $$(x_f,y_f)$$, which is the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

• y (array-like) – The coordinate $$(x_f,y_f)$$, which is the sky-right, focal-plane position relative to a reference on-sky position $$(x_0,y_0)$$ relative to the center of the ellipse (galaxy center),

Returns:

Two arrays with the semi-major-axis polar coordinates: $$R, \theta$$.

Return type:

numpy.ndarray

polar_invert(r, theta)[source]

Calculate $${\mathbf f}$$ using solve() for the provided $$(R,\theta)$$ and return focal-plane cartesian coordinates $$(x_f,y_f)$$.

Parameters:
• r (array-like) – The semi-major-axis polar coordinates $$(R,\theta)$$.

• theta (array-like) – The semi-major-axis polar coordinates $$(R,\theta)$$.

Returns:

Two arrays with the focal-plane Cartesian coordinates $$(x_f,y_f)$$.

Return type:

numpy.ndarray

solve(x, y)[source]

Use scipy.linalg.lu_solve to solve $${\mathbf x} = {\mathbf A}^{-1}\ {\mathbf b}$$.

Parameters:
• x (array-like) – The coordinates $$(x_f,y_f)$$, which are the sky-right, focal-plane Cartesian coordinates relative to a reference on-sky position $$(x_0,y_0)$$, which is relative to the center of the ellipse (galaxy center).

• y (array-like) – The coordinates $$(x_f,y_f)$$, which are the sky-right, focal-plane Cartesian coordinates relative to a reference on-sky position $$(x_0,y_0)$$, which is relative to the center of the ellipse (galaxy center).

Returns:

The $${\mathbf x}$$ vectors (separated by rows) as defined by the solution to $${\mathbf A}^{-1}\ {\mathbf b}$$

Return type:

numpy.ndarray

Raises:

ValueError – Raised if object was not properly defined or if the X and Y arrays do not have the same size.

solve_inverse(x, y)[source]

Use scipy.linalg.lu_solve to solve $${\mathbf f} = {\mathbf C}^{-1}\ {\mathbf d}$$.

Parameters:
• x (array-like) – The semi-major-axis Cartesian coordinates $$(x_a,y_a)$$.

• y (array-like) – The semi-major-axis Cartesian coordinates $$(x_a,y_a)$$.

Returns:

The $${\mathbf f}$$ vector as defined by the solution to $${\mathbf C}^{-1}\ {\mathbf d}$$

Return type:

numpy.ndarray

Raises:

ValueError – Raised if object was not properly defined or if the X and Y arrays do not have the same size.

Determine if one or more points is inside the provided polygon.

Primarily a wrapper for polygon_winding_number(), that returns True for each poing that is inside the polygon.

Parameters:
• polygon (numpy.ndarray) – An Nx2 array containing the x,y coordinates of a polygon. The points should be ordered either counter-clockwise or clockwise.

• point (numpy.ndarray) – One or more points for the winding number calculation. Must be either a 2-element array for a single (x,y) pair, or an Nx2 array with N (x,y) points.

Returns:

Boolean indicating whether or not each point is within the polygon.

Return type:

bool or numpy.ndarray

Compute the area of a polygon using the Shoelace formula.

Inspired by this discussion.

Parameters:
• x (numpy.ndarray) – Vector with the Cartesian x-coordinates of the polygon vertices.

• y (numpy.ndarray) – Vector with the Cartesian y-coordinates of the polygon vertices.

Returns:

Polygon area

Return type:

float

Determine the winding number of a 2D polygon about a point. The code does not check if the polygon is simple (no interesecting line segments). Algorithm taken from Numerical Recipies Section 21.4.

Parameters:
• polygon (numpy.ndarray) – An Nx2 array containing the x,y coordinates of a polygon. The points should be ordered either counter-clockwise or clockwise.

• point (numpy.ndarray) – One or more points for the winding number calculation. Must be either a 2-element array for a single (x,y) pair, or an Nx2 array with N (x,y) points.

Returns:

The winding number of each point with respect to the provided polygon. Points inside the polygon have winding numbers of 1 or -1; see point_inside_polygon().

Return type:

int or numpy.ndarray

Raises:

ValueError – Raised if polygon is not 2D, if polygon does not have two columns, or if the last axis of point does not have 2 and only 2 elements.

Calculate the in-plane polar coordinates of an inclined plane.

The position angle, $$\phi_0$$, is the rotation from the $$y=0$$ axis through the $$x=0$$ axis. I.e., $$\phi_0 = \pi/2$$ is along the $$+x$$ axis and $$\phi_0 = \pi$$ is along the $$-y$$ axis.

The inclination, $$i$$, is the angle of the plane normal with respect to the line-of-sight. I.e., $$i=0$$ is a face-on (top-down) view of the plane and $$i=\pi/2$$ is an edge-on view.

The returned coordinates are the projected distance from the $$(x,y) = (0,0)$$ and the project azimuth. The projected azimuth, $$\theta$$, is defined to increase in the same direction as $$\phi_0$$, with $$\theta = 0$$ at $$\phi_0$$.

Warning

Calculation of the disk-plane y coordinate is undefined at $$i = \pi/2$$. Only use this function with $$i < \pi/2$$!

Parameters:
• x (array-like) – Cartesian x coordinates.

• y (array-like) – Cartesian y coordinates. Shape must match x, but this is not checked.

• pa (float) – Position angle, as defined above, in radians.

• inc (float) – Inclination, as defined above, in radians.

Returns:

Returns two arrays with the projected radius and in-plane azimuth. The radius units are identical to the provided cartesian coordinates. The azimuth is in radians over the range $$[0,2\pi)$$.

Return type:

tuple

Rotate a set of coordinates about $$(x,y) = (0,0)$$.

Warning

The rot argument should be a float. If it is an array, the code will either fault if rot cannot be broadcast to match x and y or the rotation will be different for each x and y element.

Parameters:
• x (array-like) – Cartesian x coordinates.

• y (array-like) – Cartesian y coordinates. Shape must match x, but this is not checked.

• rot (float) – Rotation angle in radians.

• clockwise (bool, optional) –

Perform a clockwise rotation. Rotation is counter-clockwise by default. By definition and implementation, setting this to True is identical to calling the function with a negative counter-clockwise rotation. I.e.:

xr, yr = rotate(x, y, rot, clockwise=True)
_xr, _yr = rotate(x, y, -rot)
assert numpy.array_equal(xr, _xr) and numpy.array_equal(yr, _yr)


Returns:

Two numpy.ndarray objects with the rotated x and y coordinates.

Return type:

tuple