Hide keyboard shortcuts

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 

16 

17 

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 

35 

36 

37class TestNDSlicerSetup(unittest.TestCase): 

38 

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 

46 

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') 

52 

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) 

65 

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) 

90 

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) 

102 

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]) 

116 

117 

118class TestNDSlicerEqual(unittest.TestCase): 

119 

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) 

129 

130 def tearDown(self): 

131 del self.testslicer 

132 self.testslicer = None 

133 

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) 

159 

160 

161class TestNDSlicerIteration(unittest.TestCase): 

162 

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) 

181 

182 def tearDown(self): 

183 del self.testslicer 

184 self.testslicer = None 

185 

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) 

190 

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)) 

196 

197 

198class TestNDSlicerSlicing(unittest.TestCase): 

199 

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) 

208 

209 def tearDown(self): 

210 del self.testslicer 

211 self.testslicer = None 

212 

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) 

238 

239 

240class TestMemory(lsst.utils.tests.MemoryTestCase): 

241 pass 

242 

243 

244def setup_module(module): 

245 lsst.utils.tests.init() 

246 

247 

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()