Source code for skypy.position._uniform

'''Implementations of uniform distributions.'''

import numpy as np
from astropy import units
from astropy.coordinates import SkyCoord

TWO_PI = 2*np.pi


[docs]@units.quantity_input(area=units.sr) def uniform_around(centre, area, size): '''Uniform distribution of points around location. Draws randomly distributed points from a circular region of the given area around the centre point. Parameters ---------- centre : `~astropy.coordinates.SkyCoord` Centre of the sampling region. area : `~astropy.units.Quantity` Area of the sampling region as a `~astropy.units.Quantity` in units of solid angle. size : int Number of points to draw. Returns ------- coords : `~astropy.coordinates.SkyCoord` Randomly distributed points around the centre. The coordinates are returned in the same frame as the input. Examples -------- See :ref:`User Documentation <skypy.position.uniform_around>`. ''' # get cosine of maximum separation from area cos_theta_max = 1 - area.to_value(units.sr)/TWO_PI # randomly sample points within separation theta = np.arccos(np.random.uniform(cos_theta_max, 1, size=size)) phi = np.random.uniform(0, TWO_PI, size=size) # construct random sky coordinates around centre return centre.directional_offset_by(phi, theta)
[docs]def uniform_in_pixel(nside, ipix, size, nest=False): '''Uniform distribution of points over healpix pixel. Draws randomly distributed points from the healpix pixel `ipix` for a map with a given `nside` parameter. Parameters ---------- nside : int Healpix map `nside` parameter. ipix : int Healpix map pixel index. size : int Number of points to draw. nest : bool, optional If True assume ``NESTED`` pixel ordering, otherwise ``RING`` pixel ordering. Default is ``RING`` pixel ordering. Returns ------- coords : `~astropy.coordinates.SkyCoord` Randomly distributed points over the healpix pixel. Warnings -------- This function requires the ``healpy`` package. Examples -------- See :ref:`User Documentation <skypy.position.uniform_in_pixel>`. ''' from healpy import pix2ang, max_pixrad, nside2pixarea, ang2pix # get the centre of the healpix pixel as a SkyCoord centre_lon, centre_lat = pix2ang(nside, ipix, nest=nest, lonlat=True) centre = SkyCoord(centre_lon, centre_lat, unit=units.deg) # get the maximum radius of a healpix pixel in radian r = max_pixrad(nside) # use that radius as the aperture of a spherical area in steradian area = TWO_PI*(1 - np.cos(r))*units.sr # oversampling factor = 1/(probability of the draw) over = area.value/nside2pixarea(nside) # the array of longitudes and latitudes of the sample lon, lat = np.empty(0), np.empty(0) # rejection sampling over irregularly shaped healpix pixels miss = size while miss > 0: # get the coordinates in a circular aperture around centre sample = uniform_around(centre, area, int(np.ceil(miss*over))) # get longitude and latitude of the sample sample_lon, sample_lat = sample.ra.deg, sample.dec.deg # accept those positions that are inside the correct pixel accept = ipix == ang2pix(nside, sample_lon, sample_lat, nest=nest, lonlat=True) # store the new positions lon = np.append(lon, np.extract(accept, sample_lon)) lat = np.append(lat, np.extract(accept, sample_lat)) miss = size - len(lon) # construct the coordinates return SkyCoord(lon[:size], lat[:size], unit=units.deg)