Coverage for tests/test_repair.py: 94%

50 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-21 09:22 +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/>. 

21 

22"""Tests for RepairTask cosmic ray finding.""" 

23import unittest 

24 

25import numpy as np 

26 

27import lsst.afw.detection as afwDet 

28import lsst.afw.image as afwImage 

29import lsst.geom 

30import lsst.utils.tests 

31from lsst.pipe.tasks.repair import RepairTask 

32 

33 

34class RepairTaskTestCase(lsst.utils.tests.TestCase): 

35 """Test RepairTask.cosmicRay with and without a local background model.""" 

36 

37 def setUp(self): 

38 self.sky = 100.0 

39 self.gain = 2.0 

40 self.crValue = 5000.0 

41 self.crPosition = (40, 60) # x, y 

42 rng = np.random.default_rng(12345) 

43 size = 200 

44 exposure = afwImage.ExposureF(lsst.geom.Box2I(lsst.geom.Point2I(0, 0), 

45 lsst.geom.Extent2I(size, size))) 

46 image = exposure.image.array 

47 image[:] = rng.normal(self.sky, np.sqrt(self.sky/self.gain), size=(size, size)) 

48 x, y = self.crPosition 

49 image[y, x] = self.crValue 

50 exposure.variance.array[:] = image/self.gain 

51 exposure.setPsf(afwDet.GaussianPsf(11, 11, 1.5)) 

52 self.exposure = exposure 

53 self.originalMedian = np.median(image) 

54 

55 def _checkRepaired(self, exposure): 

56 x, y = self.crPosition 

57 crBit = exposure.mask.getPlaneBitMask("CR") 

58 self.assertEqual(exposure.mask.array[y, x] & crBit, crBit) 

59 self.assertLess(exposure.image.array[y, x], 10*np.sqrt(self.sky/self.gain) + self.sky) 

60 # The background must not be changed by the repair. 

61 self.assertFloatsAlmostEqual(np.median(exposure.image.array), self.originalMedian, rtol=0.02) 

62 

63 def testConstantBackground(self): 

64 """With the default binSize (larger than the image) a single median 

65 background is used.""" 

66 config = RepairTask.ConfigClass() 

67 config.doInterpolate = False 

68 task = RepairTask(config=config) 

69 task.run(self.exposure) 

70 self._checkRepaired(self.exposure) 

71 

72 def testLocalBackground(self): 

73 """With binSize smaller than the image a background model is 

74 subtracted before finding cosmic rays and added back afterwards.""" 

75 config = RepairTask.ConfigClass() 

76 config.doInterpolate = False 

77 config.cosmicray.background.binSize = 64 

78 task = RepairTask(config=config) 

79 task.run(self.exposure) 

80 self._checkRepaired(self.exposure) 

81 

82 

83class MemoryTester(lsst.utils.tests.MemoryTestCase): 

84 pass 

85 

86 

87def setup_module(module): 

88 lsst.utils.tests.init() 

89 

90 

91if __name__ == "__main__": 91 ↛ 92line 91 didn't jump to line 92 because the condition on line 91 was never true

92 lsst.utils.tests.init() 

93 unittest.main()