LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
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)