Coverage for tests/testNDSlicer.py : 18%

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 str
2from builtins import zip
3from builtins import range
4import matplotlib
5matplotlib.use("Agg")
6import warnings
7import numpy as np
8import numpy.lib.recfunctions as rfn
9import matplotlib
10matplotlib.use('Agg')
11import itertools
12import unittest
13from lsst.sims.maf.slicers.nDSlicer import NDSlicer
14from lsst.sims.maf.slicers.uniSlicer import UniSlicer
15import lsst.utils.tests
18def makeDataValues(size=100, min=0., max=1., nd=3, random=-1):
19 """Generate a simple array of numbers, evenly arranged between min/max, in nd dimensions, but (optional)
20 random order."""
21 data = []
22 for d in range(nd):
23 datavalues = np.arange(0, size, dtype='float')
24 datavalues *= (float(max) - float(min)) / (datavalues.max() - datavalues.min())
25 datavalues += min
26 if random > 0:
27 rng = np.random.RandomState(random)
28 randorder = rng.rand(size)
29 randind = np.argsort(randorder)
30 datavalues = datavalues[randind]
31 datavalues = np.array(list(zip(datavalues)), dtype=[('testdata' + '%d' % (d), 'float')])
32 data.append(datavalues)
33 data = rfn.merge_arrays(data, flatten=True, usemask=False)
34 return data
37class TestNDSlicerSetup(unittest.TestCase):
39 def setUp(self):
40 self.dvmin = 0
41 self.dvmax = 1
42 nvalues = 1000
43 self.nd = 3
44 self.dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=608)
45 self.dvlist = self.dv.dtype.names
47 def testSlicertype(self):
48 """Test instantiation of slicer sets slicer type as expected."""
49 testslicer = NDSlicer(self.dvlist)
50 self.assertEqual(testslicer.slicerName, testslicer.__class__.__name__)
51 self.assertEqual(testslicer.slicerName, 'NDSlicer')
53 def testSetupSlicerBins(self):
54 """Test setting up slicer using defined bins."""
55 # Used right bins?
56 bins = np.arange(self.dvmin, self.dvmax, 0.1)
57 binlist = []
58 for d in range(self.nd):
59 binlist.append(bins)
60 testslicer = NDSlicer(self.dvlist, binsList=binlist)
61 testslicer.setupSlicer(self.dv)
62 for d in range(self.nd):
63 np.testing.assert_equal(testslicer.bins[d], bins)
64 self.assertEqual(testslicer.nslice, (len(bins)-1)**self.nd)
66 def testSetupSlicerNbins(self):
67 """Test setting up slicer using nbins."""
68 for nvalues in (100, 1000):
69 for nbins in (5, 25, 74):
70 dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=-1)
71 # Right number of bins?
72 # expect one more 'bin' to accomodate last right edge, but nbins accounts for this
73 testslicer = NDSlicer(self.dvlist, binsList=nbins)
74 testslicer.setupSlicer(dv)
75 self.assertEqual(testslicer.nslice, nbins**self.nd)
76 # Bins of the right size?
77 for i in range(self.nd):
78 bindiff = np.diff(testslicer.bins[i])
79 expectedbindiff = (self.dvmax - self.dvmin) / float(nbins)
80 np.testing.assert_allclose(bindiff, expectedbindiff)
81 # Can we use a list of nbins too and get the right number of bins?
82 nbinsList = []
83 expectednbins = 1
84 for d in range(self.nd):
85 nbinsList.append(nbins + d)
86 expectednbins *= (nbins + d)
87 testslicer = NDSlicer(self.dvlist, binsList=nbinsList)
88 testslicer.setupSlicer(dv)
89 self.assertEqual(testslicer.nslice, expectednbins)
91 def testSetupSlicerNbinsZeros(self):
92 """Test handling case of data being single values."""
93 dv = makeDataValues(100, 0, 0, self.nd, random=-1)
94 nbins = 10
95 testslicer = NDSlicer(self.dvlist, binsList=nbins)
96 with warnings.catch_warnings(record=True) as w:
97 warnings.simplefilter("always")
98 testslicer.setupSlicer(dv)
99 self.assertIn('creasing binMax', str(w[-1].message))
100 expectednbins = nbins ** self.nd
101 self.assertEqual(testslicer.nslice, expectednbins)
103 def testSetupSlicerEquivalent(self):
104 """Test setting up slicer using defined bins and nbins is equal where expected."""
105 for nbins in (20, 105):
106 testslicer = NDSlicer(self.dvlist, binsList=nbins)
107 bins = makeDataValues(nbins+1, self.dvmin, self.dvmax, self.nd, random=-1)
108 binsList = []
109 for i in bins.dtype.names:
110 binsList.append(bins[i])
111 for nvalues in (100, 10000):
112 dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=64432)
113 testslicer.setupSlicer(dv)
114 for i in range(self.nd):
115 np.testing.assert_allclose(testslicer.bins[i], binsList[i])
118class TestNDSlicerEqual(unittest.TestCase):
120 def setUp(self):
121 self.dvmin = 0
122 self.dvmax = 1
123 nvalues = 1000
124 self.nd = 3
125 self.dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=20367)
126 self.dvlist = self.dv.dtype.names
127 self.testslicer = NDSlicer(self.dvlist, binsList=100)
128 self.testslicer.setupSlicer(self.dv)
130 def tearDown(self):
131 del self.testslicer
132 self.testslicer = None
134 def testEquivalence(self):
135 """Test equals method."""
136 # Note that two ND slicers will be considered equal if they are both the same kind of
137 # slicer AND have the same bins in all dimensions.
138 # Set up another slicer to match (same bins, although not the same data).
139 dv2 = makeDataValues(100, self.dvmin, self.dvmax, self.nd, random=10029)
140 dvlist = dv2.dtype.names
141 testslicer2 = NDSlicer(sliceColList=dvlist, binsList=self.testslicer.bins)
142 testslicer2.setupSlicer(dv2)
143 self.assertEqual(self.testslicer, testslicer2)
144 # Set up another slicer that should not match (different bins)
145 dv2 = makeDataValues(1000, self.dvmin+1, self.dvmax+1, self.nd, random=209837)
146 testslicer2 = NDSlicer(sliceColList=dvlist, binsList=100)
147 testslicer2.setupSlicer(dv2)
148 self.assertNotEqual(self.testslicer, testslicer2)
149 # Set up another slicer that should not match (different dimensions)
150 dv2 = makeDataValues(1000, self.dvmin, self.dvmax, self.nd-1, random=50623)
151 testslicer2 = NDSlicer(dv2.dtype.names, binsList=100)
152 testslicer2.setupSlicer(dv2)
153 self.assertNotEqual(self.testslicer, testslicer2)
154 # Set up a different kind of slicer that should not match.
155 testslicer2 = UniSlicer()
156 dv2 = makeDataValues(100, 0, 1, random=22310098)
157 testslicer2.setupSlicer(dv2)
158 self.assertNotEqual(self.testslicer, testslicer2)
161class TestNDSlicerIteration(unittest.TestCase):
163 def setUp(self):
164 self.dvmin = 0
165 self.dvmax = 1
166 nvalues = 1000
167 self.nd = 3
168 self.dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=11081)
169 self.dvlist = self.dv.dtype.names
170 nvalues = 1000
171 bins = np.arange(self.dvmin, self.dvmax, 0.1)
172 binsList = []
173 self.iterlist = []
174 for i in range(self.nd):
175 binsList.append(bins)
176 # (remember iteration doesn't use the very last bin in 'bins')
177 self.iterlist.append(bins[:-1])
178 dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=17)
179 self.testslicer = NDSlicer(self.dvlist, binsList=binsList)
180 self.testslicer.setupSlicer(dv)
182 def tearDown(self):
183 del self.testslicer
184 self.testslicer = None
186 def testIteration(self):
187 """Test iteration."""
188 for s, ib in zip(self.testslicer, itertools.product(*self.iterlist)):
189 self.assertEqual(s['slicePoint']['binLeft'], ib)
191 def testGetItem(self):
192 """Test getting indexed binpoint."""
193 for i, s in enumerate(self.testslicer):
194 self.assertEqual(self.testslicer[i]['slicePoint']['binLeft'], s['slicePoint']['binLeft'])
195 self.assertEqual(self.testslicer[0]['slicePoint']['binLeft'], (0.0, 0.0, 0.0))
198class TestNDSlicerSlicing(unittest.TestCase):
200 def setUp(self):
201 self.dvmin = 0
202 self.dvmax = 1
203 nvalues = 1000
204 self.nd = 3
205 self.dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=173)
206 self.dvlist = self.dv.dtype.names
207 self.testslicer = NDSlicer(self.dvlist)
209 def tearDown(self):
210 del self.testslicer
211 self.testslicer = None
213 def testSlicing(self):
214 """Test slicing."""
215 # Test get error if try to slice before setup.
216 self.assertRaises(NotImplementedError, self.testslicer._sliceSimData, 0)
217 nbins = 10
218 binsize = (self.dvmax - self.dvmin) / (float(nbins))
219 self.testslicer = NDSlicer(self.dvlist, binsList=nbins)
220 for nvalues in (1000, 10000):
221 dv = makeDataValues(nvalues, self.dvmin, self.dvmax, self.nd, random=1735)
222 self.testslicer.setupSlicer(dv)
223 sum = 0
224 for i, s in enumerate(self.testslicer):
225 idxs = s['idxs']
226 dataslice = dv[idxs]
227 sum += len(idxs)
228 if len(dataslice) > 0:
229 for i, dvname, b in zip(list(range(self.nd)), self.dvlist, s['slicePoint']['binLeft']):
230 self.assertGreaterEqual((dataslice[dvname].min() - b), 0)
231 if i < self.testslicer.nslice-1:
232 self.assertLessEqual((dataslice[dvname].max() - b), binsize)
233 else:
234 self.assertAlmostEqual((dataslice[dvname].max() - b), binsize)
235 self.assertEqual(len(dataslice), nvalues/float(nbins))
236 # and check that every data value was assigned somewhere.
237 self.assertEqual(sum, nvalues)
240class TestMemory(lsst.utils.tests.MemoryTestCase):
241 pass
244def setup_module(module):
245 lsst.utils.tests.init()
248if __name__ == "__main__": 248 ↛ 249line 248 didn't jump to line 249, because the condition on line 248 was never true
249 lsst.utils.tests.init()
250 unittest.main()