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 self.assertRaises(ValueError, HealpixSlicer, nside=3)
90class TestHealpixSlicerEqual(unittest.TestCase):
92 def setUp(self):
93 self.nside = 16
94 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False, lonCol='ra', latCol='dec')
95 nvalues = 10000
96 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
97 ramin=0, ramax=2*np.pi,
98 decmin=-np.pi, decmax=0,
99 random=22)
100 self.testslicer.setupSlicer(self.dv)
102 def tearDown(self):
103 del self.testslicer
104 del self.dv
105 self.testslicer = None
107 def testSlicerEquivalence(self):
108 """Test that slicers are marked equal when appropriate, and unequal when appropriate."""
109 # Note that they are judged equal based on nsides (not on data in ra/dec spatial tree).
110 testslicer2 = HealpixSlicer(nside=self.nside, verbose=False, lonCol='ra', latCol='dec')
111 self.assertEqual(self.testslicer, testslicer2)
112 assert((self.testslicer != testslicer2) is False)
113 testslicer2 = HealpixSlicer(nside=self.nside/2.0, verbose=False, lonCol='ra', latCol='dec')
114 self.assertNotEqual(self.testslicer, testslicer2)
115 assert((self.testslicer != testslicer2) is True)
118class TestHealpixSlicerIteration(unittest.TestCase):
120 def setUp(self):
121 self.nside = 8
122 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False, lonCol='ra', latCol='dec')
123 nvalues = 10000
124 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
125 ramin=0, ramax=2*np.pi,
126 decmin=-np.pi, decmax=0,
127 random=33)
128 self.testslicer.setupSlicer(self.dv)
130 def tearDown(self):
131 del self.testslicer
132 self.testslicer = None
134 def testIteration(self):
135 """Test iteration goes through expected range and ra/dec are in expected range (radians)."""
136 npix = hp.nside2npix(self.nside)
137 for i, s in enumerate(self.testslicer):
138 self.assertEqual(i, s['slicePoint']['sid'])
139 ra = s['slicePoint']['ra']
140 dec = s['slicePoint']['dec']
141 self.assertGreaterEqual(ra, 0)
142 self.assertLessEqual(ra, 2*np.pi)
143 self.assertGreaterEqual(dec, -np.pi)
144 self.assertLessEqual(dec, np.pi)
145 # npix would count starting at 1, while i counts starting at 0 ..
146 # so add one to check end point
147 self.assertEqual(i+1, npix)
149 def testGetItem(self):
150 """Test getting indexed value."""
151 for i, s in enumerate(self.testslicer):
152 np.testing.assert_equal(self.testslicer[i], s)
155class TestHealpixSlicerSlicing(unittest.TestCase):
156 # Note that this is really testing baseSpatialSlicer, as slicing is done there for healpix grid
158 def setUp(self):
159 self.nside = 8
160 self.radius = 1.8
161 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False,
162 lonCol='ra', latCol='dec', latLonDeg=False,
163 radius=self.radius)
164 nvalues = 10000
165 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
166 ramin=0, ramax=2*np.pi,
167 decmin=-np.pi, decmax=0,
168 random=44)
170 def tearDown(self):
171 del self.testslicer
172 self.testslicer = None
174 def testSlicing(self):
175 """Test slicing returns (all) data points which are within 'radius' of bin point."""
176 # Test that slicing fails before setupSlicer
177 self.assertRaises(NotImplementedError, self.testslicer._sliceSimData, 0)
178 # Set up and test actual slicing.
179 self.testslicer.setupSlicer(self.dv)
180 for s in self.testslicer:
181 ra = s['slicePoint']['ra']
182 dec = s['slicePoint']['dec']
183 distances = calcDist_vincenty(ra, dec, self.dv['ra'], self.dv['dec'])
184 didxs = np.where(distances <= np.radians(self.radius))
185 sidxs = s['idxs']
186 self.assertEqual(len(sidxs), len(didxs[0]))
187 if len(sidxs) > 0:
188 didxs = np.sort(didxs[0])
189 sidxs = np.sort(sidxs)
190 np.testing.assert_equal(self.dv['testdata'][didxs], self.dv['testdata'][sidxs])
193class TestHealpixChipGap(unittest.TestCase):
194 # Note that this is really testing baseSpatialSlicer, as slicing is done there for healpix grid
196 def setUp(self):
197 self.nside = 8
198 self.radius = 2.041
199 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False,
200 lonCol='ra', latCol='dec', latLonDeg=False,
201 radius=self.radius, useCamera=True,
202 chipNames=['R:1,1 S:1,1'])
203 nvalues = 1000
204 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
205 ramin=0, ramax=2*np.pi,
206 decmin=-np.pi, decmax=0,
207 random=55)
209 def tearDown(self):
210 del self.testslicer
211 self.testslicer = None
213 def testSlicing(self):
214 """Test slicing returns (most) data points which are within 'radius' of bin point."""
215 # Test that slicing fails before setupSlicer
216 self.assertRaises(NotImplementedError, self.testslicer._sliceSimData, 0)
217 # Set up and test actual slicing.
218 self.testslicer.setupSlicer(self.dv)
219 for s in self.testslicer:
220 ra = s['slicePoint']['ra']
221 dec = s['slicePoint']['dec']
222 distances = calcDist_vincenty(ra, dec, self.dv['ra'], self.dv['dec'])
223 didxs = np.where(distances <= np.radians(self.radius))
224 sidxs = s['idxs']
225 self.assertLessEqual(len(sidxs), len(didxs[0]))
226 if len(sidxs) > 0:
227 for indx in sidxs:
228 self.assertIn(self.dv['testdata'][indx], self.dv['testdata'][didxs])
231class TestHealpixSlicerPlotting(unittest.TestCase):
233 def setUp(self):
234 rng = np.random.RandomState(713244122)
235 self.nside = 16
236 self.radius = 1.8
237 self.testslicer = HealpixSlicer(nside=self.nside, verbose=False, latLonDeg=False,
238 lonCol='ra', latCol='dec', radius=self.radius)
239 nvalues = 10000
240 self.dv = makeDataValues(size=nvalues, minval=0., maxval=1.,
241 ramin=0, ramax=2*np.pi,
242 decmin=-np.pi, decmax=0,
243 random=66)
244 self.testslicer.setupSlicer(self.dv)
245 self.metricdata = ma.MaskedArray(data=np.zeros(len(self.testslicer), dtype='float'),
246 mask=np.zeros(len(self.testslicer), 'bool'),
247 fill_value=self.testslicer.badval)
248 for i, b in enumerate(self.testslicer):
249 idxs = b['idxs']
250 if len(idxs) > 0:
251 self.metricdata.data[i] = np.mean(self.dv['testdata'][idxs])
252 else:
253 self.metricdata.mask[i] = True
254 self.metricdata2 = ma.MaskedArray(data=rng.rand(len(self.testslicer)),
255 mask=np.zeros(len(self.testslicer), 'bool'),
256 fill_value=self.testslicer.badval)
258 def tearDown(self):
259 del self.testslicer
260 self.testslicer = None
263class TestMemory(lsst.utils.tests.MemoryTestCase):
264 pass
267def setup_module(module):
268 lsst.utils.tests.init()
271if __name__ == "__main__": 271 ↛ 272line 271 didn't jump to line 272, because the condition on line 271 was never true
272 lsst.utils.tests.init()
273 unittest.main()