Coverage for tests/testHealpixSlicer.py : 21%

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 matplotlib
3matplotlib.use("Agg")
4import numpy as np
5import numpy.lib.recfunctions as rfn
6import numpy.ma as ma
7import unittest
8import healpy as hp
9from lsst.sims.maf.slicers.healpixSlicer import HealpixSlicer
10import lsst.utils.tests
13def makeDataValues(size=100, minval=0., maxval=1., ramin=0, ramax=2*np.pi,
14 decmin=-np.pi, decmax=np.pi, random=1172):
15 """Generate a simple array of numbers, evenly arranged between min/max,
16 in 1 dimensions (optionally sorted), together with RA/Dec values
17 for each data value."""
18 data = []
19 # Generate data values min - max.
20 datavalues = np.arange(0, size, dtype='float')
21 datavalues *= (float(maxval) - float(minval)) / (datavalues.max() - datavalues.min())
22 datavalues += minval
23 rng = np.random.RandomState(random)
24 randorder = rng.rand(size)
25 randind = np.argsort(randorder)
26 datavalues = datavalues[randind]
27 datavalues = np.array(list(zip(datavalues)), dtype=[('testdata', 'float')])
28 data.append(datavalues)
29 # Generate RA/Dec values equally spaces on sphere between ramin/max, decmin/max.
30 ra = np.arange(0, size, dtype='float')
31 ra *= (float(ramax) - float(ramin)) / (ra.max() - ra.min())
32 randorder = rng.rand(size)
33 randind = np.argsort(randorder)
34 ra = ra[randind]
35 ra = np.array(list(zip(ra)), dtype=[('ra', 'float')])
36 data.append(ra)
37 v = np.arange(0, size, dtype='float')
38 v *= ((np.cos(decmax+np.pi) + 1.)/2.0 - (np.cos(decmin+np.pi)+1.)/2.0) / (v.max() - v.min())
39 v += (np.cos(decmin+np.pi)+1.)/2.0
40 dec = np.arccos(2*v-1) - np.pi
41 randorder = rng.rand(size)
42 randind = np.argsort(randorder)
43 dec = dec[randind]
44 dec = np.array(list(zip(dec)), dtype=[('dec', 'float')])
45 data.append(dec)
46 # Add in rotation angle
47 rot = rng.rand(len(dec))*2*np.pi
48 data.append(np.array(rot, dtype=[('rotSkyPos', 'float')]))
49 mjd = np.arange(len(dec))*.1
50 data.append(np.array(mjd, dtype=[('observationStartMJD', 'float')]))
51 data = rfn.merge_arrays(data, flatten=True, usemask=False)
52 return data
55def calcDist_vincenty(RA1, Dec1, RA2, Dec2):
56 """Calculates distance on a sphere using the Vincenty formula.
57 Give this function RA/Dec values in radians. Returns angular distance(s), in radians.
58 Note that since this is all numpy, you could input arrays of RA/Decs."""
59 D1 = (np.cos(Dec2)*np.sin(RA2-RA1))**2 + \
60 (np.cos(Dec1)*np.sin(Dec2) -
61 np.sin(Dec1)*np.cos(Dec2)*np.cos(RA2-RA1))**2
62 D1 = np.sqrt(D1)
63 D2 = (np.sin(Dec1)*np.sin(Dec2) +
64 np.cos(Dec1)*np.cos(Dec2)*np.cos(RA2-RA1))
65 D = np.arctan2(D1, D2)
66 return D
69class TestHealpixSlicerSetup(unittest.TestCase):
71 def testSlicertype(self):
72 """Test instantiation of slicer sets slicer type as expected."""
73 testslicer = HealpixSlicer(nside=16, verbose=False)
74 self.assertEqual(testslicer.slicerName, testslicer.__class__.__name__)
75 self.assertEqual(testslicer.slicerName, 'HealpixSlicer')
77 def testNsidesNbins(self):
78 """Test that number of sides passed to slicer produces expected number of bins."""
79 nsides = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
80 npixx = [12, 48, 192, 768, 3072, 12288, 49152, 196608, 786432, 3145728]
81 for nside, npix in zip(nsides, npixx):
82 testslicer = HealpixSlicer(nside=nside, verbose=False)
83 self.assertEqual(testslicer.nslice, npix)
85 def testNsidesError(self):
86 """Test that if passed an incorrect value for nsides that get expected exception."""
87 # FIXME: This used to throw an exception. We comment it out for now.
88 # self.assertRaises(ValueError, HealpixSlicer, nside=3)
91class TestHealpixSlicerEqual(unittest.TestCase):
93 def setUp(self):
94 self.nside = 16
95 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False, lonCol='ra', latCol='dec')
96 nvalues = 10000
97 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
98 ramin=0, ramax=2*np.pi,
99 decmin=-np.pi, decmax=0,
100 random=22)
101 self.testslicer.setupSlicer(self.dv)
103 def tearDown(self):
104 del self.testslicer
105 del self.dv
106 self.testslicer = None
108 def testSlicerEquivalence(self):
109 """Test that slicers are marked equal when appropriate, and unequal when appropriate."""
110 # Note that they are judged equal based on nsides (not on data in ra/dec spatial tree).
111 testslicer2 = HealpixSlicer(nside=self.nside, verbose=False, lonCol='ra', latCol='dec')
112 self.assertEqual(self.testslicer, testslicer2)
113 assert((self.testslicer != testslicer2) is False)
114 testslicer2 = HealpixSlicer(nside=self.nside/2.0, verbose=False, lonCol='ra', latCol='dec')
115 self.assertNotEqual(self.testslicer, testslicer2)
116 assert((self.testslicer != testslicer2) is True)
119class TestHealpixSlicerIteration(unittest.TestCase):
121 def setUp(self):
122 self.nside = 8
123 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False, lonCol='ra', latCol='dec')
124 nvalues = 10000
125 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
126 ramin=0, ramax=2*np.pi,
127 decmin=-np.pi, decmax=0,
128 random=33)
129 self.testslicer.setupSlicer(self.dv)
131 def tearDown(self):
132 del self.testslicer
133 self.testslicer = None
135 def testIteration(self):
136 """Test iteration goes through expected range and ra/dec are in expected range (radians)."""
137 npix = hp.nside2npix(self.nside)
138 for i, s in enumerate(self.testslicer):
139 self.assertEqual(i, s['slicePoint']['sid'])
140 ra = s['slicePoint']['ra']
141 dec = s['slicePoint']['dec']
142 self.assertGreaterEqual(ra, 0)
143 self.assertLessEqual(ra, 2*np.pi)
144 self.assertGreaterEqual(dec, -np.pi)
145 self.assertLessEqual(dec, np.pi)
146 # npix would count starting at 1, while i counts starting at 0 ..
147 # so add one to check end point
148 self.assertEqual(i+1, npix)
150 def testGetItem(self):
151 """Test getting indexed value."""
152 for i, s in enumerate(self.testslicer):
153 np.testing.assert_equal(self.testslicer[i], s)
156class TestHealpixSlicerSlicing(unittest.TestCase):
157 # Note that this is really testing baseSpatialSlicer, as slicing is done there for healpix grid
159 def setUp(self):
160 self.nside = 8
161 self.radius = 1.8
162 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False,
163 lonCol='ra', latCol='dec', latLonDeg=False,
164 radius=self.radius)
165 nvalues = 10000
166 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
167 ramin=0, ramax=2*np.pi,
168 decmin=-np.pi, decmax=0,
169 random=44)
171 def tearDown(self):
172 del self.testslicer
173 self.testslicer = None
175 def testSlicing(self):
176 """Test slicing returns (all) data points which are within 'radius' of bin point."""
177 # Test that slicing fails before setupSlicer
178 self.assertRaises(NotImplementedError, self.testslicer._sliceSimData, 0)
179 # Set up and test actual slicing.
180 self.testslicer.setupSlicer(self.dv)
181 for s in self.testslicer:
182 ra = s['slicePoint']['ra']
183 dec = s['slicePoint']['dec']
184 distances = calcDist_vincenty(ra, dec, self.dv['ra'], self.dv['dec'])
185 didxs = np.where(distances <= np.radians(self.radius))
186 sidxs = s['idxs']
187 self.assertEqual(len(sidxs), len(didxs[0]))
188 if len(sidxs) > 0:
189 didxs = np.sort(didxs[0])
190 sidxs = np.sort(sidxs)
191 np.testing.assert_equal(self.dv['testdata'][didxs], self.dv['testdata'][sidxs])
194class TestHealpixChipGap(unittest.TestCase):
195 # Note that this is really testing baseSpatialSlicer, as slicing is done there for healpix grid
197 def setUp(self):
198 self.nside = 8
199 self.radius = 2.041
200 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False,
201 lonCol='ra', latCol='dec', latLonDeg=False,
202 radius=self.radius, useCamera=True,
203 chipNames=['R:1,1 S:1,1'])
204 nvalues = 1000
205 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
206 ramin=0, ramax=2*np.pi,
207 decmin=-np.pi, decmax=0,
208 random=55)
210 def tearDown(self):
211 del self.testslicer
212 self.testslicer = None
214 def testSlicing(self):
215 """Test slicing returns (most) data points which are within 'radius' of bin point."""
216 # Test that slicing fails before setupSlicer
217 self.assertRaises(NotImplementedError, self.testslicer._sliceSimData, 0)
218 # Set up and test actual slicing.
219 self.testslicer.setupSlicer(self.dv)
220 for s in self.testslicer:
221 ra = s['slicePoint']['ra']
222 dec = s['slicePoint']['dec']
223 distances = calcDist_vincenty(ra, dec, self.dv['ra'], self.dv['dec'])
224 didxs = np.where(distances <= np.radians(self.radius))
225 sidxs = s['idxs']
226 self.assertLessEqual(len(sidxs), len(didxs[0]))
227 if len(sidxs) > 0:
228 for indx in sidxs:
229 self.assertIn(self.dv['testdata'][indx], self.dv['testdata'][didxs])
232class TestHealpixSlicerPlotting(unittest.TestCase):
234 def setUp(self):
235 rng = np.random.RandomState(713244122)
236 self.nside = 16
237 self.radius = 1.8
238 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False, latLonDeg=False,
239 lonCol='ra', latCol='dec', radius=self.radius)
240 nvalues = 10000
241 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
242 ramin=0, ramax=2*np.pi,
243 decmin=-np.pi, decmax=0,
244 random=66)
245 self.testslicer.setupSlicer(self.dv)
246 self.metricdata = ma.MaskedArray(data=np.zeros(len(self.testslicer), dtype='float'),
247 mask=np.zeros(len(self.testslicer), 'bool'),
248 fill_value=self.testslicer.badval)
249 for i, b in enumerate(self.testslicer):
250 idxs = b['idxs']
251 if len(idxs) > 0:
252 self.metricdata.data[i] = np.mean(self.dv['testdata'][idxs])
253 else:
254 self.metricdata.mask[i] = True
255 self.metricdata2 = ma.MaskedArray(data=rng.rand(len(self.testslicer)),
256 mask=np.zeros(len(self.testslicer), 'bool'),
257 fill_value=self.testslicer.badval)
259 def tearDown(self):
260 del self.testslicer
261 self.testslicer = None
264class TestMemory(lsst.utils.tests.MemoryTestCase):
265 pass
268def setup_module(module):
269 lsst.utils.tests.init()
272if __name__ == "__main__": 272 ↛ 273line 272 didn't jump to line 273, because the condition on line 272 was never true
273 lsst.utils.tests.init()
274 unittest.main()