Coverage for tests/test_ScaledApertureFlux.py: 38%
74 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-01 01:35 -0700
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-01 01:35 -0700
1# This file is part of meas_base.
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 unittest
23import math
25import lsst.geom
26import lsst.afw.image
27import lsst.afw.table
28from lsst.meas.base.tests import (AlgorithmTestCase, FluxTransformTestCase,
29 SingleFramePluginTransformSetupHelper)
30import lsst.utils.tests
33class ScaledApertureFluxTestCase(AlgorithmTestCase, lsst.utils.tests.TestCase):
35 def setUp(self):
36 self.center = lsst.geom.Point2D(50.1, 49.8)
37 self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
38 lsst.geom.Extent2I(100, 100))
39 self.dataset = lsst.meas.base.tests.TestDataset(self.bbox)
40 self.sourceFlux = 100000.0
41 self.dataset.addSource(self.sourceFlux, self.center)
43 def tearDown(self):
44 del self.center
45 del self.bbox
46 del self.dataset
48 def makeAlgorithm(self, ctrl=None):
49 """Construct an and return both it and its schema.
50 """
51 if ctrl is None:
52 ctrl = lsst.meas.base.ScaledApertureFluxControl()
53 schema = lsst.meas.base.tests.TestDataset.makeMinimalSchema()
54 algorithm = lsst.meas.base.ScaledApertureFluxAlgorithm(ctrl, "base_ScaledApertureFlux", schema)
55 return algorithm, schema
57 def testSourceFlux(self):
58 """Check that we recover the source instFlux.
59 """
60 ctrl = lsst.meas.base.ScaledApertureFluxControl()
61 algorithm, schema = self.makeAlgorithm(ctrl)
62 exposure, catalog = self.dataset.realize(10.0, schema, randomSeed=0)
64 # Default aperture should collect ~all source instFlux.
65 algorithm.measure(catalog[0], exposure)
66 self.assertAlmostEqual(catalog[0].get("base_ScaledApertureFlux_instFlux") / self.sourceFlux, 1.0, 2)
67 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag"))
68 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag_apertureTruncated"))
69 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag_sincCoeffsTruncated"))
71 # Aperture equal to the PSF FWHM should collect ~93.7% of the
72 # instFlux.
73 ctrl.scale = 1.0
74 algorithm, schema = self.makeAlgorithm(ctrl)
75 algorithm.measure(catalog[0], exposure)
76 self.assertAlmostEqual(catalog[0].get("base_ScaledApertureFlux_instFlux") / self.sourceFlux,
77 0.9375, 2)
78 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag"))
79 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag_apertureTruncated"))
80 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag_sincCoeffsTruncated"))
82 def testApertureTruncated(self):
83 """Check that a flag is set when the aperture overflows the image.
85 Notes
86 -----
87 This is a fatal failure: we do not return a useful result, but rather
88 set the global flag.
89 """
90 ctrl = lsst.meas.base.ScaledApertureFluxControl()
91 ctrl.scale = 100
92 algorithm, schema = self.makeAlgorithm(ctrl)
93 exposure, catalog = self.dataset.realize(10.0, schema, randomSeed=1)
95 algorithm.measure(catalog[0], exposure)
96 self.assertTrue(math.isnan(catalog[0].get("base_ScaledApertureFlux_instFlux")))
97 self.assertTrue(catalog[0].get("base_ScaledApertureFlux_flag"))
98 self.assertTrue(catalog[0].get("base_ScaledApertureFlux_flag_apertureTruncated"))
99 self.assertTrue(catalog[0].get("base_ScaledApertureFlux_flag_sincCoeffsTruncated"))
101 def testSincCoeffsTruncated(self):
102 """Check that a flag is set when the coefficient image is clipped.
104 Notes
105 -----
106 This is not regarded as a fatal failure, so the global flag is not set
107 and we still provide a numeric result.
108 """
109 ctrl = lsst.meas.base.ScaledApertureFluxControl()
110 ctrl.scale = 10
111 algorithm, schema = self.makeAlgorithm(ctrl)
112 exposure, catalog = self.dataset.realize(10.0, schema, randomSeed=2)
114 algorithm.measure(catalog[0], exposure)
115 self.assertFalse(math.isnan(catalog[0].get("base_ScaledApertureFlux_instFlux")))
116 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag"))
117 self.assertFalse(catalog[0].get("base_ScaledApertureFlux_flag_apertureTruncated"))
118 self.assertTrue(catalog[0].get("base_ScaledApertureFlux_flag_sincCoeffsTruncated"))
121class ScaledApertureFluxTransformTestCase(FluxTransformTestCase,
122 SingleFramePluginTransformSetupHelper,
123 lsst.utils.tests.TestCase):
124 controlClass = lsst.meas.base.ScaledApertureFluxControl
125 algorithmClass = lsst.meas.base.ScaledApertureFluxAlgorithm
126 transformClass = lsst.meas.base.ScaledApertureFluxTransform
127 flagNames = ('flag', 'flag_apertureTruncated', 'flag_sincCoeffsTruncated')
128 singleFramePlugins = ('base_ScaledApertureFlux',)
129 forcedPlugins = ('base_ScaledApertureFlux',)
132class TestMemory(lsst.utils.tests.MemoryTestCase):
133 pass
136def setup_module(module):
137 lsst.utils.tests.init()
140if __name__ == "__main__": 140 ↛ 141line 140 didn't jump to line 141, because the condition on line 140 was never true
141 lsst.utils.tests.init()
142 unittest.main()