Coverage for tests/test_makeSurveyPropertyMaps.py: 21%

124 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-09-13 02:59 -0700

1# This file is part of pipe_tasks. 

2# 

3# LSST Data Management System 

4# This product includes software developed by the 

5# LSST Project (http://www.lsst.org/). 

6# See COPYRIGHT file at the top of the source tree. 

7# 

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

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

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

11# (at your option) any later version. 

12# 

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

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

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

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <https://www.lsstcorp.org/LegalNotices/>. 

21# 

22"""Test HealSparsePropertyMapTask. 

23""" 

24import unittest 

25import numpy as np 

26import healsparse as hsp 

27import esutil 

28 

29import lsst.utils.tests 

30import lsst.daf.butler 

31import lsst.afw.table as afwTable 

32import lsst.afw.geom as afwGeom 

33import lsst.afw.image as afwImage 

34from lsst.skymap.discreteSkyMap import DiscreteSkyMap 

35import lsst.geom as geom 

36 

37from lsst.pipe.tasks.healSparseMapping import HealSparsePropertyMapTask 

38from lsst.pipe.tasks.healSparseMappingProperties import (register_property_map, 

39 BasePropertyMap) 

40 

41from surveyPropertyMapsTestUtils import (makeMockVisitSummary, 

42 MockVisitSummaryReference, 

43 MockCoaddReference, 

44 MockInputMapReference) 

45 

46 

47# Test creation of an arbitrary new property map by registering it here 

48# and using it in the test class. 

49@register_property_map("dist_times_psfarea") 

50class DistTimesPsfAreaPropertyMap(BasePropertyMap): 

51 """Property map to compute the distance from the boresight center 

52 by the psf area. Do not try this at home.""" 

53 requires_psf = True 

54 

55 def _compute(self, row, ra, dec, scalings, psf_array=None): 

56 boresight = row.getVisitInfo().getBoresightRaDec() 

57 dist = esutil.coords.sphdist(ra, dec, 

58 boresight.getRa().asDegrees(), boresight.getDec().asDegrees()) 

59 return np.deg2rad(dist)*psf_array['psf_area'] 

60 

61 

62class HealSparsePropertyMapTaskTestCase(lsst.utils.tests.TestCase): 

63 """Test of HealSparsePropertyMapTask. 

64 

65 These tests bypass the middleware used for accessing data and 

66 managing Task execution. 

67 """ 

68 def setUp(self): 

69 tract = 0 

70 band = 'r' 

71 patch = 0 

72 visits = [100, 101] 

73 # Good to test crossing 0. 

74 ra_center = 0.0 

75 dec_center = -45.0 

76 pixel_scale = 0.2 

77 coadd_zp = 27.0 

78 

79 # Generate a mock skymap with one patch 

80 config = DiscreteSkyMap.ConfigClass() 

81 config.raList = [ra_center] 

82 config.decList = [dec_center] 

83 config.radiusList = [150*pixel_scale/3600.] 

84 config.patchInnerDimensions = (350, 350) 

85 config.patchBorder = 50 

86 config.tractOverlap = 0.0 

87 config.pixelScale = pixel_scale 

88 sky_map = DiscreteSkyMap(config) 

89 

90 visit_summaries = [makeMockVisitSummary(visit, 

91 ra_center=ra_center, 

92 dec_center=dec_center) 

93 for visit in visits] 

94 visit_summary_refs = [MockVisitSummaryReference(visit_summary, visit) 

95 for visit_summary, visit in zip(visit_summaries, visits)] 

96 self.visit_summary_dict = {visit: ref.get() 

97 for ref, visit in zip(visit_summary_refs, visits)} 

98 

99 # Generate an input map. Note that this does not need to be consistent 

100 # with the visit_summary projections, we're just tracking values. 

101 input_map = hsp.HealSparseMap.make_empty(nside_coverage=256, 

102 nside_sparse=32768, 

103 dtype=hsp.WIDE_MASK, 

104 wide_mask_maxbits=len(visits)*2) 

105 patch_poly = afwGeom.Polygon(geom.Box2D(sky_map[tract][patch].getOuterBBox())) 

106 sph_pts = sky_map[tract].getWcs().pixelToSky(patch_poly.convexHull().getVertices()) 

107 patch_poly_radec = np.array([(sph.getRa().asDegrees(), sph.getDec().asDegrees()) 

108 for sph in sph_pts]) 

109 poly = hsp.Polygon(ra=patch_poly_radec[: -1, 0], 

110 dec=patch_poly_radec[: -1, 1], 

111 value=[0]) 

112 poly_pixels = poly.get_pixels(nside=input_map.nside_sparse) 

113 # The input map has full coverage for bits 0 and 1 

114 input_map.set_bits_pix(poly_pixels, [0]) 

115 input_map.set_bits_pix(poly_pixels, [1]) 

116 

117 input_map_ref = MockInputMapReference(input_map, patch=patch, tract=tract) 

118 self.input_map_dict = {patch: input_map_ref} 

119 

120 coadd = afwImage.ExposureF(sky_map[tract][patch].getOuterBBox(), 

121 sky_map[tract].getWcs()) 

122 instFluxMag0 = 10.**(coadd_zp/2.5) 

123 pc = afwImage.makePhotoCalibFromCalibZeroPoint(instFluxMag0) 

124 coadd.setPhotoCalib(pc) 

125 

126 # Mock the coadd input ccd table 

127 schema = afwTable.ExposureTable.makeMinimalSchema() 

128 schema.addField("ccd", type="I") 

129 schema.addField("visit", type="I") 

130 schema.addField("weight", type="F") 

131 ccds = afwTable.ExposureCatalog(schema) 

132 ccds.resize(2) 

133 ccds['id'] = np.arange(2) 

134 ccds['visit'][0] = visits[0] 

135 ccds['visit'][1] = visits[1] 

136 ccds['ccd'][0] = 0 

137 ccds['ccd'][1] = 1 

138 ccds['weight'] = 10.0 

139 for ccd_row in ccds: 

140 summary = self.visit_summary_dict[ccd_row['visit']].find(ccd_row['ccd']) 

141 ccd_row.setWcs(summary.getWcs()) 

142 ccd_row.setPsf(summary.getPsf()) 

143 ccd_row.setBBox(summary.getBBox()) 

144 ccd_row.setPhotoCalib(summary.getPhotoCalib()) 

145 

146 inputs = afwImage.CoaddInputs() 

147 inputs.ccds = ccds 

148 coadd.getInfo().setCoaddInputs(inputs) 

149 

150 coadd_ref = MockCoaddReference(coadd, patch=patch, tract=tract) 

151 self.coadd_dict = {patch: coadd_ref} 

152 

153 self.tract = tract 

154 self.band = band 

155 self.sky_map = sky_map 

156 self.input_map = input_map 

157 

158 def testPropertyMapCreation(self): 

159 """Test creation of property maps.""" 

160 config = HealSparsePropertyMapTask.ConfigClass() 

161 

162 # Add our new test map to the set of maps 

163 config.property_maps.names |= ['dist_times_psfarea'] 

164 config.property_maps['dist_times_psfarea'].do_min = True 

165 config.property_maps['dist_times_psfarea'].do_max = True 

166 config.property_maps['dist_times_psfarea'].do_mean = True 

167 

168 property_task = HealSparsePropertyMapTask(config=config) 

169 

170 property_task.run(self.sky_map, 

171 self.tract, 

172 self.band, 

173 self.coadd_dict, 

174 self.input_map_dict, 

175 self.visit_summary_dict) 

176 

177 valid_pixels = self.input_map.valid_pixels 

178 

179 # Verify each map exists and has the correct pixels set. 

180 for name, map_config, PropertyMapClass in config.property_maps.apply(): 

181 self.assertTrue(name in property_task.property_maps) 

182 property_map = property_task.property_maps[name] 

183 if map_config.do_min: 

184 self.assertTrue(hasattr(property_map, 'min_map')) 

185 np.testing.assert_array_equal(property_map.min_map.valid_pixels, valid_pixels) 

186 else: 

187 self.assertFalse(hasattr(property_map, 'min_map')) 

188 if map_config.do_max: 

189 self.assertTrue(hasattr(property_map, 'max_map')) 

190 np.testing.assert_array_equal(property_map.max_map.valid_pixels, valid_pixels) 

191 else: 

192 self.assertFalse(hasattr(property_map, 'max_map')) 

193 if map_config.do_mean: 

194 self.assertTrue(hasattr(property_map, 'mean_map')) 

195 np.testing.assert_array_equal(property_map.mean_map.valid_pixels, valid_pixels) 

196 else: 

197 self.assertFalse(hasattr(property_map, 'mean_map')) 

198 if map_config.do_weighted_mean: 

199 self.assertTrue(hasattr(property_map, 'weighted_mean_map')) 

200 np.testing.assert_array_equal(property_map.weighted_mean_map.valid_pixels, valid_pixels) 

201 else: 

202 self.assertFalse(hasattr(property_map, 'weighted_mean_map')) 

203 if map_config.do_sum: 

204 self.assertTrue(hasattr(property_map, 'sum_map')) 

205 np.testing.assert_array_equal(property_map.sum_map.valid_pixels, valid_pixels) 

206 else: 

207 self.assertFalse(hasattr(property_map, 'sum_map')) 

208 

209 

210class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase): 

211 pass 

212 

213 

214def setup_module(module): 

215 lsst.utils.tests.init() 

216 

217 

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

219 lsst.utils.tests.init() 

220 unittest.main()