Source code for lenstronomy.GalKin.aperture_types

__author__ = "sibirrer"

import numpy as np

from lenstronomy.Util.package_util import exporter

export, __all__ = exporter()


[docs] @export class Slit(object): """Slit aperture description."""
[docs] def __init__(self, length, width, center_ra=0, center_dec=0, angle=0): """ :param length: length of slit :param width: width of slit :param center_ra: center of slit :param center_dec: center of slit :param angle: orientation angle of slit, angle=0 corresponds length in RA direction """ self._length = length self._width = width self._center_ra, self._center_dec = center_ra, center_dec self._angle = angle
[docs] def aperture_select(self, ra, dec): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :return: bool, True if photon/ray is within the slit, False otherwise """ return ( slit_select( ra, dec, self._length, self._width, self._center_ra, self._center_dec, self._angle, ), 0, )
@property def num_segments(self): """Number of segments with separate measurements of the velocity dispersion. :return: int """ return 1
[docs] @export def slit_select(ra, dec, length, width, center_ra=0, center_dec=0, angle=0): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :param length: length of slit :param width: width of slit :param center_ra: center of slit :param center_dec: center of slit :param angle: orientation angle of slit, angle=0 corresponds length in RA direction :return: bool, True if photon/ray is within the slit, False otherwise """ ra_ = ra - center_ra dec_ = dec - center_dec x = np.cos(angle) * ra_ + np.sin(angle) * dec_ y = -np.sin(angle) * ra_ + np.cos(angle) * dec_ if abs(x) < length / 2.0 and abs(y) < width / 2.0: return True else: return False
[docs] @export class Frame(object): """Rectangular box with a hole in the middle (also rectangular), effectively a frame."""
[docs] def __init__(self, width_outer, width_inner, center_ra=0, center_dec=0, angle=0): """ :param width_outer: width of box to the outer parts :param width_inner: width of inner removed box :param center_ra: center of slit :param center_dec: center of slit :param angle: orientation angle of slit, angle=0 corresponds length in RA direction """ self._width_outer = width_outer self._width_inner = width_inner self._center_ra, self._center_dec = center_ra, center_dec self._angle = angle
[docs] def aperture_select(self, ra, dec): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :return: bool, True if photon/ray is within the slit, False otherwise """ return ( frame_select( ra, dec, self._width_outer, self._width_inner, self._center_ra, self._center_dec, self._angle, ), 0, )
@property def num_segments(self): """Number of segments with separate measurements of the velocity dispersion. :return: int """ return 1
[docs] @export def frame_select(ra, dec, width_outer, width_inner, center_ra=0, center_dec=0, angle=0): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :param width_outer: width of box to the outer parts :param width_inner: width of inner removed box :param center_ra: center of slit :param center_dec: center of slit :param angle: orientation angle of slit, angle=0 corresponds length in RA direction :return: bool, True if photon/ray is within the box with a hole, False otherwise """ ra_ = ra - center_ra dec_ = dec - center_dec x = np.cos(angle) * ra_ + np.sin(angle) * dec_ y = -np.sin(angle) * ra_ + np.cos(angle) * dec_ if abs(x) < width_outer / 2.0 and abs(y) < width_outer / 2.0: if abs(x) < width_inner / 2.0 and abs(y) < width_inner / 2.0: return False else: return True return False
[docs] @export class Shell(object): """Shell aperture."""
[docs] def __init__(self, r_in, r_out, center_ra=0, center_dec=0): """ :param r_in: innermost radius to be selected :param r_out: outermost radius to be selected :param center_ra: center of the sphere :param center_dec: center of the sphere """ self._r_in, self._r_out = r_in, r_out self._center_ra, self._center_dec = center_ra, center_dec
[docs] def aperture_select(self, ra, dec): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :return: bool, True if photon/ray is within the slit, False otherwise """ return ( shell_select( ra, dec, self._r_in, self._r_out, self._center_ra, self._center_dec ), 0, )
@property def num_segments(self): """Number of segments with separate measurements of the velocity dispersion. :return: int """ return 1
[docs] @export def shell_select(ra, dec, r_in, r_out, center_ra=0, center_dec=0): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :param r_in: innermost radius to be selected :param r_out: outermost radius to be selected :param center_ra: center of the sphere :param center_dec: center of the sphere :return: boolean, True if within the radial range, False otherwise """ x = ra - center_ra y = dec - center_dec r = np.sqrt(x**2 + y**2) if (r >= r_in) and (r < r_out): return True else: return False
[docs] @export class IFUShells(object): """Class for an Integral Field Unit spectrograph with azimuthal shells where the kinematics are measured."""
[docs] def __init__(self, r_bins, center_ra=0, center_dec=0): """ :param r_bins: array of radial bins to average the dispersion spectra in ascending order. It starts with the innermost edge to the outermost edge. :param center_ra: center of the sphere :param center_dec: center of the sphere """ self._r_bins = r_bins self._center_ra, self._center_dec = center_ra, center_dec
[docs] def aperture_select(self, ra, dec): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :return: bool, True if photon/ray is within the slit, False otherwise, index of shell """ return shell_ifu_select( ra, dec, self._r_bins, self._center_ra, self._center_dec )
@property def num_segments(self): """Number of segments with separate measurements of the velocity dispersion :return: int.""" return len(self._r_bins) - 1
[docs] @export class IFUGrid(object): """Class for an Integral Field Unit spectrograph with rectangular grid where the kinematics are measured."""
[docs] def __init__(self, x_grid, y_grid): """ :param x_grid: x coordinates of the grid :param y_grid: y coordinates of the grid """ self._x_grid = x_grid self._y_grid = y_grid
[docs] def aperture_select(self, ra, dec): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :return: bool, True if photon/ray is within the slit, False otherwise, index of shell """ return grid_ifu_select(ra, dec, self._x_grid, self._y_grid)
@property def num_segments(self): """Number of segments with separate measurements of the velocity dispersion. :return: int """ return self._x_grid.shape[0], self._x_grid.shape[1] @property def x_grid(self): """X coordinates of the grid.""" return self._x_grid @property def y_grid(self): """Y coordinates of the grid.""" return self._y_grid
[docs] @export def grid_ifu_select(ra, dec, x_grid, y_grid): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :param x_grid: array of x_grid bins :param y_grid: array of y_grid bins :return: boolean, True if within the grid range, False otherwise """ x_pixel_size = x_grid[0, 1] - x_grid[0, 0] y_pixel_size = y_grid[1, 0] - y_grid[0, 0] for i in range(x_grid.shape[0]): for j in range(x_grid.shape[1]): x_down = x_grid[i, j] - x_pixel_size / 2 x_up = x_grid[i, j] + x_pixel_size / 2 y_down = y_grid[i, j] - y_pixel_size / 2 y_up = y_grid[i, j] + y_pixel_size / 2 if (x_down <= ra <= x_up) and (y_down <= dec <= y_up): return True, (i, j) return False, None
[docs] @export def shell_ifu_select(ra, dec, r_bin, center_ra=0, center_dec=0): """ :param ra: angular coordinate of photon/ray :param dec: angular coordinate of photon/ray :param r_bin: array of radial bins to average the dispersion spectra in ascending order. It starts with the inner-most edge to the outermost edge. :param center_ra: center of the sphere :param center_dec: center of the sphere :return: boolean, True if within the radial range, False otherwise """ x = ra - center_ra y = dec - center_dec r = np.sqrt(x**2 + y**2) for i in range(0, len(r_bin) - 1): if (r >= r_bin[i]) and (r < r_bin[i + 1]): return True, i return False, None