Coverage for tests/test_makeSurveyPropertyMaps.py: 21%
124 statements
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-24 02:36 -0700
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-24 02:36 -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
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
37from lsst.pipe.tasks.healSparseMapping import HealSparsePropertyMapTask
38from lsst.pipe.tasks.healSparseMappingProperties import (register_property_map,
39 BasePropertyMap)
41from surveyPropertyMapsTestUtils import (makeMockVisitSummary,
42 MockVisitSummaryReference,
43 MockCoaddReference,
44 MockInputMapReference)
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
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']
62class HealSparsePropertyMapTaskTestCase(lsst.utils.tests.TestCase):
63 """Test of HealSparsePropertyMapTask.
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
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)
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)}
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])
117 input_map_ref = MockInputMapReference(input_map, patch=patch, tract=tract)
118 self.input_map_dict = {patch: input_map_ref}
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)
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())
146 inputs = afwImage.CoaddInputs()
147 inputs.ccds = ccds
148 coadd.getInfo().setCoaddInputs(inputs)
150 coadd_ref = MockCoaddReference(coadd, patch=patch, tract=tract)
151 self.coadd_dict = {patch: coadd_ref}
153 self.tract = tract
154 self.band = band
155 self.sky_map = sky_map
156 self.input_map = input_map
158 def testPropertyMapCreation(self):
159 """Test creation of property maps."""
160 config = HealSparsePropertyMapTask.ConfigClass()
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
168 property_task = HealSparsePropertyMapTask(config=config)
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)
177 valid_pixels = self.input_map.valid_pixels
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'))
210class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase):
211 pass
214def setup_module(module):
215 lsst.utils.tests.init()
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()