Coverage for tests/test_diaForcedSource.py : 17%

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 ap_association.
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/>.
22import numpy as np
23import unittest
24import unittest.mock
26from lsst.afw.cameraGeom.testUtils import DetectorWrapper
27import lsst.afw.geom as afwGeom
28import lsst.afw.image as afwImage
29import lsst.afw.image.utils as afwImageUtils
30import lsst.afw.table as afwTable
31import lsst.daf.base as dafBase
32import lsst.meas.algorithms as measAlg
33from lsst.ap.association import \
34 DiaForcedSourceTask, \
35 make_dia_object_schema
36import lsst.utils.tests
39def create_test_dia_objects(n_points, wcs, startPos=100):
40 """Create dummy DIASources or DIAObjects for use in our tests.
41 Parameters
42 ----------
43 n_points : `int`
44 Number of DiaObject test points to create.
45 wcs : `lsst.afw.geom.SkyWcs`
46 Wcs to convert RA/Dec to pixel x/y.
47 startPos : `int`
48 Start position to iterate from when creating test DiaObjects
50 Returns
51 -------
52 test_points : `lsst.afw.table.SourceCatalog`
53 Catalog of points to test.
54 """
55 objects = afwTable.SourceCatalog(make_dia_object_schema())
57 for src_idx in range(n_points):
58 src = objects.addNew()
59 src['id'] = src_idx
60 src.setCoord(wcs.pixelToSky(startPos + src_idx,
61 startPos + src_idx))
63 # Add points outside of the CCD.
64 # Fully outside.
65 src = objects.addNew()
66 src['id'] = 10000000
67 src.setCoord(wcs.pixelToSky(-100000,
68 -100000))
69 # y outside
70 src = objects.addNew()
71 src['id'] = 10000001
72 src.setCoord(wcs.pixelToSky(100,
73 -100000))
74 # x outside
75 src = objects.addNew()
76 src['id'] = 10000001
77 src.setCoord(wcs.pixelToSky(-100000,
78 100))
80 return objects
83class TestDiaForcedSource(unittest.TestCase):
85 def setUp(self):
86 # CFHT Filters from the camera mapper.
87 self.filter_names = ["u", "g", "r", "i", "z"]
88 afwImageUtils.resetFilters()
89 afwImageUtils.defineFilter('u', lambdaEff=374, alias="u.MP9301")
90 afwImageUtils.defineFilter('g', lambdaEff=487, alias="g.MP9401")
91 afwImageUtils.defineFilter('r', lambdaEff=628, alias="r.MP9601")
92 afwImageUtils.defineFilter('i', lambdaEff=778, alias="i.MP9701")
93 afwImageUtils.defineFilter('z', lambdaEff=1170, alias="z.MP9801")
95 # metadata taken from CFHT data
96 # v695856-e0/v695856-e0-c000-a00.sci_img.fits
97 self.metadata = dafBase.PropertySet()
99 self.metadata.set("SIMPLE", "T")
100 self.metadata.set("BITPIX", -32)
101 self.metadata.set("NAXIS", 2)
102 self.metadata.set("NAXIS1", 1024)
103 self.metadata.set("NAXIS2", 1153)
104 self.metadata.set("RADECSYS", 'FK5')
105 self.metadata.set("EQUINOX", 2000.)
107 self.metadata.setDouble("CRVAL1", 215.604025685476)
108 self.metadata.setDouble("CRVAL2", 53.1595451514076)
109 self.metadata.setDouble("CRPIX1", 1109.99981456774)
110 self.metadata.setDouble("CRPIX2", 560.018167811613)
111 self.metadata.set("CTYPE1", 'RA---SIN')
112 self.metadata.set("CTYPE2", 'DEC--SIN')
114 self.metadata.setDouble("CD1_1", 5.10808596133527E-05)
115 self.metadata.setDouble("CD1_2", 1.85579539217196E-07)
116 self.metadata.setDouble("CD2_2", -5.10281493481982E-05)
117 self.metadata.setDouble("CD2_1", -8.27440751733828E-07)
119 self.wcs = afwGeom.makeSkyWcs(self.metadata)
121 self.calibration = 10000
122 self.calibrationErr = 100
123 self.exposureId = 1234
124 self.exposureTime = 200.
125 self.imageSize = [1024, 1153]
126 self.dateTime = "2014-05-13T17:00:00.000000000"
128 # Make images with one source in them and distinct values and
129 # variance for each image.
130 # Direct Image
131 source_image = afwImage.MaskedImageF(
132 lsst.geom.ExtentI(self.imageSize[0] + 1, self.imageSize[1] + 1))
133 source_image.image[100, 100, afwImage.LOCAL] = 10
134 source_image.getVariance().set(1)
135 bbox = lsst.geom.BoxI(
136 lsst.geom.PointI(1, 1),
137 lsst.geom.ExtentI(self.imageSize[0],
138 self.imageSize[1]))
139 masked_image = afwImage.MaskedImageF(source_image, bbox, afwImage.LOCAL)
140 self.exposure = afwImage.makeExposure(masked_image, self.wcs)
142 detector = DetectorWrapper(
143 id=23, bbox=self.exposure.getBBox()).detector
144 visit = afwImage.VisitInfo(
145 exposureId=self.exposureId,
146 exposureTime=self.exposureTime,
147 date=dafBase.DateTime(self.dateTime,
148 dafBase.DateTime.Timescale.TAI))
149 self.exposure.setDetector(detector)
150 self.exposure.getInfo().setVisitInfo(visit)
151 self.exposure.setFilter(afwImage.Filter('g'))
152 self.exposure.setPhotoCalib(afwImage.PhotoCalib(self.calibration, self.calibrationErr))
154 # Difference Image
155 source_image = afwImage.MaskedImageF(
156 lsst.geom.ExtentI(self.imageSize[0] + 1, self.imageSize[1] + 1))
157 source_image.image[100, 100, afwImage.LOCAL] = 20
158 source_image.getVariance().set(2)
159 bbox = lsst.geom.BoxI(
160 lsst.geom.PointI(1, 1),
161 lsst.geom.ExtentI(self.imageSize[0],
162 self.imageSize[1]))
163 masked_image = afwImage.MaskedImageF(source_image, bbox, afwImage.LOCAL)
164 self.diffim = afwImage.makeExposure(masked_image, self.wcs)
165 self.diffim.setDetector(detector)
166 self.diffim.getInfo().setVisitInfo(visit)
167 self.diffim.setFilter(afwImage.Filter('g'))
168 self.diffim.setPhotoCalib(afwImage.PhotoCalib(self.calibration, self.calibrationErr))
170 self.expIdBits = 16
172 FWHM = 5
173 psf = measAlg.DoubleGaussianPsf(15, 15, FWHM/(2*np.sqrt(2*np.log(2))))
174 self.exposure.setPsf(psf)
175 self.diffim.setPsf(psf)
177 self.testDiaObjects = create_test_dia_objects(5, self.wcs)
178 self.expected_n_columns = 11
180 def testRun(self):
181 """Test that forced source catalogs are successfully created and have
182 sensible values.
183 """
184 test_objects = self._convert_to_pandas(self.testDiaObjects)
186 dfs = DiaForcedSourceTask()
187 dia_forced_sources = dfs.run(
188 test_objects, self.expIdBits, self.exposure, self.diffim)
190 direct_values = [199854.48417094944, 160097.40719241602,
191 82299.17897267535, 27148.604434624354,
192 5746.988388215507]
193 direct_var = [75240.939811168, 75231.42933749466,
194 75218.89495113207, 75214.88248249644,
195 75214.41447602339]
196 diff_values = [399708.9683418989, 320194.81438483205,
197 164598.3579453507, 54297.20886924871,
198 11493.976776431015]
199 diff_var = [106444.28782374493, 106417.39592887461,
200 106381.94840437356, 106370.59980584883,
201 106369.27608815048]
203 # Should be number of test objects minus one as one object is purposely
204 # outside of the ccd area.
205 self.assertEqual(len(dia_forced_sources), len(self.testDiaObjects) - 3)
206 self.assertEqual(len(dia_forced_sources.columns),
207 self.expected_n_columns)
209 for (diaFS_id, diaFS), testObj, dirVal, diffVal, dirVar, diffVar in zip(dia_forced_sources.iterrows(),
210 self.testDiaObjects,
211 direct_values,
212 diff_values,
213 direct_var,
214 diff_var):
215 self.assertAlmostEqual(diaFS["psFlux"] / diffVal, 1.)
216 self.assertAlmostEqual(diaFS["psFluxErr"] / diffVar, 1.)
218 self.assertAlmostEqual(diaFS["totFlux"] / dirVal, 1.)
219 self.assertAlmostEqual(diaFS["totFluxErr"] / dirVar, 1.)
221 self.assertEqual(diaFS["ccdVisitId"], self.exposureId)
223 def _convert_to_pandas(self, dia_objects):
224 """Convert input afw table to pandas.
226 Parameters
227 ----------
228 dia_objects : `lsst.afw.table.SourceCatalog`
229 Catalog to convert
231 Returns
232 -------
233 output_catalog : `pandas.DataFrame`
234 Converted catalog
235 """
236 output_catalog = dia_objects.asAstropy().to_pandas()
237 output_catalog.rename(columns={"id": "diaObjectId",
238 "coord_ra": "ra",
239 "coord_dec": "decl"},
240 inplace=True)
242 output_catalog.loc[:, "ra"] = np.degrees(output_catalog["ra"])
243 output_catalog.loc[:, "decl"] = np.degrees(output_catalog["decl"])
245 return output_catalog
248class MemoryTester(lsst.utils.tests.MemoryTestCase):
249 pass
252def setup_module(module):
253 lsst.utils.tests.init()
256if __name__ == "__main__": 256 ↛ 257line 256 didn't jump to line 257, because the condition on line 256 was never true
257 lsst.utils.tests.init()
258 unittest.main()