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 

2from lsst.sims.utils import cartesianFromSpherical 

3from lsst.sims.utils import sphericalFromCartesian 

4from lsst.sims.utils import rotationMatrixFromVectors 

5 

6__all__ = ["_FieldRotator"] 

7 

8class _FieldRotator(object): 

9 

10 def __init__(self, ra0, dec0, ra1, dec1): 

11 """ 

12 Parameters 

13 ---------- 

14 ra0, dec0 are the coordinates of the original field 

15 center in radians 

16 

17 ra1, dec1 are the coordinates of the new field center 

18 in radians 

19 

20 The transform() method of this class operates by first 

21 applying a rotation that carries the original field center 

22 into the new field center. Points are then transformed into 

23 a basis in which the unit vector defining the new field center 

24 is the x-axis. A rotation about the x-axis is applied so that 

25 a point that was due north of the original field center is still 

26 due north of the field center at the new location. Finally, 

27 points are transformed back into the original x,y,z bases. 

28 """ 

29 

30 self._ra0 = ra0 

31 self._dec0 = dec0 

32 self._ra1 = ra1 

33 self._dec1 = dec1 

34 

35 # find the rotation that carries the original field center 

36 # to the new field center 

37 xyz = cartesianFromSpherical(ra0, dec0) 

38 xyz1 = cartesianFromSpherical(ra1, dec1) 

39 if np.abs(1.0-np.dot(xyz, xyz1))<1.0e-10: 

40 self._transformation = np.identity(3, dtype=float) 

41 return 

42 

43 first_rotation = rotationMatrixFromVectors(xyz, xyz1) 

44 

45 # create a basis set in which the unit vector 

46 # defining the new field center is the x axis 

47 xx = np.dot(first_rotation, xyz) 

48 rng = np.random.RandomState(99) 

49 mag = np.NaN 

50 while np.abs(mag)<1.0e-20 or np.isnan(mag): 

51 random_vec = rng.random_sample(3) 

52 comp = np.dot(random_vec, xx) 

53 yy = random_vec - comp*xx 

54 mag = np.sqrt((yy**2).sum()) 

55 yy /= mag 

56 

57 zz = np.cross(xx, yy) 

58 

59 to_self_bases = np.array([xx, 

60 yy, 

61 zz]) 

62 

63 out_of_self_bases =to_self_bases.transpose() 

64 

65 # Take a point due north of the original field 

66 # center. Apply first_rotation to carry it to 

67 # the new field. Transform it to the [xx, yy, zz] 

68 # bases and find the rotation about xx that will 

69 # make it due north of the new field center. 

70 # Finally, transform back to the original bases. 

71 d_dec = np.radians(0.1) 

72 north = cartesianFromSpherical(ra0,dec0+d_dec) 

73 

74 north = np.dot(first_rotation, north) 

75 

76 #print(np.degrees(sphericalFromCartesian(north))) 

77 

78 north_true = cartesianFromSpherical(ra1, dec1+d_dec) 

79 

80 north = np.dot(to_self_bases, north) 

81 north_true = np.dot(to_self_bases, north_true) 

82 north = np.array([north[1], north[2]]) 

83 north /= np.sqrt((north**2).sum()) 

84 north_true = np.array([north_true[1], north_true[2]]) 

85 north_true /= np.sqrt((north_true**2).sum()) 

86 

87 c = north_true[0]*north[0]+north_true[1]*north[1] 

88 s = north[0]*north_true[1]-north[1]*north_true[0] 

89 norm = np.sqrt(c*c+s*s) 

90 c = c/norm 

91 s = s/norm 

92 

93 nprime = np.array([c*north[0]-s*north[1], 

94 s*north[0]+c*north[1]]) 

95 

96 yz_rotation = np.array([[1.0, 0.0, 0.0], 

97 [0.0, c, -s], 

98 [0.0, s, c]]) 

99 

100 second_rotation = np.dot(out_of_self_bases, 

101 np.dot(yz_rotation, 

102 to_self_bases)) 

103 

104 self._transformation = np.dot(second_rotation, 

105 first_rotation) 

106 

107 def transform(self, ra, dec): 

108 """ 

109 ra, dec are in radians; return the RA, Dec coordinates 

110 of the point about the new field center 

111 """ 

112 xyz = cartesianFromSpherical(ra, dec).transpose() 

113 xyz = np.dot(self._transformation, xyz).transpose() 

114 ra_out, dec_out = sphericalFromCartesian(xyz) 

115 return ra_out, dec_out