LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
associationUtils.py
Go to the documentation of this file.
1 # This file is part of pipe_tasks.
2 
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 #
22 
23 """Utilities for interfacing with healpy. Originally implemented in
24 http://github.com/LSSTDESC/dia_pipe
25 """
26 
27 import healpy as hp
28 import numpy as np
29 
30 
31 def toIndex(nside, ra, dec):
32  """Return healpix index given ra, dec in degrees
33 
34  Parameters
35  ----------
36  nside : `int`
37  Power of 2 nside healpix resolution.
38  ra : `float`
39  RA in degrees.
40  dec : `float`
41  Declination in degrees
42 
43  Returns
44  -------
45  index : `int`
46  Unique healpix pixel ID containing point RA, DEC at resolution nside.
47  """
48  return hp.pixelfunc.ang2pix(nside, np.radians(-dec + 90), np.radians(ra))
49 
50 
51 def toRaDec(nside, index):
52  """Convert from healpix index to ra,dec in degrees
53 
54  Parameters
55  ----------
56  nside : `int`
57  Resolution of healpixel "grid".
58  index : `int`
59  Index of the healpix pixel we want to find the location of.
60 
61  Returns
62  -------
63  pos : `numpy.ndarray`, (2,)
64  RA and DEC of healpix pixel location in degrees.
65  """
66  vec = hp.pix2ang(nside, index)
67  dec = np.rad2deg(-vec[0]) + 90
68  ra = np.rad2deg(vec[1])
69  return np.dstack((ra, dec))[0]
70 
71 
72 def eq2xyz(ra, dec):
73  """Convert from equatorial ra,dec in degrees to x,y,z on unit sphere.
74 
75  Parameters
76  ----------
77  ra : `float`
78  RA in degrees.
79  dec : `float`
80  Declination in degrees
81 
82  Returns
83  -------
84  xyz : `numpy.ndarray`, (3,)
85  Float xyz positions on the unit sphere.
86  """
87  phi = np.deg2rad(ra)
88  theta = np.pi/2 - np.deg2rad(dec)
89  sintheta = np.sin(theta)
90  x = sintheta*np.cos(phi)
91  y = sintheta*np.sin(phi)
92  z = np.cos(theta)
93  return np.array([x, y, z])
94 
95 
96 def eq2xyzVec(ra, dec):
97  """Convert equatorial ra,dec in degrees to x,y,z on the unit sphere
98  parameters
99 
100  Vectorized version of ``eq2xyz``
101 
102  Parameters
103  ----------
104  ra : array_like, (N,)
105  Array of RA in degrees.
106  dec : array_like, (N,)
107  Declination in degrees
108 
109  Returns
110  -------
111  vec : `numpy.ndarray`, (N,3)
112  Array of unitsphere 3-vectors.
113  """
114  ra = np.array(ra, dtype='f8', ndmin=1, copy=False)
115  dec = np.array(dec, dtype='f8', ndmin=1, copy=False)
116  if ra.size != dec.size:
117  raise ValueError("ra,dec not same size: %s,%s" % (ra.size, dec.size))
118 
119  vec = eq2xyz(ra, dec)
120 
121  return vec
122 
123 
124 def convert_spherical(ra, dec):
125  """Convert from ra,dec to spherical coordinates.
126 
127  Used in query_disc.
128 
129  Parameters
130  ----------
131  ra : `float`
132  RA in radians.
133  dec : `float`
134  Declination in radians
135  """
136  return np.dstack([np.cos(dec*np.pi/180)*np.cos(ra*np.pi/180),
137  np.cos(dec*np.pi/180)*np.sin(ra*np.pi/180),
138  np.sin(dec*np.pi/180)])[0]
139 
140 
142  """Convert from and a array ra,dec to spherical coordinates.
143 
144  Used in query_disc
145 
146  Parameters
147  ----------
148  array : `numpy.ndarray`, (N, 2)
149  (N, 2) Array of RA, DEC values.
150 
151  Returns
152  -------
153  vecs : `numpy.ndarray`, (N, 3)
154  Vectors on the unit sphere
155  """
156  ra = array[:, 0]
157  dec = array[:, 1]
158  return convert_spherical(ra, dec)
159 
160 
161 def query_disc(nside, ra, dec, max_rad, min_rad=0):
162  """Get the list of healpix indices within max_rad, min_rad given in radians
163  around ra,dec given in degrees
164 
165  Parameters
166  ----------
167  nside : `int`
168  Resolution of the healpixels to search/return.
169  ra : `float`
170  RA in degrees.
171  dec : `float`
172  Declination in degrees
173  max_rad : `float`
174  Max distance in radians to search nearby healpixels.
175  min_rad : `float`, optional
176  Minimum distance in radians to search healpixels. Default = 0.
177  """
178  if np.isscalar(ra):
179  ra = np.array([ra])
180  dec = np.array([dec])
181 
182  pixels = np.unique(
183  [hp.query_disc(nside, eq2xyzVec(a, b), max_rad)
184  for (a, b) in zip(ra, dec)])
185 
186  if min_rad > 0 and len(pixels) > 0:
187  vec0 = convert_spherical(ra, dec)
188  min_rad2 = min_rad**2
189  vecs = convert_spherical_array(toRaDec(nside, pixels))
190  dsq = np.sum((vecs - vec0)**2, axis=1)
191  match = dsq > min_rad2
192  pixels = pixels[match]
193 
194  return pixels
def query_disc(nside, ra, dec, max_rad, min_rad=0)