Hide keyboard shortcuts

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 

2 

3import lsst.geom as geom 

4 

5__all__ = ( 

6 "averageRaFromCat", 

7 "averageDecFromCat", 

8 "averageRaDecFromCat", 

9 "averageRaDec", 

10 "sphDist", 

11) 

12 

13 

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 

32 

33 

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 

52 

53 

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")) 

69 

70 

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) 

85 

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 ] 

91 

92 meanRa, meanDec = geom.averageSpherePoint(coords) 

93 

94 return meanRa.asRadians(), meanDec.asRadians() 

95 

96 

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)) 

122 

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)) 

125 

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() 

131 

132 return dist