Skip to content

Commit 8449ab8

Browse files
committed
Add unittests for model PSF ellipticity thresholds
1 parent 7396da9 commit 8449ab8

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

tests/test_calibrate.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,10 @@ class CalibrateTaskTestCaseNoButler(lsst.utils.tests.TestCase):
202202
def testNoAperCorrMap(self):
203203
expPath = os.path.join(TESTDIR, "data", "v695833-e0-c000-a00.sci.fits")
204204
exposure = lsst.afw.image.ExposureF(expPath)
205+
band = exposure.filter.bandLabel
205206

206207
charImConfig = CharacterizeImageConfig()
208+
charImConfig.maxUnNormPsfEllipticityPerBand[band] = 3.0
207209
charImConfig.measurePsf.psfDeterminer = 'piff'
208210
charImConfig.measurePsf.psfDeterminer['piff'].spatialOrder = 0
209211
charImConfig.measureApCorr.sourceSelector["science"].doSignalToNoise = False

tests/test_psfCandidateSelection.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def setUp(self):
3636
# Load sample input from disk
3737
expPath = os.path.join(TESTDIR, "data", "v695833-e0-c000-a00.sci.fits")
3838
self.exposure = afwImage.ExposureF(expPath)
39+
self.band = self.exposure.filter.bandLabel
3940

4041
def tearDown(self):
4142
del self.exposure
@@ -44,6 +45,7 @@ def testFlags(self):
4445
# Test that all of the flags are defined and there is no reservation by default
4546
# also test that used sources are a subset of candidate sources
4647
config = CharacterizeImageConfig()
48+
config.maxUnNormPsfEllipticityPerBand[self.band] = 3.0
4749
config.measurePsf.psfDeterminer = 'piff'
4850
config.measurePsf.psfDeterminer['piff'].spatialOrder = 0
4951
config.measureApCorr.sourceSelector["science"].doSignalToNoise = False

tests/test_unNormPsfEllipticity.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# This file is part of pipe_tasks.
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/>.
21+
22+
import os
23+
import unittest
24+
25+
import lsst.afw.image as afwImage
26+
import lsst.meas.extensions.piff.piffPsfDeterminer
27+
import lsst.pipe.base as pipeBase
28+
import lsst.utils.tests
29+
from lsst.pipe.tasks.characterizeImage import CharacterizeImageTask, CharacterizeImageConfig
30+
31+
TESTDIR = os.path.abspath(os.path.dirname(__file__))
32+
33+
34+
class UnNormPsfEllipticityTestCase(lsst.utils.tests.TestCase):
35+
36+
def setUp(self):
37+
# Load sample input from disk
38+
expPath = os.path.join(TESTDIR, "data", "v695833-e0-c000-a00.sci.fits")
39+
self.exposure = afwImage.ExposureF(expPath)
40+
self.band = self.exposure.filter.bandLabel
41+
42+
def tearDown(self):
43+
del self.exposure
44+
45+
def testUnNormPsfEllipticity(self):
46+
"""Tests that UnprocessableDataError is raised when the unnormalized
47+
PSF model ellipticity excedes config.maxUnNormPsfEllipticity.
48+
"""
49+
self._checkUnNormPsfEllipticity(allowPass=True)
50+
self._checkUnNormPsfEllipticity(allowPass=False)
51+
52+
def testUnNormPsfEllipticityFallback(self):
53+
"""Tests that the fallback value is set when band is missing from
54+
config.maxUnNormPsfEllipticityPerBand.
55+
"""
56+
charImConfig = CharacterizeImageConfig()
57+
charImConfig.measurePsf.psfDeterminer = 'piff'
58+
charImConfig.measurePsf.psfDeterminer['piff'].spatialOrder = 0
59+
charImConfig.measureApCorr.sourceSelector["science"].doSignalToNoise = False
60+
# Pop the band entry from the config dict to impose need for fallback.
61+
tempDict = charImConfig.maxUnNormPsfEllipticityPerBand
62+
tempDict.pop(self.band)
63+
charImConfig.maxUnNormPsfEllipticityPerBand = tempDict
64+
charImTask = CharacterizeImageTask(config=charImConfig)
65+
charImTask.run(self.exposure)
66+
with self.assertRaises(pipeBase.UnprocessableDataError):
67+
charImConfig.maxUnNormPsfEllipticityFallback = 0.0
68+
charImTask = CharacterizeImageTask(config=charImConfig)
69+
charImTask.run(self.exposure)
70+
71+
def _checkUnNormPsfEllipticity(self, allowPass):
72+
"""Check unnormalized model PSF ellipticity threshold functionality.
73+
74+
Parameters
75+
----------
76+
allowPass : `bool`
77+
Whether to update from the default config to allow this exporsure
78+
to pass the threshold check.
79+
"""
80+
charImConfig = CharacterizeImageConfig()
81+
charImConfig.measurePsf.psfDeterminer = 'piff'
82+
charImConfig.measurePsf.psfDeterminer['piff'].spatialOrder = 0
83+
charImConfig.measureApCorr.sourceSelector["science"].doSignalToNoise = False
84+
if not allowPass:
85+
charImConfig.maxUnNormPsfEllipticityPerBand[self.band] = 0.0
86+
charImTask = CharacterizeImageTask(config=charImConfig)
87+
if allowPass:
88+
charImTask.run(self.exposure)
89+
else:
90+
with self.assertRaises(pipeBase.UnprocessableDataError):
91+
charImTask.run(self.exposure)
92+
93+
94+
class MemoryTester(lsst.utils.tests.MemoryTestCase):
95+
pass
96+
97+
98+
def setup_module(module):
99+
lsst.utils.tests.init()
100+
101+
102+
if __name__ == "__main__":
103+
lsst.utils.tests.init()
104+
unittest.main()

0 commit comments

Comments
 (0)