Coverage for tests/testCompoundCoordinateTransformations.py : 9%

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
3from builtins import range
4import unittest
5import numpy as np
6import lsst.utils.tests
7import lsst.sims.utils as utils
10def setup_module(module):
11 lsst.utils.tests.init()
14def controlAltAzFromRaDec(raRad_in, decRad_in, longRad, latRad, mjd):
15 """
16 Converts RA and Dec to altitude and azimuth
18 @param [in] raRad is the RA in radians
19 (observed geocentric)
21 @param [in] decRad is the Dec in radians
22 (observed geocentric)
24 @param [in] longRad is the longitude of the observer in radians
25 (positive east of the prime meridian)
27 @param [in[ latRad is the latitude of the observer in radians
28 (positive north of the equator)
30 @param [in] mjd is the universal time expressed as an MJD
32 @param [out] altitude in radians
34 @param [out[ azimuth in radians
36 see: http://www.stargazing.net/kepler/altaz.html#twig04
37 """
38 obs = utils.ObservationMetaData(mjd=utils.ModifiedJulianDate(UTC=mjd),
39 site=utils.Site(longitude=np.degrees(longRad),
40 latitude=np.degrees(latRad),
41 name='LSST'))
43 if hasattr(raRad_in, '__len__'):
44 raRad, decRad = utils._observedFromICRS(raRad_in, decRad_in, obs_metadata=obs,
45 epoch=2000.0, includeRefraction=True)
46 else:
47 raRad, decRad = utils._observedFromICRS(raRad_in, decRad_in,
48 obs_metadata=obs, epoch=2000.0, includeRefraction=True)
50 lst = utils.calcLmstLast(obs.mjd.UT1, longRad)
51 last = lst[1]
52 haRad = np.radians(last * 15.) - raRad
54 sinDec = np.sin(decRad)
55 cosLat = np.cos(latRad)
56 sinLat = np.sin(latRad)
57 sinAlt = sinDec*sinLat + np.cos(decRad)*cosLat*np.cos(haRad)
58 altRad = np.arcsin(sinAlt)
59 azRad = np.arccos((sinDec - sinAlt*sinLat) / (np.cos(altRad)*cosLat))
60 azRadOut = np.where(np.sin(haRad) >= 0.0, 2.0 * np.pi - azRad, azRad)
61 if isinstance(altRad, float):
62 return altRad, float(azRadOut)
63 return altRad, azRadOut
66class CompoundCoordinateTransformationsTests(unittest.TestCase):
68 def setUp(self):
69 self.rng = np.random.RandomState(32)
70 self.mjd = 57087.0
71 self.tolerance = 1.0e-5
73 def testExceptions(self):
74 """
75 Test to make sure that methods complain when incorrect data types are passed.
76 """
77 obs = utils.ObservationMetaData(pointingRA=55.0, pointingDec=-72.0, mjd=53467.8)
79 raFloat = 1.1
80 raList = np.array([0.2, 0.3])
82 decFloat = 1.1
83 decList = np.array([0.2, 0.3])
85 self.assertRaises(RuntimeError, utils._altAzPaFromRaDec, raList, decFloat, obs)
86 self.assertRaises(RuntimeError, utils._altAzPaFromRaDec, raFloat, decList, obs)
87 utils._altAzPaFromRaDec(raFloat, decFloat, obs)
88 utils._altAzPaFromRaDec(raList, decList, obs)
90 self.assertRaises(RuntimeError, utils._raDecFromAltAz, raList, decFloat, obs)
91 self.assertRaises(RuntimeError, utils._raDecFromAltAz, raFloat, decList, obs)
92 utils._raDecFromAltAz(raFloat, decFloat, obs)
93 utils._raDecFromAltAz(raList, decList, obs)
95 self.assertRaises(RuntimeError, utils.altAzPaFromRaDec, raList, decFloat, obs)
96 self.assertRaises(RuntimeError, utils.altAzPaFromRaDec, raFloat, decList, obs)
97 utils.altAzPaFromRaDec(raFloat, decFloat, obs)
98 utils.altAzPaFromRaDec(raList, decList, obs)
100 self.assertRaises(RuntimeError, utils.raDecFromAltAz, raList, decFloat, obs)
101 self.assertRaises(RuntimeError, utils.raDecFromAltAz, raFloat, decList, obs)
102 utils.raDecFromAltAz(raFloat, decFloat, obs)
103 utils.raDecFromAltAz(raList, decList, obs)
105 def test_raDecFromAltAz(self):
106 """
107 Test conversion of Alt, Az to Ra, Dec using data on the Sun
109 This site gives the altitude and azimuth of the Sun as a function
110 of time and position on the earth
112 http://aa.usno.navy.mil/data/docs/AltAz.php
114 This site gives the apparent geocentric RA, Dec of major celestial objects
115 as a function of time
117 http://aa.usno.navy.mil/data/docs/geocentric.php
119 This site converts calendar dates into Julian Dates
121 http://aa.usno.navy.mil/data/docs/JulianDate.php
122 """
124 hours = np.radians(360.0 / 24.0)
125 minutes = hours / 60.0
126 seconds = minutes / 60.0
128 longitude_list = []
129 latitude_list = []
130 mjd_list = []
131 alt_list = []
132 az_list = []
133 ra_app_list = []
134 dec_app_list = []
136 longitude_list.append(np.radians(-22.0 - 33.0 / 60.0))
137 latitude_list.append(np.radians(11.0 + 45.0 / 60.0))
138 mjd_list.append(2457364.958333 - 2400000.5) # 8 December 2015 11:00 UTC
139 alt_list.append(np.radians(41.1))
140 az_list.append(np.radians(134.7))
141 ra_app_list.append(16.0 * hours + 59.0 * minutes + 16.665 * seconds)
142 dec_app_list.append(np.radians(-22.0 - 42.0 / 60.0 - 2.94 / 3600.0))
144 longitude_list.append(np.radians(-22.0 - 33.0 / 60.0))
145 latitude_list.append(np.radians(11.0 + 45.0 / 60.0))
146 mjd_list.append(2457368.958333 - 2400000.5) # 12 December 2015 11:00 UTC
147 alt_list.append(np.radians(40.5))
148 az_list.append(np.radians(134.7))
149 ra_app_list.append(17.0 * hours + 16.0 * minutes + 51.649 * seconds)
150 dec_app_list.append(np.radians(-23.0 - 3 / 60.0 - 50.35 / 3600.0))
152 longitude_list.append(np.radians(145.0 + 23.0 / 60.0))
153 latitude_list.append(np.radians(-64.0 - 5.0 / 60.0))
154 mjd_list.append(2456727.583333 - 2400000.5) # 11 March 2014, 02:00 UTC
155 alt_list.append(np.radians(29.5))
156 az_list.append(np.radians(8.2))
157 ra_app_list.append(23.0 * hours + 24.0 * minutes + 46.634 * seconds)
158 dec_app_list.append(np.radians(-3.0 - 47.0 / 60.0 - 47.81 / 3600.0))
160 longitude_list.append(np.radians(145.0 + 23.0 / 60.0))
161 latitude_list.append(np.radians(-64.0 - 5.0 / 60.0))
162 mjd_list.append(2456731.583333 - 2400000.5) # 15 March 2014, 02:00 UTC
163 alt_list.append(np.radians(28.0))
164 az_list.append(np.radians(7.8))
165 ra_app_list.append(23.0 * hours + 39.0 * minutes + 27.695 * seconds)
166 dec_app_list.append(np.radians(-2.0 - 13.0 / 60.0 - 18.32 / 3600.0))
168 for longitude, latitude, mjd, alt, az, ra_app, dec_app in \
169 zip(longitude_list, latitude_list, mjd_list, alt_list, az_list,
170 ra_app_list, dec_app_list):
172 obs = utils.ObservationMetaData(site=utils.Site(longitude=np.degrees(longitude),
173 latitude=np.degrees(latitude), name='LSST'),
174 mjd=utils.ModifiedJulianDate(UTC=mjd))
176 ra_icrs, dec_icrs = utils._raDecFromAltAz(alt, az, obs)
177 ra_test, dec_test = utils._appGeoFromICRS(ra_icrs, dec_icrs, mjd=obs.mjd)
179 distance = np.degrees(utils.haversine(ra_app, dec_app, ra_test, dec_test))
180 # this is all the precision we have in the alt,az data taken from the USNO
181 self.assertLess(distance, 0.1)
183 correction = np.degrees(utils.haversine(ra_test, dec_test, ra_icrs, dec_icrs))
184 self.assertLess(distance, correction)
186 def testAltAzRADecRoundTrip(self):
187 """
188 Test that altAzPaFromRaDec and raDecFromAltAz really invert each other
189 """
191 mjd = 58350.0
193 alt_in = []
194 az_in = []
195 for alt in np.arange(0.0, 90.0, 10.0):
196 for az in np.arange(0.0, 360.0, 10.0):
197 alt_in.append(alt)
198 az_in.append(az)
200 alt_in = np.array(alt_in)
201 az_in = np.array(az_in)
203 for lon in (0.0, 90.0, 135.0):
204 for lat in (60.0, 30.0, -60.0, -30.0):
206 obs = utils.ObservationMetaData(mjd=mjd,
207 site=utils.Site(longitude=lon, latitude=lat, name='LSST'))
209 ra_in, dec_in = utils.raDecFromAltAz(alt_in, az_in, obs)
211 self.assertIsInstance(ra_in, np.ndarray)
212 self.assertIsInstance(dec_in, np.ndarray)
214 self.assertFalse(np.isnan(ra_in).any(), msg='there were NaNs in ra_in')
215 self.assertFalse(np.isnan(dec_in).any(), msg='there were NaNs in dec_in')
217 # test that passing them in one at a time gives the same answer
218 for ix in range(len(alt_in)):
219 ra_f, dec_f = utils.raDecFromAltAz(alt_in[ix], az_in[ix], obs)
220 self.assertIsInstance(ra_f, np.float)
221 self.assertIsInstance(dec_f, np.float)
222 self.assertAlmostEqual(ra_f, ra_in[ix], 12)
223 self.assertAlmostEqual(dec_f, dec_in[ix], 12)
225 alt_out, az_out, pa_out = utils.altAzPaFromRaDec(ra_in, dec_in, obs)
227 self.assertFalse(np.isnan(pa_out).any(), msg='there were NaNs in pa_out')
229 for alt_c, az_c, alt_t, az_t in \
230 zip(np.radians(alt_in), np.radians(az_in), np.radians(alt_out), np.radians(az_out)):
231 distance = utils.arcsecFromRadians(utils.haversine(az_c, alt_c, az_t, alt_t))
232 self.assertLess(distance, 0.2)
233 # not sure why 0.2 arcsec is the limiting precision of this test
235 def testAltAzFromRaDec(self):
236 """
237 Test conversion from RA, Dec to Alt, Az
238 """
240 nSamples = 100
241 ra = self.rng.random_sample(nSamples)*2.0*np.pi
242 dec = (self.rng.random_sample(nSamples)-0.5)*np.pi
243 lon_rad = 1.467
244 lat_rad = -0.234
245 controlAlt, controlAz = controlAltAzFromRaDec(ra, dec,
246 lon_rad, lat_rad,
247 self.mjd)
249 obs = utils.ObservationMetaData(mjd=utils.ModifiedJulianDate(UTC=self.mjd),
250 site=utils.Site(longitude=np.degrees(lon_rad),
251 latitude=np.degrees(lat_rad),
252 name='LSST'))
254 # verify parallactic angle against an expression from
255 # http://www.astro.washington.edu/groups/APO/Mirror.Motions/Feb.2000.Image.Jumps/report.html#Image%20motion%20directions
256 #
257 ra_obs, dec_obs = utils._observedFromICRS(ra, dec, obs_metadata=obs, epoch=2000.0,
258 includeRefraction=True)
260 lmst, last = utils.calcLmstLast(obs.mjd.UT1, lon_rad)
261 hourAngle = np.radians(last * 15.0) - ra_obs
262 controlSinPa = np.sin(hourAngle) * np.cos(lat_rad) / np.cos(controlAlt)
264 testAlt, testAz, testPa = utils._altAzPaFromRaDec(ra, dec, obs)
266 distance = utils.arcsecFromRadians(utils.haversine(controlAz, controlAlt, testAz, testAlt))
267 self.assertLess(distance.max(), 0.0001)
268 self.assertLess(np.abs(np.sin(testPa) - controlSinPa).max(), self.tolerance)
270 # test non-vectorized version
271 for r, d in zip(ra, dec):
272 controlAlt, controlAz = controlAltAzFromRaDec(r, d, lon_rad, lat_rad, self.mjd)
273 testAlt, testAz, testPa = utils._altAzPaFromRaDec(r, d, obs)
274 lmst, last = utils.calcLmstLast(obs.mjd.UT1, lon_rad)
275 r_obs, dec_obs = utils._observedFromICRS(r, d, obs_metadata=obs,
276 epoch=2000.0, includeRefraction=True)
277 hourAngle = np.radians(last * 15.0) - r_obs
278 controlSinPa = np.sin(hourAngle) * np.cos(lat_rad) / np.cos(controlAlt)
279 distance = utils.arcsecFromRadians(utils.haversine(controlAz, controlAlt, testAz, testAlt))
280 self.assertLess(distance, 0.0001)
281 self.assertLess(np.abs(np.sin(testPa) - controlSinPa), self.tolerance)
283 def test_altAzPaFromRaDec_no_refraction(self):
284 """
285 Test that altAzPaFromRaDec gives a sane answer when you turn off
286 refraction.
287 """
289 rng = np.random.RandomState(44)
290 n_samples = 10
291 n_batches = 10
292 for i_batch in range(n_batches):
293 # first, generate some sane RA, Dec values by generating sane
294 # Alt, Az values with refraction and converting them into
295 # RA, Dec
296 alt_sane = rng.random_sample(n_samples)*45.0 + 45.0
297 az_sane = rng.random_sample(n_samples)*360.0
298 mjd_input = rng.random_sample(n_samples)*10000.0 + 40000.0
299 mjd_list = utils.ModifiedJulianDate.get_list(TAI=mjd_input)
301 ra_sane = []
302 dec_sane = []
303 obs_sane = []
304 for alt, az, mjd in zip(alt_sane, az_sane, mjd_list):
305 obs = utils.ObservationMetaData(mjd=mjd)
306 ra, dec = utils.raDecFromAltAz(alt, az, obs)
307 ra_sane.append(ra)
308 dec_sane.append(dec)
309 obs_sane.append(obs)
311 # Now, loop over our refracted RA, Dec, Alt, Az values.
312 # Convert from RA, Dec to unrefracted Alt, Az. Then, apply refraction
313 # with our applyRefraction method. Check that the resulting refracted
314 # zenith distance is:
315 # 1) within 0.1 arcsec of the zenith distance of the already refracted
316 # alt value calculated above
317 #
318 # 2) closer to the zenith distance calculated above than to the
319 # unrefracted zenith distance
320 for ra, dec, obs, alt_ref, az_ref in \
321 zip(ra_sane, dec_sane, obs_sane, alt_sane, az_sane):
323 alt, az, pa = utils.altAzPaFromRaDec(ra, dec, obs,
324 includeRefraction = False)
326 tanz, tanz3 = utils.refractionCoefficients(site=obs.site)
327 refracted_zd = utils.applyRefraction(np.radians(90.0-alt), tanz, tanz3)
329 # Check that the two independently refracted zenith distances agree
330 # to within 0.1 arcsec
331 self.assertLess(np.abs(utils.arcsecFromRadians(refracted_zd) -
332 utils.arcsecFromRadians(np.radians(90.0-alt_ref))),
333 0.1)
335 # Check that the two refracted zenith distances are closer to each other
336 # than to the unrefracted zenith distance
337 self.assertLess(np.abs(np.degrees(refracted_zd)-(90.0-alt_ref)),
338 np.abs((90.0-alt_ref) - (90.0-alt)))
340 self.assertLess(np.abs(np.degrees(refracted_zd)-(90.0-alt_ref)),
341 np.abs(np.degrees(refracted_zd) - (90.0-alt)))
343 def test_raDecFromAltAz_noref(self):
344 """
345 test that raDecFromAltAz correctly inverts altAzPaFromRaDec, even when
346 refraction is turned off
347 """
349 rng = np.random.RandomState(55)
350 n_samples = 10
351 n_batches = 10
353 for i_batch in range(n_batches):
354 d_sun = 0.0
355 while d_sun < 45.0: # because ICRS->Observed transformation breaks down close to the sun
357 alt_in = rng.random_sample(n_samples)*50.0 + 20.0
358 az_in = rng.random_sample(n_samples)*360.0
359 obs = utils.ObservationMetaData(mjd=43000.0)
360 ra_in, dec_in = utils.raDecFromAltAz(alt_in, az_in, obs=obs, includeRefraction=False)
362 d_sun = utils.distanceToSun(ra_in, dec_in, obs.mjd).min()
364 alt_out, az_out, pa_out = utils.altAzPaFromRaDec(ra_in, dec_in, obs=obs,
365 includeRefraction=False)
367 dd = utils.haversine(np.radians(alt_out), np.radians(az_out),
368 np.radians(alt_in), np.radians(az_in))
369 self.assertLess(utils.arcsecFromRadians(dd).max(), 0.01)
371 def test_raDecAltAz_noRefraction_degVsRadians(self):
372 """
373 Check that raDecFromAltAz and altAzPaFromRaDec are consistent in a degrees-versus-radians
374 sense when refraction is turned off
375 """
377 rng = np.random.RandomState(34)
378 n_samples = 10
379 ra_in = rng.random_sample(n_samples)*360.0
380 dec_in = rng.random_sample(n_samples)*180.0 - 90.0
381 mjd = 43000.0
382 obs = utils.ObservationMetaData(mjd=mjd)
383 alt, az, pa = utils.altAzPaFromRaDec(ra_in, dec_in, obs, includeRefraction=False)
384 alt_rad, az_rad, pa_rad = utils._altAzPaFromRaDec(np.radians(ra_in),
385 np.radians(dec_in),
386 obs, includeRefraction=False)
388 distance = utils.haversine(az_rad, alt_rad,
389 np.radians(az), np.radians(alt))
390 self.assertLess(utils.arcsecFromRadians(distance).min(), 0.001)
391 np.testing.assert_array_almost_equal(pa, np.degrees(pa_rad), decimal=12)
393 ra, dec = utils.raDecFromAltAz(alt, az, obs, includeRefraction=False)
394 ra_rad, dec_rad = utils._raDecFromAltAz(alt_rad, az_rad, obs, includeRefraction=False)
395 distance = utils.haversine(ra_rad, dec_rad, np.radians(ra), np.radians(dec))
396 self.assertLess(utils.arcsecFromRadians(distance).min(), 0.001)
399class MemoryTestClass(lsst.utils.tests.MemoryTestCase):
400 pass
402if __name__ == "__main__": 402 ↛ 403line 402 didn't jump to line 403, because the condition on line 402 was never true
403 lsst.utils.tests.init()
404 unittest.main()