Coverage for tests/test_NoiseReplacer.py: 45%
Shortcuts 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
Shortcuts 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_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
24import numpy as np
26import lsst.geom
27import lsst.afw.geom
28import lsst.afw.detection
29import lsst.afw.table
30import lsst.meas.base.tests
31import lsst.utils.tests
34@lsst.meas.base.register("test_NoiseReplacer")
35class NoiseReplacerTestPlugin(lsst.meas.base.SingleFramePlugin):
36 """Plugin that sums instFlux inside and outside the source footprint.
37 """
39 @staticmethod
40 def getExecutionOrder():
41 return 2.0
43 def __init__(self, config, name, schema, metadata):
44 lsst.meas.base.SingleFramePlugin.__init__(self, config, name, schema, metadata)
45 self.insideKey = schema.addField("%s_inside" % (name,), type=np.float64,
46 doc="instFlux inside footprint")
47 self.outsideKey = schema.addField("%s_outside" % (name,), type=np.float64,
48 doc="instFlux outside footprint")
50 def measure(self, measRecord, exposure):
51 footprint = measRecord.getFootprint()
52 fullArray = exposure.getMaskedImage().getImage().getArray()
53 insideArray = np.zeros(footprint.getArea(), dtype=fullArray.dtype)
54 footprint.spans.flatten(insideArray, fullArray, exposure.getXY0())
55 insideFlux = float(insideArray.sum())
56 outsideFlux = float(fullArray.sum()) - insideFlux
57 measRecord.set(self.insideKey, insideFlux)
58 measRecord.set(self.outsideKey, outsideFlux)
61class NoiseReplacerTestCase(lsst.meas.base.tests.AlgorithmTestCase, lsst.utils.tests.TestCase):
63 def setUp(self):
64 self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(-20, -30),
65 lsst.geom.Extent2I(240, 260))
66 self.dataset = lsst.meas.base.tests.TestDataset(self.bbox)
67 # first source is a point
68 self.dataset.addSource(100000.0, lsst.geom.Point2D(50.1, 49.8))
69 # second source is extended
70 self.dataset.addSource(120000.0, lsst.geom.Point2D(149.9, 50.3),
71 lsst.afw.geom.Quadrupole(8, 9, 3))
72 with self.dataset.addBlend() as family:
73 family.addChild(110000.0, lsst.geom.Point2D(65.2, 150.7),
74 lsst.afw.geom.Quadrupole(7, 5, -1))
75 family.addChild(140000.0, lsst.geom.Point2D(72.3, 149.1))
76 family.addChild(90000.0, lsst.geom.Point2D(68.5, 156.9))
78 def testSingleFrameMeasurement(self):
79 """Test noise replacement in single frame measurement.
81 We compare the instFlux inside and outside source Footprints on an
82 extremely high S/N image.
83 """
85 # We choose a random seed which causes the test to pass.
86 task = self.makeSingleFrameMeasurementTask("test_NoiseReplacer")
87 exposure, catalog = self.dataset.realize(1.0, task.schema, randomSeed=0)
88 task.run(catalog, exposure)
89 sumVariance = exposure.getMaskedImage().getVariance().getArray().sum()
90 for record in catalog:
91 self.assertFloatsAlmostEqual(record.get("test_NoiseReplacer_inside"),
92 record.get("truth_instFlux"), rtol=1E-3)
94 # N.B. Next line checks that a random value is correct to a
95 # statistical 1-sigma prediction; some RNG seeds may cause it to
96 # fail (indeed, 67% should)
97 self.assertLess(record.get("test_NoiseReplacer_outside"), np.sqrt(sumVariance))
99 def tearDown(self):
100 del self.bbox
101 del self.dataset
104class TestMemory(lsst.utils.tests.MemoryTestCase):
105 pass
108def setup_module(module):
109 lsst.utils.tests.init()
112if __name__ == "__main__": 112 ↛ 113line 112 didn't jump to line 113, because the condition on line 112 was never true
113 lsst.utils.tests.init()
114 unittest.main()