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

1# This file is part of meas_algorithms. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22import unittest 

23import numpy as np 

24import tempfile 

25 

26from lsst.meas.algorithms import brightStarStamps 

27from lsst.afw import image as afwImage 

28from lsst.daf.base import PropertyList 

29import lsst.utils.tests 

30 

31 

32class BrightStarStampsTestCase(lsst.utils.tests.TestCase): 

33 """Test BrightStarStamps. 

34 """ 

35 def setUp(self): 

36 np.random.seed(12) 

37 stampSize = (25, 25) 

38 # create dummy star stamps 

39 starImages = [afwImage.maskedImage.MaskedImageF(*stampSize) 

40 for _ in range(3)] 

41 for starIm in starImages: 

42 starImArray = starIm.image.array 

43 starImArray += np.random.rand(*stampSize) 

44 ids = ["111", "aaa", "bbb"] 

45 mags = np.random.rand(3) 

46 # faint object to test magnitude cuts 

47 self.faintObjIdx = 1 

48 mags[self.faintObjIdx] = 18. 

49 ids[self.faintObjIdx] = "faint" 

50 fluxes = np.random.rand(3) 

51 self.starStamps = [brightStarStamps.BrightStarStamp(stamp_im=starIm, 

52 gaiaGMag=mag, 

53 gaiaId=gaiaId, 

54 annularFlux=flux) 

55 for starIm, mag, gaiaId, flux in zip(starImages, mags, ids, fluxes)] 

56 self.unnormalizedStarStamps = [brightStarStamps.BrightStarStamp(stamp_im=starIm, 

57 gaiaGMag=mag, 

58 gaiaId=gaiaId) 

59 for starIm, mag, gaiaId, flux in zip(starImages, mags, ids, fluxes)] 

60 self.toBeNormalizedStarStamps = [brightStarStamps.BrightStarStamp(stamp_im=starIm, 

61 gaiaGMag=mag, 

62 gaiaId=gaiaId) 

63 for starIm, mag, gaiaId, flux in zip(starImages, mags, ids, fluxes)] 

64 self.innerRadius = 5 

65 self.outerRadius = 10 

66 self.bss = brightStarStamps.BrightStarStamps(self.starStamps, 

67 innerRadius=self.innerRadius, 

68 outerRadius=self.outerRadius) 

69 

70 def tearDown(self): 

71 del self.bss 

72 del self.starStamps 

73 del self.unnormalizedStarStamps 

74 del self.toBeNormalizedStarStamps 

75 del self.innerRadius 

76 del self.outerRadius 

77 del self.faintObjIdx 

78 

79 def testIO(self): 

80 """Test the class' write and readFits methods. 

81 

82 The ``options`` argument to the read method is only used to read 

83 sub-BBoxes, which is handled by the Butler. Tests of this are done in 

84 afw. 

85 """ 

86 with tempfile.NamedTemporaryFile() as f: 

87 self.bss.writeFits(f.name) 

88 options = PropertyList() 

89 bss2 = brightStarStamps.BrightStarStamps.readFitsWithOptions(f.name, options) 

90 self.assertEqual(len(self.bss), len(bss2)) 

91 for mi1, mi2 in zip(self.bss.getMaskedImages(), bss2.getMaskedImages()): 

92 self.assertMaskedImagesAlmostEqual(mi1, mi2) 

93 np.testing.assert_almost_equal(self.bss.getMagnitudes(), bss2.getMagnitudes()) 

94 np.testing.assert_almost_equal(self.bss.getAnnularFluxes(), bss2.getAnnularFluxes()) 

95 for id1, id2 in zip(self.bss.getGaiaIds(), bss2.getGaiaIds()): 

96 self.assertEqual(id1, id2) 

97 

98 def testMagnitudeSelection(self): 

99 brightOnly = self.bss.selectByMag(magMax=7) 

100 self.assertEqual(len(brightOnly), 2) 

101 self.assertFalse("faint" in brightOnly.getGaiaIds()) 

102 

103 faintOnly = self.bss.selectByMag(magMin=7) 

104 self.assertEqual(len(faintOnly), 1) 

105 self.assertEqual(faintOnly.getGaiaIds()[0], "faint") 

106 faintObj = self.bss[self.faintObjIdx] 

107 self.assertMaskedImagesAlmostEqual(faintObj.stamp_im, faintOnly.getMaskedImages()[0]) 

108 

109 def testTypeMismatchHandling(self): 

110 fullStar = self.bss[0] 

111 # try passing on a dictionary and a maskedImage instead of a 

112 # BrightStarStamp 

113 falseStar = {"starStamp": fullStar.stamp_im, "gaiaGMag": fullStar.gaiaGMag, 

114 "gaiaId": fullStar.gaiaId, "annularFlux": fullStar.annularFlux} 

115 starIm = fullStar.stamp_im 

116 for wrongType in [falseStar, starIm]: 

117 # test at initialization 

118 with self.assertRaises(ValueError): 

119 _ = brightStarStamps.BrightStarStamps([fullStar, wrongType], innerRadius=self.innerRadius, 

120 outerRadius=self.outerRadius) 

121 # test at appending time 

122 with self.assertRaises(ValueError): 

123 self.bss.append(wrongType, innerRadius=self.innerRadius, outerRadius=self.outerRadius) 

124 

125 def testAnnulusMismatch(self): 

126 """Test an exception is raised if mismatching annulus radii are 

127 given (as the annularFlux values would then be meaningless).""" 

128 # starStamps are already normalized; an Exception should be raised when 

129 # trying to pass them onto the initAndNormalize classmethod 

130 with self.assertRaises(AttributeError): 

131 _ = brightStarStamps.BrightStarStamps.initAndNormalize(self.starStamps, 

132 innerRadius=self.innerRadius, 

133 outerRadius=self.outerRadius) 

134 # unnormalizedStarStamps can be kept unnormalized provided no radii are 

135 # passed on as arguments 

136 bss2 = brightStarStamps.BrightStarStamps(self.unnormalizedStarStamps) 

137 with self.assertRaises(AttributeError): 

138 _ = brightStarStamps.BrightStarStamps(self.unnormalizedStarStamps, 

139 innerRadius=self.innerRadius, 

140 outerRadius=self.outerRadius) 

141 # or normalized at initialization, in which case radii must be passed 

142 # on 

143 bss3 = brightStarStamps.BrightStarStamps.initAndNormalize(self.toBeNormalizedStarStamps, 

144 innerRadius=self.innerRadius, 

145 outerRadius=self.outerRadius) 

146 # BrightStarStamps instances can be concatenated if the radii used are 

147 # the same 

148 self.bss.extend(bss3) 

149 # but an Exception should be raised when trying to concatenate a mix of 

150 # normalized and unnormalized stamps 

151 with self.assertRaises(AttributeError): 

152 self.bss.extend(bss2) 

153 # or stamps normalized with different annular radii 

154 bss4 = brightStarStamps.BrightStarStamps.initAndNormalize(self.unnormalizedStarStamps, 

155 innerRadius=int(self.innerRadius/2), 

156 outerRadius=self.outerRadius) 

157 with self.assertRaises(AttributeError): 

158 self.bss.extend(bss4) 

159 # or when appending an extra stamp with different annulus radii 

160 fullStar = self.bss[0] 

161 with self.assertRaises(AttributeError): 

162 self.bss.append(fullStar, innerRadius=int(self.innerRadius/2), outerRadius=self.outerRadius + 1) 

163 # or a normalized stamp to unnormalized BrightStarStamps, or vice-versa 

164 with self.assertRaises(AttributeError): 

165 bss2.append(fullStar, innerRadius=self.innerRadius, outerRadius=self.outerRadius) 

166 unNormFullStar = bss2[0] 

167 with self.assertRaises(AttributeError): 

168 self.bss.append(unNormFullStar) 

169 

170 

171class MemoryTester(lsst.utils.tests.MemoryTestCase): 

172 pass 

173 

174 

175def setup_module(module): 

176 lsst.utils.tests.init() 

177 

178 

179if __name__ == "__main__": 179 ↛ 180line 179 didn't jump to line 180, because the condition on line 179 was never true

180 lsst.utils.tests.init() 

181 unittest.main()