Coverage for tests/testWcsUtils.py : 14%

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 builtins import zip
2import unittest
3import numpy as np
4import lsst.utils.tests
6from lsst.sims.utils import raDecFromNativeLonLat, nativeLonLatFromRaDec
7from lsst.sims.utils import _raDecFromNativeLonLat, _nativeLonLatFromRaDec
8from lsst.sims.utils import observedFromICRS, icrsFromObserved
9from lsst.sims.utils import ObservationMetaData, haversine
10from lsst.sims.utils import arcsecFromRadians, raDecFromAltAz, Site
13def setup_module(module):
14 lsst.utils.tests.init()
17class NativeLonLatTest(unittest.TestCase):
19 def testNativeLonLat(self):
20 """
21 Test that nativeLonLatFromRaDec works by considering stars and pointings
22 at intuitive locations
23 """
25 mjd = 53855.0
27 raList_obs = [0.0, 0.0, 0.0, 270.0]
28 decList_obs = [90.0, 90.0, 0.0, 0.0]
30 raPointList_obs = [0.0, 270.0, 270.0, 0.0]
31 decPointList_obs = [0.0, 0.0, 0.0, 0.0]
33 lonControlList = [180.0, 180.0, 90.0, 270.0]
34 latControlList = [0.0, 0.0, 0.0, 0.0]
36 for rr_obs, dd_obs, rp_obs, dp_obs, lonc, latc in \
37 zip(raList_obs, decList_obs, raPointList_obs, decPointList_obs,
38 lonControlList, latControlList):
40 obsTemp = ObservationMetaData(mjd=mjd)
42 rr, dd = icrsFromObserved(np.array([rr_obs, rp_obs]),
43 np.array([dd_obs, dp_obs]),
44 obs_metadata=obsTemp,
45 epoch=2000.0, includeRefraction=True)
47 obs = ObservationMetaData(
48 pointingRA=rr[1], pointingDec=dd[1], mjd=mjd)
49 lon, lat = nativeLonLatFromRaDec(rr[0], dd[0], obs)
50 distance = arcsecFromRadians(haversine(lon, lat, lonc, latc))
51 self.assertLess(distance, 1.0)
53 def testNativeLongLatComplicated(self):
54 """
55 Test that nativeLongLatFromRaDec works by considering stars and pointings
56 at non-intuitive locations.
57 """
59 rng = np.random.RandomState(42)
60 nPointings = 10
61 raPointingList_icrs = rng.random_sample(nPointings) * 360.0
62 decPointingList_icrs = rng.random_sample(
63 nPointings) * 180.0 - 90.0
64 mjdList = rng.random_sample(nPointings) * 10000.0 + 43000.0
66 nStars = 10
67 for raPointing_icrs, decPointing_icrs, mjd in \
68 zip(raPointingList_icrs, decPointingList_icrs, mjdList):
70 obs = ObservationMetaData(pointingRA=raPointing_icrs, pointingDec=decPointing_icrs, mjd=mjd)
71 raList_icrs = rng.random_sample(nStars) * 360.0
72 decList_icrs = rng.random_sample(nStars) * 180.0 - 90.0
73 raList_obs, decList_obs = observedFromICRS(raList_icrs, decList_icrs, obs_metadata=obs,
74 epoch=2000.0, includeRefraction=True)
76 obsTemp = ObservationMetaData(mjd=mjd)
77 raPointing_obs, decPointing_obs = observedFromICRS(raPointing_icrs,
78 decPointing_icrs,
79 obs_metadata=obsTemp, epoch=2000.0,
80 includeRefraction=True)
82 for ra_obs, dec_obs, ra_icrs, dec_icrs in \
83 zip(raList_obs, decList_obs, raList_icrs, decList_icrs):
85 raRad = np.radians(ra_obs)
86 decRad = np.radians(dec_obs)
87 sinRa = np.sin(raRad)
88 cosRa = np.cos(raRad)
89 sinDec = np.sin(decRad)
90 cosDec = np.cos(decRad)
92 # the three dimensional position of the star
93 controlPosition = np.array([-cosDec * sinRa, cosDec * cosRa, sinDec])
95 # calculate the rotation matrices needed to transform the
96 # x, y, and z axes into the local x, y, and z axes
97 # (i.e. the axes with z lined up with raPointing_obs, decPointing_obs)
98 alpha = 0.5 * np.pi - np.radians(decPointing_obs)
99 ca = np.cos(alpha)
100 sa = np.sin(alpha)
101 rotX = np.array([[1.0, 0.0, 0.0],
102 [0.0, ca, sa],
103 [0.0, -sa, ca]])
105 cb = np.cos(np.radians(raPointing_obs))
106 sb = np.sin(np.radians(raPointing_obs))
107 rotZ = np.array([[cb, -sb, 0.0],
108 [sb, cb, 0.0],
109 [0.0, 0.0, 1.0]])
111 # rotate the coordinate axes into the local basis
112 xAxis = np.dot(rotZ, np.dot(rotX, np.array([1.0, 0.0, 0.0])))
113 yAxis = np.dot(rotZ, np.dot(rotX, np.array([0.0, 1.0, 0.0])))
114 zAxis = np.dot(rotZ, np.dot(rotX, np.array([0.0, 0.0, 1.0])))
116 # calculate the local longitude and latitude of the star
117 lon, lat = nativeLonLatFromRaDec(ra_icrs, dec_icrs, obs)
118 cosLon = np.cos(np.radians(lon))
119 sinLon = np.sin(np.radians(lon))
120 cosLat = np.cos(np.radians(lat))
121 sinLat = np.sin(np.radians(lat))
123 # the x, y, z position of the star in the local coordinate
124 # basis
125 transformedPosition = np.array([-cosLat * sinLon,
126 cosLat * cosLon,
127 sinLat])
129 # convert that position back into the un-rotated bases
130 testPosition = transformedPosition[0] * xAxis + \
131 transformedPosition[1] * yAxis + \
132 transformedPosition[2] * zAxis
134 # assert that testPosition and controlPosition should be equal
135 distance = np.sqrt(np.power(controlPosition - testPosition, 2).sum())
136 self.assertLess(distance, 1.0e-12)
138 def testNativeLonLatVector(self):
139 """
140 Test that nativeLonLatFromRaDec works in a vectorized way; we do this
141 by performing a bunch of tansformations passing in ra and dec as numpy arrays
142 and then comparing them to results computed in an element-wise way
143 """
145 obs = ObservationMetaData(pointingRA=123.0, pointingDec=43.0, mjd=53467.2)
147 nSamples = 100
148 rng = np.random.RandomState(42)
149 raList = rng.random_sample(nSamples) * 360.0
150 decList = rng.random_sample(nSamples) * 180.0 - 90.0
152 lonList, latList = nativeLonLatFromRaDec(raList, decList, obs)
154 for rr, dd, lon, lat in zip(raList, decList, lonList, latList):
155 lonControl, latControl = nativeLonLatFromRaDec(rr, dd, obs)
156 distance = arcsecFromRadians(haversine(np.radians(lon), np.radians(lat),
157 np.radians(lonControl), np.radians(latControl)))
159 self.assertLess(distance, 0.0001)
161 def testRaDec(self):
162 """
163 Test that raDecFromNativeLonLat does invert
164 nativeLonLatFromRaDec
165 """
166 rng = np.random.RandomState(42)
167 nSamples = 100
168 # because raDecFromNativeLonLat is only good
169 rrList = rng.random_sample(nSamples) * 50.0
170 # out to a zenith distance of ~ 70 degrees
172 thetaList = rng.random_sample(nSamples) * 2.0 * np.pi
174 rrPointingList = rng.random_sample(10) * 50.0
175 thetaPointingList = rng.random_sample(10) * 2.0 * np.pi
176 mjdList = rng.random_sample(nSamples) * 10000.0 + 43000.0
178 for rrp, thetap, mjd in \
179 zip(rrPointingList, thetaPointingList, mjdList):
181 site = Site(name='LSST')
182 raZenith, decZenith = raDecFromAltAz(180.0, 0.0,
183 ObservationMetaData(mjd=mjd, site=site))
185 rp = raZenith + rrp * np.cos(thetap)
186 dp = decZenith + rrp * np.sin(thetap)
187 obs = ObservationMetaData(pointingRA=rp, pointingDec=dp, mjd=mjd, site=site)
189 raList_icrs = (raZenith + rrList * np.cos(thetaList)) % 360.0
190 decList_icrs = decZenith + rrList * np.sin(thetaList)
192 raList_obs, decList_obs = observedFromICRS(raList_icrs, decList_icrs,
193 obs_metadata=obs,
194 epoch=2000.0, includeRefraction=True)
196 # calculate the distance between the ICRS position and the observed
197 # geocentric position
198 dd_icrs_obs_list = arcsecFromRadians(haversine(np.radians(raList_icrs),
199 np.radians(decList_icrs),
200 np.radians(raList_obs),
201 np.radians(decList_obs)))
203 for rr, dd, dd_icrs_obs in zip(raList_icrs, decList_icrs, dd_icrs_obs_list):
204 lon, lat = nativeLonLatFromRaDec(rr, dd, obs)
205 r1, d1 = raDecFromNativeLonLat(lon, lat, obs)
207 # the distance between the input RA, Dec and the round-trip output
208 # RA, Dec
209 distance = arcsecFromRadians(haversine(np.radians(r1), np.radians(d1),
210 np.radians(rr), np.radians(dd)))
212 rr_obs, dec_obs = observedFromICRS(rr, dd,
213 obs_metadata=obs, epoch=2000.0, includeRefraction=True)
215 # verify that the round trip through nativeLonLat only changed
216 # RA, Dec by less than an arcsecond
217 self.assertLess(distance, 1.0)
219 # verify that any difference in the round trip is much less
220 # than the distance between the ICRS and the observed geocentric
221 # RA, Dec
222 self.assertLess(distance, dd_icrs_obs * 0.01)
224 def testRaDecVector(self):
225 """
226 Test that raDecFromNativeLonLat does invert
227 nativeLonLatFromRaDec (make sure it works in a vectorized way)
228 """
229 rng = np.random.RandomState(42)
230 nSamples = 100
231 latList = rng.random_sample(nSamples) * 360.0
232 lonList = rng.random_sample(nSamples) * 180.0 - 90.0
233 raPoint = 95.0
234 decPoint = 75.0
236 obs = ObservationMetaData(
237 pointingRA=raPoint, pointingDec=decPoint, mjd=53467.89)
239 raList, decList = raDecFromNativeLonLat(lonList, latList, obs)
241 for lon, lat, ra0, dec0 in zip(lonList, latList, raList, decList):
242 ra1, dec1 = raDecFromNativeLonLat(lon, lat, obs)
243 distance = arcsecFromRadians(haversine(np.radians(ra0), np.radians(dec0),
244 np.radians(ra1), np.radians(dec1)))
245 self.assertLess(distance, 0.1)
247 def testDegreesVersusRadians(self):
248 """
249 Test that the radian and degree versions of nativeLonLatFromRaDec
250 and raDecFromNativeLonLat are consistent with each other
251 """
253 rng = np.random.RandomState(873)
254 nSamples = 1000
255 obs = ObservationMetaData(
256 pointingRA=45.0, pointingDec=-34.5, mjd=54656.76)
257 raList = rng.random_sample(nSamples) * 360.0
258 decList = rng.random_sample(nSamples) * 180.0 - 90.0
260 lonDeg, latDeg = nativeLonLatFromRaDec(raList, decList, obs)
261 lonRad, latRad = _nativeLonLatFromRaDec(np.radians(raList), np.radians(decList), obs)
262 np.testing.assert_array_almost_equal(np.radians(lonDeg), lonRad, 15)
263 np.testing.assert_array_almost_equal(np.radians(latDeg), latRad, 15)
265 raDeg, decDeg = raDecFromNativeLonLat(raList, decList, obs)
266 raRad, decRad = _raDecFromNativeLonLat(np.radians(raList), np.radians(decList), obs)
267 np.testing.assert_array_almost_equal(np.radians(raDeg), raRad, 15)
268 np.testing.assert_array_almost_equal(np.radians(decDeg), decRad, 15)
271class MemoryTestClass(lsst.utils.tests.MemoryTestCase):
272 pass
274if __name__ == "__main__": 274 ↛ 275line 274 didn't jump to line 275, because the condition on line 274 was never true
275 lsst.utils.tests.init()
276 unittest.main()