Coverage for python/lsst/sims/utils/WcsUtils.py : 11%

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
1from __future__ import division
2from builtins import zip
3import numpy as np
4import numbers
5from lsst.sims.utils import _observedFromICRS, _icrsFromObserved
7__all__ = ["_nativeLonLatFromPointing", "_lonLatFromNativeLonLat",
8 "_nativeLonLatFromRaDec", "_raDecFromNativeLonLat",
9 "nativeLonLatFromRaDec", "raDecFromNativeLonLat"]
12def _nativeLonLatFromPointing(lon, lat, lonPointing, latPointing):
13 """
14 Convert the longitude and latitude of a point into `native'
15 longitude and latitude defined by a telescope pointing.
17 Native longitude and latitude are defined as what longitude and latitude would be
18 if the pole were at the location where the telescope is pointing.
19 The transformation is achieved by rotating the vector pointing to the lon
20 and lat being transformed once about the x axis and once about the z axis.
21 These are the Euler rotations referred to in Section 2.3 of
23 Calabretta and Greisen (2002), A&A 395, p. 1077
25 Note: This method does not assume anything about the input coordinate
26 system. It merely takes a longitude-like coordinate, a latitude-like coordinate
27 and a longitude-like coordinate of the pointing and a latitude-like coordinate
28 of the pointing and transforms them using spherical geometry.
30 @param [in] a longitude-like coordinate in radians
32 @param [in] a latitude-like coordinate in radians
34 @param [in] a longitude-like coordinate of the telescope pointing in radians
36 @param [in] a latitude-like coordinate of the telescope pointing in radians
38 @param [out] the native longitude of the transformed point(s) in radians
40 @param [out] the native latitude of the transformed point(s) in radians
41 """
43 x = -1.0 * np.cos(lat) * np.sin(lon)
44 y = np.cos(lat) * np.cos(lon)
45 z = np.sin(lat)
47 alpha = latPointing - 0.5 * np.pi
48 beta = lonPointing
50 ca = np.cos(alpha)
51 sa = np.sin(alpha)
52 cb = np.cos(beta)
53 sb = np.sin(beta)
55 v2 = np.dot(np.array([[1.0, 0.0, 0.0], [0.0, ca, sa], [0.0, -1.0 * sa, ca]]),
56 np.dot(np.array([[cb, sb, 0.0], [-sb, cb, 0.0], [0.0, 0.0, 1.0]]), np.array([x, y, z])))
58 cc = np.sqrt(v2[0] * v2[0] + v2[1] * v2[1])
59 latOut = np.arctan2(v2[2], cc)
61 _y = v2[1] / np.cos(latOut)
62 _ra_raw = np.arccos(_y)
64 # control for _y=1.0, -1.0 but actually being stored as just outside
65 # the bounds of -1.0<=_y<=1.0 because of floating point error
66 if hasattr(_ra_raw, '__len__'):
67 _ra = np.array([rr
68 if not np.isnan(rr)
69 else 0.5 * np.pi * (1.0 - np.sign(yy))
70 for rr, yy in zip(_ra_raw, _y)])
71 else:
72 if np.isnan(_ra_raw):
73 if np.sign(_y) < 0.0:
74 _ra = np.pi
75 else:
76 _ra = 0.0
77 else:
78 _ra = _ra_raw
80 _x = -np.sin(_ra)
82 if isinstance(_ra, numbers.Number):
83 if np.isnan(_ra):
84 lonOut = 0.0
85 elif (np.abs(_x) > 1.0e-9 and np.sign(_x) != np.sign(v2[0])) or \
86 (np.abs(_y) > 1.0e-9 and np.sign(_y) != np.sign(v2[1])):
88 lonOut = 2.0 * np.pi - _ra
89 else:
90 lonOut = _ra
91 else:
92 _lonOut = [2.0 * np.pi - rr
93 if (np.abs(xx) > 1.0e-9 and np.sign(xx) != np.sign(v2_0)) or
94 (np.abs(yy) > 1.0e-9 and np.sign(yy) != np.sign(v2_1))
95 else rr
96 for rr, xx, yy, v2_0, v2_1 in zip(_ra, _x, _y, v2[0], v2[1])]
98 lonOut = np.array([0.0 if np.isnan(ll) else ll for ll in _lonOut])
100 return lonOut, latOut
103def _lonLatFromNativeLonLat(nativeLon, nativeLat, lonPointing, latPointing):
104 """
105 Transform a position in native longitude and latitude into
106 longitude and latitude in a coordinate system where the telescope pointing
107 is defined. See the doc string for _nativeLonLatFromPointing for definitions
108 of native longitude and latitude.
110 @param [in] nativeLon is the native longitude in radians
112 @param [in] nativeLat is the native latitude in radians
114 @param [in] lonPointing is the longitude-like coordinate of the telescope
115 pointing in radians
117 @param [in] latPointing is the latitude-like coordinate of the telescope
118 pointing in radians
120 @param [out] latOut is the latitude of the transformed point(s)
121 in the same coordinate system as the telescope pointing in radians
123 @param [in] latOut is the latitude of the transformed point(s)
124 in the same coordinate system as the telescope pointing in radians
125 """
126 x = -1.0 * np.cos(nativeLat) * np.sin(nativeLon)
127 y = np.cos(nativeLat) * np.cos(nativeLon)
128 z = np.sin(nativeLat)
130 alpha = 0.5 * np.pi - latPointing
131 beta = lonPointing
133 ca = np.cos(alpha)
134 sa = np.sin(alpha)
135 cb = np.cos(beta)
136 sb = np.sin(beta)
138 v2 = np.dot(np.array([[cb, -1.0 * sb, 0.0], [sb, cb, 0.0], [0.0, 0.0, 1.0]]),
139 np.dot(np.array([[1.0, 0.0, 0.0], [0.0, ca, sa], [0.0, -1.0 * sa, ca]]), np.array([x, y, z])))
141 cc = np.sqrt(v2[0] * v2[0] + v2[1] * v2[1])
142 latOut = np.arctan2(v2[2], cc)
144 _y = v2[1] / np.cos(latOut)
145 _lonOut = np.arccos(_y)
146 _x = -np.sin(_lonOut)
148 if isinstance(_lonOut, numbers.Number):
149 if np.isnan(_lonOut):
150 lonOut = 0.0
151 elif (np.abs(_x) > 1.0e-9 and np.sign(_x) != np.sign(v2[0])) or \
152 (np.abs(_y) > 1.0e-9 and np.sign(_y) != np.sign(v2[1])):
154 lonOut = 2.0 * np.pi - _lonOut
155 else:
156 lonOut = _lonOut
157 else:
158 _lonOut = [2.0 * np.pi - rr
159 if (np.abs(xx) > 1.0e-9 and np.sign(xx) != np.sign(v2_0)) or
160 (np.abs(yy) > 1.0e-9 and np.sign(yy) != np.sign(v2_1))
161 else rr
162 for rr, xx, yy, v2_0, v2_1 in zip(_lonOut, _x, _y, v2[0], v2[1])]
164 lonOut = np.array([0.0 if np.isnan(rr) else rr for rr in _lonOut])
166 return lonOut, latOut
169def _nativeLonLatFromRaDec(ra_in, dec_in, obs_metadata):
170 """
171 Convert the RA and Dec of a star into `native' longitude and latitude.
173 Native longitude and latitude are defined as what RA and Dec would be
174 if the celestial pole were at the location where the telescope is pointing.
175 The transformation is achieved by rotating the vector pointing to the RA
176 and Dec being transformed once about the x axis and once about the z axis.
177 These are the Euler rotations referred to in Section 2.3 of
179 Calabretta and Greisen (2002), A&A 395, p. 1077
181 Note: RA, and Dec are assumed to be in the International Celestial Reference
182 System. Before calculating native longitude and latitude, this method will
183 convert RA and Dec to observed geocentric coordinates.
185 WARNING: This method does not account for apparent motion due to parallax.
186 This method is only useful for mapping positions on a theoretical
187 celestial sphere.
189 @param [in] ra is the RA of the star being transformed in radians
190 (in the International Celestial Reference System)
192 @param [in] dec is the Dec of the star being transformed in radians
193 (in the International Celestial Reference System)
195 @param [in] obs_metadata is an ObservationMetaData characterizing the pointing of
196 the telescope.
198 @param [out] lonOut is the native longitude in radians
200 @param [out] latOut is the native latitude in radians
201 """
203 ra, dec = _observedFromICRS(ra_in, dec_in,
204 obs_metadata=obs_metadata, epoch=2000.0,
205 includeRefraction=True)
207 raPointing, decPointing = _observedFromICRS(obs_metadata._pointingRA,
208 obs_metadata._pointingDec,
209 obs_metadata=obs_metadata, epoch=2000.0,
210 includeRefraction=True)
212 return _nativeLonLatFromPointing(ra, dec, raPointing, decPointing)
215def nativeLonLatFromRaDec(ra, dec, obs_metadata):
216 """
217 Convert the RA and Dec of a star into `native' longitude and latitude.
219 Native longitude and latitude are defined as what RA and Dec would be
220 if the celestial pole were at the location where the telescope is pointing.
221 The coordinate basis axes for this system is achieved by taking the true
222 coordinate basis axes and rotating them once about the z axis and once about
223 the x axis (or, by rotating the vector pointing to the RA and Dec being
224 transformed once about the x axis and once about the z axis). These
225 are the Euler rotations referred to in Section 2.3 of
227 Calabretta and Greisen (2002), A&A 395, p. 1077
229 Note: RA, and Dec are assumed to be in the International Celestial Reference
230 System. Before calculating native longitude and latitude, this method will
231 convert RA and Dec to observed geocentric coordinates.
233 WARNING: This method does not account for apparent motion due to parallax.
234 This method is only useful for mapping positions on a theoretical
235 celestial sphere.
237 @param [in] ra is the RA of the star being transformed in degrees
238 (in the International Celestial Reference System)
240 @param [in] dec is the Dec of the star being transformed in degrees
241 (in the International Celestial Reference System)
243 @param [in] obs_metadata is an ObservationMetaData characterizing the pointing of
244 the telescope.
246 @param [out] lonOut is the native longitude in degrees
248 @param [out] latOut is the native latitude in degrees
249 """
251 lon, lat = _nativeLonLatFromRaDec(np.radians(ra), np.radians(dec),
252 obs_metadata)
254 return np.degrees(lon), np.degrees(lat)
257def _raDecFromNativeLonLat(lon, lat, obs_metadata):
258 """
259 Transform a star's position in native longitude and latitude into
260 RA and Dec. See the doc string for _nativeLonLatFromRaDec for definitions
261 of native longitude and latitude.
263 @param [in] lon is the native longitude in radians
265 @param [in] lat is the native latitude in radians
267 @param [in] obs_metadata is an ObservationMetaData characterizing the pointing
268 of the telescope
270 @param [out] raOut is the RA of the star in radians
271 (in the International Celestial Reference System)
273 @param [in] decOut is the Dec of the star in radians
274 (in the International Celestial Reference System)
276 Note: Because of its reliance on icrsFromObserved, this
277 method is only accurate at angular distances from the sun of greater
278 than 45 degrees and zenith distances of less than 75 degrees.
279 """
281 raPointing, decPointing = _observedFromICRS(obs_metadata._pointingRA,
282 obs_metadata._pointingDec,
283 obs_metadata=obs_metadata, epoch=2000.0,
284 includeRefraction=True)
286 raObs, decObs = _lonLatFromNativeLonLat(lon, lat, raPointing, decPointing)
288 # convert from observed geocentric coordinates to International Celestial Reference System
289 # coordinates
291 raOut, decOut = _icrsFromObserved(raObs, decObs, obs_metadata=obs_metadata,
292 epoch=2000.0, includeRefraction=True)
294 return raOut, decOut
297def raDecFromNativeLonLat(lon, lat, obs_metadata):
298 """
299 Transform a star's position in native longitude and latitude into
300 RA and Dec. See the doc string for nativeLonLatFromRaDec for definitions
301 of native longitude and latitude.
303 @param [in] lon is the native longitude in degrees
305 @param [in] lat is the native latitude in degrees
307 @param [in] obs_metadata is an ObservationMetaData characterizing the
308 pointing of the telescope
310 @param [out] raOut is the RA of the star in degrees
311 (in the International Celestial Reference System)
313 @param [in] decOut is the Dec of the star in degrees
314 (in the International Celestial Reference System)
316 Note: Because of its reliance on icrsFromObserved, this
317 method is only accurate at angular distances from the sun of greater
318 than 45 degrees and zenith distances of less than 75 degrees.
319 """
321 ra, dec = _raDecFromNativeLonLat(np.radians(lon),
322 np.radians(lat),
323 obs_metadata)
325 return np.degrees(ra), np.degrees(dec)