Source code for lvmsurveysim.utils.spherical

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# @Author: José Sánchez-Gallego (gallegoj@uw.edu)
# @Date: 2017-10-20
# @Filename: spherical.py
# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause)
#
# @Last modified by: José Sánchez-Gallego (gallegoj@uw.edu)
# @Last modified time: 2019-09-25 15:43:16

import numpy

__all__ = ['great_circle_distance', 'ellipse_bbox', 'get_lst', 'get_altitude']


[docs]def great_circle_distance(ra0, dec0, ra1, dec1): """Returns the great angle distance between two points. Parameters ---------- ra0,dec0 : float or ~numpy.ndarray The RA and Dec coordinates of the first point. In degrees. ra1,dec1 : float or ~numpy.ndarray The RA and Dec coordinates of the first point. In degrees. Returns ------- separation : `float` or `~numpy.ndarray` The separation between the two sets of coordinates, in degrees. """ val = (numpy.cos(numpy.deg2rad(dec0)) * numpy.cos(numpy.deg2rad(dec1)) * numpy.cos(numpy.deg2rad(ra1 - ra0)) + numpy.sin(numpy.deg2rad(dec0)) * numpy.sin(numpy.deg2rad(dec1))) val[val > 1] = 1.0 return numpy.rad2deg(numpy.arccos(val))
[docs]def ellipse_bbox(ra, dec, a, b, pa, padding=0): """Returns the bounding box in RA and Dec for a rotated ellipse. All parameters must be float numbers in degrees. See `~lvmsurveysim.target.region.EllipticalRegion` for details. """ pa_rad = numpy.deg2rad(pa) a_x = a * numpy.sin(pa_rad) a_y = a * numpy.cos(pa_rad) b_x = b * numpy.cos(pa_rad) b_y = b * numpy.sin(pa_rad) ra_delta = numpy.sqrt(a_x**2 + b_x**2) / numpy.cos(numpy.deg2rad(dec)) dec_delta = numpy.sqrt(a_y**2 + b_y**2) return (numpy.array([ra - ra_delta - padding, ra + ra_delta + padding]), numpy.array([dec - dec_delta - padding, dec + dec_delta + padding]))
[docs]def get_lst(jd, lon): """Returns the approximate Local Median Sidereal Time. Parameters ---------- jd : float or ~numpy.ndarray The Julian Date or an array of dates. lon : float The longitude of the location. Returns ------- lmst : `float` or `~numpy.ndarray` The Local Median Sideral Time in hours. Same shape as the input ``jd``. """ dd = jd - 2451545.0 lmst = ((280.46061837 + 360.98564736629 * dd + # 0.000388 * (dd / 36525.)**2 + # 0.1s / century, can be neglected here lon) % 360) / 15. return lmst
[docs]def get_altitude(ra, dec, jd=None, lst=None, lon=None, lat=None, airmass=False): r"""Returns the altitude of an object from its equatorial coordinates in degrees. Parameters ---------- ra : float or ~numpy.ndarray The Right Ascension of the object(s) in degrees. ra : float or ~numpy.ndarray The declination of the object(s) in degrees. jd : float or ~numpy.ndarray The Julian Date or an array of dates. The local sidereal time will be calculated from these dates using the longitude. lst : float or ~numpy.ndarray The local sidereal time, in hours. Overrides ``jd``. lon : float The longitude of the location. lat : float The latitude of the location. airmass : bool If `True`, returns the airmass (:math:`\sec z`) instead of the altitude. Returns ------- altitude : `float` or `~numpy.ndarray` The altitude of the object at the given time. Returns the airmass if ``airmass=True``. """ ra = numpy.atleast_1d(ra) dec = numpy.atleast_1d(dec) assert len(ra) == len(dec), 'ra and dec must have the same length.' if jd is not None: assert lst is None, 'cannot set jd and lst at the same time.' jd = numpy.atleast_1d(jd) lst = get_lst(jd, lon) if len(lst) == 1: lst = numpy.repeat(lst, len(ra)) elif len(lst) != len(ra): raise ValueError('jd does not have the same length as the coordinates.') ha = (lst * 15. - ra) % 360. sin_alt = (numpy.sin(numpy.radians(dec)) * numpy.sin(numpy.radians(lat)) + numpy.cos(numpy.radians(dec)) * numpy.cos(numpy.radians(lat)) * numpy.cos(numpy.radians(ha))) alt = numpy.rad2deg(numpy.arcsin(sin_alt)) if airmass: return 1 / numpy.cos(numpy.radians(90 - alt)) return alt