Coverage for python/lsst/faro/utils/coord_util.py : 27%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import numpy as np
3import lsst.geom as geom
5__all__ = (
6 "averageRaFromCat",
7 "averageDecFromCat",
8 "averageRaDecFromCat",
9 "averageRaDec",
10 "sphDist",
11)
14def averageRaFromCat(cat):
15 """Compute the average right ascension from a catalog of measurements.
16 This function is used as an aggregate function to extract just RA
17 from a lsst.afw.table.MultiMatch final match catalog.
18 The actual computation involves both RA and Dec.
19 The intent is to use this for a set of measurements of the same source
20 but that's neither enforced nor required.
21 Parameters
22 ----------
23 cat : collection
24 Object with .get method for 'coord_ra', 'coord_dec' that returns radians.
25 Returns
26 -------
27 ra_mean : `float`
28 Mean RA in radians.
29 """
30 meanRa, meanDec = averageRaDecFromCat(cat)
31 return meanRa
34def averageDecFromCat(cat):
35 """Compute the average declination from a catalog of measurements.
36 This function is used as an aggregate function to extract just declination
37 from a lsst.afw.table.MultiMatch final match catalog.
38 The actual computation involves both RA and Dec.
39 The intent is to use this for a set of measurements of the same source
40 but that's neither enforced nor required.
41 Parameters
42 ----------
43 cat : collection
44 Object with .get method for 'coord_ra', 'coord_dec' that returns radians.
45 Returns
46 -------
47 dec_mean : `float`
48 Mean Dec in radians.
49 """
50 meanRa, meanDec = averageRaDecFromCat(cat)
51 return meanDec
54def averageRaDecFromCat(cat):
55 """Calculate the average right ascension and declination from a catalog.
56 Convenience wrapper around averageRaDec
57 Parameters
58 ----------
59 cat : collection
60 Object with .get method for 'coord_ra', 'coord_dec' that returns radians.
61 Returns
62 -------
63 ra_mean : `float`
64 Mean RA in radians.
65 dec_mean : `float`
66 Mean Dec in radians.
67 """
68 return averageRaDec(cat.get("coord_ra"), cat.get("coord_dec"))
71def averageRaDec(ra, dec):
72 """Calculate average RA, Dec from input lists using spherical geometry.
73 Parameters
74 ----------
75 ra : `list` [`float`]
76 RA in [radians]
77 dec : `list` [`float`]
78 Dec in [radians]
79 Returns
80 -------
81 float, float
82 meanRa, meanDec -- Tuple of average RA, Dec [radians]
83 """
84 assert len(ra) == len(dec)
86 angleRa = [geom.Angle(r, geom.radians) for r in ra]
87 angleDec = [geom.Angle(d, geom.radians) for d in dec]
88 coords = [
89 geom.SpherePoint(ar, ad, geom.radians) for (ar, ad) in zip(angleRa, angleDec)
90 ]
92 meanRa, meanDec = geom.averageSpherePoint(coords)
94 return meanRa.asRadians(), meanDec.asRadians()
97def sphDist(ra_mean, dec_mean, ra, dec):
98 """Calculate distance on the surface of a unit sphere.
99 Parameters
100 ----------
101 ra_mean : `float`
102 Mean RA in radians.
103 dec_mean : `float`
104 Mean Dec in radians.
105 ra : `numpy.array` [`float`]
106 Array of RA in radians.
107 dec : `numpy.array` [`float`]
108 Array of Dec in radians.
109 Notes
110 -----
111 Uses the Haversine formula to preserve accuracy at small angles.
112 Law of cosines approach doesn't work well for the typically very small
113 differences that we're looking at here.
114 """
115 # Haversine
116 dra = ra - ra_mean
117 ddec = dec - dec_mean
118 a = np.square(np.sin(ddec / 2)) + np.cos(dec_mean) * np.cos(dec) * np.square(
119 np.sin(dra / 2)
120 )
121 dist = 2 * np.arcsin(np.sqrt(a))
123 # This is what the law of cosines would look like
124 # dist = np.arccos(np.sin(dec1)*np.sin(dec2) + np.cos(dec1)*np.cos(dec2)*np.cos(ra1 - ra2))
126 # This will also work, but must run separately for each element
127 # whereas the numpy version will run on either scalars or arrays:
128 # sp1 = geom.SpherePoint(ra1, dec1, geom.radians)
129 # sp2 = geom.SpherePoint(ra2, dec2, geom.radians)
130 # return sp1.separation(sp2).asRadians()
132 return dist