Coverage for tests/test_maskStreaks.py: 17%
80 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-12-01 21:12 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2022-12-01 21:12 +0000
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/>.
22import unittest
23import numpy as np
25import lsst.utils.tests
26import lsst.afw.image
27import lsst.afw.math
28from lsst.pipe.tasks.maskStreaks import MaskStreaksTask, LineProfile, Line, setDetectionMask
31class TestMaskStreaks(lsst.utils.tests.TestCase):
33 def setUp(self):
34 self.config = MaskStreaksTask.ConfigClass()
35 self.config.dChi2Tolerance = 1e-6
36 self.fst = MaskStreaksTask(config=self.config)
38 self.testx = 500
39 self.testy = 600
40 self.exposure = lsst.afw.image.ExposureF(self.testy, self.testx)
41 rand = lsst.afw.math.Random()
42 lsst.afw.math.randomGaussianImage(self.exposure.image, rand)
43 self.exposure.maskedImage.variance.set(1)
44 self.maskName = "STREAK"
45 self.detectedPlane = "DETECTED"
47 def test_binning(self):
48 """Test the two binning methods and the no-binning method"""
50 binSize = 4
51 self.assertEqual(self.testx % binSize, 0)
52 self.assertEqual(self.testy % binSize, 0)
54 testExposure1 = self.exposure.clone()
55 setDetectionMask(testExposure1, binning=binSize, detectedPlane=self.detectedPlane)
56 mask1 = testExposure1.getMask()
57 reshapeBinning = mask1.array & mask1.getPlaneBitMask(self.detectedPlane)
58 testExposure2 = self.exposure.clone()
59 with self.assertWarns(Warning):
60 setDetectionMask(testExposure2, binning=binSize, forceSlowBin=True)
61 mask2 = testExposure2.getMask()
62 scipyBinning = mask2.array & mask2.getPlaneBitMask(self.detectedPlane)
63 self.assertAlmostEqual(reshapeBinning.tolist(), scipyBinning.tolist())
65 def test_canny(self):
66 """Test that Canny filter returns binary of equal shape"""
68 zeroExposure = lsst.afw.image.ExposureF(self.testy, self.testx)
69 cannyZeroExposure = self.fst._cannyFilter(zeroExposure.image.array)
70 self.assertEqual(cannyZeroExposure.tolist(), zeroExposure.image.array.tolist())
72 exposure = self.exposure.clone()
73 setDetectionMask(exposure, detectedPlane=self.detectedPlane)
74 mask = exposure.getMask()
75 processedImage = mask.array & mask.getPlaneBitMask(self.detectedPlane)
76 cannyNonZero = self.fst._cannyFilter(processedImage)
77 self.assertEqual(cannyNonZero.tolist(), cannyNonZero.astype(bool).tolist())
79 def test_runkht(self):
80 """Test the whole thing"""
82 # Empty image:
83 zeroArray = np.zeros((self.testx, self.testy))
84 zeroLines = self.fst._runKHT(zeroArray)
85 self.assertEqual(len(zeroLines), 0)
86 testExposure = self.exposure.clone()
87 result = self.fst.run(testExposure)
88 self.assertEqual(len(result.lines), 0)
89 resultMask = testExposure.mask.array & testExposure.mask.getPlaneBitMask(self.maskName)
90 self.assertEqual(resultMask.tolist(), zeroArray.tolist())
92 # Make image with line and check that input line is recovered:
93 testExposure1 = self.exposure.clone()
94 inputRho = 150
95 inputTheta = 45
96 inputSigma = 3
97 testLine = Line(inputRho, inputTheta, inputSigma)
98 lineProfile = LineProfile(testExposure.image.array, testExposure.variance.array**-1,
99 line=testLine)
100 testData = lineProfile.makeProfile(testLine, fitFlux=False)
101 testExposure1.image.array = testData * 100
102 detectedInd = abs(testData) > 0.1 * (abs(testData)).max()
104 testExposure1.mask.addMaskPlane(self.detectedPlane)
105 testExposure1.mask.array[detectedInd] |= testExposure1.mask.getPlaneBitMask(self.detectedPlane)
106 testExposure2 = testExposure1.clone()
107 setDetectionMask(testExposure2, detectedPlane=self.detectedPlane)
109 result_withSetDetMask = self.fst.run(testExposure2)
110 self.assertEqual(len(result_withSetDetMask.lines), 1)
111 self.assertAlmostEqual(inputRho, result_withSetDetMask.lines[0].rho, places=2)
112 self.assertAlmostEqual(inputTheta, result_withSetDetMask.lines[0].theta, places=2)
113 self.assertAlmostEqual(inputSigma, result_withSetDetMask.lines[0].sigma, places=2)
115 result = self.fst.run(testExposure1)
116 self.assertEqual(len(result.lines), 1)
117 self.assertAlmostEqual(inputRho, result.lines[0].rho, places=2)
118 self.assertAlmostEqual(inputTheta, result.lines[0].theta, places=2)
119 self.assertAlmostEqual(inputSigma, result.lines[0].sigma, places=2)
122def setup_module(module):
123 lsst.utils.tests.init()
126if __name__ == "__main__": 126 ↛ 127line 126 didn't jump to line 127, because the condition on line 126 was never true
127 lsst.utils.tests.init()
128 unittest.main()