mangadap.util.geometry module
Provides a set of utility functions dealing with computational geometry.
Copyright © 2019, SDSS-IV/MaNGA Pipeline Group
- 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 ofcartesian()
andpolar()
, 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.
- mangadap.util.geometry.point_inside_polygon(polygon, point)[source]
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
- mangadap.util.geometry.polygon_area(x, y)[source]
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
- mangadap.util.geometry.polygon_winding_number(polygon, point)[source]
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.
- mangadap.util.geometry.projected_polar(x, y, pa, inc)[source]
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
- mangadap.util.geometry.rotate(x, y, rot, clockwise=False)[source]
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 ifrot
cannot be broadcast to matchx
andy
or the rotation will be different for eachx
andy
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